blob: feb55409b42952974260d656228881c6a47b793a [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
Biswarup Pal37a75182024-01-16 15:53:35 +000024#include <camera/CameraUtils.h>
25
Austin Borger86a588e2022-05-23 12:41:58 -070026#include "../CameraService.h"
27#include "../utils/CameraServiceProxyWrapper.h"
28
29#include <gtest/gtest.h>
30
31#include <memory>
32#include <vector>
33
34using namespace android;
35using namespace android::hardware::camera;
36
37// Empty service listener.
38class TestCameraServiceListener : public hardware::BnCameraServiceListener {
39public:
Biswarup Pal37a75182024-01-16 15:53:35 +000040 virtual ~TestCameraServiceListener() {}
Austin Borger86a588e2022-05-23 12:41:58 -070041
Biswarup Pal37a75182024-01-16 15:53:35 +000042 virtual binder::Status onStatusChanged(int32_t , const std::string&, int32_t) {
Austin Borger86a588e2022-05-23 12:41:58 -070043 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000044 }
Austin Borger86a588e2022-05-23 12:41:58 -070045
46 virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000047 const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/,
48 int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070049 // No op
50 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000051 }
Austin Borger86a588e2022-05-23 12:41:58 -070052
Austin Borger1c1bee02023-06-01 16:51:35 -070053 virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000054 const std::string& /*cameraId*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070055 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000056 }
Austin Borger86a588e2022-05-23 12:41:58 -070057
58 virtual binder::Status onCameraAccessPrioritiesChanged() {
59 // No op
60 return binder::Status::ok();
61 }
62
Austin Borger1c1bee02023-06-01 16:51:35 -070063 virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000064 const std::string& /*clientPackageName*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070065 // No op
66 return binder::Status::ok();
67 }
68
Biswarup Pal37a75182024-01-16 15:53:35 +000069 virtual binder::Status onCameraClosed(const std::string& /*cameraId*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070070 // No op
71 return binder::Status::ok();
72 }
73
Austin Borger1c1bee02023-06-01 16:51:35 -070074 virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000075 int32_t /*torchStrength*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070076 // No op
77 return binder::Status::ok();
78 }
79};
80
81// Empty device callback.
82class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
83public:
84 TestCameraDeviceCallbacks() {}
85
86 virtual ~TestCameraDeviceCallbacks() {}
87
88 virtual binder::Status onDeviceError(int /*errorCode*/,
89 const CaptureResultExtras& /*resultExtras*/) {
90 return binder::Status::ok();
91 }
92
93 virtual binder::Status onDeviceIdle() {
94 return binder::Status::ok();
95 }
96
97 virtual binder::Status onCaptureStarted(const CaptureResultExtras& /*resultExtras*/,
98 int64_t /*timestamp*/) {
99 return binder::Status::ok();
100 }
101
102 virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
103 const CaptureResultExtras& /*resultExtras*/,
104 const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
105 return binder::Status::ok();
106 }
107
108 virtual binder::Status onPrepared(int /*streamId*/) {
109 return binder::Status::ok();
110 }
111
112 virtual binder::Status onRepeatingRequestError(
113 int64_t /*lastFrameNumber*/, int32_t /*stoppedSequenceId*/) {
114 return binder::Status::ok();
115 }
116
117 virtual binder::Status onRequestQueueEmpty() {
118 return binder::Status::ok();
119 }
120};
121
122// Override isCameraDisabled from the CameraServiceProxy with a flag.
123class CameraServiceProxyOverride : public ::android::hardware::BnCameraServiceProxy {
124public:
125 CameraServiceProxyOverride() :
126 mCameraServiceProxy(CameraServiceProxyWrapper::getDefaultCameraServiceProxy()),
Greg Kaiserf18ea7c2022-06-06 09:39:00 -0700127 mCameraDisabled(false), mOverrideCameraDisabled(false)
Austin Borger86a588e2022-05-23 12:41:58 -0700128 { }
129
Austin Borger1c1bee02023-06-01 16:51:35 -0700130 virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
Austin Borger86a588e2022-05-23 12:41:58 -0700131 int userId, int *ret) override {
132 return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
133 userId, ret);
134 }
135
Austin Borger1c1bee02023-06-01 16:51:35 -0700136 virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
Bharatt Kukreja7146ced2022-10-25 15:45:29 +0000137 return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
138 }
139
Austin Borger86a588e2022-05-23 12:41:58 -0700140 virtual binder::Status pingForUserUpdate() override {
141 return mCameraServiceProxy->pingForUserUpdate();
142 }
143
144 virtual binder::Status notifyCameraState(
145 const hardware::CameraSessionStats& cameraSessionStats) override {
146 return mCameraServiceProxy->notifyCameraState(cameraSessionStats);
147 }
148
Shuzhen Wange3e8e732024-05-22 17:48:01 -0700149 virtual binder::Status notifyFeatureCombinationStats(
150 const hardware::CameraFeatureCombinationStats& featureCombStats) override {
151 return mCameraServiceProxy->notifyFeatureCombinationStats(featureCombStats);
152 }
153
Austin Borger9bfa0a72022-08-03 17:50:40 -0700154 virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
Austin Borger86a588e2022-05-23 12:41:58 -0700155 if (mOverrideCameraDisabled) {
156 *ret = mCameraDisabled;
157 return binder::Status::ok();
158 }
Austin Borger9bfa0a72022-08-03 17:50:40 -0700159 return mCameraServiceProxy->isCameraDisabled(userId, ret);
Austin Borger86a588e2022-05-23 12:41:58 -0700160 }
161
162 void setCameraDisabled(bool cameraDisabled) {
163 mCameraDisabled = cameraDisabled;
164 }
165
166 void setOverrideCameraDisabled(bool overrideCameraDisabled) {
167 mOverrideCameraDisabled = overrideCameraDisabled;
168 }
169
170protected:
171 sp<hardware::ICameraServiceProxy> mCameraServiceProxy;
172 bool mCameraDisabled;
173 bool mOverrideCameraDisabled;
174};
175
176class AutoDisconnectDevice {
177public:
178 AutoDisconnectDevice(sp<hardware::camera2::ICameraDeviceUser> device) :
179 mDevice(device)
180 { }
181
182 ~AutoDisconnectDevice() {
Austin Borger9bfa0a72022-08-03 17:50:40 -0700183 if (mDevice != nullptr) {
Austin Borger86a588e2022-05-23 12:41:58 -0700184 mDevice->disconnect();
185 }
186 }
187
188private:
189 sp<hardware::camera2::ICameraDeviceUser> mDevice;
190};
191
192class CameraPermissionsTest : public ::testing::Test {
193protected:
194 static sp<CameraService> sCameraService;
195 static sp<CameraServiceProxyOverride> sCameraServiceProxy;
196 static std::shared_ptr<CameraServiceProxyWrapper> sCameraServiceProxyWrapper;
197 static uid_t sOldUid;
198
199 static void SetUpTestSuite() {
200 sOldUid = getuid();
201 setuid(AID_CAMERASERVER);
202 sCameraServiceProxy = new CameraServiceProxyOverride();
203 sCameraServiceProxyWrapper =
204 std::make_shared<CameraServiceProxyWrapper>(sCameraServiceProxy);
205 sCameraService = new CameraService(sCameraServiceProxyWrapper);
206 sCameraService->clearCachedVariables();
207 }
208
209 static void TearDownTestSuite() {
210 sCameraServiceProxyWrapper = nullptr;
211 sCameraServiceProxy = nullptr;
212 sCameraService = nullptr;
213 setuid(sOldUid);
214 }
215};
216
217sp<CameraService> CameraPermissionsTest::sCameraService = nullptr;
218sp<CameraServiceProxyOverride> CameraPermissionsTest::sCameraServiceProxy = nullptr;
219std::shared_ptr<CameraServiceProxyWrapper>
220CameraPermissionsTest::sCameraServiceProxyWrapper = nullptr;
221uid_t CameraPermissionsTest::sOldUid = 0;
222
223// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
224// policy, and succeed when it isn't.
225TEST_F(CameraPermissionsTest, TestCameraDisabled) {
226 std::vector<hardware::CameraStatus> statuses;
227 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
228 sCameraService->addListenerTest(serviceListener, &statuses);
229 sCameraServiceProxy->setOverrideCameraDisabled(true);
230
231 sCameraServiceProxy->setCameraDisabled(true);
232 for (auto s : statuses) {
233 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
234 sp<hardware::camera2::ICameraDeviceUser> device;
235 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700236 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700237 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000238 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
239 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000240 kDefaultDeviceId, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700241 AutoDisconnectDevice autoDisconnect(device);
242 ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
243 ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
244 << "connectDevice returned exception code " << status.exceptionCode();
245 }
246
247 sCameraServiceProxy->setCameraDisabled(false);
248 for (auto s : statuses) {
249 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
250 sp<hardware::camera2::ICameraDeviceUser> device;
251 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700252 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700253 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000254 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
255 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000256 kDefaultDeviceId, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700257 AutoDisconnectDevice autoDisconnect(device);
258 ASSERT_TRUE(status.isOk());
259 }
260}
261
262// Test that consecutive camera connections succeed.
263TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
264 std::vector<hardware::CameraStatus> statuses;
265 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
266 sCameraService->addListenerTest(serviceListener, &statuses);
267 sCameraServiceProxy->setOverrideCameraDisabled(false);
268
269 for (auto s : statuses) {
270 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
271 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
272 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700273 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700274 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000275 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
276 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000277 kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700278 AutoDisconnectDevice autoDisconnectA(deviceA);
279 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
280 " service specific error code " << status.serviceSpecificErrorCode();
281 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700282 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700283 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000284 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
285 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000286 kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700287 AutoDisconnectDevice autoDisconnectB(deviceB);
288 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
289 " service specific error code " << status.serviceSpecificErrorCode();
290 }
291}
292
293// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
294// in the second call.
295TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
296 std::vector<hardware::CameraStatus> statuses;
297 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
298 sCameraService->addListenerTest(serviceListener, &statuses);
299 sCameraServiceProxy->setOverrideCameraDisabled(false);
300
301 for (auto s : statuses) {
302 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
303 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
304 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700305 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700306 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000307 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
308 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000309 kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700310 AutoDisconnectDevice autoDisconnectA(deviceA);
311 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
312 " service specific error code " << status.serviceSpecificErrorCode();
313 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700314 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700315 android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000316 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
317 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000318 kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700319 AutoDisconnectDevice autoDisconnectB(deviceB);
320 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
321 " service specific error code " << status.serviceSpecificErrorCode();
322 }
323}