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

Commit d832a53f authored by Jyoti Bhayana's avatar Jyoti Bhayana
Browse files

Fix missing NDK session closed callback

NDK session closed callback is not coming when client calls session close api
if another client is also streaming at the same time. This is due to the
ACameraCaptureSession destructor not being called as the busysession
strong pointer is not being freed due to missing onIdle callback.

Flag: com.android.internal.camera.flags.camera_multi_client
Bug: 392933426
Test: Run CTS test SharedCameraTest
Change-Id: I2325d58f8592a12bf3097ed1bcdbc4980dd39d3f
parent 7ad1b46d
Loading
Loading
Loading
Loading
+85 −23
Original line number Diff line number Diff line
@@ -391,6 +391,7 @@ binder::Status CameraDeviceClient::startStreaming(const std::vector<int>& stream
        mSharedStreamingRequest = {sharedReqID, submitInfo->mRequestId};
    }

    markClientActive();
    ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.c_str());
    return binder::Status::ok();
}
@@ -725,6 +726,7 @@ binder::Status CameraDeviceClient::submitRequestList(
            mStreamingRequestId = submitInfo->mRequestId;
            if (flags::camera_multi_client() && mSharedMode) {
                mSharedStreamingRequest = {sharedReqID, submitInfo->mRequestId};
                markClientActive();
            }
        }
    } else {
@@ -745,6 +747,7 @@ binder::Status CameraDeviceClient::submitRequestList(
        }
        if (flags::camera_multi_client() && mSharedMode) {
            mSharedRequestMap[sharedReqID] = submitInfo->mRequestId;
            markClientActive();
        }
        ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
    }
