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

Commit 309d05d0 authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

CameraNDK: implement abortCaptures API

Bug: 27102995
Change-Id: Idaf1db02e0bcc60bb9cdb2797b4479ea0389f5f9
parent d9bd004b
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -122,7 +122,16 @@ camera_status_t ACameraCaptureSession_stopRepeating(ACameraCaptureSession* sessi
}

EXPORT
camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession*) {
camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session) {
    ATRACE_CALL();
    return ACAMERA_OK;
    if (session == nullptr) {
        ALOGE("%s: Error: session is null", __FUNCTION__);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    if (session->isClosed()) {
        ALOGE("%s: session %p is already closed", __FUNCTION__, session);
        return ACAMERA_ERROR_SESSION_CLOSED;
    }
    return session->abortCaptures();
}
+18 −0
Original line number Diff line number Diff line
@@ -89,6 +89,24 @@ ACameraCaptureSession::stopRepeating() {
    return ret;
}

camera_status_t
ACameraCaptureSession::abortCaptures() {
    sp<CameraDevice> dev = getDeviceSp();
    if (dev == nullptr) {
        ALOGE("Error: Device associated with session %p has been closed!", this);
        return ACAMERA_ERROR_SESSION_CLOSED;
    }

    camera_status_t ret;
    dev->lockDeviceForSessionOps();
    {
        Mutex::Autolock _l(mSessionLock);
        ret = dev->flushLocked(this);
    }
    dev->unlockDevice();
    return ret;
}

camera_status_t
ACameraCaptureSession::setRepeatingRequest(
        /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
+2 −1
Original line number Diff line number Diff line
@@ -77,6 +77,8 @@ struct ACameraCaptureSession : public RefBase {

    camera_status_t stopRepeating();

    camera_status_t abortCaptures();

    camera_status_t setRepeatingRequest(
            /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
            int numRequests, ACaptureRequest** requests,
@@ -104,7 +106,6 @@ struct ACameraCaptureSession : public RefBase {
    const wp<CameraDevice> mDevice;
    bool  mIsClosed = false;
    bool  mClosedByApp = false;
    bool  mIdle = true;
    Mutex mSessionLock;
};

+54 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ CameraDevice::createCaptureSession(
    // set new session as current session
    newSession->incStrong((void *) ACameraDevice_createCaptureSession);
    mCurrentSession = newSession;
    mFlushing = false;
    *session = newSession;
    return ACAMERA_OK;
}
@@ -388,6 +389,58 @@ CameraDevice::stopRepeatingLocked() {
    return ACAMERA_OK;
}

camera_status_t
CameraDevice::flushLocked(ACameraCaptureSession* session) {
    camera_status_t ret = checkCameraClosedOrErrorLocked();
    if (ret != ACAMERA_OK) {
        ALOGE("Camera %s abort captures failed! ret %d", getId(), ret);
        return ret;
    }

    // This should never happen because creating a new session will close
    // previous one and thus reject any API call from previous session.
    // But still good to check here in case something unexpected happen.
    if (session != mCurrentSession) {
        ALOGE("Camera %s session %p is not current active session!", getId(), session);
        return ACAMERA_ERROR_INVALID_OPERATION;
    }

    if (mFlushing) {
        ALOGW("Camera %s is already aborting captures", getId());
        return ACAMERA_OK;
    }

    mFlushing = true;
    // Send onActive callback to guarantee there is always active->ready transition
    sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
    msg->setPointer(kContextKey, session->mUserSessionCallback.context);
    msg->setObject(kSessionSpKey, session);
    msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onActive);
    msg->post();

    // If device is already idling, send callback and exit early
    if (mIdle) {
        sp<AMessage> msg = new AMessage(kWhatSessionStateCb, mHandler);
        msg->setPointer(kContextKey, session->mUserSessionCallback.context);
        msg->setObject(kSessionSpKey, session);
        msg->setPointer(kCallbackFpKey, (void*) session->mUserSessionCallback.onReady);
        msg->post();
        mFlushing = false;
        return ACAMERA_OK;
    }

    int64_t lastFrameNumber;
    binder::Status remoteRet = mRemote->flush(&lastFrameNumber);
    if (!remoteRet.isOk()) {
        ALOGE("Abort captures fails in remote: %s", remoteRet.toString8().string());
        return ACAMERA_ERROR_UNKNOWN;
    }
    if (mRepeatingSequenceId != REQUEST_ID_NONE) {
        checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
    }
    return ACAMERA_OK;
}

camera_status_t
CameraDevice::waitUntilIdleLocked() {
    camera_status_t ret = checkCameraClosedOrErrorLocked();
@@ -1109,6 +1162,7 @@ CameraDevice::ServiceCallback::onDeviceIdle() {
        msg->post();
    }
    dev->mIdle = true;
    dev->mFlushing = false;
    return ret;
}

+6 −3
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ class CameraDevice final : public RefBase {

    camera_status_t stopRepeatingLocked();

    camera_status_t flushLocked(ACameraCaptureSession*);

    camera_status_t waitUntilIdleLocked();


@@ -152,13 +154,13 @@ class CameraDevice final : public RefBase {
    std::atomic_bool mClosing;
    inline bool isClosed() { return mClosing; }

    bool mInError;
    camera_status_t mError;
    bool mInError = false;
    camera_status_t mError = ACAMERA_OK;
    void onCaptureErrorLocked(
            int32_t errorCode,
            const CaptureResultExtras& resultExtras);

    bool mIdle;
    bool mIdle = true;
    // This will avoid a busy session being deleted before it's back to idle state
    sp<ACameraCaptureSession> mBusySession;

@@ -203,6 +205,7 @@ class CameraDevice final : public RefBase {
     ***********************************/
    // The current active session
    ACameraCaptureSession* mCurrentSession = nullptr;
    bool mFlushing = false;

    int mNextSessionId = 0;
    // TODO: might need another looper/handler to handle callbacks from service