Spatializer dumpsys: Add parameters and local logs in dumpsys

Bug: 233092747
Test: m and "adb shell dumpsys media.audio_policy"

Change-Id: Idbcd4686987e48511302cb3afed8e8035b2a502c
Merged-In: Idbcd4686987e48511302cb3afed8e8035b2a502c
(cherry picked from commit afc0c2ec992ed1e301a98643d83326198bff4dc8)
diff --git a/media/libheadtracking/Android.bp b/media/libheadtracking/Android.bp
index 9d63f9b..7e2c762 100644
--- a/media/libheadtracking/Android.bp
+++ b/media/libheadtracking/Android.bp
@@ -22,6 +22,10 @@
       "StillnessDetector.cpp",
       "Twist.cpp",
     ],
+    shared_libs: [
+        "libaudioutils",
+        "libbase",
+    ],
     export_include_dirs: [
         "include",
     ],
@@ -39,6 +43,7 @@
       "SensorPoseProvider.cpp",
     ],
     shared_libs: [
+        "libbase",
         "libheadtracking",
         "liblog",
         "libsensor",
diff --git a/media/libheadtracking/HeadTrackingProcessor.cpp b/media/libheadtracking/HeadTrackingProcessor.cpp
index 71fae8a..fb44567 100644
--- a/media/libheadtracking/HeadTrackingProcessor.cpp
+++ b/media/libheadtracking/HeadTrackingProcessor.cpp
@@ -13,7 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <inttypes.h>
 
+#include <android-base/stringprintf.h>
+#include <audio_utils/SimpleLog.h>
 #include "media/HeadTrackingProcessor.h"
 
 #include "ModeSelector.h"
@@ -26,6 +29,7 @@
 namespace media {
 namespace {
 
+using android::base::StringAppendF;
 using Eigen::Quaternionf;
 using Eigen::Vector3f;
 
@@ -136,10 +140,12 @@
         if (recenterHead) {
             mHeadPoseBias.recenter();
             mHeadStillnessDetector.reset();
+            mLocalLog.log("recenter Head");
         }
         if (recenterScreen) {
             mScreenPoseBias.recenter();
             mScreenStillnessDetector.reset();
+            mLocalLog.log("recenter Screen");
         }
 
         // If a sensor being recentered is included in the current mode, apply rate limiting to
@@ -152,6 +158,35 @@
         }
     }
 
+    std::string toString_l(unsigned level) const override {
+        std::string prefixSpace(level, ' ');
+        std::string ss = prefixSpace + "HeadTrackingProcessor:\n";
+        StringAppendF(&ss, "%smaxTranslationalVelocity: %f\n", prefixSpace.c_str(),
+                      mOptions.maxTranslationalVelocity);
+        StringAppendF(&ss, "%smaxRotationalVelocity: %f\n", prefixSpace.c_str(),
+                      mOptions.maxRotationalVelocity);
+        StringAppendF(&ss, "%sfreshnessTimeout: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.freshnessTimeout);
+        StringAppendF(&ss, "%spredictionDuration: %f\n", prefixSpace.c_str(),
+                      mOptions.predictionDuration);
+        StringAppendF(&ss, "%sautoRecenterWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterWindowDuration);
+        StringAppendF(&ss, "%sautoRecenterTranslationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterTranslationalThreshold);
+        StringAppendF(&ss, "%sautoRecenterRotationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.autoRecenterRotationalThreshold);
+        StringAppendF(&ss, "%sscreenStillnessWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessWindowDuration);
+        StringAppendF(&ss, "%sscreenStillnessTranslationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessTranslationalThreshold);
+        StringAppendF(&ss, "%sscreenStillnessRotationalThreshold: %f\n", prefixSpace.c_str(),
+                      mOptions.screenStillnessRotationalThreshold);
+        ss.append(prefixSpace + "ReCenterHistory:\n");
+        ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
+        // TODO: 233092747 add string from PoseRateLimiter/PoseRateLimiter etc...
+        return ss;
+    }
+
   private:
     const Options mOptions;
     float mPhysicalToLogicalAngle = 0;
@@ -168,6 +203,8 @@
     ScreenHeadFusion mScreenHeadFusion;
     ModeSelector mModeSelector;
     PoseRateLimiter mRateLimiter;
+    static constexpr std::size_t mMaxLocalLogLine = 10;
+    SimpleLog mLocalLog{mMaxLocalLogLine};
 };
 
 }  // namespace
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index e5e1521..6c0a96d 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -24,6 +24,7 @@
 #include <map>
 #include <thread>
 
+#include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 #include <log/log_main.h>
 #include <sensor/SensorEventQueue.h>
@@ -36,6 +37,8 @@
 namespace media {
 namespace {
 
+using android::base::StringAppendF;
+
 // Identifier to use for our event queue on the loop.
 // The number 19 is arbitrary, only useful if using multiple objects on the same looper.
 constexpr int kIdent = 19;
@@ -153,6 +156,38 @@
         mEnabledSensorsExtra.erase(handle);
     }
 
+    std::string toString(unsigned level) override {
+        std::string prefixSpace(level, ' ');
+        std::string ss = prefixSpace + "SensorPoseProvider:\n";
+        bool needUnlock = false;
+
+        prefixSpace += " ";
+        auto now = std::chrono::steady_clock::now();
+        if (!mMutex.try_lock_until(now + media::kSpatializerDumpSysTimeOutInSecond)) {
+            ss.append(prefixSpace).append("try_lock failed, dumpsys below maybe INACCURATE!\n");
+        } else {
+            needUnlock = true;
+        }
+
+        // Enabled sensor information
+        StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
+                      mEnabledSensorsExtra.size());
+        for (auto sensor : mEnabledSensorsExtra) {
+            StringAppendF(&ss, "%s[Handle: 0x%08x, Format %s", prefixSpace.c_str(), sensor.first,
+                          toString(sensor.second.format).c_str());
+            if (sensor.second.discontinuityCount.has_value()) {
+                StringAppendF(&ss, ", DiscontinuityCount: %d",
+                              sensor.second.discontinuityCount.value());
+            }
+            ss += "]\n";
+        }
+
+        if (needUnlock) {
+            mMutex.unlock();
+        }
+        return ss;
+    }
+
   private:
     enum DataFormat {
         kUnknown,
@@ -174,7 +209,7 @@
     sp<Looper> mLooper;
     Listener* const mListener;
     SensorManager* const mSensorManager;
-    std::mutex mMutex;
+    std::timed_mutex mMutex;
     std::map<int32_t, SensorEnableGuard> mEnabledSensors;
     std::map<int32_t, SensorExtra> mEnabledSensorsExtra GUARDED_BY(mMutex);
     sp<SensorEventQueue> mQueue;
@@ -193,7 +228,6 @@
           mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))) {
         mThread = std::thread([this] { threadFunc(); });
     }
-
     void initFinished(bool success) { mInitPromise.set_value(success); }
 
     bool waitInitFinished() { return mInitPromise.get_future().get(); }
@@ -346,6 +380,19 @@
                 LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
         }
     }
+
+    const std::string toString(DataFormat format) {
+        switch (format) {
+            case DataFormat::kUnknown:
+                return "kUnknown";
+            case DataFormat::kQuaternion:
+                return "kQuaternion";
+            case DataFormat::kRotationVectorsAndDiscontinuityCount:
+                return "kRotationVectorsAndDiscontinuityCount";
+            default:
+                return "NotImplemented";
+        }
+    }
 };
 
 }  // namespace
