Merge changes from topic "foldable_orientation" into sc-v2-dev

* changes:
  Camera: Only override rotate&crop for Camera2 clients
  Camera: Allow dynamic sensor orientation updates
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 86781e5..c353b2d 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -4578,6 +4578,25 @@
      *
      * <p>Also defines the direction of rolling shutter readout, which is from top to bottom in
      * the sensor's coordinate system.</p>
+     * <p>Starting with Android API level 32, camera clients that query the orientation via
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#get">CameraCharacteristics#get</a> on foldable devices which
+     * include logical cameras can receive a value that can dynamically change depending on the
+     * device/fold state.
+     * Clients are advised to not cache or store the orientation value of such logical sensors.
+     * In case repeated queries to CameraCharacteristics are not preferred, then clients can
+     * also access the entire mapping from device state to sensor orientation in
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/params/DeviceStateOrientationMap.html">DeviceStateOrientationMap</a>.
+     * Do note that a dynamically changing sensor orientation value in camera characteristics
+     * will not be the best way to establish the orientation per frame. Clients that want to
+     * know the sensor orientation of a particular captured frame should query the
+     * ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID from the corresponding capture result and
+     * check the respective physical camera orientation.</p>
+     * <p>Native camera clients must query ACAMERA_INFO_DEVICE_STATE_ORIENTATIONS for the mapping
+     * between device state and camera sensor orientation. Dynamic updates to the sensor
+     * orientation are not supported in this code path.</p>
+     *
+     * @see ACAMERA_INFO_DEVICE_STATE_ORIENTATIONS
+     * @see ACAMERA_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID
      */
     ACAMERA_SENSOR_ORIENTATION =                                // int32
             ACAMERA_SENSOR_START + 14,
@@ -6284,6 +6303,21 @@
      */
     ACAMERA_INFO_VERSION =                                      // byte
             ACAMERA_INFO_START + 1,
+    /**
+     *
+     * <p>Type: int64[2*n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>HAL must populate the array with
+     * (hardware::camera::provider::V2_5::DeviceState, sensorOrientation) pairs for each
+     * supported device state bitwise combination.</p>
+     */
+    ACAMERA_INFO_DEVICE_STATE_ORIENTATIONS =                    // int64[2*n]
+            ACAMERA_INFO_START + 3,
     ACAMERA_INFO_END,
 
     /**
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 8aff9b4..f51ebce 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1834,8 +1834,9 @@
         // Set rotate-and-crop override behavior
         if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
             client->setRotateAndCropOverride(mOverrideRotateAndCropMode);
-        } else if (CameraServiceProxyWrapper::isRotateAndCropOverrideNeeded(clientPackageName,
-                    orientation, facing)) {
+        } else if ((effectiveApiLevel == API_2) &&
+                CameraServiceProxyWrapper::isRotateAndCropOverrideNeeded(clientPackageName,
+                        orientation, facing) ) {
             client->setRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_90);
         }
 
@@ -2216,7 +2217,7 @@
     for (auto& current : clients) {
         if (current != nullptr) {
             const auto basicClient = current->getValue();
-            if (basicClient.get() != nullptr) {
+            if (basicClient.get() != nullptr && basicClient->canCastToApiClient(API_2)) {
                 if (CameraServiceProxyWrapper::isRotateAndCropOverrideNeeded(
                             basicClient->getPackageName(), basicClient->getCameraOrientation(),
                             basicClient->getCameraFacing())) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 556ddda..9abb972 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -373,6 +373,7 @@
             res = singleRes;
             // continue to do the rest of the providers instead of returning now
         }
+        provider->notifyDeviceInfoStateChangeLocked(mDeviceState);
     }
     return res;
 }
@@ -2039,6 +2040,14 @@
     return OK;
 }
 
+void CameraProviderManager::ProviderInfo::notifyDeviceInfoStateChangeLocked(
+        hardware::hidl_bitfield<provider::V2_5::DeviceState> newDeviceState) {
+    std::lock_guard<std::mutex> lock(mLock);
+    for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
+        (*it)->notifyDeviceStateChange(newDeviceState);
+    }
+}
+
 status_t CameraProviderManager::ProviderInfo::notifyDeviceStateChange(
         hardware::hidl_bitfield<provider::V2_5::DeviceState> newDeviceState) {
     mDeviceState = newDeviceState;
@@ -2293,6 +2302,18 @@
         return;
     }
 
+    if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+        const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
+        if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
+            for (size_t i = 0; i < stateMap.count; i += 2) {
+                mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
+            }
+        } else {
+            ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
+                    stateMap.count);
+        }
+    }
+
     mSystemCameraKind = getSystemCameraKind();
 
     status_t res = fixupMonochromeTags();
@@ -2421,6 +2442,16 @@
 
 CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
 
+void CameraProviderManager::ProviderInfo::DeviceInfo3::notifyDeviceStateChange(
+        hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState> newState) {
+
+    if (!mDeviceStateOrientationMap.empty() &&
+            (mDeviceStateOrientationMap.find(newState) != mDeviceStateOrientationMap.end())) {
+        mCameraCharacteristics.update(ANDROID_SENSOR_ORIENTATION,
+                &mDeviceStateOrientationMap[newState], 1);
+    }
+}
+
 status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
     return setTorchModeForDevice<InterfaceT>(enabled);
 }
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index d8c1f59..e3763a1 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -40,7 +40,6 @@
 #include <camera/VendorTagDescriptor.h>
 
 namespace android {
-
 /**
  * The vendor tag descriptor class that takes HIDL vendor tag information as
  * input. Not part of VendorTagDescriptor class because that class is used
@@ -440,6 +439,15 @@
         std::vector<std::unordered_set<std::string>> getConcurrentCameraIdCombinations();
 
         /**
+         * Notify 'DeviceInfo' instanced about top-level device physical state changes
+         *
+         * Note that 'mInterfaceMutex' should be held when calling this method.
+         */
+        void notifyDeviceInfoStateChangeLocked(
+               hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState>
+                   newDeviceState);
+
+        /**
          * Query the camera provider for concurrent stream configuration support
          */
         status_t isConcurrentSessionConfigurationSupported(
@@ -491,6 +499,9 @@
                 return INVALID_OPERATION;
             }
             virtual status_t filterSmallJpegSizes() = 0;
