Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7dd0928b authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Camera: Fix deadlock in ACameraCaptureSession destructor" am: 66ce6895

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I5ce901af0abf2a7c4343ab19911d352c82120d7d
parents 6870233d 66ce6895
Loading
Loading
Loading
Loading
+31 −29
Original line number Diff line number Diff line
@@ -1361,31 +1361,11 @@ CameraDevice::checkAndFireSequenceCompleteLocked() {
                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 {
@@ -1412,13 +1392,7 @@ CameraDevice::removeCompletedCallbackHolderLocked(int64_t lastCompletedRegularFr
                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);
@@ -1709,5 +1683,33 @@ CameraDevice::ServiceCallback::onRepeatingRequestError(
    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
+1 −0
Original line number Diff line number Diff line
@@ -354,6 +354,7 @@ class CameraDevice final : public RefBase {
    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