diff --git a/media/libheadtracking/include/media/HeadTrackingProcessor.h b/media/libheadtracking/include/media/HeadTrackingProcessor.h
index 1744be3..8ef8ab0 100644
--- a/media/libheadtracking/include/media/HeadTrackingProcessor.h
+++ b/media/libheadtracking/include/media/HeadTrackingProcessor.h
@@ -96,8 +96,12 @@
      * This causes the current poses for both the head and/or screen to be considered "center".
      */
     virtual void recenter(bool recenterHead = true, bool recenterScreen = true) = 0;
-};
 
+    /**
+     * Dump HeadTrackingProcessor parameters under caller lock.
+     */
+    virtual std::string toString_l(unsigned level) const = 0;
+};
 /**
  * Creates an instance featuring a default implementation of the HeadTrackingProcessor interface.
  */
diff --git a/media/libheadtracking/include/media/SensorPoseProvider.h b/media/libheadtracking/include/media/SensorPoseProvider.h
index 0f42074..4609e0c 100644
--- a/media/libheadtracking/include/media/SensorPoseProvider.h
+++ b/media/libheadtracking/include/media/SensorPoseProvider.h
@@ -28,6 +28,9 @@
 namespace android {
 namespace media {
 
+// Timeout for Spatializer dumpsys trylock, don't block for more than 3 seconds.
+constexpr auto kSpatializerDumpSysTimeOutInSecond = std::chrono::seconds(3);
+
 /**
  * A utility providing streaming of pose data from motion sensors provided by the Sensor Framework.
  *
@@ -100,6 +103,11 @@
      * discover properties of the sensor.
      */
     virtual std::optional<const Sensor> getSensorByHandle(int32_t handle) = 0;
+
+    /**
+     * Dump SensorPoseProvider parameters and history data.
+     */
+    virtual std::string toString(unsigned level) = 0;
 };
 
 }  // namespace media