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

Commit 002001be authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera3Device: Fix spurious onIdle callback during internal reconfig

Because the request thread went idle before it notified the parent to
reconfigure, the flag to avoid spurious notifications was set too
late; an idle notification would already be sent by then.

Move the flag setting to the beginning of the sequence to correctly
suppress all needed notifications.

Test: No crash in previously affected app; camera CTS continues to pass
Bug: 72392658
Change-Id: Id7d1f66bab455035bbec7b04f7dd4157ad94b773
parent 1c838c48
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -1668,10 +1668,16 @@ void Camera3Device::internalUpdateStatusLocked(Status status) {
    mStatusChanged.broadcast();
}

void Camera3Device::pauseStateNotify(bool enable) {
    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);

    mPauseStateNotify = enable;
}

// Pause to reconfigure
status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
    mRequestThread->setPaused(true);
    mPauseStateNotify = true;

    ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
          maxExpectedDuration);
@@ -1690,6 +1696,8 @@ status_t Camera3Device::internalResumeLocked() {

    mRequestThread->setPaused(false);

    ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
            kActiveTimeout);
    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
    if (res != OK) {
        SET_ERR_L("Can't transition to active in %f seconds!",
@@ -1970,8 +1978,8 @@ void Camera3Device::notifyStatus(bool idle) {
        if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
            return;
        }
        ALOGV("%s: Camera %s: Now %s", __FUNCTION__, mId.string(),
                idle ? "idle" : "active");
        ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
                idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
        internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);

        // Skip notifying listener if we're doing some user-transparent
@@ -4433,9 +4441,13 @@ bool Camera3Device::RequestThread::threadLoop() {
        if (res == OK) {
            sp<StatusTracker> statusTracker = mStatusTracker.promote();
            if (statusTracker != 0) {
                sp<Camera3Device> parent = mParent.promote();
                if (parent != nullptr) {
                    parent->pauseStateNotify(true);
                }

                statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);

                sp<Camera3Device> parent = mParent.promote();
                if (parent != nullptr) {
                    mReconfigured |= parent->reconfigureCamera(mLatestSessionParams);
                }
+8 −1
Original line number Diff line number Diff line
@@ -553,9 +553,16 @@ class Camera3Device :
    sp<CaptureRequest> createCaptureRequest(const PhysicalCameraSettingsList &request,
                                            const SurfaceMap &surfaceMap);

    /**
     * Pause state updates to the client application.  Needed to mask out idle/active
     * transitions during internal reconfigure
     */
    void pauseStateNotify(bool enable);

    /**
     * Internally re-configure camera device using new session parameters.
     * This will get triggered by the request thread.
     * This will get triggered by the request thread. Be sure to call
     * pauseStateNotify(true) before going idle in the requesting location.
     */
    bool reconfigureCamera(const CameraMetadata& sessionParams);