+            virtual void notifyDeviceStateChange(
+                    hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState>
+                        /*newState*/) {}
 
             template<class InterfaceT>
             sp<InterfaceT> startDeviceInterface();
@@ -551,6 +562,9 @@
                     bool *status /*out*/)
                     override;
             virtual status_t filterSmallJpegSizes() override;
+            virtual void notifyDeviceStateChange(
+                    hardware::hidl_bitfield<hardware::camera::provider::V2_5::DeviceState>
+                        newState) override;
 
             DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
                     const std::string &id, uint16_t minorVersion,
@@ -560,6 +574,8 @@
             virtual ~DeviceInfo3();
         private:
             CameraMetadata mCameraCharacteristics;
+            // Map device states to sensor orientations
+            std::unordered_map<int64_t, int32_t> mDeviceStateOrientationMap;
             // A copy of mCameraCharacteristics without performance class
             // override
             std::unique_ptr<CameraMetadata> mCameraCharNoPCOverride;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 87c1c75..a4288cd 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2677,6 +2677,7 @@
     }
 
     mGroupIdPhysicalCameraMap.clear();
+    bool composerSurfacePresent = false;
     for (size_t i = 0; i < mOutputStreams.size(); i++) {
 
         // Don't configure bidi streams twice, nor add them twice to the list
@@ -2716,6 +2717,10 @@
             const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
             mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
         }
+
+        if (outputStream->usage & GraphicBuffer::USAGE_HW_COMPOSER) {
+            composerSurfacePresent = true;
+        }
     }
 
     config.streams = streams.editArray();
@@ -2783,6 +2788,8 @@
         }
     }
 
+    mRequestThread->setComposerSurface(composerSurfacePresent);
+
     // Request thread needs to know to avoid using repeat-last-settings protocol
     // across configure_streams() calls
     if (notifyRequestThread) {
@@ -4179,6 +4186,7 @@
         mCurrentAfTriggerId(0),
         mCurrentPreCaptureTriggerId(0),
         mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
+        mComposerOutput(false),
         mCameraMute(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF),
         mCameraMuteChanged(false),
         mRepeatingLastFrameNumber(
@@ -4829,7 +4837,11 @@
         bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
         mPrevTriggers = triggerCount;
 
-        bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
+        // Do not override rotate&crop for stream configurations that include
+        // SurfaceViews(HW_COMPOSER) output. The display rotation there will be
+        // compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
+        bool rotateAndCropChanged = mComposerOutput ? false :
+            overrideAutoRotateAndCrop(captureRequest);
         bool testPatternChanged = overrideTestPattern(captureRequest);
 
         // If the request is the same as last, or we had triggers now or last time or
@@ -5335,6 +5347,13 @@
     return OK;
 }
 
+status_t Camera3Device::RequestThread::setComposerSurface(bool composerSurfacePresent) {
+    ATRACE_CALL();
+    Mutex::Autolock l(mTriggerMutex);
+    mComposerOutput = composerSurfacePresent;
+    return OK;
+}
+
 status_t Camera3Device::RequestThread::setCameraMute(int32_t muteMode) {
     ATRACE_CALL();
     Mutex::Autolock l(mTriggerMutex);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index df941b2..3a1853b 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -919,6 +919,7 @@
 
         status_t setRotateAndCropAutoBehavior(
                 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue);
+        status_t setComposerSurface(bool composerSurfacePresent);
 
         status_t setCameraMute(int32_t muteMode);
 
@@ -1071,6 +1072,7 @@
         uint32_t           mCurrentAfTriggerId;
         uint32_t           mCurrentPreCaptureTriggerId;
         camera_metadata_enum_android_scaler_rotate_and_crop_t mRotateAndCropOverride;
+        bool               mComposerOutput;
         int32_t            mCameraMute; // 0 = no mute, otherwise the TEST_PATTERN_MODE to use
         bool               mCameraMuteChanged;