cameraserver: Allow CameraManager to specify rotation override for clients

CameraManager can specify a rotation override value which can
help clients get rotated feeds from the camera even in cases where
the sensor isn't overriden to be portrait - for example: it could
already be a portrait sensor and in some mode decided by the
WindowManager clients may want rotated sensor feeds.

Bug: 331307771

Test: Desktop mode on large screen device

Change-Id: Ie41f6c2449b11971bf083c737a301a3295a31b1e
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 5d32871..8018390 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -70,11 +70,11 @@
 }
 
 sp<Camera> Camera::connect(int cameraId, const std::string& clientPackageName,
-        int clientUid, int clientPid, int targetSdkVersion, bool overrideToPortrait,
+        int clientUid, int clientPid, int targetSdkVersion, int rotationOverride,
         bool forceSlowJpegMode, int32_t deviceId, int32_t devicePolicy)
 {
     return CameraBaseT::connect(cameraId, clientPackageName, clientUid,
-            clientPid, targetSdkVersion, overrideToPortrait, forceSlowJpegMode, deviceId,
+            clientPid, targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
             devicePolicy);
 }
 
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index b2f7cc7..d7415a3 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -163,7 +163,7 @@
 sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                                const std::string& clientPackageName,
                                                int clientUid, int clientPid, int targetSdkVersion,