@@ -2334,12 +2337,18 @@ void CameraDeviceClient::notifyError(int32_t errorCode,
    bool skipClientNotification = false;
    if (flags::camera_multi_client() && mSharedMode && (resultExtras.requestId != -1)) {
        int clientReqId;
        if (!matchClientRequest(resultExtras, &clientReqId)) {
        bool matchStreamingRequest = matchSharedStreamingRequest(resultExtras.requestId);
        bool matchCaptureRequest = matchSharedCaptureRequest(resultExtras.requestId);
        if (matchStreamingRequest) {
            clientReqId = mSharedStreamingRequest.second;
        } else if (matchCaptureRequest) {
            clientReqId = mSharedRequestMap[resultExtras.requestId];
            mSharedRequestMap.erase(resultExtras.requestId);
        } else {
            return;
        }
        CaptureResultExtras mutableResultExtras = resultExtras;
        mutableResultExtras.requestId = clientReqId;
        mSharedRequestMap.erase(resultExtras.requestId);
        if (remoteCb != 0) {
            remoteCb->onDeviceError(errorCode, mutableResultExtras);
        }
@@ -2410,7 +2419,13 @@ void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
    CaptureResultExtras mutableResultExtras = resultExtras;
    if (flags::camera_multi_client() && mSharedMode) {
        int clientReqId;
        if (!matchClientRequest(resultExtras, &clientReqId)) {
        bool matchStreamingRequest = matchSharedStreamingRequest(resultExtras.requestId);
        bool matchCaptureRequest = matchSharedCaptureRequest(resultExtras.requestId);
        if (matchStreamingRequest) {
            clientReqId = mSharedStreamingRequest.second;
        } else if (matchCaptureRequest) {
            clientReqId = mSharedRequestMap[resultExtras.requestId];
        } else {
            return;
        }
        mutableResultExtras.requestId = clientReqId;
@@ -2556,26 +2571,28 @@ std::vector<PhysicalCaptureResultInfo> CameraDeviceClient::convertToFMQ(
    return retVal;
}

bool CameraDeviceClient::matchClientRequest(const CaptureResultExtras& resultExtras,
        int* clientReqId) {
bool CameraDeviceClient::matchSharedStreamingRequest(int reqId) {
    if (!flags::camera_multi_client() || !mSharedMode) {
        *clientReqId = resultExtras.requestId;
        return true;
        return false;
    }

    // In shared mode, check if the result req id matches the streaming request
    // sent by client.
    if (resultExtras.requestId == mSharedStreamingRequest.first) {
        *clientReqId = mSharedStreamingRequest.second;
    if (reqId == mSharedStreamingRequest.first) {
        return true;
    }
    return false;
}

bool CameraDeviceClient::matchSharedCaptureRequest(int reqId) {
    if (!flags::camera_multi_client() || !mSharedMode) {
        return false;
    }
    // In shared mode, only primary clients can send the capture request. If the
    // result req id does not match the streaming request id, check against the
    // capture request ids sent by the primary client.
    if (mIsPrimaryClient) {
        auto iter = mSharedRequestMap.find(resultExtras.requestId);
        auto iter = mSharedRequestMap.find(reqId);
        if (iter != mSharedRequestMap.end()) {
            *clientReqId = iter->second;
            return true;
        }
    }
@@ -2586,21 +2603,29 @@ void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
    ATRACE_CALL();
    ALOGVV("%s E", __FUNCTION__);
    CaptureResult mutableResult = result;
    bool matchStreamingRequest, matchCaptureRequest, sharedStreamingLastFrame;
    if (flags::camera_multi_client() && mSharedMode) {
        int clientReqId;
        if (!matchClientRequest(result.mResultExtras, &clientReqId)) {
            return;
        }
        matchStreamingRequest = matchSharedStreamingRequest(result.mResultExtras.requestId);
        matchCaptureRequest = matchSharedCaptureRequest(result.mResultExtras.requestId);
        if (matchStreamingRequest) {
            clientReqId = mSharedStreamingRequest.second;
            // When a client stops streaming using cancelRequest, we still need to deliver couple
            // more capture results to the client, till the lastframe number returned by the
            // cancelRequest. Therefore, only clean the shared streaming request once all the frames for
            // the repeating request have been delivered to the client.
        if ((mStreamingRequestId == REQUEST_ID_NONE) &&
                (result.mResultExtras.frameNumber > mStreamingRequestLastFrameNumber)) {
            sharedStreamingLastFrame = (mStreamingRequestId == REQUEST_ID_NONE)
                    && (result.mResultExtras.frameNumber >= mStreamingRequestLastFrameNumber);
            if (sharedStreamingLastFrame) {
                mSharedStreamingRequest.first = REQUEST_ID_NONE;
                mSharedStreamingRequest.second = REQUEST_ID_NONE;
            }
        } else if (matchCaptureRequest) {
            clientReqId = mSharedRequestMap[result.mResultExtras.requestId];
            mSharedRequestMap.erase(result.mResultExtras.requestId);
        } else {
            return;
        }
        mutableResult.mResultExtras.requestId = clientReqId;
        if (mutableResult.mMetadata.update(ANDROID_REQUEST_ID, &clientReqId, 1) != OK) {
            ALOGE("%s Failed to set request ID in metadata.", __FUNCTION__);
@@ -2633,6 +2658,13 @@ void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {

        remoteCb->onResultReceived(resultInfo, mutableResult.mResultExtras,
                physicalMetadatas);
        if (flags::camera_multi_client() && mSharedMode) {
            // If all the capture requests for this client has been processed,
            // send onDeviceidle callback.
            if ((mSharedStreamingRequest.first == REQUEST_ID_NONE) && mSharedRequestMap.empty() ) {
                markClientIdle();
            }
        }
    }

    // Access to the composite stream map must be synchronized
@@ -2643,6 +2675,36 @@ void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
    ALOGVV("%s X", __FUNCTION__);
}

void CameraDeviceClient::markClientActive() {
    if (mDeviceActive) {
        // Already in active state.
        return;
    }
    status_t res = startCameraStreamingOps();
    if (res != OK) {
        ALOGE("%s: Camera %s: Error starting camera streaming ops: %d", __FUNCTION__,
                mCameraIdStr.c_str(), res);
    }
    mDeviceActive = true;
}

void CameraDeviceClient::markClientIdle() {
    if (!mDeviceActive) {
        // Already in idle state.
        return;
    }
    sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
    if (remoteCb != NULL) {
        remoteCb->onDeviceIdle();
    }
    status_t res = finishCameraStreamingOps();
    if (res != OK) {
        ALOGE("%s: Camera %s: Error finishing streaming ops: %d", __FUNCTION__,
                mCameraIdStr.c_str(), res);
    }
    mDeviceActive = false;
}

binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
    if (mDisconnected) {
        return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
+4 −1
Original line number Diff line number Diff line
@@ -334,7 +334,10 @@ private:
    // Surface only
    status_t getSurfaceKey(sp<Surface> surface, SurfaceKey* out) const;

    bool matchClientRequest(const CaptureResultExtras& resultExtras, int* clientReqId);
    bool matchSharedStreamingRequest(int reqId);
    bool matchSharedCaptureRequest(int reqId);
    void markClientActive();
    void markClientIdle();

    // IGraphicsBufferProducer binder -> Stream ID + Surface ID for output streams
    KeyedVector<SurfaceKey, StreamSurfaceId> mStreamMap;