spatialier: more head pose controller optimizations

Spatializer:
- do not suppress pose updates when actual head tracking mode is
  disabled
- remove redundant check on mode changed in onActualModeChangeMsg()
- do not wait for pose calculation when creating the head pose
  controller

SpatializerPoseController:
- fix potential race condition between mShouldExit and mShouldCalculate
- allow constuction without maxUpdatePeriod

Bug: 227740874
Test: Spatial audio playback with and without head pose sensor
Change-Id: I92fa5158ba7ffda564a021b03e81b6ff3d124351
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 3b466d7..389233e 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -459,9 +459,7 @@
     }
     std::lock_guard lock(mLock);
     mScreenSensor = sensorHandle;
-    if (mPoseController != nullptr) {
-        mPoseController->setScreenSensor(mScreenSensor);
-    }
+    checkSensorsState_l();
     return Status::ok();
 }
 
@@ -569,9 +567,6 @@
     sp<media::ISpatializerHeadTrackingCallback> callback;
     {
         std::lock_guard lock(mLock);
-        if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
-            return;
-        }
         callback = mHeadTrackingCallback;
         if (mEngine != nullptr) {
             setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -595,7 +590,6 @@
     ALOGV("%s(%d)", __func__, (int) mode);
     sp<media::ISpatializerHeadTrackingCallback> callback;
     SpatializerHeadTrackingMode spatializerMode;
-    bool modeChanged = false;
     {
         std::lock_guard lock(mLock);
         if (!mSupportsHeadTracking) {
@@ -615,21 +609,19 @@
                     LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
             }
         }
-        modeChanged = mActualHeadTrackingMode != spatializerMode;
         mActualHeadTrackingMode = spatializerMode;
-        if (modeChanged && mEngine != nullptr) {
+        if (mEngine != nullptr) {
             setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
                                  std::vector<SpatializerHeadTrackingMode>{spatializerMode});
         }
         callback = mHeadTrackingCallback;
     }
-    if (callback != nullptr && modeChanged) {
+    if (callback != nullptr) {
         callback->onHeadTrackingModeChanged(spatializerMode);
     }
 }
 
 status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
-    std::shared_ptr<SpatializerPoseController> poseController;
     bool outputChanged = false;
     sp<media::INativeSpatializerCallback> callback;
 
@@ -663,14 +655,9 @@
         if (mSupportsHeadTracking) {
             checkPoseController_l();
             checkSensorsState_l();
-            poseController = mPoseController;
         }
         callback = mSpatializerCallback;
     }
-    if (poseController != nullptr) {
-        poseController->calculateAsync();
-        poseController->waitUntilCalculated();
-    }
 
     if (outputChanged && callback != nullptr) {
         callback->onOutputChanged(output);
@@ -750,7 +737,7 @@
     if (isControllerNeeded && mPoseController == nullptr) {
         mPoseController = std::make_shared<SpatializerPoseController>(
                 static_cast<SpatializerPoseController::Listener*>(this),
-                10ms, std::chrono::microseconds::max());
+                10ms, std::nullopt);
         LOG_ALWAYS_FATAL_IF(mPoseController == nullptr,
                             "%s could not allocate pose controller", __func__);
         mPoseController->setDisplayOrientation(mDisplayOrientation);
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 58a57ac..d3649dc 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -79,8 +79,8 @@
 }  // namespace
 
 SpatializerPoseController::SpatializerPoseController(Listener* listener,
-                                                     std::chrono::microseconds sensorPeriod,
-                                                     std::chrono::microseconds maxUpdatePeriod)
+                                        std::chrono::microseconds sensorPeriod,
+                                        std::optional<std::chrono::microseconds> maxUpdatePeriod)
     : mListener(listener),
       mSensorPeriod(sensorPeriod),
       mProcessor(createHeadTrackingProcessor(HeadTrackingProcessor::Options{
@@ -102,8 +102,12 @@
               std::optional<HeadTrackingMode> modeIfChanged;
               {
                   std::unique_lock lock(mMutex);
-                  mCondVar.wait_for(lock, maxUpdatePeriod,
-                                    [this] { return mShouldExit || mShouldCalculate; });
+                  if (maxUpdatePeriod.has_value()) {
+                      mCondVar.wait_for(lock, maxUpdatePeriod.value(),
+                                        [this] { return mShouldExit || mShouldCalculate; });
+                  } else {
+                      mCondVar.wait(lock, [this] { return mShouldExit || mShouldCalculate; });
+                  }
                   if (mShouldExit) {
                       ALOGV("Exiting thread");
                       return;
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index 2b5c189..2c6d79a 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -60,10 +60,10 @@
      * Ctor.
      * sensorPeriod determines how often to receive updates from the sensors (input rate).
      * maxUpdatePeriod determines how often to produce an output when calculateAsync() isn't
-     * invoked.
+     * invoked; passing nullopt means an output is never produced.
      */
     SpatializerPoseController(Listener* listener, std::chrono::microseconds sensorPeriod,
-                               std::chrono::microseconds maxUpdatePeriod);
+                               std::optional<std::chrono::microseconds> maxUpdatePeriod);
 
     /** Dtor. */
     ~SpatializerPoseController();