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

Commit 56663d80 authored by Bharatt Kukreja's avatar Bharatt Kukreja Committed by Automerger Merge Worker
Browse files

Merge changes from topic "cherrypicker-L89600000960032981:N30900001359241375"...

Merge changes from topic "cherrypicker-L89600000960032981:N30900001359241375" into udc-dev am: 1c7a8919

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



Change-Id: I86722e27e20c7827f6a2e1fd2371589d034c9537
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 6f936d6e 1c7a8919
Loading
Loading
Loading
Loading
+118 −99
Original line number Diff line number Diff line
@@ -265,12 +265,12 @@ status_t Camera3Device::disconnect() {

status_t Camera3Device::disconnectImpl() {
    ATRACE_CALL();
    Mutex::Autolock il(mInterfaceLock);

    ALOGI("%s: E", __FUNCTION__);

    status_t res = OK;
    std::vector<wp<Camera3StreamInterface>> streams;
    {
        Mutex::Autolock il(mInterfaceLock);
    nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
    {
        Mutex::Autolock l(mLock);
@@ -283,7 +283,8 @@ status_t Camera3Device::disconnectImpl() {
                    SET_ERR_L("Can't stop streaming");
                    // Continue to close device even in case of error
                } else {
                        res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
                    res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                                  /*requestThreadInvocation*/ false);
                    if (res != OK) {
                        SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
                                maxExpectedDuration);
@@ -320,19 +321,16 @@ status_t Camera3Device::disconnectImpl() {
            streams.push_back(mInputStream);
        }
    }
    }
    // Joining done without holding mLock and mInterfaceLock, otherwise deadlocks may ensue
    // as the threads try to access parent state (b/143513518)

    // Joining done without holding mLock, otherwise deadlocks may ensue
    // as the threads try to access parent state
    if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
        // HAL may be in a bad state, so waiting for request thread
        // (which may be stuck in the HAL processCaptureRequest call)
        // could be dangerous.
        // give up mInterfaceLock here and then lock it again. Could this lead
        // to other deadlocks
        mRequestThread->join();
    }
    {
        Mutex::Autolock il(mInterfaceLock);

    if (mStatusTracker != NULL) {
        mStatusTracker->join();
    }
@@ -373,7 +371,6 @@ status_t Camera3Device::disconnectImpl() {
                    __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
        }
    }
    }
    ALOGI("%s: X", __FUNCTION__);

    if (mCameraServiceWatchdog != NULL) {
@@ -843,7 +840,7 @@ status_t Camera3Device::submitRequestsHelper(
    }

    if (res == OK) {
        waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
        waitUntilStateThenRelock(/*active*/true, kActiveTimeout, /*requestThreadInvocation*/false);
        if (res != OK) {
            SET_ERR_L("Can't transition to active in %f seconds!",
                    kActiveTimeout/1e9);
@@ -968,7 +965,8 @@ status_t Camera3Device::createInputStream(
            break;
        case STATUS_ACTIVE:
            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
            res = internalPauseAndWaitLocked(maxExpectedDuration);
            res = internalPauseAndWaitLocked(maxExpectedDuration,
                          /*requestThreadInvocation*/ false);
            if (res != OK) {
                SET_ERR_L("Can't pause captures to reconfigure streams!");
                return res;
@@ -1085,7 +1083,8 @@ status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
            break;
        case STATUS_ACTIVE:
            ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
            res = internalPauseAndWaitLocked(maxExpectedDuration);
            res = internalPauseAndWaitLocked(maxExpectedDuration,
                          /*requestThreadInvocation*/ false);
            if (res != OK) {
                SET_ERR_L("Can't pause captures to reconfigure streams!");
                return res;
@@ -1558,7 +1557,8 @@ status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
    }
    ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
            maxExpectedDuration);
    status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
    status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                           /*requestThreadInvocation*/ false);
    if (res != OK) {
        mStatusTracker->dumpActiveComponents();
        SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
@@ -1569,12 +1569,14 @@ status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {

void Camera3Device::internalUpdateStatusLocked(Status status) {
    mStatus = status;
    mRecentStatusUpdates.add(mStatus);
    mStatusIsInternal = mPauseStateNotify ? true : false;
    mRecentStatusUpdates.add({mStatus, mStatusIsInternal});
    mStatusChanged.broadcast();
}

// Pause to reconfigure
status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration,
        bool requestThreadInvocation) {
    if (mRequestThread.get() != nullptr) {
        mRequestThread->setPaused(true);
    } else {
@@ -1583,7 +1585,8 @@ status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration)

    ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
          maxExpectedDuration);
    status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
    status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                           requestThreadInvocation);
    if (res != OK) {
        mStatusTracker->dumpActiveComponents();
        SET_ERR_L("Can't idle device in %f seconds!",
@@ -1601,7 +1604,9 @@ status_t Camera3Device::internalResumeLocked() {

    ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
            kActiveTimeout);
    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
    // internalResumeLocked is always called from a binder thread.
    res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout,
                  /*requestThreadInvocation*/ false);
    if (res != OK) {
        SET_ERR_L("Can't transition to active in %f seconds!",
                kActiveTimeout/1e9);
@@ -1610,7 +1615,8 @@ status_t Camera3Device::internalResumeLocked() {
    return OK;
}

status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout,
        bool requestThreadInvocation) {
    status_t res = OK;

    size_t startIndex = 0;
@@ -1639,7 +1645,8 @@ status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
    bool stateSeen = false;
    nsecs_t startTime = systemTime();
    do {
        if (active == (mStatus == STATUS_ACTIVE)) {
        if (active == (mStatus == STATUS_ACTIVE) &&
            (requestThreadInvocation || !mStatusIsInternal)) {
            // Desired state is current
            break;
        }
@@ -1661,9 +1668,14 @@ status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
                "%s: Skipping status updates in Camera3Device, may result in deadlock.",
                __FUNCTION__);

        // Encountered desired state since we began waiting
        // Encountered desired state since we began waiting. Internal invocations coming from
        // request threads (such as reconfigureCamera) should be woken up immediately, whereas
        // invocations from binder threads (such as createInputStream) should only be woken up if
        // they are not paused. This avoids intermediate pause signals from reconfigureCamera as it
        // changes the status to active right after.
        for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
            if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
            if (active == (mRecentStatusUpdates[i].status == STATUS_ACTIVE) &&
                (requestThreadInvocation || !mRecentStatusUpdates[i].isInternal)) {
                stateSeen = true;
                break;
            }
@@ -2310,7 +2322,9 @@ bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int c

    nsecs_t startTime = systemTime();

    Mutex::Autolock il(mInterfaceLock);
    // We must not hold mInterfaceLock here since this function is called from
    // RequestThread::threadLoop and holding mInterfaceLock could lead to
    // deadlocks (http://b/143513518)
    nsecs_t maxExpectedDuration = getExpectedInFlightDuration();

    Mutex::Autolock l(mLock);
@@ -2325,8 +2339,18 @@ bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int c
    if (mStatus == STATUS_ACTIVE) {
        markClientActive = true;
        mPauseStateNotify = true;
        mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);

        rc = internalPauseAndWaitLocked(maxExpectedDuration);
        // This is essentially the same as calling rc = internalPauseAndWaitLocked(..), except that
        // we don't want to call setPaused(true) to avoid it interfering with setPaused() called
        // from createInputStream/createStream.
        rc = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration,
                /*requestThreadInvocation*/ true);
        if (rc != OK) {
            mStatusTracker->dumpActiveComponents();
            SET_ERR_L("Can't idle device in %f seconds!",
                maxExpectedDuration/1e9);
        }
    }

    if (rc == NO_ERROR) {
@@ -3567,13 +3591,8 @@ bool Camera3Device::RequestThread::threadLoop() {
        if (res == OK) {
            sp<Camera3Device> parent = mParent.promote();
            if (parent != nullptr) {
                sp<StatusTracker> statusTracker = mStatusTracker.promote();
                if (statusTracker != nullptr) {
                    statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
                }
                mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
            }
            setPaused(false);

            if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
                mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
+13 −3
Original line number Diff line number Diff line
@@ -366,6 +366,7 @@ class Camera3Device :

    // A lock to enforce serialization on the input/configure side
    // of the public interface.
    // Only locked by public methods inherited from CameraDeviceBase.
    // Not locked by methods guarded by mOutputLock, since they may act
    // concurrently to the input/configure side of the interface.
    // Must be locked before mLock if both will be locked by a method
@@ -571,8 +572,15 @@ class Camera3Device :
        STATUS_ACTIVE
    }                          mStatus;

    struct StatusInfo {
        Status status;
        bool isInternal; // status triggered by internal reconfigureCamera.
    };

    bool                       mStatusIsInternal;

    // Only clear mRecentStatusUpdates, mStatusWaiters from waitUntilStateThenRelock
    Vector<Status>             mRecentStatusUpdates;
    Vector<StatusInfo>         mRecentStatusUpdates;
    int                        mStatusWaiters;

    Condition                  mStatusChanged;
@@ -717,7 +725,8 @@ class Camera3Device :
     * CameraDeviceBase interface we shouldn't need to.
     * Must be called with mLock and mInterfaceLock both held.
     */
    status_t internalPauseAndWaitLocked(nsecs_t maxExpectedDuration);
    status_t internalPauseAndWaitLocked(nsecs_t maxExpectedDuration,
                     bool requestThreadInvocation);

    /**
     * Resume work after internalPauseAndWaitLocked()
@@ -736,7 +745,8 @@ class Camera3Device :
     * During the wait mLock is released.
     *
     */
    status_t waitUntilStateThenRelock(bool active, nsecs_t timeout);
    status_t waitUntilStateThenRelock(bool active, nsecs_t timeout,
                     bool requestThreadInvocation);

    /**
     * Implementation of waitUntilDrained. On success, will transition to IDLE state.
+4 −2
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ status_t Camera3Device::Camera3DeviceInjectionMethods::injectCamera(
    if (parent->mStatus == STATUS_ACTIVE) {
        ALOGV("%s: Let the device be IDLE and the request thread is paused",
                __FUNCTION__);
        res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
        res = parent->internalPauseAndWaitLocked(maxExpectedDuration,
                                                 /*requestThreadInvocation*/false);
        if (res != OK) {
            ALOGE("%s: Can't pause captures to inject camera!", __FUNCTION__);
            return res;
@@ -117,7 +118,8 @@ status_t Camera3Device::Camera3DeviceInjectionMethods::stopInjection() {
    if (parent->mStatus == STATUS_ACTIVE) {
        ALOGV("%s: Let the device be IDLE and the request thread is paused",
                __FUNCTION__);
        res = parent->internalPauseAndWaitLocked(maxExpectedDuration);
        res = parent->internalPauseAndWaitLocked(maxExpectedDuration,
                                                 /*requestThreadInvocation*/false);
        if (res != OK) {
            ALOGE("%s: Can't pause captures to stop injection!", __FUNCTION__);
            return res;