Implement client playback timestamps with 64 bit accuracy

Provide server timestamps if the HAL doesn't provide it.
Provide monotonic - boottime translation.

Bug: 17472992
Bug: 26682703
Bug: 27749434
Change-Id: I6c9b213d9f9284092e34d57f52870e02c72df62a
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
index 531b548..969003c 100644
--- a/include/media/AudioTimestamp.h
+++ b/include/media/AudioTimestamp.h
@@ -69,12 +69,23 @@
     // or NTP adjustment.
     int64_t mTimebaseOffset[TIMEBASE_MAX];
 
+    // Playback only:
+    // mFlushed is number of flushed frames before entering the server mix;
+    // hence not included in mPosition. This is used for adjusting server positions
+    // information for frames "dropped".
+    // FIXME: This variable should be eliminated, with the offset added on the server side
+    // before sending to client, but differences in legacy position offset handling
+    // and new extended timestamps require this to be maintained as a separate quantity.
+    int64_t mFlushed;
+
+    // Call to reset the timestamp to the original (invalid) state
     void clear() {
         memset(mPosition, 0, sizeof(mPosition)); // actually not necessary if time is -1
         for (int i = 0; i < LOCATION_MAX; ++i) {
             mTimeNs[i] = -1;
         }
         memset(mTimebaseOffset, 0, sizeof(mTimebaseOffset));
+        mFlushed = 0;
     }
 
     // Returns the best timestamp as judged from the closest-to-hw stage in the
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index bdd6372..b96a450 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -727,12 +727,51 @@
      *                     because the audio device changed or AudioFlinger died.
      *                     This typically occurs for direct or offload tracks
      *                     or if mDoNotReconnect is true.
-     *         INVALID_OPERATION  if called on a FastTrack, wrong state, or some other error.
+     *         INVALID_OPERATION  wrong state, or some other error.
      *
      * The timestamp parameter is undefined on return, if status is not NO_ERROR.
      */
             status_t    getTimestamp(AudioTimestamp& timestamp);
 
+    /* Return the extended timestamp, with additional timebase info and improved drain behavior.
+     *
+     * This is similar to the AudioTrack.java API:
+     * getTimestamp(@NonNull AudioTimestamp timestamp, @AudioTimestamp.Timebase int timebase)
+     *
+     * Some differences between this method and the getTimestamp(AudioTimestamp& timestamp) method
+     *
+     *   1. stop() by itself does not reset the frame position.
+     *      A following start() resets the frame position to 0.
+     *   2. flush() by itself does not reset the frame position.
+     *      The frame position advances by the number of frames flushed,
+     *      when the first frame after flush reaches the audio sink.
+     *   3. BOOTTIME clock offsets are provided to help synchronize with
+     *      non-audio streams, e.g. sensor data.
+     *   4. Position is returned with 64 bits of resolution.
+     *
+     * Parameters:
+     *  timestamp: A pointer to the caller allocated ExtendedTimestamp.
+     *
+     * Returns NO_ERROR    on success; timestamp is filled with valid data.
+     *         BAD_VALUE   if timestamp is NULL.
+     *         WOULD_BLOCK if called immediately after start() when the number
+     *                     of frames consumed is less than the
+     *                     overall hardware latency to physical output. In WOULD_BLOCK cases,
+     *                     one might poll again, or use getPosition(), or use 0 position and
+     *                     current time for the timestamp.
+     *                     If WOULD_BLOCK is returned, the timestamp is still
+     *                     modified with the LOCATION_CLIENT portion filled.
+     *         DEAD_OBJECT if AudioFlinger dies or the output device changes and
+     *                     the track cannot be automatically restored.
+     *                     The application needs to recreate the AudioTrack
+     *                     because the audio device changed or AudioFlinger died.
+     *                     This typically occurs for direct or offloaded tracks
+     *                     or if mDoNotReconnect is true.
+     *         INVALID_OPERATION  if called on a offloaded or direct track.
+     *                     Use getTimestamp(AudioTimestamp& timestamp) instead.
+     */
+            status_t getTimestamp(ExtendedTimestamp *timestamp);
+
     /* Add an AudioDeviceCallback. The caller will be notified when the audio device to which this
      * AudioTrack is routed is updated.
      * Replaces any previously installed callback.
@@ -956,6 +995,13 @@
 
     uint32_t                mUnderrunCountOffset;   // updated when restoring tracks
 
+    int64_t                 mFramesWritten;         // total frames written. reset to zero after
+                                                    // the start() following stop(). It is not
+                                                    // changed after restoring the track or
+                                                    // after flush.
+    int64_t                 mFramesWrittenServerOffset; // An offset to server frames due to
+                                                    // restoring AudioTrack, or stop/start.
+
     audio_output_flags_t    mFlags;                 // same as mOrigFlags, except for bits that may
                                                     // be denied by client or server, such as
                                                     // AUDIO_OUTPUT_FLAG_FAST.  mLock must be
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 92cf6bb..ffdb9b5 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -522,6 +522,9 @@
         mTimestampMutator.push(timestamp);
     }
 
+    // Total count of the number of flushed frames since creation (never reset).
+    virtual int64_t     framesFlushed() const { return mFlushed; }
+
     // Get dynamic buffer size from the shared control block.
     uint32_t            getBufferSizeInFrames() const {
         return android_atomic_acquire_load((int32_t *)&mCblk->mBufferSizeInFrames);
@@ -531,7 +534,7 @@
     size_t      mAvailToClient; // estimated frames available to client prior to releaseBuffer()
     int32_t     mFlush;         // our copy of cblk->u.mStreaming.mFlush, for streaming output only
     int64_t     mReleased;      // our copy of cblk->mServer, at 64 bit resolution
-
+    int64_t     mFlushed;       // flushed frames to account for client-server discrepancy
     ExtendedTimestampQueue::Mutator mTimestampMutator;
 };