Camera: Handle the case of calling Uid being cameraserver
With HAL1-camera2 legacy implementation, the getCameraCharacteristics
may be called without camera permission. So the cameraserver's Uid is
used in that case.
AppOpsManager returns MODE_IGNORED when the cameraserver's Uid is passed.
Do not treat this as an error case.
Bug: 153511543
Test: On Pixel 2 device, run "adb root; adb shell setprop
persist.camera.HAL3.enabled 0; adb reboot", then "atest
cts/tests/camera/CaptureRequestTest"
Change-Id: I29aaa2045b14233537c737bf0738fbc32422540e
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9af1c36..f92d673 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2742,7 +2742,7 @@
mClientPackageName(clientPackageName),
mClientPid(clientPid), mClientUid(clientUid),
mServicePid(servicePid),
- mDisconnected(false),
+ mDisconnected(false), mUidIsTrusted(false),
mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE),
mRemoteBinder(remoteCallback)
{
@@ -2791,6 +2791,8 @@
if (getCurrentServingCall() != BinderCallType::HWBINDER) {
mAppOpsManager = std::make_unique<AppOpsManager>();
}
+
+ mUidIsTrusted = isTrustedCallingUid(mClientUid);
}
CameraService::BasicClient::~BasicClient() {
@@ -2905,7 +2907,9 @@
return PERMISSION_DENIED;
}
- if (res == AppOpsManager::MODE_IGNORED) {
+ // If the calling Uid is trusted (a native service), the AppOpsManager could
+ // return MODE_IGNORED. Do not treat such case as error.
+ if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
ALOGI("Camera %s: Access for \"%s\" has been restricted",
mCameraIdStr.string(), String8(mClientPackageName).string());
// Return the same error as for device policy manager rejection
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 1adf15a..18cf77a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -323,6 +323,7 @@
const uid_t mClientUid;
const pid_t mServicePid;
bool mDisconnected;
+ bool mUidIsTrusted;
mutable Mutex mAudioRestrictionLock;
int32_t mAudioRestriction;
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 8f20685..237c24b 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -197,7 +197,9 @@
return PERMISSION_DENIED;
}
- if (res == AppOpsManager::MODE_IGNORED) {
+ // If the calling Uid is trusted (a native service), the AppOpsManager could
+ // return MODE_IGNORED. Do not treat such case as error.
+ if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
ALOGI("Offline Camera %s: Access for \"%s\" has been restricted",
mCameraIdStr.string(), String8(mClientPackageName).string());
// Return the same error as for device policy manager rejection