Check the device policy for the camera disabled flag before trying to
open a connection to the camera.

When the camera is disabled from both the device policy and camera
settings, GCA will not receive onError with ERROR_CAMERA_DISABLED. This
is incorrect behavior which is fixed by this patch.

Bug: 230026863, 203063139
Test: Verified camera app closes when both settings are disabled.
Change-Id: I514b38c23a136994de702ea4aacc9be65ab46d70
diff --git a/camera/aidl/android/hardware/ICameraServiceProxy.aidl b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
index f5d0120..88783fb 100644
--- a/camera/aidl/android/hardware/ICameraServiceProxy.aidl
+++ b/camera/aidl/android/hardware/ICameraServiceProxy.aidl
@@ -44,4 +44,9 @@
      * {@link android.hardware.camera2.CameraMetadata#SCALER_ROTATE_AND_CROP_270}).
      */
     int getRotateAndCropOverride(String packageName, int lensFacing, int userId);
+
+    /**
+     * Checks if the camera has been disabled via device policy.
+     */
+    boolean isCameraDisabled();
 }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a965080..9542b89 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1688,6 +1688,13 @@
         return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
     }
 
+    if (CameraServiceProxyWrapper::isCameraDisabled()) {
+        String8 msg =
+                String8::format("Camera disabled by device policy");
+        ALOGE("%s: %s", __FUNCTION__, msg.string());
+        return STATUS_ERROR(ERROR_DISABLED, msg.string());
+    }
+
     // enforce system camera permissions
     if (oomScoreOffset > 0 &&
             !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid())) {
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
index a00b221..f7cede8 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.cpp
@@ -260,4 +260,16 @@
     sessionStats->onClose(latencyMs);
 }
 
+bool CameraServiceProxyWrapper::isCameraDisabled() {
+    sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
+    if (proxyBinder == nullptr) return true;
+    bool ret = false;
+    auto status = proxyBinder->isCameraDisabled(&ret);
+    if (!status.isOk()) {
+        ALOGE("%s: Failed during camera disabled query: %s", __FUNCTION__,
+                status.exceptionMessage().c_str());
+    }
+    return ret;
+}
+
 }; // namespace android
diff --git a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
index 6604aa1..61fc915 100644
--- a/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
+++ b/services/camera/libcameraservice/utils/CameraServiceProxyWrapper.h
@@ -95,6 +95,9 @@
 
     // Return the current top activity rotate and crop override.
     static int getRotateAndCropOverride(String16 packageName, int lensFacing, int userId);
+
+    // Detect if the camera is disabled by device policy.
+    static bool isCameraDisabled();
 };
 
 } // android