Introduce AttributionAndPermissionUtils.
The CameraService class is getting large and permission checking is
becoming a large portion of it. Separate this logic out into its own
utils class to make it easier to find code responsible for verifying
client permissions and the identity of the caller.
Bug: 190657833
Test: Smoke testof GCA, CtsCameraTestCases
Change-Id: I305706846db399eb92c8409271fb3e591539032f
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 5b76bb0..b748888 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -186,6 +186,7 @@
"aidl/AidlCameraServiceListener.cpp",
"aidl/AidlUtils.cpp",
"aidl/DeathPipe.cpp",
+ "utils/AttributionAndPermissionUtils.cpp",
"utils/CameraServiceProxyWrapper.cpp",
"utils/CameraThreadState.cpp",
"utils/CameraTraces.cpp",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 2d55f39..ebe771e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -38,7 +38,6 @@
#include <aidl/AidlCameraService.h>
#include <android-base/macros.h>
#include <android-base/parseint.h>
-#include <android/permission/PermissionChecker.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -129,20 +128,16 @@
// ----------------------------------------------------------------------------
-static const std::string sDumpPermission("android.permission.DUMP");
-static const std::string sManageCameraPermission("android.permission.MANAGE_CAMERA");
-static const std::string sCameraPermission("android.permission.CAMERA");
-static const std::string sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
-static const std::string sCameraHeadlessSystemUserPermission(
- "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
-static const std::string sCameraPrivacyAllowlistPermission(
- "android.permission.CAMERA_PRIVACY_ALLOWLIST");
-static const std::string
- sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
-static const std::string sCameraOpenCloseListenerPermission(
- "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
-static const std::string
- sCameraInjectExternalCameraPermission("android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
+// Permission strings (references to AttributionAndPermissionUtils for brevity)
+static const std::string &sDumpPermission =
+ AttributionAndPermissionUtils::sDumpPermission;
+static const std::string &sManageCameraPermission =
+ AttributionAndPermissionUtils::sManageCameraPermission;
+static const std::string &sCameraSendSystemEventsPermission =
+ AttributionAndPermissionUtils::sCameraSendSystemEventsPermission;
+static const std::string &sCameraInjectExternalCameraPermission =
+ AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission;
+
// Constant integer for FGS Logging, used to denote the API type for logger
static const int LOG_FGS_CAMERA_API = 1;
const char *sFileName = "lastOpenSessionDumpFile";
@@ -158,9 +153,13 @@
static std::set<std::string> sServiceErrorEventSet;
CameraService::CameraService(
- std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper) :
+ std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils) :
mCameraServiceProxyWrapper(cameraServiceProxyWrapper == nullptr ?
std::make_shared<CameraServiceProxyWrapper>() : cameraServiceProxyWrapper),
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils == nullptr ?
+ std::make_shared<AttributionAndPermissionUtils>(this)\
+ : attributionAndPermissionUtils),
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
mNumberOfCamerasWithoutSystemCamera(0),
@@ -215,7 +214,7 @@
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
- mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this, mAttributionAndPermissionUtils);
mSensorPrivacyPolicy->registerSelf();
mInjectionStatusListener = new InjectionStatusListener(this);
@@ -708,34 +707,15 @@
broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}
-static bool isAutomotiveDevice() {
- // Checks the property ro.hardware.type and returns true if it is
- // automotive.
- char value[PROPERTY_VALUE_MAX] = {0};
- property_get("ro.hardware.type", value, "");
- return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+bool CameraService::isAutomotiveDevice() const {
+ return mAttributionAndPermissionUtils->isAutomotiveDevice();
}
-static bool isHeadlessSystemUserMode() {
- // Checks if the device is running in headless system user mode
- // by checking the property ro.fw.mu.headless_system_user.
- char value[PROPERTY_VALUE_MAX] = {0};
- property_get("ro.fw.mu.headless_system_user", value, "");
- return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
+bool CameraService::isAutomotivePrivilegedClient(int32_t uid) const {
+ return mAttributionAndPermissionUtils->isAutomotivePrivilegedClient(uid);
}
-static bool isAutomotivePrivilegedClient(int32_t uid) {
- // Returns false if this is not an automotive device type.
- if (!isAutomotiveDevice())
- return false;
-
- // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
- // privileged client uid used for safety critical use cases such as
- // rear view and surround view.
- return uid == AID_AUTOMOTIVE_EVS;
-}
-
-bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const{
+bool CameraService::isAutomotiveExteriorSystemCamera(const std::string& cam_id) const {
// Returns false if this is not an automotive device type.
if (!isAutomotiveDevice())
return false;
@@ -780,54 +760,47 @@
return true;
}
-bool CameraService::checkPermission(const std::string& cameraId, const std::string& permission,
- const AttributionSourceState& attributionSource, const std::string& message,
- int32_t attributedOpCode) const{
- if (isAutomotivePrivilegedClient(attributionSource.uid)) {
- // If cameraId is empty, then it means that this check is not used for the
- // purpose of accessing a specific camera, hence grant permission just
- // based on uid to the automotive privileged client.
- if (cameraId.empty())
- return true;
- // If this call is used for accessing a specific camera then cam_id must be provided.
- // In that case, only pre-grants the permission for accessing the exterior system only
- // camera.
- return isAutomotiveExteriorSystemCamera(cameraId);
- }
+static AttributionSourceState attributionSourceFromPidAndUid(int callingPid, int callingUid) {
+ AttributionSourceState attributionSource{};
+ attributionSource.pid = callingPid;
+ attributionSource.uid = callingUid;
+ return attributionSource;
+}
- permission::PermissionChecker permissionChecker;
- return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
- toString16(message), attributedOpCode)
- != permission::PermissionChecker::PERMISSION_HARD_DENIED;
+bool CameraService::hasPermissionsForCamera(int callingPid, int callingUid) const {
+ return hasPermissionsForCamera(std::string(), callingPid, callingUid);
+}
+
+bool CameraService::hasPermissionsForCamera(const std::string& cameraId, int callingPid,
+ int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCamera(cameraId, attributionSource);
}
bool CameraService::hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid,
- int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = checkPermission(cameraId,
- sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- bool checkPermissionForCamera = checkPermission(cameraId,
- sCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
- return checkPermissionForSystemCamera && checkPermissionForCamera;
+ int callingUid, bool checkCameraPermissions) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForSystemCamera(
+ cameraId, attributionSource, checkCameraPermissions);
}
bool CameraService::hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
- int callingPid, int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- return checkPermission(cameraId, sCameraHeadlessSystemUserPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+ int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCameraHeadlessSystemUser(
+ cameraId, attributionSource);
}
-bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const{
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- return checkPermission(std::string(), sCameraPrivacyAllowlistPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+bool CameraService::hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForCameraPrivacyAllowlist(
+ attributionSource);
+}
+
+bool CameraService::hasPermissionsForOpenCloseListener(int callingPid, int callingUid) const {
+ auto attributionSource = attributionSourceFromPidAndUid(callingPid, callingUid);
+ return mAttributionAndPermissionUtils->hasPermissionsForOpenCloseListener(
+ attributionSource);
}
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
@@ -1272,13 +1245,9 @@
const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
auto callingPid = CameraThreadState::getCallingPid();
auto callingUid = CameraThreadState::getCallingUid();
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForSystemCamera = checkPermission(std::to_string(cameraIdInt),
- sSystemCameraPermission, attributionSource, std::string(),
- AppOpsManager::OP_NONE);
- if (checkPermissionForSystemCamera || getpid() == callingPid) {
+ bool systemCameraPermissions = hasPermissionsForSystemCamera(std::to_string(cameraIdInt),
+ callingPid, callingUid, /* checkCameraPermissions= */ false);
+ if (systemCameraPermissions || getpid() == callingPid) {
deviceIds = &mNormalDeviceIds;
}
if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(deviceIds->size())) {
@@ -1351,11 +1320,7 @@
// If it's not calling from cameraserver, check the permission only if
// android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
// it would've already been checked in shouldRejectSystemCameraConnection.
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
+ bool checkPermissionForCamera = hasPermissionsForCamera(cameraId, callingPid, callingUid);
if ((callingPid != getpid()) &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
!checkPermissionForCamera) {
@@ -1541,7 +1506,7 @@
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, cameraService->mCameraServiceProxyWrapper,
- packageName, featureId, cameraId,
+ cameraService->mAttributionAndPermissionUtils, packageName, featureId, cameraId,
api1CameraId, facing, sensorOrientation,
clientPid, clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
forceSlowJpegMode);
@@ -1551,7 +1516,8 @@
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
*client = new CameraDeviceClient(cameraService, tmp,
- cameraService->mCameraServiceProxyWrapper, packageName, systemNativeClient,
+ cameraService->mCameraServiceProxyWrapper,
+ cameraService->mAttributionAndPermissionUtils, packageName, systemNativeClient,
featureId, cameraId, facing, sensorOrientation, clientPid, clientUid, servicePid,
overrideForPerfClass, overrideToPortrait, originalCameraId);
ALOGI("%s: Camera2 API, override to portrait %d", __FUNCTION__, overrideToPortrait);
@@ -1716,35 +1682,13 @@
}
// Can camera service trust the caller based on the calling UID?
-static bool isTrustedCallingUid(uid_t uid) {
- switch (uid) {
- case AID_MEDIA: // mediaserver
- case AID_CAMERASERVER: // cameraserver
- case AID_RADIO: // telephony
- return true;
- default:
- return false;
- }
+bool CameraService::isTrustedCallingUid(uid_t uid) const {
+ return mAttributionAndPermissionUtils->isTrustedCallingUid(uid);
}
-static status_t getUidForPackage(const std::string &packageName, int userId, /*inout*/uid_t& uid,
- int err) {
- PermissionController pc;
- uid = pc.getPackageUid(toString16(packageName), 0);
- if (uid <= 0) {
- ALOGE("Unknown package: '%s'", packageName.c_str());
- dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
- return BAD_VALUE;
- }
-
- if (userId < 0) {
- ALOGE("Invalid user: %d", userId);
- dprintf(err, "Invalid user: %d\n", userId);
- return BAD_VALUE;
- }
-
- uid = multiuser_get_uid(userId, uid);
- return NO_ERROR;
+status_t CameraService::getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err) const {
+ return mAttributionAndPermissionUtils->getUidForPackage(packageName, userId, uid, err);
}
Status CameraService::validateConnectLocked(const std::string& cameraId,
@@ -1798,8 +1742,6 @@
Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
const std::string& clientName, int& clientUid, int& clientPid,
/*out*/int& originalClientPid) const {
- AttributionSourceState attributionSource{};
-
int callingPid = CameraThreadState::getCallingPid();
int callingUid = CameraThreadState::getCallingUid();
@@ -1846,11 +1788,7 @@
// If it's not calling from cameraserver, check the permission if the
// device isn't a system only camera (shouldRejectSystemCameraConnection already checks for
// android.permission.SYSTEM_CAMERA for system only camera devices).
- attributionSource.pid = clientPid;
- attributionSource.uid = clientUid;
- attributionSource.packageName = clientName;
- bool checkPermissionForCamera = checkPermission(cameraId, sCameraPermission, attributionSource,
- std::string(), AppOpsManager::OP_NONE);
+ bool checkPermissionForCamera = hasPermissionsForCamera(cameraId, clientPid, clientUid);
if (callingPid != getpid() &&
(deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
@@ -1906,8 +1844,9 @@
// If the System User tries to access the camera when the device is running in
// headless system user mode, ensure that client has the required permission
// CAMERA_HEADLESS_SYSTEM_USER.
- if (isHeadlessSystemUserMode() && (clientUserId == USER_SYSTEM) &&
- !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
+ if (mAttributionAndPermissionUtils->isHeadlessSystemUserMode()
+ && (clientUserId == USER_SYSTEM)
+ && !hasPermissionsForCameraHeadlessSystemUser(cameraId, callingPid, callingUid)) {
ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
"Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" as Headless System \
@@ -2273,7 +2212,7 @@
}
// (1) Cameraserver trying to connect, accept.
- if (CameraThreadState::getCallingPid() == getpid()) {
+ if (mAttributionAndPermissionUtils->isCallerCameraServerNotDelegating()) {
return false;
}
// (2)
@@ -3323,22 +3262,6 @@
return Status::ok();
}
-bool CameraService::hasCameraPermissions() const {
- int callingPid = CameraThreadState::getCallingPid();
- int callingUid = CameraThreadState::getCallingUid();
- AttributionSourceState attributionSource{};
- attributionSource.pid = callingPid;
- attributionSource.uid = callingUid;
- bool res = checkPermission(std::string(), sCameraPermission,
- attributionSource, std::string(), AppOpsManager::OP_NONE);
-
- bool hasPermission = ((callingPid == getpid()) || res);
- if (!hasPermission) {
- ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
- }
- return hasPermission;
-}
-
Status CameraService::isConcurrentSessionConfigurationSupported(
const std::vector<CameraIdAndSessionConfiguration>& cameraIdsAndSessionConfigurations,
int targetSdkVersion, /*out*/bool* isSupported) {
@@ -3354,7 +3277,11 @@
}
// Check for camera permissions
- if (!hasCameraPermissions()) {
+ int callingPid = CameraThreadState::getCallingPid();
+ int callingUid = CameraThreadState::getCallingUid();
+ bool hasCameraPermission = ((callingPid == getpid()) ||
+ hasPermissionsForCamera(callingPid, callingUid));
+ if (!hasCameraPermission) {
return STATUS_ERROR(ERROR_PERMISSION_DENIED,
"android.permission.CAMERA needed to call"
"isConcurrentSessionConfigurationSupported");
@@ -3398,15 +3325,9 @@
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, "Null listener given to addListener");
}
- auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
- AttributionSourceState attributionSource{};
- attributionSource.uid = clientUid;
- attributionSource.pid = clientPid;
-
- bool openCloseCallbackAllowed = checkPermission(std::string(),
- sCameraOpenCloseListenerPermission, attributionSource, std::string(),
- AppOpsManager::OP_NONE);
+ auto clientUid = CameraThreadState::getCallingUid();
+ bool openCloseCallbackAllowed = hasPermissionsForOpenCloseListener(clientPid, clientUid);
Mutex::Autolock lock(mServiceLock);
@@ -4049,6 +3970,7 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName, bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraIdStr,
@@ -4057,6 +3979,7 @@
int servicePid, bool overrideToPortrait) :
CameraService::BasicClient(cameraService,
IInterface::asBinder(cameraClient),
+ attributionAndPermissionUtils,
clientPackageName, systemNativeClient, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation,
clientPid, clientUid,
@@ -4087,10 +4010,12 @@
CameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName, bool nativeClient,
const std::optional<std::string>& clientFeatureId, const std::string& cameraIdStr,
int cameraFacing, int sensorOrientation, int clientPid, uid_t clientUid,
int servicePid, bool overrideToPortrait):
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils),
mDestructionStarted(false),
mCameraIdStr(cameraIdStr), mCameraFacing(cameraFacing), mOrientation(sensorOrientation),
mClientPackageName(clientPackageName), mSystemNativeClient(nativeClient),
@@ -4123,7 +4048,7 @@
mAppOpsManager = std::make_unique<AppOpsManager>();
}
- mUidIsTrusted = isTrustedCallingUid(mClientUid);
+ mUidIsTrusted = mAttributionAndPermissionUtils->isTrustedCallingUid(mClientUid);
}
CameraService::BasicClient::~BasicClient() {
@@ -4862,7 +4787,7 @@
}
hasCameraPrivacyFeature(); // Called so the result is cached
mSpm.addSensorPrivacyListener(this);
- if (isAutomotiveDevice()) {
+ if (mAttributionAndPermissionUtils->isAutomotiveDevice()) {
mSpm.addToggleSensorPrivacyListener(this);
}
mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled();
@@ -4902,7 +4827,7 @@
void CameraService::SensorPrivacyPolicy::unregisterSelf() {
Mutex::Autolock _l(mSensorPrivacyLock);
mSpm.removeSensorPrivacyListener(this);
- if (isAutomotiveDevice()) {
+ if (mAttributionAndPermissionUtils->isAutomotiveDevice()) {
mSpm.removeToggleSensorPrivacyListener(this);
}
mSpm.unlinkToDeath(this);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8822cd3..11cf1a1 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -53,6 +53,7 @@
#include "utils/ClientManager.h"
#include "utils/IPCTransport.h"
#include "utils/CameraServiceProxyWrapper.h"
+#include "utils/AttributionAndPermissionUtils.h"
#include <set>
#include <string>
@@ -119,7 +120,9 @@
// Non-null arguments for cameraServiceProxyWrapper should be provided for
// testing purposes only.
CameraService(std::shared_ptr<CameraServiceProxyWrapper>
- cameraServiceProxyWrapper = nullptr);
+ cameraServiceProxyWrapper = nullptr,
+ std::shared_ptr<AttributionAndPermissionUtils>
+ attributionAndPermissionUtils = nullptr);
virtual ~CameraService();
/////////////////////////////////////////////////////////////////////
@@ -314,6 +317,21 @@
// Shared utilities
static binder::Status filterGetInfoErrorCode(status_t err);
+ bool isAutomotiveDevice() const;
+
+ /**
+ * Returns true if the client has uid AID_AUTOMOTIVE_EVS and the device is an automotive device.
+ */
+ bool isAutomotivePrivilegedClient(int32_t uid) const;
+
+ /**
+ * Returns true if the device is an automotive device and cameraId is system
+ * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
+ * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
+ * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
+ */
+ bool isAutomotiveExteriorSystemCamera(const std::string& cameraId) const;
+
/////////////////////////////////////////////////////////////////////
// CameraClient functionality
@@ -428,6 +446,7 @@
protected:
BasicClient(const sp<CameraService>& cameraService,
const sp<IBinder>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool nativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -441,6 +460,8 @@
virtual ~BasicClient();
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
+
// the instance is in the middle of destruction. When this is set,
// the instance should not be accessed from callback.
// CameraService's mClientLock should be acquired to access this.
@@ -541,6 +562,7 @@
// Interface used by CameraService
Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -644,13 +666,6 @@
int32_t updateAudioRestrictionLocked();
private:
- /**
- * Returns true if the device is an automotive device and cameraId is system
- * only camera which has characteristic AUTOMOTIVE_LOCATION value as either
- * AUTOMOTIVE_LOCATION_EXTERIOR_LEFT,AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT,
- * AUTOMOTIVE_LOCATION_EXTERIOR_FRONT or AUTOMOTIVE_LOCATION_EXTERIOR_REAR.
- */
- bool isAutomotiveExteriorSystemCamera(const std::string& cameraId) const;
// TODO: b/263304156 update this to make use of a death callback for more
// robust/fault tolerant logging
@@ -666,29 +681,20 @@
return activityManager;
}
- /**
- * Pre-grants the permission if the attribution source uid is for an automotive
- * privileged client. Otherwise uses system service permission checker to check
- * for the appropriate permission. If this function is called for accessing a specific
- * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
- * privileged client so that permission is pre-granted only to access system camera device
- * which is located outside of the vehicle body frame because camera located inside the vehicle
- * cabin would need user permission.
- */
- bool checkPermission(const std::string& cameraId, const std::string& permission,
- const content::AttributionSourceState& attributionSource, const std::string& message,
- int32_t attributedOpCode) const;
+ bool hasPermissionsForCamera(int callingPid, int callingUid) const;
- bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid)
- const;
+ bool hasPermissionsForCamera(const std::string& cameraId, int callingPid, int callingUid) const;
+
+ bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid,
+ bool checkCameraPermissions = true) const;
bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
int callingUid) const;
- bool hasCameraPermissions() const;
-
bool hasPermissionsForCameraPrivacyAllowlist(int callingPid, int callingUid) const;
+ bool hasPermissionsForOpenCloseListener(int callingPid, int callingUid) const;
+
/**
* Typesafe version of device status, containing both the HAL-layer and the service interface-
* layer values.
@@ -875,8 +881,11 @@
public virtual IBinder::DeathRecipient,
public virtual IServiceManager::LocalRegistrationCallback {
public:
- explicit SensorPrivacyPolicy(wp<CameraService> service)
- : mService(service), mSensorPrivacyEnabled(false),
+ explicit SensorPrivacyPolicy(wp<CameraService> service,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils)
+ : mService(service),
+ mAttributionAndPermissionUtils(attributionAndPermissionUtils),
+ mSensorPrivacyEnabled(false),
mCameraPrivacyState(SensorPrivacyManager::DISABLED), mRegistered(false) {}
void registerSelf();
@@ -900,6 +909,7 @@
private:
SensorPrivacyManager mSpm;
wp<CameraService> mService;
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
Mutex mSensorPrivacyLock;
bool mSensorPrivacyEnabled;
int mCameraPrivacyState;
@@ -914,6 +924,7 @@
sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
std::shared_ptr<CameraServiceProxyWrapper> mCameraServiceProxyWrapper;
+ std::shared_ptr<AttributionAndPermissionUtils> mAttributionAndPermissionUtils;
// Delay-load the Camera HAL module
virtual void onFirstRef();
@@ -926,6 +937,11 @@
void addStates(const std::string& id);
void removeStates(const std::string& id);
+ bool isTrustedCallingUid(uid_t uid) const;
+
+ status_t getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err) const;
+
// Check if we can connect, before we acquire the service lock.
// The returned originalClientPid is the PID of the original process that wants to connect to
// camera.
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index caa6424..19e2999 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -56,6 +56,7 @@
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraDeviceId,
@@ -68,7 +69,8 @@
bool overrideForPerfClass,
bool overrideToPortrait,
bool forceSlowJpegMode):
- Camera2ClientBase(cameraService, cameraClient, cameraServiceProxyWrapper, clientPackageName,
+ Camera2ClientBase(cameraService, cameraClient, cameraServiceProxyWrapper,
+ attributionAndPermissionUtils, clientPackageName,
false/*systemNativeClient - since no ndk for api1*/, clientFeatureId,
cameraDeviceId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
clientUid, servicePid, overrideForPerfClass, overrideToPortrait,
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 2cb7af0..2654a25 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -103,6 +103,7 @@
Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraDeviceId,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 508d487..7c2f71c 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -61,6 +61,7 @@
CameraDeviceClientBase::CameraDeviceClientBase(
const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -74,6 +75,7 @@
bool overrideToPortrait) :
BasicClient(cameraService,
IInterface::asBinder(remoteCallback),
+ attributionAndPermissionUtils,
clientPackageName,
systemNativeClient,
clientFeatureId,
@@ -92,6 +94,7 @@
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -104,7 +107,8 @@
bool overrideForPerfClass,
bool overrideToPortrait,
const std::string& originalCameraId) :
- Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper, clientPackageName,
+ Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper,
+ attributionAndPermissionUtils, clientPackageName,
systemNativeClient, clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing,
sensorOrientation, clientPid, clientUid, servicePid, overrideForPerfClass,
overrideToPortrait),
@@ -1900,9 +1904,9 @@
sp<CameraOfflineSessionClient> offlineClient;
if (offlineSession.get() != nullptr) {
offlineClient = new CameraOfflineSessionClient(sCameraService,
- offlineSession, offlineCompositeStreamMap, cameraCb, mClientPackageName,
- mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation, mClientPid, mClientUid,
- mServicePid);
+ offlineSession, offlineCompositeStreamMap, cameraCb, mAttributionAndPermissionUtils,
+ mClientPackageName, mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation,
+ mClientPid, mClientUid, mServicePid);
ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index b2c9626..d93eaff 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -50,6 +50,7 @@
protected:
CameraDeviceClientBase(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -181,6 +182,7 @@
CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool clientPackageOverride,
const std::optional<std::string>& clientFeatureId,
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 804498f..c6f3e06 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -47,6 +47,7 @@
sp<CameraOfflineSessionBase> session,
const KeyedVector<sp<IBinder>, sp<CompositeStream>>& offlineCompositeStreamMap,
const sp<ICameraDeviceCallbacks>& remoteCallback,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
const std::optional<std::string>& clientFeatureId,
const std::string& cameraIdStr, int cameraFacing, int sensorOrientation,
@@ -54,6 +55,7 @@
CameraService::BasicClient(
cameraService,
IInterface::asBinder(remoteCallback),
+ attributionAndPermissionUtils,
// (v)ndk doesn't have offline session support
clientPackageName, /*overridePackageName*/false, clientFeatureId,
cameraIdStr, cameraFacing, sensorOrientation, clientPid, clientUid, servicePid,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index a126f61..3a78937 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -50,6 +50,7 @@
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
@@ -63,9 +64,9 @@
bool overrideForPerfClass,
bool overrideToPortrait,
bool legacyClient):
- TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
- clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
- clientUid, servicePid, overrideToPortrait),
+ TClientBase(cameraService, remoteCallback, attributionAndPermissionUtils, clientPackageName,
+ systemNativeClient, clientFeatureId, cameraId, api1CameraId, cameraFacing,
+ sensorOrientation, clientPid, clientUid, servicePid, overrideToPortrait),
mSharedCameraCallbacks(remoteCallback),
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mDeviceActive(false), mApi1CameraId(api1CameraId)
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 2bb90d9..b8a6d8b 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -21,6 +21,7 @@
#include "camera/CameraMetadata.h"
#include "camera/CaptureResult.h"
#include "utils/CameraServiceProxyWrapper.h"
+#include "utils/AttributionAndPermissionUtils.h"
#include "CameraServiceWatchdog.h"
namespace android {
@@ -51,6 +52,7 @@
Camera2ClientBase(const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
+ std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
const std::string& clientPackageName,
bool systemNativeClient,
const std::optional<std::string>& clientFeatureId,
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
new file mode 100644
index 0000000..e63b30b
--- /dev/null
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AttributionAndPermissionUtils.h"
+
+#include <binder/AppOpsManager.h>
+#include <binder/PermissionController.h>
+#include <cutils/properties.h>
+#include <private/android_filesystem_config.h>
+
+#include "CameraService.h"
+#include "CameraThreadState.h"
+
+namespace android {
+
+const std::string AttributionAndPermissionUtils::sDumpPermission("android.permission.DUMP");
+const std::string AttributionAndPermissionUtils::sManageCameraPermission(
+ "android.permission.MANAGE_CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraPermission(
+ "android.permission.CAMERA");
+const std::string AttributionAndPermissionUtils::sSystemCameraPermission(
+ "android.permission.SYSTEM_CAMERA");
+const std::string AttributionAndPermissionUtils::sCameraHeadlessSystemUserPermission(
+ "android.permission.CAMERA_HEADLESS_SYSTEM_USER");
+const std::string AttributionAndPermissionUtils::sCameraPrivacyAllowlistPermission(
+ "android.permission.CAMERA_PRIVACY_ALLOWLIST");
+const std::string AttributionAndPermissionUtils::sCameraSendSystemEventsPermission(
+ "android.permission.CAMERA_SEND_SYSTEM_EVENTS");
+const std::string AttributionAndPermissionUtils::sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
+const std::string AttributionAndPermissionUtils::sCameraInjectExternalCameraPermission(
+ "android.permission.CAMERA_INJECT_EXTERNAL_CAMERA");
+
+bool AttributionAndPermissionUtils::checkAutomotivePrivilegedClient(const std::string &cameraId,
+ const AttributionSourceState &attributionSource) {
+ if (isAutomotivePrivilegedClient(attributionSource.uid)) {
+ // If cameraId is empty, then it means that this check is not used for the
+ // purpose of accessing a specific camera, hence grant permission just
+ // based on uid to the automotive privileged client.
+ if (cameraId.empty())
+ return true;
+
+ auto cameraService = mCameraService.promote();
+ if (cameraService == nullptr) {
+ ALOGE("%s: CameraService unavailable.", __FUNCTION__);
+ return false;
+ }
+
+ // If this call is used for accessing a specific camera then cam_id must be provided.
+ // In that case, only pre-grants the permission for accessing the exterior system only
+ // camera.
+ return cameraService->isAutomotiveExteriorSystemCamera(cameraId);
+ }
+
+ return false;
+}
+
+bool AttributionAndPermissionUtils::checkPermissionForPreflight(const std::string &cameraId,
+ const std::string &permission, const AttributionSourceState &attributionSource,
+ const std::string& message, int32_t attributedOpCode) {
+ if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
+ return true;
+ }
+
+ PermissionChecker permissionChecker;
+ return permissionChecker.checkPermissionForPreflight(toString16(permission), attributionSource,
+ toString16(message), attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
+}
+
+// Can camera service trust the caller based on the calling UID?
+bool AttributionAndPermissionUtils::isTrustedCallingUid(uid_t uid) {
+ switch (uid) {
+ case AID_MEDIA: // mediaserver
+ case AID_CAMERASERVER: // cameraserver
+ case AID_RADIO: // telephony
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool AttributionAndPermissionUtils::isAutomotiveDevice() {
+ // Checks the property ro.hardware.type and returns true if it is
+ // automotive.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.hardware.type", value, "");
+ return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
+}
+
+bool AttributionAndPermissionUtils::isHeadlessSystemUserMode() {
+ // Checks if the device is running in headless system user mode
+ // by checking the property ro.fw.mu.headless_system_user.
+ char value[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.fw.mu.headless_system_user", value, "");
+ return strncmp(value, "true", PROPERTY_VALUE_MAX) == 0;
+}
+
+bool AttributionAndPermissionUtils::isAutomotivePrivilegedClient(int32_t uid) {
+ // Returns false if this is not an automotive device type.
+ if (!isAutomotiveDevice())
+ return false;
+
+ // Returns true if the uid is AID_AUTOMOTIVE_EVS which is a
+ // privileged client uid used for safety critical use cases such as
+ // rear view and surround view.
+ return uid == AID_AUTOMOTIVE_EVS;
+}
+
+status_t AttributionAndPermissionUtils::getUidForPackage(const std::string &packageName,
+ int userId, /*inout*/uid_t& uid, int err) {
+ PermissionController pc;
+ uid = pc.getPackageUid(toString16(packageName), 0);
+ if (uid <= 0) {
+ ALOGE("Unknown package: '%s'", packageName.c_str());
+ dprintf(err, "Unknown package: '%s'\n", packageName.c_str());
+ return BAD_VALUE;
+ }
+
+ if (userId < 0) {
+ ALOGE("Invalid user: %d", userId);
+ dprintf(err, "Invalid user: %d\n", userId);
+ return BAD_VALUE;
+ }
+
+ uid = multiuser_get_uid(userId, uid);
+ return NO_ERROR;
+}
+
+bool AttributionAndPermissionUtils::isCallerCameraServerNotDelegating() {
+ return CameraThreadState::getCallingPid() == getpid();
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(cameraId, sCameraPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForSystemCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource, bool checkCameraPermissions) {
+ bool systemCameraPermission = checkPermissionForPreflight(cameraId,
+ sSystemCameraPermission, attributionSource, std::string(), AppOpsManager::OP_NONE);
+ return systemCameraPermission && (!checkCameraPermissions
+ || hasPermissionsForCamera(cameraId, attributionSource));
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCameraHeadlessSystemUser(
+ const std::string& cameraId, const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(cameraId, sCameraHeadlessSystemUserPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForCameraPrivacyAllowlist(
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(std::string(), sCameraPrivacyAllowlistPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+bool AttributionAndPermissionUtils::hasPermissionsForOpenCloseListener(
+ const AttributionSourceState& attributionSource) {
+ return checkPermissionForPreflight(std::string(), sCameraOpenCloseListenerPermission,
+ attributionSource, std::string(), AppOpsManager::OP_NONE);
+}
+
+} // namespace android
diff --git a/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
new file mode 100644
index 0000000..dc4cfb1
--- /dev/null
+++ b/services/camera/libcameraservice/utils/AttributionAndPermissionUtils.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+#define ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H
+
+#include <android/content/AttributionSourceState.h>
+#include <android/permission/PermissionChecker.h>
+#include <binder/BinderService.h>
+
+namespace android {
+
+class CameraService;
+
+using content::AttributionSourceState;
+using permission::PermissionChecker;
+
+/**
+ * Utility class consolidating methods/data for verifying permissions and the identity of the
+ * caller.
+ */
+class AttributionAndPermissionUtils {
+public:
+ AttributionAndPermissionUtils(wp<CameraService> cameraService) : mCameraService(cameraService)
+ {}
+ virtual ~AttributionAndPermissionUtils() {}
+
+ /**
+ * Pre-grants the permission if the attribution source uid is for an automotive
+ * privileged client. Otherwise uses system service permission checker to check
+ * for the appropriate permission. If this function is called for accessing a specific
+ * camera,then the cameraID must not be empty. CameraId is used only in case of automotive
+ * privileged client so that permission is pre-granted only to access system camera device
+ * which is located outside of the vehicle body frame because camera located inside the vehicle
+ * cabin would need user permission.
+ */
+ virtual bool checkPermissionForPreflight(const std::string &cameraId,
+ const std::string &permission, const AttributionSourceState& attributionSource,
+ const std::string& message, int32_t attributedOpCode);
+ virtual bool isTrustedCallingUid(uid_t uid);
+ virtual bool isAutomotiveDevice();
+ virtual bool isHeadlessSystemUserMode();
+ virtual bool isAutomotivePrivilegedClient(int32_t uid);
+ virtual status_t getUidForPackage(const std::string &packageName, int userId,
+ /*inout*/uid_t& uid, int err);
+ virtual bool isCallerCameraServerNotDelegating();
+
+ // Utils for checking specific permissions
+ virtual bool hasPermissionsForCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForSystemCamera(const std::string& cameraId,
+ const AttributionSourceState& attributionSource, bool checkCameraPermissions = true);
+ virtual bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId,
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForCameraPrivacyAllowlist(
+ const AttributionSourceState& attributionSource);
+ virtual bool hasPermissionsForOpenCloseListener(
+ const AttributionSourceState& attributionSource);
+
+ static const std::string sDumpPermission;
+ static const std::string sManageCameraPermission;
+ static const std::string sCameraPermission;
+ static const std::string sSystemCameraPermission;
+ static const std::string sCameraHeadlessSystemUserPermission;
+ static const std::string sCameraPrivacyAllowlistPermission;
+ static const std::string sCameraSendSystemEventsPermission;
+ static const std::string sCameraOpenCloseListenerPermission;
+ static const std::string sCameraInjectExternalCameraPermission;
+
+protected:
+ wp<CameraService> mCameraService;
+
+ bool checkAutomotivePrivilegedClient(const std::string &cameraId,
+ const AttributionSourceState &attributionSource);
+};
+
+} // namespace android
+
+#endif // ANDROID_SERVERS_CAMERA_ATTRIBUTION_AND_PERMISSION_UTILS_H