diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index e7e72b2f61..ba17eb6559 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -1979,7 +1979,14 @@ binder::Status CameraDeviceClient::switchToOffline( mClientFeatureId, mCameraIdStr, mCameraFacing, mClientPid, mClientUid, mServicePid); ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient); if (ret == OK) { - // TODO: We need to update mStreamMap, mConfiguredOutputs, mCompositeStreams + // A successful offline session switch must reset the current camera client + // and release any resources occupied by previously configured streams. + mStreamMap.clear(); + mConfiguredOutputs.clear(); + mDeferredStreams.clear(); + mStreamInfoMap.clear(); + mCompositeStreamMap.clear(); + mInputStream = {false, 0, 0, 0, 0}; } else { switch(ret) { case BAD_VALUE: diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp index f713419c4c..af7b9e18dc 100644 --- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp +++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ //#define LOG_NDEBUG 0 #include "CameraOfflineSessionClient.h" +#include "utils/CameraThreadState.h" #include namespace android { @@ -26,22 +27,71 @@ namespace android { using binder::Status; status_t CameraOfflineSessionClient::initialize(sp, const String8&) { + ATRACE_CALL(); + + // Verify ops permissions + auto res = startCameraOps(); + if (res != OK) { + return res; + } + + if (mOfflineSession.get() == nullptr) { + ALOGE("%s: Camera %s: No valid offline session", + __FUNCTION__, mCameraIdStr.string()); + return NO_INIT; + } + + wp weakThis(this); + res = mOfflineSession->initialize(weakThis); + if (res != OK) { + ALOGE("%s: Camera %s: unable to initialize device: %s (%d)", + __FUNCTION__, mCameraIdStr.string(), strerror(-res), res); + return res; + } + return OK; } -status_t CameraOfflineSessionClient::dump(int /*fd*/, const Vector& /*args*/) { - return OK; +status_t CameraOfflineSessionClient::dump(int fd, const Vector& args) { + return BasicClient::dump(fd, args); } -status_t CameraOfflineSessionClient::dumpClient(int /*fd*/, const Vector& /*args*/) { +status_t CameraOfflineSessionClient::dumpClient(int fd, const Vector& /*args*/) { + String8 result; + + result = " Offline session dump:\n"; + write(fd, result.string(), result.size()); + + if (mOfflineSession.get() == nullptr) { + result = " *** Offline session is detached\n"; + write(fd, result.string(), result.size()); + return NO_ERROR; + } + + auto res = mOfflineSession->dump(fd); + if (res != OK) { + result = String8::format(" Error dumping offline session: %s (%d)", + strerror(-res), res); + write(fd, result.string(), result.size()); + } + return OK; } binder::Status CameraOfflineSessionClient::disconnect() { + Mutex::Autolock icl(mBinderSerializationLock); + binder::Status res = Status::ok(); if (mDisconnected) { return res; } + // Allow both client and the media server to disconnect at all times + int callingPid = CameraThreadState::getCallingPid(); + if (callingPid != mClientPid && + callingPid != mServicePid) { + return res; + } + mDisconnected = true; sCameraService->removeByClient(this); @@ -59,6 +109,15 @@ binder::Status CameraOfflineSessionClient::disconnect() { // client shouldn't be able to call into us anymore mClientPid = 0; + if (mOfflineSession.get() != nullptr) { + auto ret = mOfflineSession->disconnect(); + if (ret != OK) { + ALOGE("%s: Failed disconnecting from offline session %s (%d)", __FUNCTION__, + strerror(-ret), ret); + } + mOfflineSession = nullptr; + } + for (size_t i = 0; i < mCompositeStreamMap.size(); i++) { auto ret = mCompositeStreamMap.valueAt(i)->deleteInternalStreams(); if (ret != OK) { @@ -74,8 +133,6 @@ binder::Status CameraOfflineSessionClient::disconnect() { void CameraOfflineSessionClient::notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) { // Thread safe. Don't bother locking. - sp remoteCb = getRemoteCallback(); - // // Composites can have multiple internal streams. Error notifications coming from such internal // streams may need to remain within camera service. bool skipClientNotification = false; @@ -83,8 +140,8 @@ void CameraOfflineSessionClient::notifyError(int32_t errorCode, skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode, resultExtras); } - if ((remoteCb != 0) && (!skipClientNotification)) { - remoteCb->onDeviceError(errorCode, resultExtras); + if ((mRemoteCallback.get() != nullptr) && (!skipClientNotification)) { + mRemoteCallback->onDeviceError(errorCode, resultExtras); } } @@ -156,10 +213,8 @@ void CameraOfflineSessionClient::onResultAvailable(const CaptureResult& result) ATRACE_CALL(); ALOGV("%s", __FUNCTION__); - // Thread-safe. No lock necessary. - sp remoteCb = mRemoteCallback; - if (remoteCb != NULL) { - remoteCb->onResultReceived(result.mMetadata, result.mResultExtras, + if (mRemoteCallback.get() != NULL) { + mRemoteCallback->onResultReceived(result.mMetadata, result.mResultExtras, result.mPhysicalMetadatas); } @@ -170,10 +225,9 @@ void CameraOfflineSessionClient::onResultAvailable(const CaptureResult& result) void CameraOfflineSessionClient::notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) { - // Thread safe. Don't bother locking. - sp remoteCb = getRemoteCallback(); - if (remoteCb != 0) { - remoteCb->onCaptureStarted(resultExtras, timestamp); + + if (mRemoteCallback.get() != nullptr) { + mRemoteCallback->onCaptureStarted(resultExtras, timestamp); } for (size_t i = 0; i < mCompositeStreamMap.size(); i++) { @@ -181,5 +235,53 @@ void CameraOfflineSessionClient::notifyShutter(const CaptureResultExtras& result } } +void CameraOfflineSessionClient::notifyIdle() { + if (mRemoteCallback.get() != nullptr) { + mRemoteCallback->onDeviceIdle(); + } +} + +void CameraOfflineSessionClient::notifyAutoFocus(uint8_t newState, int triggerId) { + (void)newState; + (void)triggerId; + + ALOGV("%s: Autofocus state now %d, last trigger %d", + __FUNCTION__, newState, triggerId); +} + +void CameraOfflineSessionClient::notifyAutoExposure(uint8_t newState, int triggerId) { + (void)newState; + (void)triggerId; + + ALOGV("%s: Autoexposure state now %d, last trigger %d", + __FUNCTION__, newState, triggerId); +} + +void CameraOfflineSessionClient::notifyAutoWhitebalance(uint8_t newState, int triggerId) { + (void)newState; + (void)triggerId; + + ALOGV("%s: Auto-whitebalance state now %d, last trigger %d", __FUNCTION__, newState, + triggerId); +} + +void CameraOfflineSessionClient::notifyPrepared(int /*streamId*/) { + ALOGE("%s: Unexpected stream prepare notification in offline mode!", __FUNCTION__); + notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE, + CaptureResultExtras()); +} + +void CameraOfflineSessionClient::notifyRequestQueueEmpty() { + if (mRemoteCallback.get() != nullptr) { + mRemoteCallback->onRequestQueueEmpty(); + } +} + +void CameraOfflineSessionClient::notifyRepeatingRequestError(long /*lastFrameNumber*/) { + ALOGE("%s: Unexpected repeating request error in offline mode!", __FUNCTION__); + notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE, + CaptureResultExtras()); +} + // ---------------------------------------------------------------------------- }; // namespace android diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h index e92a05cedf..b0f000da7f 100644 --- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h +++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h @@ -19,6 +19,8 @@ #include #include +#include "common/FrameProcessorBase.h" +#include "common/CameraDeviceBase.h" #include "CameraService.h" #include "CompositeStream.h" @@ -35,8 +37,9 @@ using camera3::CompositeStream; // is created through ICameraDeviceUser::switchToOffline call. class CameraOfflineSessionClient : public CameraService::BasicClient, - public hardware::camera2::BnCameraOfflineSession - // public camera2::FrameProcessorBase::FilteredListener? + public hardware::camera2::BnCameraOfflineSession, + public camera2::FrameProcessorBase::FilteredListener, + public NotificationListener { public: CameraOfflineSessionClient( @@ -58,42 +61,45 @@ public: virtual ~CameraOfflineSessionClient() {} - virtual sp asBinderWrapper() override { + sp asBinderWrapper() override { return IInterface::asBinder(this); } - virtual binder::Status disconnect() override; + binder::Status disconnect() override; - virtual status_t dump(int /*fd*/, const Vector& /*args*/) override; + status_t dump(int /*fd*/, const Vector& /*args*/) override; - virtual status_t dumpClient(int /*fd*/, const Vector& /*args*/) override; + status_t dumpClient(int /*fd*/, const Vector& /*args*/) override; - virtual void notifyError(int32_t /*errorCode*/, - const CaptureResultExtras& /*resultExtras*/) override; - - virtual status_t initialize(sp /*manager*/, + status_t initialize(sp /*manager*/, const String8& /*monitorTags*/) override; // permissions management - virtual status_t startCameraOps() override; - virtual status_t finishCameraOps() override; - - // TODO: Those will be introduced when we implement FilteredListener and the device - // callbacks respectively. Just adding for now. - void onResultAvailable(const CaptureResult& result); - void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp); + status_t startCameraOps() override; + status_t finishCameraOps() override; + + // FilteredResultListener API + void onResultAvailable(const CaptureResult& result) override; + + // NotificationListener API + void notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) override; + void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp) override; + void notifyIdle() override; + void notifyAutoFocus(uint8_t newState, int triggerId) override; + void notifyAutoExposure(uint8_t newState, int triggerId) override; + void notifyAutoWhitebalance(uint8_t newState, int triggerId) override; + void notifyPrepared(int streamId) override; + void notifyRequestQueueEmpty() override; + void notifyRepeatingRequestError(long lastFrameNumber) override; private: - - const sp& getRemoteCallback() { - return mRemoteCallback; - } + mutable Mutex mBinderSerializationLock; sp mRemoteCallback; sp mOfflineSession; - // Offline composite streams + // Offline composite stream map, output surface -> composite stream KeyedVector, sp> mCompositeStreamMap; };