TimeCheck: Use clock monotonic for elapsed time

The timeout deadline uses clock monotonic.

Update the elapsed time passed to the callbacks to
use clock monotonic as well.  Clock monotonic counts only the
time the CPU is active (vs suspend) and is a better estimate
for performance monitoring.

Test: overnight stress test
Test: atest libmediautils_test
Test: atest timecheck_tests
Bug: 227594853
Change-Id: Ie35de689245a04ba50f4d4f04a10e2e0ded2293b
diff --git a/media/utils/include/mediautils/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
index 038e7dd..8bee8d1 100644
--- a/media/utils/include/mediautils/TimeCheck.h
+++ b/media/utils/include/mediautils/TimeCheck.h
@@ -27,9 +27,23 @@
 
 class TimeCheck {
   public:
+
+    // Duration for TimeCheck is based on steady_clock, typically nanoseconds.
+    using Duration = std::chrono::steady_clock::duration;
+
+    // Duration for printing is in milliseconds, using float for additional precision.
+    using FloatMs = std::chrono::duration<float, std::milli>;
+
+    // OnTimerFunc is the callback function with 2 parameters.
+    //  bool timeout  (which is true when the TimeCheck object
+    //                 times out, false when the TimeCheck object is
+    //                 destroyed or leaves scope before the timer expires.)
+    //  float elapsedMs (the elapsed time to this event).
     using OnTimerFunc = std::function<void(bool /* timeout */, float /* elapsedMs */ )>;
 
     // The default timeout is chosen to be less than system server watchdog timeout
+    // Note: kDefaultTimeOutMs should be no less than 2 seconds, otherwise spurious timeouts
+    // may occur with system suspend.
     static constexpr uint32_t kDefaultTimeOutMs = 5000;
 
     /**
@@ -44,24 +58,20 @@
      * the deallocation.
      *
      * \param tag       string associated with the TimeCheck object.
-     * \param onTimer   callback function with 2 parameters
-     *                      bool timeout  (which is true when the TimeCheck object
-     *                                    times out, false when the TimeCheck object is
-     *                                    destroyed or leaves scope before the timer expires.)
-     *                      float elapsedMs (the elapsed time to this event).
+     * \param onTimer   callback function with 2 parameters (described above in OnTimerFunc).
      *                  The callback when timeout is true will be called on a different thread.
      *                  This will cancel the callback on the destructor but is not guaranteed
      *                  to block for callback completion if it is already in progress
      *                  (for maximum concurrency and reduced deadlock potential), so use proper
      *                  lifetime analysis (e.g. shared or weak pointers).
-     * \param timeoutMs timeout in milliseconds.
+     * \param requestedTimeoutMs timeout in milliseconds.
      *                  A zero timeout means no timeout is set -
      *                  the callback is called only when
      *                  the TimeCheck object is destroyed or leaves scope.
      * \param crashOnTimeout true if the object issues an abort on timeout.
      */
     explicit TimeCheck(std::string_view tag, OnTimerFunc&& onTimer = {},
-            uint32_t timeoutMs = kDefaultTimeOutMs, bool crashOnTimeout = true);
+            uint32_t requestedTimeoutMs = kDefaultTimeOutMs, bool crashOnTimeout = true);
 
     TimeCheck() = default;
     // Remove copy constructors as there should only be one call to the destructor.
@@ -81,24 +91,32 @@
     public:
         template <typename S, typename F>
         TimeCheckHandler(S&& _tag, F&& _onTimer, bool _crashOnTimeout,
-            const std::chrono::system_clock::time_point& _startTime,
+            Duration _timeoutDuration,
+            std::chrono::system_clock::time_point _startSystemTime,
             pid_t _tid)
             : tag(std::forward<S>(_tag))
             , onTimer(std::forward<F>(_onTimer))
             , crashOnTimeout(_crashOnTimeout)
-            , startTime(_startTime)
+            , timeoutDuration(_timeoutDuration)
+            , startSystemTime(_startSystemTime)
             , tid(_tid)
             {}
         const FixedString62 tag;
         const OnTimerFunc onTimer;
         const bool crashOnTimeout;
-        const std::chrono::system_clock::time_point startTime;
+        const Duration timeoutDuration;
+        const std::chrono::system_clock::time_point startSystemTime;
         const pid_t tid;
 
         void onCancel(TimerThread::Handle handle) const;
-        void onTimeout() const;
+        void onTimeout(TimerThread::Handle handle) const;
     };
 
+    // Returns a string that represents the timeout vs elapsed time,
+    // and diagnostics if there are any potential issues.
+    static std::string analyzeTimeouts(
+            float timeoutMs, float elapsedSteadyMs, float elapsedSystemMs);
+
     static TimerThread& getTimeCheckThread();
     static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);