blob: ff58c4aa73cb85d2a09f0cfe85645e86eaa2771f [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
Austin Borger65e64642024-06-11 15:58:23 -070017#include <android/content/AttributionSourceState.h>
Austin Borger86a588e2022-05-23 12:41:58 -070018#include <android/hardware/BnCameraServiceListener.h>
19#include <android/hardware/BnCameraServiceProxy.h>
20#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
21#include <android/hardware/ICameraService.h>
22
23#include <private/android_filesystem_config.h>
24
Biswarup Pal37a75182024-01-16 15:53:35 +000025#include <camera/CameraUtils.h>
26
Austin Borger86a588e2022-05-23 12:41:58 -070027#include "../CameraService.h"
28#include "../utils/CameraServiceProxyWrapper.h"
29
30#include <gtest/gtest.h>
31
32#include <memory>
33#include <vector>
34
35using namespace android;
36using namespace android::hardware::camera;
37
38// Empty service listener.
39class TestCameraServiceListener : public hardware::BnCameraServiceListener {
40public:
Biswarup Pal37a75182024-01-16 15:53:35 +000041 virtual ~TestCameraServiceListener() {}
Austin Borger86a588e2022-05-23 12:41:58 -070042
Biswarup Pal37a75182024-01-16 15:53:35 +000043 virtual binder::Status onStatusChanged(int32_t , const std::string&, int32_t) {
Austin Borger86a588e2022-05-23 12:41:58 -070044 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000045 }
Austin Borger86a588e2022-05-23 12:41:58 -070046
47 virtual binder::Status onPhysicalCameraStatusChanged(int32_t /*status*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000048 const std::string& /*cameraId*/, const std::string& /*physicalCameraId*/,
49 int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070050 // No op
51 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000052 }
Austin Borger86a588e2022-05-23 12:41:58 -070053
Austin Borger1c1bee02023-06-01 16:51:35 -070054 virtual binder::Status onTorchStatusChanged(int32_t /*status*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000055 const std::string& /*cameraId*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070056 return binder::Status::ok();
Biswarup Pal37a75182024-01-16 15:53:35 +000057 }
Austin Borger86a588e2022-05-23 12:41:58 -070058
59 virtual binder::Status onCameraAccessPrioritiesChanged() {
60 // No op
61 return binder::Status::ok();
62 }
63
Austin Borger1c1bee02023-06-01 16:51:35 -070064 virtual binder::Status onCameraOpened(const std::string& /*cameraId*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000065 const std::string& /*clientPackageName*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070066 // No op
67 return binder::Status::ok();
68 }
69
Biswarup Pal37a75182024-01-16 15:53:35 +000070 virtual binder::Status onCameraClosed(const std::string& /*cameraId*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070071 // No op
72 return binder::Status::ok();
73 }
74
Austin Borger1c1bee02023-06-01 16:51:35 -070075 virtual binder::Status onTorchStrengthLevelChanged(const std::string& /*cameraId*/,
Biswarup Pal37a75182024-01-16 15:53:35 +000076 int32_t /*torchStrength*/, int32_t /*deviceId*/) {
Austin Borger86a588e2022-05-23 12:41:58 -070077 // No op
78 return binder::Status::ok();
79 }
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070080
81 virtual binder::Status onCameraOpenedInSharedMode(const std::string& /*cameraId*/,
82 const std::string& /*clientPackageName*/, int32_t /*deviceId*/,
83 bool /*isPrimaryClient*/) {
84 // No op
85 return binder::Status::ok();
86 }
Austin Borger86a588e2022-05-23 12:41:58 -070087};
88
89// Empty device callback.
90class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
91public:
92 TestCameraDeviceCallbacks() {}
93
94 virtual ~TestCameraDeviceCallbacks() {}
95
96 virtual binder::Status onDeviceError(int /*errorCode*/,
97 const CaptureResultExtras& /*resultExtras*/) {
98 return binder::Status::ok();
99 }
100
101 virtual binder::Status onDeviceIdle() {
102 return binder::Status::ok();
103 }
104
105 virtual binder::Status onCaptureStarted(const CaptureResultExtras& /*resultExtras*/,
106 int64_t /*timestamp*/) {
107 return binder::Status::ok();
108 }
109
110 virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
111 const CaptureResultExtras& /*resultExtras*/,
112 const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
113 return binder::Status::ok();
114 }
115
116 virtual binder::Status onPrepared(int /*streamId*/) {
117 return binder::Status::ok();
118 }
119
120 virtual binder::Status onRepeatingRequestError(
121 int64_t /*lastFrameNumber*/, int32_t /*stoppedSequenceId*/) {
122 return binder::Status::ok();
123 }
124
125 virtual binder::Status onRequestQueueEmpty() {
126 return binder::Status::ok();
127 }
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700128
129 virtual binder::Status onClientSharedAccessPriorityChanged(bool /*isPrimaryClient*/) {
130 return binder::Status::ok();
131 }
Austin Borger86a588e2022-05-23 12:41:58 -0700132};
133
134// Override isCameraDisabled from the CameraServiceProxy with a flag.
135class CameraServiceProxyOverride : public ::android::hardware::BnCameraServiceProxy {
136public:
137 CameraServiceProxyOverride() :
138 mCameraServiceProxy(CameraServiceProxyWrapper::getDefaultCameraServiceProxy()),
Greg Kaiserf18ea7c2022-06-06 09:39:00 -0700139 mCameraDisabled(false), mOverrideCameraDisabled(false)
Austin Borger86a588e2022-05-23 12:41:58 -0700140 { }
141
Austin Borger1c1bee02023-06-01 16:51:35 -0700142 virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
Austin Borger86a588e2022-05-23 12:41:58 -0700143 int userId, int *ret) override {
144 return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
145 userId, ret);
146 }
147
Austin Borger1c1bee02023-06-01 16:51:35 -0700148 virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
Bharatt Kukreja7146ced2022-10-25 15:45:29 +0000149 return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
150 }
151
Austin Borger86a588e2022-05-23 12:41:58 -0700152 virtual binder::Status pingForUserUpdate() override {
153 return mCameraServiceProxy->pingForUserUpdate();
154 }
155
156 virtual binder::Status notifyCameraState(
157 const hardware::CameraSessionStats& cameraSessionStats) override {
158 return mCameraServiceProxy->notifyCameraState(cameraSessionStats);
159 }
160
Shuzhen Wange3e8e732024-05-22 17:48:01 -0700161 virtual binder::Status notifyFeatureCombinationStats(
162 const hardware::CameraFeatureCombinationStats& featureCombStats) override {
163 return mCameraServiceProxy->notifyFeatureCombinationStats(featureCombStats);
164 }
165
Austin Borger9bfa0a72022-08-03 17:50:40 -0700166 virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
Austin Borger86a588e2022-05-23 12:41:58 -0700167 if (mOverrideCameraDisabled) {
168 *ret = mCameraDisabled;
169 return binder::Status::ok();
170 }
Austin Borger9bfa0a72022-08-03 17:50:40 -0700171 return mCameraServiceProxy->isCameraDisabled(userId, ret);
Austin Borger86a588e2022-05-23 12:41:58 -0700172 }
173
174 void setCameraDisabled(bool cameraDisabled) {
175 mCameraDisabled = cameraDisabled;
176 }
177
178 void setOverrideCameraDisabled(bool overrideCameraDisabled) {
179 mOverrideCameraDisabled = overrideCameraDisabled;
180 }
181
182protected:
183 sp<hardware::ICameraServiceProxy> mCameraServiceProxy;
184 bool mCameraDisabled;
185 bool mOverrideCameraDisabled;
186};
187
188class AutoDisconnectDevice {
189public:
190 AutoDisconnectDevice(sp<hardware::camera2::ICameraDeviceUser> device) :
191 mDevice(device)
192 { }
193
194 ~AutoDisconnectDevice() {
Austin Borger9bfa0a72022-08-03 17:50:40 -0700195 if (mDevice != nullptr) {
Austin Borger86a588e2022-05-23 12:41:58 -0700196 mDevice->disconnect();
197 }
198 }
199
200private:
201 sp<hardware::camera2::ICameraDeviceUser> mDevice;
202};
203
204class CameraPermissionsTest : public ::testing::Test {
205protected:
206 static sp<CameraService> sCameraService;
207 static sp<CameraServiceProxyOverride> sCameraServiceProxy;
208 static std::shared_ptr<CameraServiceProxyWrapper> sCameraServiceProxyWrapper;
209 static uid_t sOldUid;
210
211 static void SetUpTestSuite() {
212 sOldUid = getuid();
213 setuid(AID_CAMERASERVER);
214 sCameraServiceProxy = new CameraServiceProxyOverride();
215 sCameraServiceProxyWrapper =
216 std::make_shared<CameraServiceProxyWrapper>(sCameraServiceProxy);
217 sCameraService = new CameraService(sCameraServiceProxyWrapper);
218 sCameraService->clearCachedVariables();
219 }
220
221 static void TearDownTestSuite() {
222 sCameraServiceProxyWrapper = nullptr;
223 sCameraServiceProxy = nullptr;
224 sCameraService = nullptr;
225 setuid(sOldUid);
226 }
227};
228
229sp<CameraService> CameraPermissionsTest::sCameraService = nullptr;
230sp<CameraServiceProxyOverride> CameraPermissionsTest::sCameraServiceProxy = nullptr;
231std::shared_ptr<CameraServiceProxyWrapper>
232CameraPermissionsTest::sCameraServiceProxyWrapper = nullptr;
233uid_t CameraPermissionsTest::sOldUid = 0;
234
235// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
236// policy, and succeed when it isn't.
237TEST_F(CameraPermissionsTest, TestCameraDisabled) {
Austin Borger65e64642024-06-11 15:58:23 -0700238 AttributionSourceState clientAttribution;
239 clientAttribution.deviceId = kDefaultDeviceId;
240 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700241 clientAttribution.pid = android::CameraService::USE_CALLING_PID;
Austin Borger65e64642024-06-11 15:58:23 -0700242
Austin Borger86a588e2022-05-23 12:41:58 -0700243 std::vector<hardware::CameraStatus> statuses;
244 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
245 sCameraService->addListenerTest(serviceListener, &statuses);
246 sCameraServiceProxy->setOverrideCameraDisabled(true);
247
248 sCameraServiceProxy->setCameraDisabled(true);
249 for (auto s : statuses) {
250 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
251 sp<hardware::camera2::ICameraDeviceUser> device;
252 binder::Status status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700253 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700254 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000255 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700256 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700257 AutoDisconnectDevice autoDisconnect(device);
258 ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
259 ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
260 << "connectDevice returned exception code " << status.exceptionCode();
261 }
262
263 sCameraServiceProxy->setCameraDisabled(false);
264 for (auto s : statuses) {
265 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
266 sp<hardware::camera2::ICameraDeviceUser> device;
267 binder::Status status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700268 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700269 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000270 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700271 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700272 AutoDisconnectDevice autoDisconnect(device);
273 ASSERT_TRUE(status.isOk());
274 }
275}
276
277// Test that consecutive camera connections succeed.
278TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
Austin Borger65e64642024-06-11 15:58:23 -0700279 AttributionSourceState clientAttribution;
280 clientAttribution.deviceId = kDefaultDeviceId;
281 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
282
Austin Borger86a588e2022-05-23 12:41:58 -0700283 std::vector<hardware::CameraStatus> statuses;
284 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
285 sCameraService->addListenerTest(serviceListener, &statuses);
286 sCameraServiceProxy->setOverrideCameraDisabled(false);
287
288 for (auto s : statuses) {
289 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
290 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
291 binder::Status status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700292 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700293 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000294 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700295 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700296 AutoDisconnectDevice autoDisconnectA(deviceA);
297 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
298 " service specific error code " << status.serviceSpecificErrorCode();
299 status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700300 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700301 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000302 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700303 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700304 AutoDisconnectDevice autoDisconnectB(deviceB);
305 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
306 " service specific error code " << status.serviceSpecificErrorCode();
307 }
308}
309
310// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
311// in the second call.
312TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
Austin Borger65e64642024-06-11 15:58:23 -0700313 AttributionSourceState clientAttribution;
314 clientAttribution.deviceId = kDefaultDeviceId;
315 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
316
Austin Borger86a588e2022-05-23 12:41:58 -0700317 std::vector<hardware::CameraStatus> statuses;
318 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
319 sCameraService->addListenerTest(serviceListener, &statuses);
320 sCameraServiceProxy->setOverrideCameraDisabled(false);
321
322 for (auto s : statuses) {
323 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
324 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
325 binder::Status status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700326 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700327 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000328 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700329 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700330 AutoDisconnectDevice autoDisconnectA(deviceA);
331 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
332 " service specific error code " << status.serviceSpecificErrorCode();
333 status =
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700334 sCameraService->connectDevice(callbacks, s.cameraId,
Austin Borger65e64642024-06-11 15:58:23 -0700335 1/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000336 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700337 clientAttribution, /*devicePolicy*/0, /*sharedMode*/false, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700338 AutoDisconnectDevice autoDisconnectB(deviceB);
339 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
340 " service specific error code " << status.serviceSpecificErrorCode();
341 }
342}