Merge "Camera3Device: Don't time out on long exposures" into oc-dr1-dev
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 2d8ac6e..a3198d7 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -229,10 +229,13 @@
     case AAUDIO_ERROR_NULL:
         status = UNEXPECTED_NULL;
         break;
+    case AAUDIO_ERROR_UNAVAILABLE:
+        status = NOT_ENOUGH_DATA;
+        break;
+
     // TODO translate these result codes
     case AAUDIO_ERROR_INTERNAL:
     case AAUDIO_ERROR_UNIMPLEMENTED:
-    case AAUDIO_ERROR_UNAVAILABLE:
     case AAUDIO_ERROR_NO_FREE_HANDLES:
     case AAUDIO_ERROR_NO_MEMORY:
     case AAUDIO_ERROR_TIMEOUT:
@@ -268,6 +271,9 @@
     case WOULD_BLOCK:
         result = AAUDIO_ERROR_WOULD_BLOCK;
         break;
+    case NOT_ENOUGH_DATA:
+        result = AAUDIO_ERROR_UNAVAILABLE;
+        break;
     default:
         result = AAUDIO_ERROR_INTERNAL;
         break;
diff --git a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
index 6e70ded..9a69226 100644
--- a/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
+++ b/media/libstagefright/codecs/mpeg2dec/SoftMPEG2.cpp
@@ -89,10 +89,10 @@
 }
 
 
