blob: cf86a05abb84e12cbb7648773c792fec02931ea7 [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
Austin Borger9bfa0a72022-08-03 17:50:40 -0700149 virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
Austin Borger86a588e2022-05-23 12:41:58 -0700150 if (mOverrideCameraDisabled) {
151 *ret = mCameraDisabled;
152 return binder::Status::ok();
153 }
Austin Borger9bfa0a72022-08-03 17:50:40 -0700154 return mCameraServiceProxy->isCameraDisabled(userId, ret);
Austin Borger86a588e2022-05-23 12:41:58 -0700155 }
156
157 void setCameraDisabled(bool cameraDisabled) {
158 mCameraDisabled = cameraDisabled;
159 }
160
161 void setOverrideCameraDisabled(bool overrideCameraDisabled) {
162 mOverrideCameraDisabled = overrideCameraDisabled;
163 }
164
165protected:
166 sp<hardware::ICameraServiceProxy> mCameraServiceProxy;
167 bool mCameraDisabled;
168 bool mOverrideCameraDisabled;
169};
170
171class AutoDisconnectDevice {
172public:
173 AutoDisconnectDevice(sp<hardware::camera2::ICameraDeviceUser> device) :
174 mDevice(device)
175 { }
176
177 ~AutoDisconnectDevice() {
Austin Borger9bfa0a72022-08-03 17:50:40 -0700178 if (mDevice != nullptr) {
Austin Borger86a588e2022-05-23 12:41:58 -0700179 mDevice->disconnect();
180 }
181 }
182
183private:
184 sp<hardware::camera2::ICameraDeviceUser> mDevice;
185};
186
187class CameraPermissionsTest : public ::testing::Test {
188protected:
189 static sp<CameraService> sCameraService;
190 static sp<CameraServiceProxyOverride> sCameraServiceProxy;
191 static std::shared_ptr<CameraServiceProxyWrapper> sCameraServiceProxyWrapper;
192 static uid_t sOldUid;
193
194 static void SetUpTestSuite() {
195 sOldUid = getuid();
196 setuid(AID_CAMERASERVER);
197 sCameraServiceProxy = new CameraServiceProxyOverride();
198 sCameraServiceProxyWrapper =
199 std::make_shared<CameraServiceProxyWrapper>(sCameraServiceProxy);
200 sCameraService = new CameraService(sCameraServiceProxyWrapper);
201 sCameraService->clearCachedVariables();
202 }
203
204 static void TearDownTestSuite() {
205 sCameraServiceProxyWrapper = nullptr;
206 sCameraServiceProxy = nullptr;
207 sCameraService = nullptr;
208 setuid(sOldUid);
209 }
210};
211
212sp<CameraService> CameraPermissionsTest::sCameraService = nullptr;
213sp<CameraServiceProxyOverride> CameraPermissionsTest::sCameraServiceProxy = nullptr;
214std::shared_ptr<CameraServiceProxyWrapper>
215CameraPermissionsTest::sCameraServiceProxyWrapper = nullptr;
216uid_t CameraPermissionsTest::sOldUid = 0;
217
218// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
219// policy, and succeed when it isn't.
220TEST_F(CameraPermissionsTest, TestCameraDisabled) {
221 std::vector<hardware::CameraStatus> statuses;
222 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
223 sCameraService->addListenerTest(serviceListener, &statuses);
224 sCameraServiceProxy->setOverrideCameraDisabled(true);
225
226 sCameraServiceProxy->setCameraDisabled(true);
227 for (auto s : statuses) {
228 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
229 sp<hardware::camera2::ICameraDeviceUser> device;
230 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700231 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700232 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000233 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
234 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000235 kDefaultDeviceId, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700236 AutoDisconnectDevice autoDisconnect(device);
237 ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
238 ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
239 << "connectDevice returned exception code " << status.exceptionCode();
240 }
241
242 sCameraServiceProxy->setCameraDisabled(false);
243 for (auto s : statuses) {
244 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
245 sp<hardware::camera2::ICameraDeviceUser> device;
246 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700247 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700248 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000249 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
250 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000251 kDefaultDeviceId, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700252 AutoDisconnectDevice autoDisconnect(device);
253 ASSERT_TRUE(status.isOk());
254 }
255}
256
257// Test that consecutive camera connections succeed.
258TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
259 std::vector<hardware::CameraStatus> statuses;
260 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
261 sCameraService->addListenerTest(serviceListener, &statuses);
262 sCameraServiceProxy->setOverrideCameraDisabled(false);
263
264 for (auto s : statuses) {
265 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
266 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
267 binder::Status 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*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000270 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
271 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000272 kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700273 AutoDisconnectDevice autoDisconnectA(deviceA);
274 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
275 " service specific error code " << status.serviceSpecificErrorCode();
276 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700277 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700278 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000279 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
280 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000281 kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700282 AutoDisconnectDevice autoDisconnectB(deviceB);
283 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
284 " service specific error code " << status.serviceSpecificErrorCode();
285 }
286}
287
288// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
289// in the second call.
290TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
291 std::vector<hardware::CameraStatus> statuses;
292 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
293 sCameraService->addListenerTest(serviceListener, &statuses);
294 sCameraServiceProxy->setOverrideCameraDisabled(false);
295
296 for (auto s : statuses) {
297 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
298 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
299 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700300 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700301 android::CameraService::USE_CALLING_UID, 0/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000302 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
303 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000304 kDefaultDeviceId, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700305 AutoDisconnectDevice autoDisconnectA(deviceA);
306 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
307 " service specific error code " << status.serviceSpecificErrorCode();
308 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700309 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger86a588e2022-05-23 12:41:58 -0700310 android::CameraService::USE_CALLING_UID, 1/*oomScoreDiff*/,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000311 /*targetSdkVersion*/__ANDROID_API_FUTURE__,
312 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Biswarup Pal37a75182024-01-16 15:53:35 +0000313 kDefaultDeviceId, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700314 AutoDisconnectDevice autoDisconnectB(deviceB);
315 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
316 " service specific error code " << status.serviceSpecificErrorCode();
317 }
318}