Merge "Camera: Query the rotate&crop compensation value" into sc-v2-dev
diff --git a/camera/OWNERS b/camera/OWNERS
index d6b95da..1b548e4 100644
--- a/camera/OWNERS
+++ b/camera/OWNERS
@@ -1,8 +1,8 @@
-epeev@google.com
+# Bug component: 41727
 etalvala@google.com
+arakesh@google.com
+epeev@google.com
 jchowdhary@google.com
 shuzhenwang@google.com
-yinchiayeh@google.com
-# backup owner
-cychen@google.com
-zhijunhe@google.com
+ruchamk@google.com
+
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index c353b2d..7c728cf 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -4585,7 +4585,7 @@
      * 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>.
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/params/DeviceStateSensorOrientationMap.html">DeviceStateSensorOrientationMap</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
diff --git a/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl b/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
index 0e9634c..88b8108 100644
--- a/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
+++ b/media/libaudioclient/aidl/android/media/INativeSpatializerCallback.aidl
@@ -31,4 +31,9 @@
      * (e.g. when the spatializer is enabled or disabled)
      */
     void onLevelChanged(SpatializationLevel level);
+
+    /** Called when the output stream the Spatializer is attached to changes.
+     * Indicates the IO Handle of the new output.
+     */
+    void onOutputChanged(int output);
 }
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 502a8d0..0fdbe20 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -627,6 +627,9 @@
 
 status_t Spatializer::attachOutput(audio_io_handle_t output) {
     std::shared_ptr<SpatializerPoseController> poseController;
+    bool outputChanged = false;
+    sp<media::INativeSpatializerCallback> callback;
+
     {
         std::lock_guard lock(mLock);
         ALOGV("%s output %d mOutput %d", __func__, (int)output, (int)mOutput);
@@ -654,6 +657,7 @@
                              std::vector<SpatializerHeadTrackingMode>{mActualHeadTrackingMode});
 
         mEngine->setEnabled(true);
+        outputChanged = mOutput != output;
         mOutput = output;
 
         if (mSupportsHeadTracking) {
@@ -668,26 +672,42 @@
             mPoseController->setDisplayOrientation(mDisplayOrientation);
             poseController = mPoseController;
         }
+        callback = mSpatializerCallback;
     }
     if (poseController != nullptr) {
         poseController->waitUntilCalculated();
     }
+
+    if (outputChanged && callback != nullptr) {
+        callback->onOutputChanged(output);
+    }
+
     return NO_ERROR;
 }
 
 audio_io_handle_t Spatializer::detachOutput() {
-    std::lock_guard lock(mLock);
-    ALOGV("%s mOutput %d", __func__, (int)mOutput);
     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
-    if (mOutput == AUDIO_IO_HANDLE_NONE) {
-        return output;
+    sp<media::INativeSpatializerCallback> callback;
+
+    {
+        std::lock_guard lock(mLock);
+        ALOGV("%s mOutput %d", __func__, (int)mOutput);
+        if (mOutput == AUDIO_IO_HANDLE_NONE) {
+            return output;
+        }
+        // remove FX instance
+        mEngine->setEnabled(false);
+        mEngine.clear();
+        output = mOutput;
+        mOutput = AUDIO_IO_HANDLE_NONE;
+        mPoseController.reset();
+
+        callback = mSpatializerCallback;
     }
-    // remove FX instance
-    mEngine->setEnabled(false);
-    mEngine.clear();
-    output = mOutput;
-    mOutput = AUDIO_IO_HANDLE_NONE;
-    mPoseController.reset();
+
+    if (callback != nullptr) {
+        callback->onOutputChanged(AUDIO_IO_HANDLE_NONE);
+    }
     return output;
 }