blob: db43a025b4e421ab5f264823bcb422bb99a07f3e [file] [log] [blame]
Austin Borger86a588e2022-05-23 12:41:58 -07001/*
2 * Copyright (C) 2022 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 <android/hardware/BnCameraServiceListener.h>
18#include <android/hardware/BnCameraServiceProxy.h>
19#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
20#include <android/hardware/ICameraService.h>
21
22#include <private/android_filesystem_config.h>
23
24#include "../CameraService.h"
25#include "../utils/CameraServiceProxyWrapper.h"
26
27#include <gtest/gtest.h>
28
29#include <memory>
30#include <vector>
31
32using namespace android;
33using namespace android::hardware::camera;
34
35// Empty service listener.
36class TestCameraServiceListener : public hardware::BnCameraServiceListener {
37public:
38 virtual ~TestCameraServiceListener() {};
39
Austin Borger1c1bee02023-06-01 16:51:35 -070040 virtual binder::Status onStatusChanged(int32_t , const std::string&) {
Austin Borger86a588e2022-05-23 12:41:58 -070041 return binder::Status::ok();
42 };
43
44 virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
Austin Borger1c1bee02023-06-01 16:51:35 -070045 const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070046 // No op
47 return binder::Status::ok();
48 };
49
Austin Borger1c1bee02023-06-01 16:51:35 -070050 virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
51 const std::string& /*cameraId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070052 return binder::Status::ok();
53 };
54
55 virtual binder::Status onCameraAccessPrioritiesChanged() {
56 // No op
57 return binder::Status::ok();
58 }
59
Austin Borger1c1bee02023-06-01 16:51:35 -070060 virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
61 const std::string& /*clientPackageName*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070062 // No op
63 return binder::Status::ok();
64 }
65
Austin Borger1c1bee02023-06-01 16:51:35 -070066 virtual binder::Status onCameraClosed(const std::string& /*cameraId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070067 // No op
68 return binder::Status::ok();
69 }
70
Austin Borger1c1bee02023-06-01 16:51:35 -070071 virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
Austin Borger86a588e2022-05-23 12:41:58 -070072 int32_t /*torchStrength*/) {
73 // No op
74 return binder::Status::ok();
75 }
76};
77
78// Empty device callback.
79class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
80public:
81 TestCameraDeviceCallbacks() {}
82
83 virtual ~TestCameraDeviceCallbacks() {}
84
85 virtual binder::Status onDeviceError(int /*errorCode*/,
86 const CaptureResultExtras& /*resultExtras*/) {
87 return binder::Status::ok();
88 }
89
90 virtual binder::Status onDeviceIdle() {
91 return binder::Status::ok();
92 }
93
94 virtual binder::Status onCaptureStarted(const CaptureResultExtras& /*resultExtras*/,
95 int64_t /*timestamp*/) {
96 return binder::Status::ok();
97 }
98
99 virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
100 const CaptureResultExtras& /*resultExtras*/,
101 const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
102 return binder::Status::ok();
103 }
104
105 virtual binder::Status onPrepared(int /*streamId*/) {
106 return binder::Status::ok();
107 }
108
109 virtual binder::Status onRepeatingRequestError(
110 int64_t /*lastFrameNumber*/, int32_t /*stoppedSequenceId*/) {
111 return binder::Status::ok();
112 }
113
114 virtual binder::Status onRequestQueueEmpty() {
115 return binder::Status::ok();
116 }
117};
118
119// Override isCameraDisabled from the CameraServiceProxy with a flag.
120class CameraServiceProxyOverride : public ::android::hardware::BnCameraServiceProxy {
121public:
122 CameraServiceProxyOverride() :
123 mCameraServiceProxy(CameraServiceProxyWrapper::getDefaultCameraServiceProxy()),
Greg Kaiserf18ea7c2022-06-06 09:39:00 -0700124 mCameraDisabled(false), mOverrideCameraDisabled(false)
Austin Borger86a588e2022-05-23 12:41:58 -0700125 { }
126
Austin Borger1c1bee02023-06-01 16:51:35 -0700127 virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
Austin Borger86a588e2022-05-23 12:41:58 -0700128 int userId, int *ret) override {
129 return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
130 userId, ret);
131 }
132
Austin Borger1c1bee02023-06-01 16:51:35 -0700133 virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
Bharatt Kukreja7146ced2022-10-25 15:45:29 +0000134 return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
135 }
136
Austin Borger86a588e2022-05-23 12:41:58 -0700137 virtual binder::Status pingForUserUpdate() override {
138 return mCameraServiceProxy->pingForUserUpdate();
139 }
140
141 virtual binder::Status notifyCameraState(
142 const hardware::CameraSessionStats& cameraSessionStats) override {
143 return mCameraServiceProxy->notifyCameraState(cameraSessionStats);
144 }
145
Austin Borger9bfa0a72022-08-03 17:50:40 -0700146 virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
Austin Borger86a588e2022-05-23 12:41:58 -0700147 if (mOverrideCameraDisabled) {
148 *ret = mCameraDisabled;
149 return binder::Status::ok();
150 }
Austin Borger9bfa0a72022-08-03 17:50:40 -0700151 return mCameraServiceProxy->isCameraDisabled(userId, ret);
Austin Borger86a588e2022-05-23 12:41:58 -0700152 }
153
154 void setCameraDisabled(bool cameraDisabled) {
155 mCameraDisabled = cameraDisabled;
156 }
157
158 void setOverrideCameraDisabled(bool overrideCameraDisabled) {
159 mOverrideCameraDisabled = overrideCameraDisabled;
160 }
161
162protected:
163 sp<hardware::ICameraServiceProxy> mCameraServiceProxy;
164 bool mCameraDisabled;
165 bool mOverrideCameraDisabled;
166};
167
168class AutoDisconnectDevice {
169public:
170 AutoDisconnectDevice(sp<hardware::camera2::ICameraDeviceUser> device) :
171 mDevice(device)
172 { }
173
174 ~AutoDisconnectDevice() {
Austin Borger9bfa0a72022-08-03 17:50:40 -0700175 if (mDevice != nullptr) {
Austin Borger86a588e2022-05-23 12:41:58 -0700176 mDevice->disconnect();
177 }
178 }
179
180private:
181 sp<hardware::camera2::ICameraDeviceUser> mDevice;
182};
183
184class CameraPermissionsTest : public ::testing::Test {
185protected:
186 static sp<CameraService> sCameraService;
187 static sp<CameraServiceProxyOverride> sCameraServiceProxy;
188 static std::shared_ptr<CameraServiceProxyWrapper> sCameraServiceProxyWrapper;
189 static uid_t sOldUid;
190
191 static void SetUpTestSuite() {
192 sOldUid = getuid();
193 setuid(AID_CAMERASERVER);
194 sCameraServiceProxy = new CameraServiceProxyOverride();
195 sCameraServiceProxyWrapper =
196 std::make_shared<CameraServiceProxyWrapper>(sCameraServiceProxy);
197 sCameraService = new CameraService(sCameraServiceProxyWrapper);
198 sCameraService->clearCachedVariables();
199 }
200
201 static void TearDownTestSuite() {
202 sCameraServiceProxyWrapper = nullptr;
203 sCameraServiceProxy = nullptr;
204 sCameraService = nullptr;
205 setuid(sOldUid);
206 }
207};
208
209sp<CameraService> CameraPermissionsTest::sCameraService = nullptr;
210sp<CameraServiceProxyOverride> CameraPermissionsTest::sCameraServiceProxy = nullptr;
211std::shared_ptr<CameraServiceProxyWrapper>
212CameraPermissionsTest::sCameraServiceProxyWrapper = nullptr;
213uid_t CameraPermissionsTest::sOldUid = 0;
214
215// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
216// policy, and succeed when it isn't.
217TEST_F(CameraPermissionsTest, TestCameraDisabled) {
218 std::vector<hardware::CameraStatus> statuses;
219 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
220 sCameraService->addListenerTest(serviceListener, &statuses);
221 sCameraServiceProxy->setOverrideCameraDisabled(true);
222
223 sCameraServiceProxy->setCameraDisabled(true);
224 for (auto s : statuses) {
225 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
226 sp<hardware::camera2::ICameraDeviceUser> device;
227 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700228 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700229 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700230 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700231 AutoDisconnectDevice autoDisconnect(device);
232 ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
233 ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
234 << "connectDevice returned exception code " << status.exceptionCode();
235 }
236
237 sCameraServiceProxy->setCameraDisabled(false);
238 for (auto s : statuses) {
239 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
240 sp<hardware::camera2::ICameraDeviceUser> device;
241 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700242 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700243 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700244 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700245 AutoDisconnectDevice autoDisconnect(device);
246 ASSERT_TRUE(status.isOk());
247 }
248}
249
250// Test that consecutive camera connections succeed.
251TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
252 std::vector<hardware::CameraStatus> statuses;
253 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
254 sCameraService->addListenerTest(serviceListener, &statuses);
255 sCameraServiceProxy->setOverrideCameraDisabled(false);
256
257 for (auto s : statuses) {
258 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
259 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
260 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700261 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700262 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700263 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700264 AutoDisconnectDevice autoDisconnectA(deviceA);
265 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
266 " service specific error code " << status.serviceSpecificErrorCode();
267 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700268 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700269 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700270 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700271 AutoDisconnectDevice autoDisconnectB(deviceB);
272 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
273 " service specific error code " << status.serviceSpecificErrorCode();
274 }
275}
276
277// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
278// in the second call.
279TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
280 std::vector<hardware::CameraStatus> statuses;
281 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
282 sCameraService->addListenerTest(serviceListener, &statuses);
283 sCameraServiceProxy->setOverrideCameraDisabled(false);
284
285 for (auto s : statuses) {
286 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
287 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
288 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700289 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700290 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700291 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700292 AutoDisconnectDevice autoDisconnectA(deviceA);
293 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
294 " service specific error code " << status.serviceSpecificErrorCode();
295 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700296 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700297 android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700298 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700299 AutoDisconnectDevice autoDisconnectB(deviceB);
300 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
301 " service specific error code " << status.serviceSpecificErrorCode();
302 }
303}