blob: 752d3908c4ee68ad28ecb14dd427804408409337 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
Biswarup Pal6152a302023-12-19 12:44:09 +00002 * Copyright 2023 The Android Open Source Project
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010017#include <algorithm>
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020018#include <cstdint>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010019#include <cstdio>
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010020#include <iterator>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010021#include <memory>
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010022#include <regex>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010023
24#include "VirtualCameraService.h"
25#include "aidl/android/companion/virtualcamera/BnVirtualCameraCallback.h"
26#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
27#include "aidl/android/hardware/camera/provider/BnCameraProviderCallback.h"
28#include "aidl/android/hardware/graphics/common/PixelFormat.h"
29#include "android/binder_auto_utils.h"
30#include "android/binder_interface_utils.h"
31#include "android/binder_libbinder.h"
32#include "android/binder_status.h"
33#include "binder/Binder.h"
34#include "gmock/gmock.h"
35#include "gtest/gtest.h"
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010036#include "util/MetadataUtil.h"
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010037#include "util/Permissions.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010038#include "utils/Errors.h"
39
40namespace android {
41namespace companion {
42namespace virtualcamera {
43namespace {
44
45using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010046using ::aidl::android::companion::virtualcamera::Format;
Biswarup Pal112458f2023-12-28 19:50:17 +000047using ::aidl::android::companion::virtualcamera::LensFacing;
Biswarup Pal6152a302023-12-19 12:44:09 +000048using ::aidl::android::companion::virtualcamera::SensorOrientation;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010049using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
50using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
51using ::aidl::android::hardware::camera::common::TorchModeStatus;
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010052using ::aidl::android::hardware::camera::device::CameraMetadata;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010053using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
54using ::aidl::android::hardware::graphics::common::PixelFormat;
55using ::aidl::android::view::Surface;
56using ::testing::_;
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010057using ::testing::ElementsAre;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010058using ::testing::Eq;
59using ::testing::Ge;
60using ::testing::IsEmpty;
61using ::testing::IsNull;
62using ::testing::Not;
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010063using ::testing::Optional;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010064using ::testing::Return;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010065using ::testing::SizeIs;
66
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010067constexpr int kVgaWidth = 640;
68constexpr int kVgaHeight = 480;
Biswarup Pal6152a302023-12-19 12:44:09 +000069constexpr int kMaxFps = 30;
Biswarup Pal112458f2023-12-28 19:50:17 +000070constexpr SensorOrientation kSensorOrientation =
71 SensorOrientation::ORIENTATION_0;
72constexpr LensFacing kLensFacing = LensFacing::FRONT;
Biswarup Pal37a75182024-01-16 15:53:35 +000073constexpr int kDefaultDeviceId = 0;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010074constexpr char kCreateVirtualDevicePermissions[] =
75 "android.permission.CREATE_VIRTUAL_DEVICE";
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010076
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010077const VirtualCameraConfiguration kEmptyVirtualCameraConfiguration;
78
Jan Sebechlebsky288900f2024-05-24 14:47:54 +020079class MockVirtualCameraCallback : public BnVirtualCameraCallback {
80 public:
81 MOCK_METHOD(ndk::ScopedAStatus, onStreamConfigured,
82 (int32_t, const ::aidl::android::view::Surface&, int, int,
83 ::aidl::android::companion::virtualcamera::Format pixelFormat),
84 (override));
85 MOCK_METHOD(ndk::ScopedAStatus, onProcessCaptureRequest, (int32_t, int32_t),
86 (override));
87 MOCK_METHOD(ndk::ScopedAStatus, onStreamClosed, (int32_t), (override));
88};
89
Biswarup Pal112458f2023-12-28 19:50:17 +000090VirtualCameraConfiguration createConfiguration(const int width, const int height,
91 const Format format,
92 const int maxFps) {
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010093 VirtualCameraConfiguration configuration;
Biswarup Pal6152a302023-12-19 12:44:09 +000094 configuration.supportedStreamConfigs.push_back({.width = width,
95 .height = height,
96 .pixelFormat = format,
97 .maxFps = maxFps});
Biswarup Pal112458f2023-12-28 19:50:17 +000098 configuration.sensorOrientation = kSensorOrientation;
99 configuration.lensFacing = kLensFacing;
Jan Sebechlebsky288900f2024-05-24 14:47:54 +0200100 configuration.virtualCameraCallback =
101 ndk::SharedRefBase::make<MockVirtualCameraCallback>();
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100102 return configuration;
103}
104
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100105class MockCameraProviderCallback : public BnCameraProviderCallback {
106 public:
107 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
108 (const std::string&, CameraDeviceStatus), (override));
109 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
110 (const std::string&, TorchModeStatus), (override));
111 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
112 (const std::string&, const std::string&, CameraDeviceStatus),
113 (override));
114};
115
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100116class MockPermissionsProxy : public PermissionsProxy {
117 public:
118 MOCK_METHOD(bool, checkCallingPermission, (const std::string&),
119 (const override));
120};
121
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100122class VirtualCameraServiceTest : public ::testing::Test {
123 public:
124 void SetUp() override {
125 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
126 mMockCameraProviderCallback =
127 ndk::SharedRefBase::make<MockCameraProviderCallback>();
128 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
129 .WillByDefault([](const std::string&, CameraDeviceStatus) {
130 return ndk::ScopedAStatus::ok();
131 });
132 mCameraProvider->setCallback(mMockCameraProviderCallback);
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100133 mCameraService = ndk::SharedRefBase::make<VirtualCameraService>(
134 mCameraProvider, mMockPermissionsProxy);
Jan Sebechlebskyb36090e2024-04-11 09:19:33 +0200135 mCameraService->disableEglVerificationForTest();
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100136
137 ON_CALL(mMockPermissionsProxy, checkCallingPermission)
138 .WillByDefault(Return(true));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100139
140 mDevNullFd = open("/dev/null", O_RDWR);
141 ASSERT_THAT(mDevNullFd, Ge(0));
142 }
143
144 void createCamera() {
145 mOwnerToken = sp<BBinder>::make();
146 mNdkOwnerToken.set(AIBinder_fromPlatformBinder(mOwnerToken));
147 bool aidlRet;
148
149 ASSERT_TRUE(mCameraService
Biswarup Pal37a75182024-01-16 15:53:35 +0000150 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
151 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100152 .isOk());
153 ASSERT_TRUE(aidlRet);
154 }
155
156 void TearDown() override {
157 close(mDevNullFd);
158 }
159
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100160 binder_status_t execute_shell_command(const std::string& cmd) {
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100161 const static std::regex whitespaceRegex("\\s+");
162 std::vector<std::string> tokens;
163 std::copy_if(
164 std::sregex_token_iterator(cmd.begin(), cmd.end(), whitespaceRegex, -1),
165 std::sregex_token_iterator(), std::back_inserter(tokens),
166 [](const std::string& token) { return !token.empty(); });
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100167
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100168 std::vector<const char*> argv;
169 argv.reserve(tokens.size());
170 std::transform(tokens.begin(), tokens.end(), std::back_inserter(argv),
171 [](const std::string& str) { return str.c_str(); });
172
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100173 return mCameraService->handleShellCommand(
174 mDevNullFd, mDevNullFd, mDevNullFd, argv.data(), argv.size());
Marvin Ramina8196132024-03-15 15:55:22 +0000175 }
176
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100177 std::vector<std::string> getCameraIds() {
178 std::vector<std::string> cameraIds;
179 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
180 return cameraIds;
181 }
182
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100183 std::optional<camera_metadata_enum_android_lens_facing> getCameraLensFacing(
184 const std::string& id) {
185 std::shared_ptr<VirtualCameraDevice> camera = mCameraProvider->getCamera(id);
186 if (camera == nullptr) {
187 return std::nullopt;
188 }
189 CameraMetadata metadata;
190 camera->getCameraCharacteristics(&metadata);
191 return getLensFacing(metadata);
192 }
193
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100194 protected:
195 std::shared_ptr<VirtualCameraService> mCameraService;
196 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
197 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
198 ndk::SharedRefBase::make<MockCameraProviderCallback>();
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100199 MockPermissionsProxy mMockPermissionsProxy;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100200
201 sp<BBinder> mOwnerToken;
202 ndk::SpAIBinder mNdkOwnerToken;
203
204 int mDevNullFd;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100205
206 VirtualCameraConfiguration mVgaYUV420OnlyConfiguration =
Biswarup Pal112458f2023-12-28 19:50:17 +0000207 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100208};
209
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100210TEST_F(VirtualCameraServiceTest, RegisterCameraWithYuvInputSucceeds) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100211 sp<BBinder> token = sp<BBinder>::make();
212 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
213 bool aidlRet;
214
Biswarup Pal37a75182024-01-16 15:53:35 +0000215 ASSERT_TRUE(mCameraService
216 ->registerCamera(ndkToken, mVgaYUV420OnlyConfiguration,
217 kDefaultDeviceId, &aidlRet)
218 .isOk());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100219
220 EXPECT_TRUE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100221 EXPECT_THAT(getCameraIds(), SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100222}
223
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100224TEST_F(VirtualCameraServiceTest, RegisterCameraWithRgbaInputSucceeds) {
225 sp<BBinder> token = sp<BBinder>::make();
226 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
227 bool aidlRet;
228
229 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000230 createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100231
Biswarup Pal37a75182024-01-16 15:53:35 +0000232 ASSERT_TRUE(mCameraService
233 ->registerCamera(ndkToken, config, kDefaultDeviceId, &aidlRet)
234 .isOk());
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100235
236 EXPECT_TRUE(aidlRet);
237 EXPECT_THAT(getCameraIds(), SizeIs(1));
238}
239
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100240TEST_F(VirtualCameraServiceTest, RegisterCameraTwiceSecondReturnsFalse) {
241 createCamera();
242 bool aidlRet;
243
244 ASSERT_TRUE(mCameraService
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100245 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
Biswarup Pal37a75182024-01-16 15:53:35 +0000246 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100247 .isOk());
248 EXPECT_FALSE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100249 EXPECT_THAT(getCameraIds(), SizeIs(1));
250}
251
252TEST_F(VirtualCameraServiceTest, EmptyConfigurationFails) {
253 bool aidlRet;
254
255 ASSERT_FALSE(mCameraService
256 ->registerCamera(mNdkOwnerToken,
Biswarup Pal37a75182024-01-16 15:53:35 +0000257 kEmptyVirtualCameraConfiguration,
258 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100259 .isOk());
260 EXPECT_FALSE(aidlRet);
261 EXPECT_THAT(getCameraIds(), IsEmpty());
262}
263
Jan Sebechlebsky288900f2024-05-24 14:47:54 +0200264TEST_F(VirtualCameraServiceTest,
265 ConfigurationWithoutVirtualCameraCallbackFails) {
266 sp<BBinder> token = sp<BBinder>::make();
267 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
268 bool aidlRet;
269
270 VirtualCameraConfiguration config =
271 createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps);
272 config.virtualCameraCallback = nullptr;
273
274 ASSERT_FALSE(mCameraService
275 ->registerCamera(ndkToken, config, kDefaultDeviceId, &aidlRet)
276 .isOk());
277
278 EXPECT_FALSE(aidlRet);
279 EXPECT_THAT(getCameraIds(), IsEmpty());
280}
281
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100282TEST_F(VirtualCameraServiceTest, ConfigurationWithUnsupportedPixelFormatFails) {
283 bool aidlRet;
284
285 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000286 createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100287
288 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000289 mCameraService
290 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
291 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100292 EXPECT_FALSE(aidlRet);
293 EXPECT_THAT(getCameraIds(), IsEmpty());
294}
295
296TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighResFails) {
297 bool aidlRet;
298 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000299 createConfiguration(1000000, 1000000, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100300
301 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000302 mCameraService
303 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
304 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100305 EXPECT_FALSE(aidlRet);
306 EXPECT_THAT(getCameraIds(), IsEmpty());
307}
308
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100309TEST_F(VirtualCameraServiceTest, ConfigurationWithNegativeResolutionFails) {
310 bool aidlRet;
311 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000312 createConfiguration(-1, kVgaHeight, Format::YUV_420_888, kMaxFps);
Biswarup Pal6152a302023-12-19 12:44:09 +0000313
314 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000315 mCameraService
316 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
317 .isOk());
Biswarup Pal6152a302023-12-19 12:44:09 +0000318 EXPECT_FALSE(aidlRet);
319 EXPECT_THAT(getCameraIds(), IsEmpty());
320}
321
322TEST_F(VirtualCameraServiceTest, ConfigurationWithTooLowMaxFpsFails) {
323 bool aidlRet;
324 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000325 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 0);
Biswarup Pal6152a302023-12-19 12:44:09 +0000326
327 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000328 mCameraService
329 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
330 .isOk());
Biswarup Pal6152a302023-12-19 12:44:09 +0000331 EXPECT_FALSE(aidlRet);
332 EXPECT_THAT(getCameraIds(), IsEmpty());
333}
334
335TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighMaxFpsFails) {
336 bool aidlRet;
337 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000338 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 90);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100339
340 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000341 mCameraService
342 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
343 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100344 EXPECT_FALSE(aidlRet);
345 EXPECT_THAT(getCameraIds(), IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100346}
347
348TEST_F(VirtualCameraServiceTest, GetCamera) {
349 createCamera();
350
351 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
352
353 sp<BBinder> otherToken = sp<BBinder>::make();
354 EXPECT_THAT(mCameraService->getCamera(
355 ndk::SpAIBinder(AIBinder_fromPlatformBinder(otherToken))),
356 IsNull());
357}
358
359TEST_F(VirtualCameraServiceTest, UnregisterCamera) {
360 createCamera();
361
362 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
363
364 mCameraService->unregisterCamera(mNdkOwnerToken);
365
366 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), IsNull());
367}
368
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100369TEST_F(VirtualCameraServiceTest, RegisterCameraWithoutPermissionFails) {
370 bool aidlRet;
371 EXPECT_CALL(mMockPermissionsProxy,
372 checkCallingPermission(kCreateVirtualDevicePermissions))
373 .WillOnce(Return(false));
374
375 EXPECT_THAT(mCameraService
376 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
Biswarup Pal37a75182024-01-16 15:53:35 +0000377 kDefaultDeviceId, &aidlRet)
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100378 .getExceptionCode(),
379 Eq(EX_SECURITY));
380}
381
382TEST_F(VirtualCameraServiceTest, UnregisterCameraWithoutPermissionFails) {
383 EXPECT_CALL(mMockPermissionsProxy,
384 checkCallingPermission(kCreateVirtualDevicePermissions))
385 .WillOnce(Return(false));
386
387 EXPECT_THAT(
388 mCameraService->unregisterCamera(mNdkOwnerToken).getExceptionCode(),
389 Eq(EX_SECURITY));
390}
391
392TEST_F(VirtualCameraServiceTest, GetIdWithoutPermissionFails) {
Biswarup Pal15dcd132024-06-02 14:02:03 +0000393 std::string aidlRet;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100394 EXPECT_CALL(mMockPermissionsProxy,
395 checkCallingPermission(kCreateVirtualDevicePermissions))
396 .WillOnce(Return(false));
397
398 EXPECT_THAT(
399 mCameraService->getCameraId(mNdkOwnerToken, &aidlRet).getExceptionCode(),
400 Eq(EX_SECURITY));
401}
402
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100403TEST_F(VirtualCameraServiceTest, UnregisterCameraWithUnknownToken) {
404 createCamera();
405
406 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
407
408 auto otherToken = sp<BBinder>::make();
409 ndk::SpAIBinder ndkOtherToken(AIBinder_fromPlatformBinder(otherToken));
410 mCameraService->unregisterCamera(ndkOtherToken);
411
412 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
413}
414
415TEST_F(VirtualCameraServiceTest, ShellCmdWithNullArgs) {
416 EXPECT_EQ(mCameraService->handleShellCommand(
417 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
418 /*args=*/nullptr, /*numArgs=*/1),
419 STATUS_BAD_VALUE);
420
421 std::array<const char*, 1> args{nullptr};
422 EXPECT_EQ(mCameraService->handleShellCommand(
423 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
424 args.data(), /*numArgs=*/1),
425 STATUS_BAD_VALUE);
426}
427
Jan Sebechlebsky76d7e212023-11-28 14:10:25 +0100428TEST_F(VirtualCameraServiceTest, ShellCmdWithNoArgs) {
429 EXPECT_EQ(mCameraService->handleShellCommand(
430 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
431 /*args=*/nullptr, /*numArgs=*/0),
432 STATUS_OK);
433}
434
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100435TEST_F(VirtualCameraServiceTest, TestCameraShellCmd) {
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100436 EXPECT_THAT(execute_shell_command("enable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100437
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100438 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
439 EXPECT_THAT(cameraIdsAfterEnable, SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100440
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100441 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100442
443 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
444 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100445}
446
Marvin Ramina8196132024-03-15 15:55:22 +0000447TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithId) {
Biswarup Pal15dcd132024-06-02 14:02:03 +0000448 EXPECT_THAT(
449 execute_shell_command("enable_test_camera --camera_id=hello12345"),
450 Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000451
452 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
Biswarup Pal15dcd132024-06-02 14:02:03 +0000453 EXPECT_THAT(cameraIdsAfterEnable,
454 ElementsAre("device@1.1/virtual/hello12345"));
Marvin Ramina8196132024-03-15 15:55:22 +0000455
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100456 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000457
458 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
459 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
460}
461
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100462TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidId) {
Biswarup Pal15dcd132024-06-02 14:02:03 +0000463 EXPECT_THAT(execute_shell_command("enable_test_camera --camera_id="),
464 Eq(STATUS_BAD_VALUE));
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100465}
466
467TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithUnknownCommand) {
468 EXPECT_THAT(execute_shell_command("brew_coffee --flavor=vanilla"),
469 Eq(STATUS_BAD_VALUE));
470}
471
472TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithMalformedOption) {
473 EXPECT_THAT(execute_shell_command("enable_test_camera **camera_id=12345"),
474 Eq(STATUS_BAD_VALUE));
475}
476
477TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithLensFacing) {
478 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=front"),
479 Eq(NO_ERROR));
480
481 std::vector<std::string> cameraIds = getCameraIds();
482 ASSERT_THAT(cameraIds, SizeIs(1));
483 EXPECT_THAT(getCameraLensFacing(cameraIds[0]),
484 Optional(Eq(ANDROID_LENS_FACING_FRONT)));
485}
486
487TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidLensFacing) {
488 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=west"),
489 Eq(STATUS_BAD_VALUE));
490}
491
Jan Sebechlebsky34469e42024-05-29 10:56:12 +0200492TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInputFps) {
493 EXPECT_THAT(execute_shell_command("enable_test_camera --input_fps=15"),
494 Eq(NO_ERROR));
495
496 std::vector<std::string> cameraIds = getCameraIds();
497 ASSERT_THAT(cameraIds, SizeIs(1));
498}
499
500TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidInputFps) {
501 EXPECT_THAT(execute_shell_command("enable_test_camera --input_fps=1001"),
502 Eq(STATUS_BAD_VALUE));
503 EXPECT_THAT(execute_shell_command("enable_test_camera --input_fps=0"),
504 Eq(STATUS_BAD_VALUE));
505 EXPECT_THAT(execute_shell_command("enable_test_camera --input_fps=foo"),
506 Eq(STATUS_BAD_VALUE));
507}
508
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100509} // namespace
510} // namespace virtualcamera
511} // namespace companion
512} // namespace android