-static size_t getMinTimestampIdx(OMX_S64 *pNTimeStamp, bool *pIsTimeStampValid) {
+static ssize_t getMinTimestampIdx(OMX_S64 *pNTimeStamp, bool *pIsTimeStampValid) {
     OMX_S64 minTimeStamp = LLONG_MAX;
-    int idx = -1;
-    for (size_t i = 0; i < MAX_TIME_STAMPS; i++) {
+    ssize_t idx = -1;
+    for (ssize_t i = 0; i < MAX_TIME_STAMPS; i++) {
         if (pIsTimeStampValid[i]) {
             if (pNTimeStamp[i] < minTimeStamp) {
                 minTimeStamp = pNTimeStamp[i];
@@ -788,10 +788,15 @@
             }
 
             if (s_dec_op.u4_output_present) {
-                size_t timeStampIdx;
+                ssize_t timeStampIdx;
                 outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
 
                 timeStampIdx = getMinTimestampIdx(mTimeStamps, mTimeStampsValid);
+                if (timeStampIdx < 0) {
+                    ALOGE("b/62872863, Invalid timestamp index!");
+                    android_errorWriteLog(0x534e4554, "62872863");
+                    return;
+                }
                 outHeader->nTimeStamp = mTimeStamps[timeStampIdx];
                 mTimeStampsValid[timeStampIdx] = false;
 
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index f1b44ae..1cf9744 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -892,6 +892,11 @@
         bits.skipBits(2);
 
         unsigned aac_frame_length = bits.getBits(13);
+        if (aac_frame_length == 0){
+            ALOGE("b/62673179, Invalid AAC frame length!");
+            android_errorWriteLog(0x534e4554, "62673179");
+            return NULL;
+        }
 
         bits.skipBits(11);  // adts_buffer_fullness
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a67acd6..1bd840e 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1169,6 +1169,11 @@
         return BAD_VALUE;
     }
 
+    // always allow effects without processing load or latency
+    if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) {
+        return NO_ERROR;
+    }
+
     switch (mType) {
     case MIXER: {
         // Reject any effect on mixer multichannel sinks.
@@ -1199,10 +1204,6 @@
                 }
             }
 
-            // always allow effects without processing load or latency
-            if ((desc->flags & EFFECT_FLAG_NO_PROCESS_MASK) == EFFECT_FLAG_NO_PROCESS) {
-                break;
-            }
             if (flags & AUDIO_OUTPUT_FLAG_RAW) {
                 ALOGW("checkEffectCompatibility_l(): effect %s on playback thread in raw mode",
                       desc->name);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 16fcfb1..0fc3740 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -854,12 +854,14 @@
 hardware::Return<void> Camera3Device::processCaptureResult(
         const hardware::hidl_vec<
                 hardware::camera::device::V3_2::CaptureResult>& results) {
-    {
-        Mutex::Autolock l(mLock);
-        if (mStatus == STATUS_ERROR) {
-            // Per API contract, HAL should act as closed after device error
-            ALOGW("%s: received capture result in error state!", __FUNCTION__);
-        }
+    // Ideally we should grab mLock, but that can lead to deadlock, and
+    // it's not super important to get up to date value of mStatus for this
+    // warning print, hence skipping the lock here
+    if (mStatus == STATUS_ERROR) {
+        // Per API contract, HAL should act as closed after device error
+        // But mStatus can be set to error by framework as well, so just log
+        // a warning here.
+        ALOGW("%s: received capture result in error state.", __FUNCTION__);
     }
 
     if (mProcessCaptureResultLock.tryLock() != OK) {
@@ -992,13 +994,16 @@
 
 hardware::Return<void> Camera3Device::notify(
         const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
-    {
-        Mutex::Autolock l(mLock);
-        if (mStatus == STATUS_ERROR) {
-            // Per API contract, HAL should act as closed after device error
-            ALOGW("%s: received notify message in error state!", __FUNCTION__);
-        }
+    // Ideally we should grab mLock, but that can lead to deadlock, and
+    // it's not super important to get up to date value of mStatus for this
+    // warning print, hence skipping the lock here
+    if (mStatus == STATUS_ERROR) {
+        // Per API contract, HAL should act as closed after device error
+        // But mStatus can be set to error by framework as well, so just log
+        // a warning here.
+        ALOGW("%s: received notify message in error state.", __FUNCTION__);
     }
+
     for (const auto& msg : msgs) {
         notify(msg);
     }
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index d726d46..0f863fe 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -112,10 +112,10 @@
 }
 
 aaudio_result_t AAudioServiceEndpoint::startStream(sp<AAudioServiceStreamShared> sharedStream) {
-    // TODO use real-time technique to avoid mutex, eg. atomic command FIFO
     aaudio_result_t result = AAUDIO_OK;
-    std::lock_guard<std::mutex> lock(mLockStreams);
     if (++mRunningStreams == 1) {
+        // TODO use real-time technique to avoid mutex, eg. atomic command FIFO
+        std::lock_guard<std::mutex> lock(mLockStreams);
         result = getStreamInternal()->requestStart();
         startSharingThread_l();
     }
@@ -123,13 +123,8 @@
 }
 
 aaudio_result_t AAudioServiceEndpoint::stopStream(sp<AAudioServiceStreamShared> sharedStream) {
-    int numRunningStreams = 0;
-    {
-        std::lock_guard<std::mutex> lock(mLockStreams);
-        numRunningStreams = --mRunningStreams;
-    }
-    if (numRunningStreams == 0) {
-        // Don't call this under a lock because the callbackLoop also uses the lock.
+    // Don't lock here because the disconnectRegisteredStreams also uses the lock.
+    if (--mRunningStreams == 0) { // atomic
         stopSharingThread();
         getStreamInternal()->requestStop();
     }
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index ed995e5..e40a670 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -73,13 +73,13 @@
 
     virtual AudioStreamInternal *getStreamInternal() = 0;
 
-    std::atomic<bool>        mCallbackEnabled;
+    std::atomic<bool>        mCallbackEnabled{false};
 
     mutable std::mutex       mLockStreams;
 
     std::vector<android::sp<AAudioServiceStreamShared>> mRegisteredStreams;
 
-    size_t                   mRunningStreams = 0;
+    std::atomic<int>         mRunningStreams{0};
 
 private:
     aaudio_result_t startSharingThread_l();
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index e0f6ad4..5f7d179 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -219,6 +219,8 @@
     //          (long long) command.timestamp.timestamp);
         command.what = AAudioServiceMessage::code::TIMESTAMP;
         result = writeUpMessageQueue(&command);
+    } else if (result == AAUDIO_ERROR_UNAVAILABLE) {
+        result = AAUDIO_OK; // just not available yet, try again later
     }
     return result;
 }
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 93a522e..cebefec 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -163,6 +163,11 @@
 
     aaudio_result_t sendCurrentTimestamp();
 
+    /**
+     * @param positionFrames
+     * @param timeNanos
+     * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
+     */
     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
 
     virtual aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) = 0;
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp
index a6fb129..afa2ff0 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.cpp
+++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp
@@ -297,16 +297,18 @@
         return AAUDIO_ERROR_NULL;
     }
     status_t status = mMmapStream->getMmapPosition(&position);
-    if (status != OK) {
-        ALOGE("sendCurrentTimestamp(): getMmapPosition() returned %d", status);
+    aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
+    if (result == AAUDIO_ERROR_UNAVAILABLE) {
+        ALOGW("sendCurrentTimestamp(): getMmapPosition() has no position data yet");
+    } else if (result != AAUDIO_OK) {
+        ALOGE("sendCurrentTimestamp(): getMmapPosition() returned status %d", status);
         disconnect();
-        return AAudioConvert_androidToAAudioResult(status);
     } else {
         mFramesRead.update32(position.position_frames);
         *positionFrames = mFramesRead.get();
         *timeNanos = position.time_nanoseconds;
     }
-    return AAUDIO_OK;
+    return result;
 }
 
 void AAudioServiceStreamMMAP::onTearDown() {