blob: 01f2b8c1cad95aab95cfeb38bc611b1068b62044 [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;
Biswarup Pal37a75182024-01-16 15:53:35 +000072constexpr int kDefaultDeviceId = 0;
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +010073constexpr char kCreateVirtualDevicePermissions[] =
74 "android.permission.CREATE_VIRTUAL_DEVICE";
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010075
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010076const VirtualCameraConfiguration kEmptyVirtualCameraConfiguration;
77
Biswarup Pal112458f2023-12-28 19:50:17 +000078VirtualCameraConfiguration createConfiguration(const int width, const int height,
79 const Format format,
80 const int maxFps) {
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010081 VirtualCameraConfiguration configuration;
Biswarup Pal6152a302023-12-19 12:44:09 +000082 configuration.supportedStreamConfigs.push_back({.width = width,
83 .height = height,
84 .pixelFormat = format,
85 .maxFps = maxFps});
Biswarup Pal112458f2023-12-28 19:50:17 +000086 configuration.sensorOrientation = kSensorOrientation;
87 configuration.lensFacing = kLensFacing;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010088 return configuration;
89}
90
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010091class MockCameraProviderCallback : public BnCameraProviderCallback {
92 public:
93 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
94 (const std::string&, CameraDeviceStatus), (override));
95 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
96 (const std::string&, TorchModeStatus), (override));
97 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
98 (const std::string&, const std::string&, CameraDeviceStatus),
99 (override));
100};
101
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100102class MockPermissionsProxy : public PermissionsProxy {
103 public:
104 MOCK_METHOD(bool, checkCallingPermission, (const std::string&),
105 (const override));
106};
107
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100108class VirtualCameraServiceTest : public ::testing::Test {
109 public:
110 void SetUp() override {
111 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
112 mMockCameraProviderCallback =
113 ndk::SharedRefBase::make<MockCameraProviderCallback>();
114 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
115 .WillByDefault([](const std::string&, CameraDeviceStatus) {
116 return ndk::ScopedAStatus::ok();
117 });
118 mCameraProvider->setCallback(mMockCameraProviderCallback);
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100119 mCameraService = ndk::SharedRefBase::make<VirtualCameraService>(
120 mCameraProvider, mMockPermissionsProxy);
121
122 ON_CALL(mMockPermissionsProxy, checkCallingPermission)
123 .WillByDefault(Return(true));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100124
125 mDevNullFd = open("/dev/null", O_RDWR);
126 ASSERT_THAT(mDevNullFd, Ge(0));
127 }
128
129 void createCamera() {
130 mOwnerToken = sp<BBinder>::make();
131 mNdkOwnerToken.set(AIBinder_fromPlatformBinder(mOwnerToken));
132 bool aidlRet;
133
134 ASSERT_TRUE(mCameraService
Biswarup Pal37a75182024-01-16 15:53:35 +0000135 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
136 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100137 .isOk());
138 ASSERT_TRUE(aidlRet);
139 }
140
141 void TearDown() override {
142 close(mDevNullFd);
143 }
144
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100145 binder_status_t execute_shell_command(const std::string& cmd) {
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100146 const static std::regex whitespaceRegex("\\s+");
147 std::vector<std::string> tokens;
148 std::copy_if(
149 std::sregex_token_iterator(cmd.begin(), cmd.end(), whitespaceRegex, -1),
150 std::sregex_token_iterator(), std::back_inserter(tokens),
151 [](const std::string& token) { return !token.empty(); });
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100152
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100153 std::vector<const char*> argv;
154 argv.reserve(tokens.size());
155 std::transform(tokens.begin(), tokens.end(), std::back_inserter(argv),
156 [](const std::string& str) { return str.c_str(); });
157
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100158 return mCameraService->handleShellCommand(
159 mDevNullFd, mDevNullFd, mDevNullFd, argv.data(), argv.size());
Marvin Ramina8196132024-03-15 15:55:22 +0000160 }
161
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100162 std::vector<std::string> getCameraIds() {
163 std::vector<std::string> cameraIds;
164 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
165 return cameraIds;
166 }
167
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100168 std::optional<camera_metadata_enum_android_lens_facing> getCameraLensFacing(
169 const std::string& id) {
170 std::shared_ptr<VirtualCameraDevice> camera = mCameraProvider->getCamera(id);
171 if (camera == nullptr) {
172 return std::nullopt;
173 }
174 CameraMetadata metadata;
175 camera->getCameraCharacteristics(&metadata);
176 return getLensFacing(metadata);
177 }
178
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100179 protected:
180 std::shared_ptr<VirtualCameraService> mCameraService;
181 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
182 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
183 ndk::SharedRefBase::make<MockCameraProviderCallback>();
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100184 MockPermissionsProxy mMockPermissionsProxy;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100185
186 sp<BBinder> mOwnerToken;
187 ndk::SpAIBinder mNdkOwnerToken;
188
189 int mDevNullFd;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100190
191 VirtualCameraConfiguration mVgaYUV420OnlyConfiguration =
Biswarup Pal112458f2023-12-28 19:50:17 +0000192 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100193};
194
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100195TEST_F(VirtualCameraServiceTest, RegisterCameraWithYuvInputSucceeds) {
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100196 sp<BBinder> token = sp<BBinder>::make();
197 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
198 bool aidlRet;
199
Biswarup Pal37a75182024-01-16 15:53:35 +0000200 ASSERT_TRUE(mCameraService
201 ->registerCamera(ndkToken, mVgaYUV420OnlyConfiguration,
202 kDefaultDeviceId, &aidlRet)
203 .isOk());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100204
205 EXPECT_TRUE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100206 EXPECT_THAT(getCameraIds(), SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100207}
208
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100209TEST_F(VirtualCameraServiceTest, RegisterCameraWithRgbaInputSucceeds) {
210 sp<BBinder> token = sp<BBinder>::make();
211 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
212 bool aidlRet;
213
214 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000215 createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100216
Biswarup Pal37a75182024-01-16 15:53:35 +0000217 ASSERT_TRUE(mCameraService
218 ->registerCamera(ndkToken, config, kDefaultDeviceId, &aidlRet)
219 .isOk());
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100220
221 EXPECT_TRUE(aidlRet);
222 EXPECT_THAT(getCameraIds(), SizeIs(1));
223}
224
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100225TEST_F(VirtualCameraServiceTest, RegisterCameraTwiceSecondReturnsFalse) {
226 createCamera();
227 bool aidlRet;
228
229 ASSERT_TRUE(mCameraService
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100230 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
Biswarup Pal37a75182024-01-16 15:53:35 +0000231 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100232 .isOk());
233 EXPECT_FALSE(aidlRet);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100234 EXPECT_THAT(getCameraIds(), SizeIs(1));
235}
236
237TEST_F(VirtualCameraServiceTest, EmptyConfigurationFails) {
238 bool aidlRet;
239
240 ASSERT_FALSE(mCameraService
241 ->registerCamera(mNdkOwnerToken,
Biswarup Pal37a75182024-01-16 15:53:35 +0000242 kEmptyVirtualCameraConfiguration,
243 kDefaultDeviceId, &aidlRet)
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100244 .isOk());
245 EXPECT_FALSE(aidlRet);
246 EXPECT_THAT(getCameraIds(), IsEmpty());
247}
248
249TEST_F(VirtualCameraServiceTest, ConfigurationWithUnsupportedPixelFormatFails) {
250 bool aidlRet;
251
252 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000253 createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100254
255 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000256 mCameraService
257 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
258 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100259 EXPECT_FALSE(aidlRet);
260 EXPECT_THAT(getCameraIds(), IsEmpty());
261}
262
263TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighResFails) {
264 bool aidlRet;
265 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000266 createConfiguration(1000000, 1000000, Format::YUV_420_888, kMaxFps);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100267
268 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000269 mCameraService
270 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
271 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100272 EXPECT_FALSE(aidlRet);
273 EXPECT_THAT(getCameraIds(), IsEmpty());
274}
275
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100276TEST_F(VirtualCameraServiceTest, ConfigurationWithNegativeResolutionFails) {
277 bool aidlRet;
278 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000279 createConfiguration(-1, kVgaHeight, Format::YUV_420_888, kMaxFps);
Biswarup Pal6152a302023-12-19 12:44:09 +0000280
281 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000282 mCameraService
283 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
284 .isOk());
Biswarup Pal6152a302023-12-19 12:44:09 +0000285 EXPECT_FALSE(aidlRet);
286 EXPECT_THAT(getCameraIds(), IsEmpty());
287}
288
289TEST_F(VirtualCameraServiceTest, ConfigurationWithTooLowMaxFpsFails) {
290 bool aidlRet;
291 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000292 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 0);
Biswarup Pal6152a302023-12-19 12:44:09 +0000293
294 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000295 mCameraService
296 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
297 .isOk());
Biswarup Pal6152a302023-12-19 12:44:09 +0000298 EXPECT_FALSE(aidlRet);
299 EXPECT_THAT(getCameraIds(), IsEmpty());
300}
301
302TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighMaxFpsFails) {
303 bool aidlRet;
304 VirtualCameraConfiguration config =
Biswarup Pal112458f2023-12-28 19:50:17 +0000305 createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 90);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100306
307 ASSERT_FALSE(
Biswarup Pal37a75182024-01-16 15:53:35 +0000308 mCameraService
309 ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
310 .isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100311 EXPECT_FALSE(aidlRet);
312 EXPECT_THAT(getCameraIds(), IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100313}
314
315TEST_F(VirtualCameraServiceTest, GetCamera) {
316 createCamera();
317
318 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
319
320 sp<BBinder> otherToken = sp<BBinder>::make();
321 EXPECT_THAT(mCameraService->getCamera(
322 ndk::SpAIBinder(AIBinder_fromPlatformBinder(otherToken))),
323 IsNull());
324}
325
326TEST_F(VirtualCameraServiceTest, UnregisterCamera) {
327 createCamera();
328
329 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
330
331 mCameraService->unregisterCamera(mNdkOwnerToken);
332
333 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), IsNull());
334}
335
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100336TEST_F(VirtualCameraServiceTest, RegisterCameraWithoutPermissionFails) {
337 bool aidlRet;
338 EXPECT_CALL(mMockPermissionsProxy,
339 checkCallingPermission(kCreateVirtualDevicePermissions))
340 .WillOnce(Return(false));
341
342 EXPECT_THAT(mCameraService
343 ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
Biswarup Pal37a75182024-01-16 15:53:35 +0000344 kDefaultDeviceId, &aidlRet)
Jan Sebechlebskyde6f16f2023-11-29 09:27:36 +0100345 .getExceptionCode(),
346 Eq(EX_SECURITY));
347}
348
349TEST_F(VirtualCameraServiceTest, UnregisterCameraWithoutPermissionFails) {
350 EXPECT_CALL(mMockPermissionsProxy,
351 checkCallingPermission(kCreateVirtualDevicePermissions))
352 .WillOnce(Return(false));
353
354 EXPECT_THAT(
355 mCameraService->unregisterCamera(mNdkOwnerToken).getExceptionCode(),
356 Eq(EX_SECURITY));
357}
358
359TEST_F(VirtualCameraServiceTest, GetIdWithoutPermissionFails) {
360 int32_t aidlRet;
361 EXPECT_CALL(mMockPermissionsProxy,
362 checkCallingPermission(kCreateVirtualDevicePermissions))
363 .WillOnce(Return(false));
364
365 EXPECT_THAT(
366 mCameraService->getCameraId(mNdkOwnerToken, &aidlRet).getExceptionCode(),
367 Eq(EX_SECURITY));
368}
369
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100370TEST_F(VirtualCameraServiceTest, UnregisterCameraWithUnknownToken) {
371 createCamera();
372
373 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
374
375 auto otherToken = sp<BBinder>::make();
376 ndk::SpAIBinder ndkOtherToken(AIBinder_fromPlatformBinder(otherToken));
377 mCameraService->unregisterCamera(ndkOtherToken);
378
379 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
380}
381
382TEST_F(VirtualCameraServiceTest, ShellCmdWithNullArgs) {
383 EXPECT_EQ(mCameraService->handleShellCommand(
384 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
385 /*args=*/nullptr, /*numArgs=*/1),
386 STATUS_BAD_VALUE);
387
388 std::array<const char*, 1> args{nullptr};
389 EXPECT_EQ(mCameraService->handleShellCommand(
390 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
391 args.data(), /*numArgs=*/1),
392 STATUS_BAD_VALUE);
393}
394
Jan Sebechlebsky76d7e212023-11-28 14:10:25 +0100395TEST_F(VirtualCameraServiceTest, ShellCmdWithNoArgs) {
396 EXPECT_EQ(mCameraService->handleShellCommand(
397 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
398 /*args=*/nullptr, /*numArgs=*/0),
399 STATUS_OK);
400}
401
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100402TEST_F(VirtualCameraServiceTest, TestCameraShellCmd) {
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100403 EXPECT_THAT(execute_shell_command("enable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100404
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100405 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
406 EXPECT_THAT(cameraIdsAfterEnable, SizeIs(1));
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100407
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100408 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100409
410 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
411 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100412}
413
Marvin Ramina8196132024-03-15 15:55:22 +0000414TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithId) {
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100415 EXPECT_THAT(execute_shell_command("enable_test_camera --camera_id=12345"),
416 Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000417
418 std::vector<std::string> cameraIdsAfterEnable = getCameraIds();
Jan Sebechlebsky685ba1e2024-03-25 10:33:09 +0100419 EXPECT_THAT(cameraIdsAfterEnable, ElementsAre("device@1.1/virtual/12345"));
Marvin Ramina8196132024-03-15 15:55:22 +0000420
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100421 EXPECT_THAT(execute_shell_command("disable_test_camera"), Eq(NO_ERROR));
Marvin Ramina8196132024-03-15 15:55:22 +0000422
423 std::vector<std::string> cameraIdsAfterDisable = getCameraIds();
424 EXPECT_THAT(cameraIdsAfterDisable, IsEmpty());
425}
426
Jan Sebechlebsky773c0142024-03-25 12:17:05 +0100427TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidId) {
428 EXPECT_THAT(
429 execute_shell_command("enable_test_camera --camera_id=NotNumericalId"),
430 Eq(STATUS_BAD_VALUE));
431}
432
433TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithUnknownCommand) {
434 EXPECT_THAT(execute_shell_command("brew_coffee --flavor=vanilla"),
435 Eq(STATUS_BAD_VALUE));
436}
437
438TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithMalformedOption) {
439 EXPECT_THAT(execute_shell_command("enable_test_camera **camera_id=12345"),
440 Eq(STATUS_BAD_VALUE));
441}
442
443TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithLensFacing) {
444 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=front"),
445 Eq(NO_ERROR));
446
447 std::vector<std::string> cameraIds = getCameraIds();
448 ASSERT_THAT(cameraIds, SizeIs(1));
449 EXPECT_THAT(getCameraLensFacing(cameraIds[0]),
450 Optional(Eq(ANDROID_LENS_FACING_FRONT)));
451}
452
453TEST_F(VirtualCameraServiceTest, TestCameraShellCmdWithInvalidLensFacing) {
454 EXPECT_THAT(execute_shell_command("enable_test_camera --lens_facing=west"),
455 Eq(STATUS_BAD_VALUE));
456}
457
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100458} // namespace
459} // namespace virtualcamera
460} // namespace companion
461} // namespace android