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