Validate client permission for HeadlessSystemUser.

If device is running in  HSUM mode, if User 0 tries to access the
camera, validate that the client has the permission
android.permission.CAMERA_HEADLESS_SYSTEM_USER.

Bug:296959023
Test: Test that headless system user is not able to access
the camera without the new permission.

Change-Id: Ibc2ef43837d2e8739872697245e466d69f56f335
diff --git a/camera/camera_platform.aconfig b/camera/camera_platform.aconfig
index fc11518..6200489 100644
--- a/camera/camera_platform.aconfig
+++ b/camera/camera_platform.aconfig
@@ -6,3 +6,11 @@
      description: "Flag infrastructure test flag"
      bug: "292631208"
 }
+
+flag {
+     namespace: "camera_platform"
+     name: "camera_hsum_permission"
+     description: "Camera access by headless system user"
+     bug: "273539631"
+}
+
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c0194b9..12a10a0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -124,6 +124,8 @@
 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
         sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
 static const std::string sCameraOpenCloseListenerPermission(
@@ -704,6 +706,14 @@
     return strncmp(value, "automotive", PROPERTY_VALUE_MAX) == 0;
 }
 
+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;
+}
+
 static bool isAutomotivePrivilegedClient(int32_t uid) {
     // Returns false if this is not an automotive device type.
     if (!isAutomotiveDevice())
@@ -793,6 +803,15 @@
     return checkPermissionForSystemCamera && checkPermissionForCamera;
 }
 
+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);
+}
+
 Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
     ATRACE_CALL();
     Mutex::Autolock l(mServiceLock);
@@ -1643,6 +1662,18 @@
                 clientUserId, cameraId.c_str());
     }
 
+    // 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)) {
+        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 User\
+                without camera headless system user permission",
+                clientName.c_str(), clientUid, clientPid, cameraId.c_str());
+    }
+
     return Status::ok();
 }
 
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 48954ca..beafe00 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -104,6 +104,9 @@
     // Event log ID
     static const int SN_EVENT_LOG_ID = 0x534e4554;
 
+    // Keep this in sync with frameworks/base/core/java/android/os/UserHandle.java
+    static const userid_t USER_SYSTEM = 0;
+
     // Register camera service
     static void instantiate();
 
@@ -656,6 +659,9 @@
     bool hasPermissionsForSystemCamera(const std::string& cameraId, int callingPid, int callingUid)
             const;
 
+    bool hasPermissionsForCameraHeadlessSystemUser(const std::string& cameraId, int callingPid,
+            int callingUid) const;
+
    /**
      * Typesafe version of device status, containing both the HAL-layer and the service interface-
      * layer values.