-                                               bool overrideToPortrait, bool forceSlowJpegMode,
+                                               int rotationOverride, bool forceSlowJpegMode,
                                                int32_t deviceId, int32_t devicePolicy)
 {
     ALOGV("%s: connect", __FUNCTION__);
@@ -174,10 +174,10 @@
     binder::Status ret;
     if (cs != nullptr) {
         TCamConnectService fnConnectService = TCamTraits::fnConnectService;
-        ALOGI("Connect camera (legacy API) - overrideToPortrait %d, forceSlowJpegMode %d",
-                overrideToPortrait, forceSlowJpegMode);
+        ALOGI("Connect camera (legacy API) - rotationOverride %d, forceSlowJpegMode %d",
+                rotationOverride, forceSlowJpegMode);
         ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
-                clientPid, targetSdkVersion, overrideToPortrait, forceSlowJpegMode, deviceId,
+                clientPid, targetSdkVersion, rotationOverride, forceSlowJpegMode, deviceId,
                 devicePolicy, /*out*/ &c->mCamera);
     }
     if (ret.isOk() && c->mCamera != nullptr) {
@@ -279,11 +279,11 @@
 // this can be in BaseCamera but it should be an instance method
 template <typename TCam, typename TCamTraits>
 status_t CameraBase<TCam, TCamTraits>::getCameraInfo(int cameraId,
-        bool overrideToPortrait, int32_t deviceId, int32_t devicePolicy,
+        int rotationOverride, int32_t deviceId, int32_t devicePolicy,
         struct hardware::CameraInfo* cameraInfo) {
     const sp<::android::hardware::ICameraService> cs = getCameraService();
     if (cs == 0) return UNKNOWN_ERROR;
-    binder::Status res = cs->getCameraInfo(cameraId, overrideToPortrait, deviceId, devicePolicy,
+    binder::Status res = cs->getCameraInfo(cameraId, rotationOverride, deviceId, devicePolicy,
             cameraInfo);
     return res.isOk() ? OK : res.serviceSpecificErrorCode();
 }
diff --git a/camera/aidl/android/hardware/ICameraService.aidl b/camera/aidl/android/hardware/ICameraService.aidl
index 885749d..0edd7f2 100644
--- a/camera/aidl/android/hardware/ICameraService.aidl
+++ b/camera/aidl/android/hardware/ICameraService.aidl
@@ -76,11 +76,28 @@
     int getNumberOfCameras(int type, int deviceId, int devicePolicy);
 
     /**
+     * If changed, reflect in
+     * frameworks/base/core/java/android/hardware/camera2/CameraManager.java.
+     * We have an enum here since the decision to override to portrait mode / fetch the
+     * rotationOverride as it exists in CameraManager right now is based on a static system
+     * property and not something that changes based dynamically, say on fold state. As a result,
+     * we can't use just a boolean to differentiate between the case where cameraserver should
+     * override to portrait (sensor orientation is 0, 180) or just rotate the sensor feed (sensor
+     * orientation is 90, 270)
+     */
+    const int ROTATION_OVERRIDE_NONE = 0;
+    const int ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT = 1;
+    const int ROTATION_OVERRIDE_ROTATION_ONLY = 2;
+
+    /**
      * Fetch basic camera information for a camera.
      *
      * @param cameraId The ID of the camera to fetch information for.
-     * @param overrideToPortrait Whether to override the sensor orientation information to
-     *        correspond to portrait.
+     * @param rotationOverride Whether to override the sensor orientation information to
+     *        correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
+     *        will override the sensor orientation and rotate and crop, while {@link
+     *        ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
+     *        without changing the sensor orientation.
      * @param deviceId The device id of the context associated with the caller.
      * @param devicePolicy The camera policy of the device of the associated context (default
      *                     policy for default device context). Only virtual cameras would be exposed
@@ -88,7 +105,7 @@
      *                     policy.
      * @return CameraInfo for the camera.
      */
-    CameraInfo getCameraInfo(int cameraId, boolean overrideToPortrait, int deviceId,
+    CameraInfo getCameraInfo(int cameraId, int rotationOverride, int deviceId,
             int devicePolicy);
 
     /**
@@ -105,8 +122,12 @@
      * @param opPackageName The package name to report for the app-ops.
      * @param clientUid UID for the calling client.
      * @param clientPid PID for the calling client.
-     * @param overrideToPortrait Whether to override the sensor orientation information to
-     *        correspond to portrait.
+     * @param targetSdkVersion the target sdk level of the application calling this function.
+     * @param rotationOverride Whether to override the sensor orientation information to
+     *        correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
+     *        will override the sensor orientation and rotate and crop, while {@link
+     *        ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
+     *        without changing the sensor orientation.
      * @param forceSlowJpegMode Whether to force slow jpeg mode.
      * @param deviceId The device id of the context associated with the caller.
      * @param devicePolicy The camera policy of the device of the associated context (default
@@ -119,7 +140,7 @@
             @utf8InCpp String opPackageName,
             int clientUid, int clientPid,
             int targetSdkVersion,
-            boolean overrideToPortrait,
+            int rotationOverride,
             boolean forceSlowJpegMode,
             int deviceId,
             int devicePolicy);
@@ -131,8 +152,12 @@
      * @param cameraId The ID of the camera to open.
      * @param opPackageName The package name to report for the app-ops.
      * @param clientUid UID for the calling client.
-     * @param overrideToPortrait Whether to override the sensor orientation information to
-     *        correspond to portrait.
+     * @param targetSdkVersion the target sdk level of the application calling this function.
+     * @param rotationOverride Whether to override the sensor orientation information to
+     *        correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
+     *        will override the sensor orientation and rotate and crop, while {@link
+     *        ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
+     *        without changing the sensor orientation.
      * @param deviceId The device id of the context associated with the caller.
      * @param devicePolicy The camera policy of the device of the associated context (default
      *                     policy for default device context). Only virtual cameras would be exposed
@@ -145,7 +170,7 @@
             @nullable @utf8InCpp String featureId,
             int clientUid, int oomScoreOffset,
             int targetSdkVersion,
-            boolean overrideToPortrait,
+            int rotationOverride,
             int deviceId,
             int devicePolicy);
 
@@ -217,8 +242,12 @@
      * Only supported for device HAL versions >= 3.2
      *
      * @param cameraId The ID of the camera to fetch metadata for.
-     * @param overrideToPortrait Whether to override the sensor orientation information to
-     *        correspond to portrait.
+     * @param targetSdkVersion the target sdk level of the application calling this function.
+     * @param rotationOverride Whether to override the sensor orientation information to
+     *        correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
+     *        will override the sensor orientation and rotate and crop, while {@link
+     *        ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
+     *        without changing the sensor orientation.
      * @param deviceId The device id of the context associated with the caller.
      * @param devicePolicy The camera policy of the device of the associated context (default
      *                     policy for default device context). Only virtual cameras would be exposed
@@ -227,7 +256,7 @@
      * @return Characteristics for the given camera.
      */
     CameraMetadataNative getCameraCharacteristics(@utf8InCpp String cameraId, int targetSdkVersion,
-            boolean overrideToPortrait, int deviceId, int devicePolicy);
+            int rotationOverride, int deviceId, int devicePolicy);
 
     /**
      * Read in the vendor tag descriptors from the camera module HAL.
@@ -403,8 +432,11 @@
      *
      * @param cameraId ID of the device for which the session characteristics must be fetched.
      * @param targetSdkVersion the target sdk level of the application calling this function.
-     * @param overrideToPortrait Whether to override the sensor orientation information to
-     *                           correspond to portrait.
+     * @param rotationOverride Whether to override the sensor orientation information to
+     *        correspond to portrait: {@link ICameraService#ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT}
+     *        will override the sensor orientation and rotate and crop, while {@link
+     *        ICameraService#ROTATION_OVERRIDE_ROTATION_ONLY} will rotate and crop the camera feed
+     *        without changing the sensor orientation.
      * @param sessionConfiguration Session configuration for which the characteristics
      *                             must be fetched.
      * @param deviceId The device id of the context associated with the caller.
@@ -416,7 +448,7 @@
      */
     CameraMetadataNative getSessionCharacteristics(@utf8InCpp String cameraId,
             int targetSdkVersion,
-            boolean overrideToPortrait,
+            int rotationOverride,
             in SessionConfiguration sessionConfiguration,
             int deviceId,
             int devicePolicy);
diff --git a/camera/include/camera/Camera.h b/camera/include/camera/Camera.h
index dfa53d2..3ecd10d 100644
--- a/camera/include/camera/Camera.h
+++ b/camera/include/camera/Camera.h
@@ -59,7 +59,7 @@
     typedef ::android::hardware::ICameraClient TCamCallbacks;
     typedef ::android::binder::Status (::android::hardware::ICameraService::*TCamConnectService)
         (const sp<::android::hardware::ICameraClient>&,
-        int, const std::string&, int, int, int, bool, bool, int32_t, int32_t,
+        int, const std::string&, int, int, int, int, bool, int32_t, int32_t,
         /*out*/
         sp<::android::hardware::ICamera>*);
     static TCamConnectService     fnConnectService;
@@ -83,7 +83,7 @@
     static  sp<Camera>  connect(int cameraId,
                                 const std::string& clientPackageName,
                                 int clientUid, int clientPid, int targetSdkVersion,
-                                bool overrideToPortrait, bool forceSlowJpegMode,
+                                int rotationOverride, bool forceSlowJpegMode,
                                 int32_t deviceId = kDefaultDeviceId, int32_t devicePolicy = 0);
 
             virtual     ~Camera();
diff --git a/camera/include/camera/CameraBase.h b/camera/include/camera/CameraBase.h
index 85ddbd6..3370b3d 100644
--- a/camera/include/camera/CameraBase.h
+++ b/camera/include/camera/CameraBase.h
@@ -125,7 +125,7 @@
     static sp<TCam>      connect(int cameraId,
                                  const std::string& clientPackageName,
                                  int clientUid, int clientPid, int targetSdkVersion,
-                                 bool overrideToPortrait, bool forceSlowJpegMode,
+                                 int rotationOverride, bool forceSlowJpegMode,
                                  int32_t deviceId, int32_t devicePolicy);
     virtual void         disconnect();
 
@@ -134,7 +134,7 @@
     static int           getNumberOfCameras(int32_t deviceId, int32_t devicePolicy);
 
     static status_t      getCameraInfo(int cameraId,
-                                       bool overrideToPortrait,
+                                       int rotationOverride,
                                        int32_t deviceId,
                                        int32_t devicePolicy,
                                        /*out*/
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 0744992..d8e5f3c 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -719,7 +719,8 @@
     CameraMetadata rawMetadata;
     int targetSdkVersion = android_get_application_target_sdk_version();
     binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
-            targetSdkVersion, /*overrideToPortrait*/false, kDefaultDeviceId, /*devicePolicy*/0,
+            targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
+            kDefaultDeviceId, /*devicePolicy*/0,
             &rawMetadata);
     if (!serviceRet.isOk()) {
         switch(serviceRet.serviceSpecificErrorCode()) {
@@ -772,7 +773,8 @@
     binder::Status serviceRet = cs->connectDevice(
             callbacks, cameraId, "", {},
             hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
-            targetSdkVersion, /*overrideToPortrait*/false, kDefaultDeviceId, /*devicePolicy*/0,
+            targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
+            kDefaultDeviceId, /*devicePolicy*/0,
             /*out*/&deviceRemote);
 
     if (!serviceRet.isOk()) {