Merge "Camera: Fix deadlock in ACameraCaptureSession destructor" am: 66ce689527 am: 7dd0928bd1 am: 81429402d8

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1535309

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I858710a373350c81534eaf8a3f462193f5e191c3
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 08c88ce..dd652c7 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -1367,31 +1367,11 @@
                 it->second.isSequenceCompleted = true;
             }
 
-            if (it->second.isSequenceCompleted && hasCallback) {
-                auto cbIt = mSequenceCallbackMap.find(sequenceId);
-                CallbackHolder cbh = cbIt->second;
-
-                // send seq complete callback
-                sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
-                msg->setPointer(kContextKey, cbh.mContext);
-                msg->setObject(kSessionSpKey, cbh.mSession);
-                msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
-                msg->setInt32(kSequenceIdKey, sequenceId);
-                msg->setInt64(kFrameNumberKey, lastFrameNumber);
-
-                // Clear the session sp before we send out the message
-                // This will guarantee the rare case where the message is processed
-                // before cbh goes out of scope and causing we call the session
-                // destructor while holding device lock
-                cbh.mSession.clear();
-                postSessionMsgAndCleanup(msg);
-            }
         }
 
         if (it->second.isSequenceCompleted && it->second.isInflightCompleted) {
-            if (mSequenceCallbackMap.find(sequenceId) != mSequenceCallbackMap.end()) {
-                mSequenceCallbackMap.erase(sequenceId);
-            }
+            sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
+
             it = mSequenceLastFrameNumberMap.erase(it);
             ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
         } else {
@@ -1418,13 +1398,7 @@
                 lastCompletedRegularFrameNumber);
         if (lastFrameNumber <= lastCompletedRegularFrameNumber) {
             if (it->second.isSequenceCompleted) {
-                // Check if there is callback for this sequence
-                // This should not happen because we always register callback (with nullptr inside)
-                if (mSequenceCallbackMap.count(sequenceId) == 0) {
-                    ALOGW("No callback found for sequenceId %d", sequenceId);
-                } else {
-                    mSequenceCallbackMap.erase(sequenceId);
-                }
+                sendCaptureSequenceCompletedLocked(sequenceId, lastFrameNumber);
 
                 it = mSequenceLastFrameNumberMap.erase(it);
                 ALOGV("%s: Remove holder for sequenceId %d", __FUNCTION__, sequenceId);
@@ -1715,5 +1689,33 @@
     return ret;
 }
 
+void
+CameraDevice::sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber) {
+    auto cbIt = mSequenceCallbackMap.find(sequenceId);
+    if (cbIt != mSequenceCallbackMap.end()) {
+        CallbackHolder cbh = cbIt->second;
+        mSequenceCallbackMap.erase(cbIt);
+
+        // send seq complete callback
+        sp<AMessage> msg = new AMessage(kWhatCaptureSeqEnd, mHandler);
+        msg->setPointer(kContextKey, cbh.mContext);
+        msg->setObject(kSessionSpKey, cbh.mSession);
+        msg->setPointer(kCallbackFpKey, (void*) cbh.mOnCaptureSequenceCompleted);
+        msg->setInt32(kSequenceIdKey, sequenceId);
+        msg->setInt64(kFrameNumberKey, lastFrameNumber);
+
+        // Clear the session sp before we send out the message
+        // This will guarantee the rare case where the message is processed
+        // before cbh goes out of scope and causing we call the session
+        // destructor while holding device lock
+        cbh.mSession.clear();
+        postSessionMsgAndCleanup(msg);
+    } else {
+        // Check if there is callback for this sequence
+        // This should not happen because we always register callback (with nullptr inside)
+        ALOGW("No callback found for sequenceId %d", sequenceId);
+    }
+}
+
 } // namespace acam
 } // namespace android
diff --git a/camera/ndk/impl/ACameraDevice.h b/camera/ndk/impl/ACameraDevice.h
index 125e6e3..344d964 100644
--- a/camera/ndk/impl/ACameraDevice.h
+++ b/camera/ndk/impl/ACameraDevice.h
@@ -354,6 +354,7 @@
     void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
     void checkAndFireSequenceCompleteLocked();
     void removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFrameNumber);
+    void sendCaptureSequenceCompletedLocked(int sequenceId, int64_t lastFrameNumber);
 
     // Misc variables
     int32_t mShadingMapSize[2];   // const after constructor