blob: 4fd0b3b7174678e2b384f9fb548db64e1ab61764 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
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
17#include <cstdio>
18#include <memory>
19
20#include "VirtualCameraService.h"
21#include "aidl/android/companion/virtualcamera/BnVirtualCameraCallback.h"
22#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
23#include "aidl/android/hardware/camera/provider/BnCameraProviderCallback.h"
24#include "aidl/android/hardware/graphics/common/PixelFormat.h"
25#include "android/binder_auto_utils.h"
26#include "android/binder_interface_utils.h"
27#include "android/binder_libbinder.h"
28#include "android/binder_status.h"
29#include "binder/Binder.h"
30#include "gmock/gmock.h"
31#include "gtest/gtest.h"
32#include "utils/Errors.h"
33
34namespace android {
35namespace companion {
36namespace virtualcamera {
37namespace {
38
39using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
40using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
41using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
42using ::aidl::android::hardware::camera::common::TorchModeStatus;
43using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
44using ::aidl::android::hardware::graphics::common::PixelFormat;
45using ::aidl::android::view::Surface;
46using ::testing::_;
47using ::testing::Eq;
48using ::testing::Ge;
49using ::testing::IsEmpty;
50using ::testing::IsNull;
51using ::testing::Not;
52using ::testing::SizeIs;
53
54const VirtualCameraConfiguration kEmptyVirtualCameraConfiguration;
55
56class MockCameraProviderCallback : public BnCameraProviderCallback {
57 public:
58 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
59 (const std::string&, CameraDeviceStatus), (override));
60 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
61 (const std::string&, TorchModeStatus), (override));
62 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
63 (const std::string&, const std::string&, CameraDeviceStatus),
64 (override));
65};
66
67class VirtualCameraServiceTest : public ::testing::Test {
68 public:
69 void SetUp() override {
70 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
71 mMockCameraProviderCallback =
72 ndk::SharedRefBase::make<MockCameraProviderCallback>();
73 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
74 .WillByDefault([](const std::string&, CameraDeviceStatus) {
75 return ndk::ScopedAStatus::ok();
76 });
77 mCameraProvider->setCallback(mMockCameraProviderCallback);
78 mCameraService =
79 ndk::SharedRefBase::make<VirtualCameraService>(mCameraProvider);
80
81 mDevNullFd = open("/dev/null", O_RDWR);
82 ASSERT_THAT(mDevNullFd, Ge(0));
83 }
84
85 void createCamera() {
86 mOwnerToken = sp<BBinder>::make();
87 mNdkOwnerToken.set(AIBinder_fromPlatformBinder(mOwnerToken));
88 bool aidlRet;
89
90 ASSERT_TRUE(mCameraService
91 ->registerCamera(mNdkOwnerToken,
92 kEmptyVirtualCameraConfiguration, &aidlRet)
93 .isOk());
94 ASSERT_TRUE(aidlRet);
95 }
96
97 void TearDown() override {
98 close(mDevNullFd);
99 }
100
101 void execute_shell_command(const std::string cmd) {
102 std::array<const char*, 1> args{cmd.data()};
103 ASSERT_THAT(
104 mCameraService->handleShellCommand(mDevNullFd, mDevNullFd, mDevNullFd,
105 args.data(), args.size()),
106 Eq(NO_ERROR));
107 }
108
109 protected:
110 std::shared_ptr<VirtualCameraService> mCameraService;
111 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
112 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
113 ndk::SharedRefBase::make<MockCameraProviderCallback>();
114
115 sp<BBinder> mOwnerToken;
116 ndk::SpAIBinder mNdkOwnerToken;
117
118 int mDevNullFd;
119};
120
121TEST_F(VirtualCameraServiceTest, RegisterCameraSucceeds) {
122 sp<BBinder> token = sp<BBinder>::make();
123 ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
124 bool aidlRet;
125
126 ASSERT_TRUE(
127 mCameraService
128 ->registerCamera(ndkToken, kEmptyVirtualCameraConfiguration, &aidlRet)
129 .isOk());
130
131 EXPECT_TRUE(aidlRet);
132}
133
134TEST_F(VirtualCameraServiceTest, RegisterCameraTwiceSecondReturnsFalse) {
135 createCamera();
136 bool aidlRet;
137
138 ASSERT_TRUE(mCameraService
139 ->registerCamera(mNdkOwnerToken,
140 kEmptyVirtualCameraConfiguration, &aidlRet)
141 .isOk());
142 EXPECT_FALSE(aidlRet);
143}
144
145TEST_F(VirtualCameraServiceTest, GetCamera) {
146 createCamera();
147
148 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
149
150 sp<BBinder> otherToken = sp<BBinder>::make();
151 EXPECT_THAT(mCameraService->getCamera(
152 ndk::SpAIBinder(AIBinder_fromPlatformBinder(otherToken))),
153 IsNull());
154}
155
156TEST_F(VirtualCameraServiceTest, UnregisterCamera) {
157 createCamera();
158
159 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
160
161 mCameraService->unregisterCamera(mNdkOwnerToken);
162
163 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), IsNull());
164}
165
166TEST_F(VirtualCameraServiceTest, UnregisterCameraWithUnknownToken) {
167 createCamera();
168
169 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
170
171 auto otherToken = sp<BBinder>::make();
172 ndk::SpAIBinder ndkOtherToken(AIBinder_fromPlatformBinder(otherToken));
173 mCameraService->unregisterCamera(ndkOtherToken);
174
175 EXPECT_THAT(mCameraService->getCamera(mNdkOwnerToken), Not(IsNull()));
176}
177
178TEST_F(VirtualCameraServiceTest, ShellCmdWithNullArgs) {
179 EXPECT_EQ(mCameraService->handleShellCommand(
180 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
181 /*args=*/nullptr, /*numArgs=*/1),
182 STATUS_BAD_VALUE);
183
184 std::array<const char*, 1> args{nullptr};
185 EXPECT_EQ(mCameraService->handleShellCommand(
186 /*in=*/mDevNullFd, /*out=*/mDevNullFd, /*err=*/mDevNullFd,
187 args.data(), /*numArgs=*/1),
188 STATUS_BAD_VALUE);
189}
190
191TEST_F(VirtualCameraServiceTest, TestCameraShellCmd) {
192 execute_shell_command("enable_test_camera");
193
194 std::vector<std::string> cameraIds;
195 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
196 EXPECT_THAT(cameraIds, SizeIs(1));
197
198 execute_shell_command("disable_test_camera");
199 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
200 EXPECT_THAT(cameraIds, IsEmpty());
201}
202
203} // namespace
204} // namespace virtualcamera
205} // namespace companion
206} // namespace android