blob: cd07a69713a1bdb9523d9203f19e15688b6a7134 [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 }
80};
81
82// Empty device callback.
83class TestCameraDeviceCallbacks : public hardware::camera2::BnCameraDeviceCallbacks {
84public:
85 TestCameraDeviceCallbacks() {}
86
87 virtual ~TestCameraDeviceCallbacks() {}
88
89 virtual binder::Status onDeviceError(int /*errorCode*/,
90 const CaptureResultExtras& /*resultExtras*/) {
91 return binder::Status::ok();
92 }
93
94 virtual binder::Status onDeviceIdle() {
95 return binder::Status::ok();
96 }
97
98 virtual binder::Status onCaptureStarted(const CaptureResultExtras& /*resultExtras*/,
99 int64_t /*timestamp*/) {
100 return binder::Status::ok();
101 }
102
103 virtual binder::Status onResultReceived(const CameraMetadata& /*metadata*/,
104 const CaptureResultExtras& /*resultExtras*/,
105 const std::vector<PhysicalCaptureResultInfo>& /*physicalResultInfos*/) {
106 return binder::Status::ok();
107 }
108
109 virtual binder::Status onPrepared(int /*streamId*/) {
110 return binder::Status::ok();
111 }
112
113 virtual binder::Status onRepeatingRequestError(
114 int64_t /*lastFrameNumber*/, int32_t /*stoppedSequenceId*/) {
115 return binder::Status::ok();
116 }
117
118 virtual binder::Status onRequestQueueEmpty() {
119 return binder::Status::ok();
120 }
121};
122
123// Override isCameraDisabled from the CameraServiceProxy with a flag.
124class CameraServiceProxyOverride : public ::android::hardware::BnCameraServiceProxy {
125public:
126 CameraServiceProxyOverride() :
127 mCameraServiceProxy(CameraServiceProxyWrapper::getDefaultCameraServiceProxy()),
Greg Kaiserf18ea7c2022-06-06 09:39:00 -0700128 mCameraDisabled(false), mOverrideCameraDisabled(false)
Austin Borger86a588e2022-05-23 12:41:58 -0700129 { }
130
Austin Borger1c1bee02023-06-01 16:51:35 -0700131 virtual binder::Status getRotateAndCropOverride(const std::string& packageName, int lensFacing,
Austin Borger86a588e2022-05-23 12:41:58 -0700132 int userId, int *ret) override {
133 return mCameraServiceProxy->getRotateAndCropOverride(packageName, lensFacing,
134 userId, ret);
135 }
136
Austin Borger1c1bee02023-06-01 16:51:35 -0700137 virtual binder::Status getAutoframingOverride(const std::string& packageName, int *ret) override {
Bharatt Kukreja7146ced2022-10-25 15:45:29 +0000138 return mCameraServiceProxy->getAutoframingOverride(packageName, ret);
139 }
140
Austin Borger86a588e2022-05-23 12:41:58 -0700141 virtual binder::Status pingForUserUpdate() override {
142 return mCameraServiceProxy->pingForUserUpdate();
143 }
144
145 virtual binder::Status notifyCameraState(
146 const hardware::CameraSessionStats& cameraSessionStats) override {
147 return mCameraServiceProxy->notifyCameraState(cameraSessionStats);
148 }
149
Shuzhen Wange3e8e732024-05-22 17:48:01 -0700150 virtual binder::Status notifyFeatureCombinationStats(
151 const hardware::CameraFeatureCombinationStats& featureCombStats) override {
152 return mCameraServiceProxy->notifyFeatureCombinationStats(featureCombStats);
153 }
154
Austin Borger9bfa0a72022-08-03 17:50:40 -0700155 virtual binder::Status isCameraDisabled(int userId, bool *ret) override {
Austin Borger86a588e2022-05-23 12:41:58 -0700156 if (mOverrideCameraDisabled) {
157 *ret = mCameraDisabled;
158 return binder::Status::ok();
159 }
Austin Borger9bfa0a72022-08-03 17:50:40 -0700160 return mCameraServiceProxy->isCameraDisabled(userId, ret);
Austin Borger86a588e2022-05-23 12:41:58 -0700161 }
162
163 void setCameraDisabled(bool cameraDisabled) {
164 mCameraDisabled = cameraDisabled;
165 }
166
167 void setOverrideCameraDisabled(bool overrideCameraDisabled) {
168 mOverrideCameraDisabled = overrideCameraDisabled;
169 }
170
171protected:
172 sp<hardware::ICameraServiceProxy> mCameraServiceProxy;
173 bool mCameraDisabled;
174 bool mOverrideCameraDisabled;
175};
176
177class AutoDisconnectDevice {
178public:
179 AutoDisconnectDevice(sp<hardware::camera2::ICameraDeviceUser> device) :
180 mDevice(device)
181 { }
182
183 ~AutoDisconnectDevice() {
Austin Borger9bfa0a72022-08-03 17:50:40 -0700184 if (mDevice != nullptr) {
Austin Borger86a588e2022-05-23 12:41:58 -0700185 mDevice->disconnect();
186 }
187 }
188
189private:
190 sp<hardware::camera2::ICameraDeviceUser> mDevice;
191};
192
193class CameraPermissionsTest : public ::testing::Test {
194protected:
195 static sp<CameraService> sCameraService;
196 static sp<CameraServiceProxyOverride> sCameraServiceProxy;
197 static std::shared_ptr<CameraServiceProxyWrapper> sCameraServiceProxyWrapper;
198 static uid_t sOldUid;
199
200 static void SetUpTestSuite() {
201 sOldUid = getuid();
202 setuid(AID_CAMERASERVER);
203 sCameraServiceProxy = new CameraServiceProxyOverride();
204 sCameraServiceProxyWrapper =
205 std::make_shared<CameraServiceProxyWrapper>(sCameraServiceProxy);
206 sCameraService = new CameraService(sCameraServiceProxyWrapper);
207 sCameraService->clearCachedVariables();
208 }
209
210 static void TearDownTestSuite() {
211 sCameraServiceProxyWrapper = nullptr;
212 sCameraServiceProxy = nullptr;
213 sCameraService = nullptr;
214 setuid(sOldUid);
215 }
216};
217
218sp<CameraService> CameraPermissionsTest::sCameraService = nullptr;
219sp<CameraServiceProxyOverride> CameraPermissionsTest::sCameraServiceProxy = nullptr;
220std::shared_ptr<CameraServiceProxyWrapper>
221CameraPermissionsTest::sCameraServiceProxyWrapper = nullptr;
222uid_t CameraPermissionsTest::sOldUid = 0;
223
224// Test that camera connections fail with ERROR_DISABLED when the camera is disabled via device
225// policy, and succeed when it isn't.
226TEST_F(CameraPermissionsTest, TestCameraDisabled) {
Austin Borger65e64642024-06-11 15:58:23 -0700227 AttributionSourceState clientAttribution;
228 clientAttribution.deviceId = kDefaultDeviceId;
229 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
230
Austin Borger86a588e2022-05-23 12:41:58 -0700231 std::vector<hardware::CameraStatus> statuses;
232 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
233 sCameraService->addListenerTest(serviceListener, &statuses);
234 sCameraServiceProxy->setOverrideCameraDisabled(true);
235
236 sCameraServiceProxy->setCameraDisabled(true);
237 for (auto s : statuses) {
238 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
239 sp<hardware::camera2::ICameraDeviceUser> device;
240 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700241 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700242 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000243 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700244 clientAttribution, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700245 AutoDisconnectDevice autoDisconnect(device);
246 ASSERT_TRUE(!status.isOk()) << "connectDevice returned OK status";
247 ASSERT_EQ(status.serviceSpecificErrorCode(), hardware::ICameraService::ERROR_DISABLED)
248 << "connectDevice returned exception code " << status.exceptionCode();
249 }
250
251 sCameraServiceProxy->setCameraDisabled(false);
252 for (auto s : statuses) {
253 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
254 sp<hardware::camera2::ICameraDeviceUser> device;
255 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700256 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700257 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000258 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700259 clientAttribution, /*devicePolicy*/0, &device);
Austin Borger86a588e2022-05-23 12:41:58 -0700260 AutoDisconnectDevice autoDisconnect(device);
261 ASSERT_TRUE(status.isOk());
262 }
263}
264
265// Test that consecutive camera connections succeed.
266TEST_F(CameraPermissionsTest, TestConsecutiveConnections) {
Austin Borger65e64642024-06-11 15:58:23 -0700267 AttributionSourceState clientAttribution;
268 clientAttribution.deviceId = kDefaultDeviceId;
269 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
270
Austin Borger86a588e2022-05-23 12:41:58 -0700271 std::vector<hardware::CameraStatus> statuses;
272 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
273 sCameraService->addListenerTest(serviceListener, &statuses);
274 sCameraServiceProxy->setOverrideCameraDisabled(false);
275
276 for (auto s : statuses) {
277 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
278 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
279 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700280 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700281 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000282 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700283 clientAttribution, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700284 AutoDisconnectDevice autoDisconnectA(deviceA);
285 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
286 " service specific error code " << status.serviceSpecificErrorCode();
287 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700288 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700289 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000290 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700291 clientAttribution, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700292 AutoDisconnectDevice autoDisconnectB(deviceB);
293 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
294 " service specific error code " << status.serviceSpecificErrorCode();
295 }
296}
297
298// Test that consecutive camera connections succeed even when a nonzero oomScoreOffset is provided
299// in the second call.
300TEST_F(CameraPermissionsTest, TestConflictingOomScoreOffset) {
Austin Borger65e64642024-06-11 15:58:23 -0700301 AttributionSourceState clientAttribution;
302 clientAttribution.deviceId = kDefaultDeviceId;
303 clientAttribution.uid = android::CameraService::USE_CALLING_UID;
304
Austin Borger86a588e2022-05-23 12:41:58 -0700305 std::vector<hardware::CameraStatus> statuses;
306 sp<TestCameraServiceListener> serviceListener = new TestCameraServiceListener();
307 sCameraService->addListenerTest(serviceListener, &statuses);
308 sCameraServiceProxy->setOverrideCameraDisabled(false);
309
310 for (auto s : statuses) {
311 sp<TestCameraDeviceCallbacks> callbacks = new TestCameraDeviceCallbacks();
312 sp<hardware::camera2::ICameraDeviceUser> deviceA, deviceB;
313 binder::Status status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700314 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700315 0/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000316 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700317 clientAttribution, /*devicePolicy*/0, &deviceA);
Austin Borger86a588e2022-05-23 12:41:58 -0700318 AutoDisconnectDevice autoDisconnectA(deviceA);
319 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
320 " service specific error code " << status.serviceSpecificErrorCode();
321 status =
Austin Borger1c1bee02023-06-01 16:51:35 -0700322 sCameraService->connectDevice(callbacks, s.cameraId, std::string(), {},
Austin Borger65e64642024-06-11 15:58:23 -0700323 1/*oomScoreDiff*/, /*targetSdkVersion*/__ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000324 hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700325 clientAttribution, /*devicePolicy*/0, &deviceB);
Austin Borger86a588e2022-05-23 12:41:58 -0700326 AutoDisconnectDevice autoDisconnectB(deviceB);
327 ASSERT_TRUE(status.isOk()) << "Exception code " << status.exceptionCode() <<
328 " service specific error code " << status.serviceSpecificErrorCode();
329 }
330}