Merge "aaudio: fix race condition in timestamp path"
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 253f290..a134a13 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -77,6 +77,13 @@
      */
     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
+    /**
+     * Set time that the associated frame was presented to the hardware.
+     *
+     * @param positionFrames receive position, input value is ignored
+     * @param timeNanos receive time, input value is ignored
+     * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
+     */
     virtual aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
     int32_t getFramesPerBurst() const {
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 63b9983..fc9f155 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -192,5 +192,13 @@
 
 aaudio_result_t AAudioServiceEndpointShared::getTimestamp(int64_t *positionFrames,
                                                           int64_t *timeNanos) {
-    return mStreamInternal->getTimestamp(CLOCK_MONOTONIC, positionFrames, timeNanos);
+    aaudio_result_t result = mStreamInternal->getTimestamp(CLOCK_MONOTONIC, positionFrames, timeNanos);
+    if (result == AAUDIO_ERROR_INVALID_STATE) {
+        // getTimestamp() can return AAUDIO_ERROR_INVALID_STATE if the stream has
+        // not completely started. This can cause a race condition that kills the
+        // timestamp service thread.  So we reduce the error to a less serious one
+        // that allows the timestamp thread to continue.
+        result = AAUDIO_ERROR_UNAVAILABLE;
+    }
+    return result;
 }