diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp index 1edfbf9b11..8f20685c59 100644 --- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp +++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp @@ -59,6 +59,10 @@ status_t CameraOfflineSessionClient::initialize(sp, const return res; } + for (size_t i = 0; i < mCompositeStreamMap.size(); i++) { + mCompositeStreamMap.valueAt(i)->switchToOffline(); + } + return OK; } diff --git a/services/camera/libcameraservice/api2/CompositeStream.cpp b/services/camera/libcameraservice/api2/CompositeStream.cpp index 354eaf93eb..b47ee2e26e 100644 --- a/services/camera/libcameraservice/api2/CompositeStream.cpp +++ b/services/camera/libcameraservice/api2/CompositeStream.cpp @@ -200,5 +200,10 @@ void CompositeStream::notifyError(int64_t frameNumber) { } } +void CompositeStream::switchToOffline() { + Mutex::Autolock l(mMutex); + mDevice.clear(); +} + }; // namespace camera3 }; // namespace android diff --git a/services/camera/libcameraservice/api2/CompositeStream.h b/services/camera/libcameraservice/api2/CompositeStream.h index de894f318f..e5baf1a60b 100644 --- a/services/camera/libcameraservice/api2/CompositeStream.h +++ b/services/camera/libcameraservice/api2/CompositeStream.h @@ -48,6 +48,9 @@ public: status_t deleteStream(); + // Switch to offline mode and release any online resources. + void switchToOffline(); + // Create and register all internal camera streams. virtual status_t createInternalStreams(const std::vector>& consumers, bool hasDeferredConsumer, uint32_t width, uint32_t height, int format, diff --git a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp index acad8c6a3a..16ce52ccf0 100644 --- a/services/camera/libcameraservice/api2/DepthCompositeStream.cpp +++ b/services/camera/libcameraservice/api2/DepthCompositeStream.cpp @@ -619,14 +619,15 @@ status_t DepthCompositeStream::deleteInternalStreams() { strerror(-ret), ret); } - sp device = mDevice.promote(); - if (!device.get()) { - ALOGE("%s: Invalid camera device!", __FUNCTION__); - return NO_INIT; - } - if (mDepthStreamId >= 0) { - ret = device->deleteStream(mDepthStreamId); + // Camera devices may not be valid after switching to offline mode. + // In this case, all offline streams including internal composite streams + // are managed and released by the offline session. + sp device = mDevice.promote(); + if (device.get() != nullptr) { + ret = device->deleteStream(mDepthStreamId); + } + mDepthStreamId = -1; } diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp index d25e467fb7..f335c20100 100644 --- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp +++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp @@ -209,13 +209,14 @@ status_t HeicCompositeStream::deleteInternalStreams() { deinitCodec(); if (mAppSegmentStreamId >= 0) { + // Camera devices may not be valid after switching to offline mode. + // In this case, all offline streams including internal composite streams + // are managed and released by the offline session. sp device = mDevice.promote(); - if (!device.get()) { - ALOGE("%s: Invalid camera device!", __FUNCTION__); - return NO_INIT; + if (device.get() != nullptr) { + res = device->deleteStream(mAppSegmentStreamId); } - res = device->deleteStream(mAppSegmentStreamId); mAppSegmentStreamId = -1; } diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index f29431c560..87bdef6fd4 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -4758,6 +4758,11 @@ void Camera3Device::RequestThread::signalPipelineDrain(const std::vector& s mStreamIdsToBeDrained = streamIds; } +void Camera3Device::RequestThread::clearPreviousRequest() { + Mutex::Autolock l(mRequestLock); + mPrevRequest.clear(); +} + status_t Camera3Device::RequestThread::switchToOffline( const std::vector& streamsToKeep, /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo, @@ -5917,6 +5922,7 @@ status_t Camera3Device::switchToOffline( internalUpdateStatusLocked(STATUS_UNCONFIGURED); mOperatingMode = NO_MODE; mIsConstrainedHighSpeedConfiguration = false; + mRequestThread->clearPreviousRequest(); return OK; // TO be done by CameraDeviceClient/Camera3OfflineSession diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 0069fb34cc..b373a64826 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -837,6 +837,8 @@ class Camera3Device : /*out*/sp* offlineSession, /*out*/camera3::BufferRecords* bufferRecords); + void clearPreviousRequest(); + status_t setRotateAndCropAutoBehavior( camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue);