blob: 16f40ff70885e0982cff20bdac553b1e6d3f15d6 [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 Sebechlebsky5cb39962023-11-22 17:33:07 +010018#include <cstdio>
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010019#include <iterator>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010020#include <memory>
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010021#include <regex>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010022
23#include "VirtualCameraService.h"
24#include "aidl/android/companion/virtualcamera/BnVirtualCameraCallback.h"
25#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
26#include "aidl/android/hardware/camera/provider/BnCameraProviderCallback.h"
27#include "aidl/android/hardware/graphics/common/PixelFormat.h"
28#include "android/binder_auto_utils.h"
29#include "android/binder_interface_utils.h"
30#include "android/binder_libbinder.h"
31#include "android/binder_status.h"
32#include "binder/Binder.h"
33#include "gmock/gmock.h"
34#include "gtest/gtest.h"
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010035#include "util/MetadataUtil.h"
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010036#include "util/Permissions.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010037#include "utils/Errors.h"
38
39namespace android {
40namespace companion {
41namespace virtualcamera {
42namespace {
43
44using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010045using ::aidl::android::companion::virtualcamera::Format;
Biswarup Pal112458f2023-12-28 19:50:17 +000046using ::aidl::android::companion::virtualcamera::LensFacing;
Biswarup Pal6152a302023-12-19 12:44:09 +000047using ::aidl::android::companion::virtualcamera::SensorOrientation;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010048using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
49using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
50using ::aidl::android::hardware::camera::common::TorchModeStatus;
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010051using ::aidl::android::hardware::camera::device::CameraMetadata;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010052using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
53using ::aidl::android::hardware::graphics::common::PixelFormat;
54using ::aidl::android::view::Surface;
55using ::testing::_;
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +010056using ::testing::ElementsAre;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010057using ::testing::Eq;
58using ::testing::Ge;
59using ::testing::IsEmpty;
60using ::testing::IsNull;
61using ::testing::Not;
Jan Sebechlebsky773c0142024-03-25 12:17:05 +010062using ::testing::Optional;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010063using ::testing::Return;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010064using ::testing::SizeIs;
65
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010066constexpr int kVgaWidth = 640;
67constexpr int kVgaHeight = 480;
Biswarup Pal6152a302023-12-19 12:44:09 +000068constexpr int kMaxFps = 30;
Biswarup Pal112458f2023-12-28 19:50:17 +000069constexpr SensorOrientation kSensorOrientation =
70 SensorOrientation::ORIENTATION_0;
71constexpr LensFacing kLensFacing = LensFacing::FRONT;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010072constexpr char kCreateVirtualDevicePermissions[] =
73 "android.permission.CREATE_VIRTUAL_DEVICE";
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010074
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010075const VirtualCameraConfiguration kEmptyVirtualCameraConfiguration;
76
Biswarup Pal112458f2023-12-28 19:50:17 +000077VirtualCameraConfiguration createConfiguration(const int width, const int height,
78 const Format format,
79 const int maxFps) {
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010080 VirtualCameraConfiguration configuration;
Biswarup Pal6152a302023-12-19 12:44:09 +000081 configuration.supportedStreamConfigs.push_back({.width = width,
82 .height = height,
83 .pixelFormat = format,
84 .maxFps = maxFps});
Biswarup Pal112458f2023-12-28 19:50:17 +000085 configuration.sensorOrientation = kSensorOrientation;
86 configuration.lensFacing = kLensFacing;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010087 return configuration;
88}
89
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010090class MockCameraProviderCallback : public BnCameraProviderCallback {
91 public:
92 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
93 (const std::string&, CameraDeviceStatus), (override));
94 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
95 (const std::string&, TorchModeStatus), (override));
96 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
97 (const std::string&, const std::string&, CameraDeviceStatus),
98 (override));
99};
100
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100101class MockPermissionsProxy : public PermissionsProxy {
102 public:
103 MOCK_METHOD(bool, checkCallingPermission, (const std::string&),
104 (const override));
105};
106
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100107class VirtualCameraServiceTest : public ::testing::Test {
108 public:
109 void SetUp() override {
110 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
111 mMockCameraProviderCallback =
112 ndk::SharedRefBase::make<MockCameraProviderCallback>();
113 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
114 .WillByDefault([](const std::string&, CameraDeviceStatus) {
115 return ndk::ScopedAStatus::ok();
116 });
117 mCameraProvider->setCallback(mMockCameraProviderCallback);
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100118 mCameraService = ndk::SharedRefBase::make<VirtualCameraService>(
119 mCameraProvider, mMockPermissionsProxy);
120
121 ON_CALL(mMockPermissionsProxy, checkCallingPermission)
122 .WillByDefault(Return(true));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100123
124 mDevNullFd = open("/dev/null", O_RDWR);
125 ASSERT_THAT(mDevNullFd, Ge(0));
126 }
127
128 void createCamera() {
129 mOwnerToken = sp<BBinder>::make();
130 mNdkOwnerToken.set(AIBinder_fromPlatformBinder(mOwnerToken));
131 bool aidlRet;
132
133 ASSERT_TRUE(mCameraService
134 ->registerCamera(mNdkOwnerToken,
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100135 mVgaYUV420OnlyConfiguration, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100136 .isOk());
137 ASSERT_TRUE(aidlRet);
138 }
139
140 void TearDown() override {
141 close(mDevNullFd);
142 }
143
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100144 binder_status_t execute_shell_command(const std::string& cmd) {
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100145 const static std::regex whitespaceRegex("\\s+");
146 std::vector<std::string> tokens;
147 std::copy_if(
148 std::sregex_token_iterator(cmd.begin(), cmd.end(), whitespaceRegex, -1),
149 std::sregex_token_iterator(), std::back_inserter(tokens),
150 [](const std::string& token) { return !token.empty(); });
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100151
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100152 std::vector<const char*> argv;
153 argv.reserve(tokens.size());
154 std::transform(tokens.begin(), tokens.end(), std::back_inserter(argv),
155 [](const std::string& str) { return str.c_str(); });
156
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100157 return mCameraService->handleShellCommand(
158 mDevNullFd, mDevNullFd, mDevNullFd, argv.data(), argv.size());
Marvin Ramina8196132024-03-15 15:55:22 +0000159 }
160
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100161 std::vector<std::string> getCameraIds() {
162 std::vector<std::string> cameraIds;
163 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
164 return cameraIds;
165 }
166
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100167 std::optional<camera_metadata_enum_android_lens_facing> getCameraLensFacing(
168 const std::string& id) {
169 std::shared_ptr<VirtualCameraDevice> camera = mCameraProvider->getCamera(id);
170 if (camera == nullptr) {
171 return std::nullopt;
172 }
173 CameraMetadata metadata;
174 camera->getCameraCharacteristics(&metadata);
175 return getLensFacing(metadata);
176 }
177
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100178 protected:
179 std::shared_ptr<VirtualCameraService> mCameraService;
180 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
181 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
182 ndk::SharedRefBase::make<MockCameraProviderCallback>();
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100183 MockPermissionsProxy mMockPermissionsProxy;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100184
185 sp<BBinder> mOwnerToken;
186 ndk::SpAIBinder mNdkOwnerToken;
187
188 int mDevNullFd;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100189
190 VirtualCameraConfiguration mVgaYUV420OnlyConfiguration =
Biswarup Pal112458f2023-12-28 19:50:17 +0000191 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100192};
193
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100194TEST_F(VirtualCameraServiceTest, RegisterCameraWithYuvInputSucceeds) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100195 sp<BBinder> token = sp<BBinder>::make();
196 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
197 bool aidlRet;
198
199 ASSERT_TRUE(
200 mCameraService
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100201 ->registerCamera(ndkToken, mVgaYUV420OnlyConfiguration, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100202 .isOk());
203
204 EXPECT_TRUE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100205 EXPECT_THAT(getCameraIds(), SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100206}
207
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100208TEST_F(VirtualCameraServiceTest, RegisterCameraWithRgbaInputSucceeds) {
209 sp<BBinder> token = sp<BBinder>::make();
210 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
211 bool aidlRet;
212
213 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000214 createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100215
216 ASSERT_TRUE(mCameraService->registerCamera(ndkToken, config, &aidlRet).isOk());
217
218 EXPECT_TRUE(aidlRet);
219 EXPECT_THAT(getCameraIds(), SizeIs(1));
220}
221
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100222TEST_F(VirtualCameraServiceTest, RegisterCameraTwiceSecondReturnsFalse) {
223 createCamera();
224 bool aidlRet;
225
226 ASSERT_TRUE(mCameraService
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100227 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
228 &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100229 .isOk());
230 EXPECT_FALSE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100231 EXPECT_THAT(getCameraIds(), SizeIs(1));
232}
233
234TEST_F(VirtualCameraServiceTest, EmptyConfigurationFails) {
235 bool aidlRet;
236
237 ASSERT_FALSE(mCameraService
238 ->registerCamera(mNdkOwnerToken,
239 kEmptyVirtualCameraConfiguration, &aidlRet)
240 .isOk());
241 EXPECT_FALSE(aidlRet);
242 EXPECT_THAT(getCameraIds(), IsEmpty());
243}
244
245TEST_F(VirtualCameraServiceTest, ConfigurationWithUnsupportedPixelFormatFails) {
246 bool aidlRet;
247
248 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000249 createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100250
251 ASSERT_FALSE(
252 mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
253 EXPECT_FALSE(aidlRet);
254 EXPECT_THAT(getCameraIds(), IsEmpty());
255}
256
257TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighResFails) {
258 bool aidlRet;
259 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000260 createConfiguration(1000000, 1000000, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100261
262 ASSERT_FALSE(
263 mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
264 EXPECT_FALSE(aidlRet);
265 EXPECT_THAT(getCameraIds(), IsEmpty());
266}
267
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100268TEST_F(VirtualCameraServiceTest, ConfigurationWithNegativeResolutionFails) {
269 bool aidlRet;
270 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000271 createConfiguration(-1, kVgaHeight, Format::YUV_420_888, kMaxFps);
Biswarup Pal6152a302023-12-19 12:44:09 +0000272
273 ASSERT_FALSE(
274 mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
275 EXPECT_FALSE(aidlRet);
276 EXPECT_THAT(getCameraIds(), IsEmpty());
277}
278
279TEST_F(VirtualCameraServiceTest, ConfigurationWithTooLowMaxFpsFails) {
280 bool aidlRet;
281 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000282 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 0);
Biswarup Pal6152a302023-12-19 12:44:09 +0000283
284 ASSERT_FALSE(
285 mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
286 EXPECT_FALSE(aidlRet);
287 EXPECT_THAT(getCameraIds(), IsEmpty());
288}
289
290TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighMaxFpsFails) {
291 bool aidlRet;
292 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000293 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 90);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100294
295 ASSERT_FALSE(
296 mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
297 EXPECT_FALSE(aidlRet);
298 EXPECT_THAT(getCameraIds(), IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100299}
300
301TEST_F(VirtualCameraServiceTest, GetCamera) {
302 createCamera();
303
304 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
305
306 sp<BBinder> otherToken = sp<BBinder>::make();
307 EXPECT_THAT(mCameraService->getCamera(
308 ndk::SpAIBinder(AIBinder_fromPlatformBinder(otherToken))),
309 IsNull());
310}
311
312TEST_F(VirtualCameraServiceTest, UnregisterCamera) {
313 createCamera();
314
315 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
316
317 mCameraService->unregisterCamera(mNdkOwnerToken);
318
319 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), IsNull());
320}
321
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100322TEST_F(VirtualCameraServiceTest, RegisterCameraWithoutPermissionFails) {
323 bool aidlRet;
324 EXPECT_CALL(mMockPermissionsProxy,
325 checkCallingPermission(kCreateVirtualDevicePermissions))
326 .WillOnce(Return(false));
327
328 EXPECT_THAT(mCameraService
329 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
330 &aidlRet)
331 .getExceptionCode(),
332 Eq(EX_SECURITY));
333}
334
335TEST_F(VirtualCameraServiceTest, UnregisterCameraWithoutPermissionFails) {
336 EXPECT_CALL(mMockPermissionsProxy,
337 checkCallingPermission(kCreateVirtualDevicePermissions))
338 .WillOnce(Return(false));
339
340 EXPECT_THAT(
341 mCameraService->unregisterCamera(mNdkOwnerToken).getExceptionCode(),
342 Eq(EX_SECURITY));
343}
344
345TEST_F(VirtualCameraServiceTest, GetIdWithoutPermissionFails) {
346 int32_t aidlRet;
347 EXPECT_CALL(mMockPermissionsProxy,
348 checkCallingPermission(kCreateVirtualDevicePermissions))
349 .WillOnce(Return(false));
350
351 EXPECT_THAT(
352 mCameraService->getCameraId(mNdkOwnerToken, &aidlRet).getExceptionCode(),
353 Eq(EX_SECURITY));
354}
355
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100356TEST_F(VirtualCameraServiceTest, UnregisterCameraWithUnknownToken) {
357 createCamera();
358
359 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
360
361 auto otherToken = sp<BBinder>::make();
362 ndk::SpAIBinder ndkOtherToken(AIBinder_fromPlatformBinder(otherToken));
363 mCameraService->unregisterCamera(ndkOtherToken);
364
365 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
366}
367
368TEST_F(VirtualCameraServiceTest, ShellCmdWithNullArgs) {
369 EXPECT_EQ(mCameraService->handleShellCommand(
370 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
371 /*args=*/nullptr, /*numArgs=*/1),
372 STATUS_BAD_VALUE);
373
374 std::array<const char*, 1> args{nullptr};
375 EXPECT_EQ(mCameraService->handleShellCommand(
376 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
377 args.data(), /*numArgs=*/1),
378 STATUS_BAD_VALUE);
379}
380
Jan Sebechlebsky76d7e212023-11-28 14:10:25 +0100381TEST_F(VirtualCameraServiceTest, ShellCmdWithNoArgs) {
382 EXPECT_EQ(mCameraService->handleShellCommand(
383 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
384 /*args=*/nullptr, /*numArgs=*/0),
385 STATUS_OK);
386}
387
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100388TEST_F(VirtualCameraServiceTest, TestCameraShellCmd) {
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100389 EXPECT_THAT(execute_shell_command("enable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100390
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100391 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
392 EXPECT_THAT(cameraIdsAfterEnable, SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100393
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100394 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100395
396 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
397 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100398}
399
Marvin Ramina8196132024-03-15 15:55:22 +0000400TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithId) {
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100401 EXPECT_THAT(execute_shell_command("enable_test_camera --camera_id=12345"),
402 Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000403
404 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100405 EXPECT_THAT(cameraIdsAfterEnable, ElementsAre("device@1.1/virtual/12345"));
Marvin Ramina8196132024-03-15 15:55:22 +0000406
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100407 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000408
409 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
410 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
411}
412
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100413TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidId) {
414 EXPECT_THAT(
415 execute_shell_command("enable_test_camera --camera_id=NotNumericalId"),
416 Eq(STATUS_BAD_VALUE));
417}
418
419TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithUnknownCommand) {
420 EXPECT_THAT(execute_shell_command("brew_coffee --flavor=vanilla"),
421 Eq(STATUS_BAD_VALUE));
422}
423
424TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithMalformedOption) {
425 EXPECT_THAT(execute_shell_command("enable_test_camera **camera_id=12345"),
426 Eq(STATUS_BAD_VALUE));
427}
428
429TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithLensFacing) {
430 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=front"),
431 Eq(NO_ERROR));
432
433 std::vector<std::string> cameraIds = getCameraIds();
434 ASSERT_THAT(cameraIds, SizeIs(1));
435 EXPECT_THAT(getCameraLensFacing(cameraIds[0]),
436 Optional(Eq(ANDROID_LENS_FACING_FRONT)));
437}
438
439TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidLensFacing) {
440 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=west"),
441 Eq(STATUS_BAD_VALUE));
442}
443
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100444} // namespace
445} // namespace virtualcamera
446} // namespace companion
447} // namespace android