From b2bc5a46efe3e77a5962ba0f2f770c524e93e03f Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Wed, 20 Nov 2019 16:02:14 -0800 Subject: [PATCH] Camera: Initial offline session client Test: N/A, no implementation yet Bug: 135142453 Change-Id: I08fecba80ab88a8b70fe71fdd4b660d49e40324c --- .../hardware/camera2/ICameraDeviceUser.aidl | 2 +- services/camera/libcameraservice/Android.bp | 1 + .../camera/libcameraservice/CameraService.cpp | 139 +++++++++++++---- .../camera/libcameraservice/CameraService.h | 107 +++---------- .../api2/CameraDeviceClient.cpp | 44 ++++-- .../api2/CameraDeviceClient.h | 2 +- .../api2/CameraOfflineSessionClient.cpp | 140 ++++++++++++++++++ .../api2/CameraOfflineSessionClient.h | 59 ++++---- 8 files changed, 335 insertions(+), 159 deletions(-) create mode 100644 services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp diff --git a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl index cdb7ac3a9d..a442a91a40 100644 --- a/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl +++ b/camera/aidl/android/hardware/camera2/ICameraDeviceUser.aidl @@ -189,5 +189,5 @@ interface ICameraDeviceUser * @return Offline session object. */ ICameraOfflineSession switchToOffline(in ICameraDeviceCallbacks callbacks, - in Surface[] offlineOutputs); + in int[] offlineOutputIds); } diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp index 518a04f3f4..496a21b6dc 100644 --- a/services/camera/libcameraservice/Android.bp +++ b/services/camera/libcameraservice/Android.bp @@ -41,6 +41,7 @@ cc_library_shared { "api1/client2/CaptureSequencer.cpp", "api1/client2/ZslProcessor.cpp", "api2/CameraDeviceClient.cpp", + "api2/CameraOfflineSessionClient.cpp", "api2/CompositeStream.cpp", "api2/DepthCompositeStream.cpp", "api2/HeicEncoderInfoManager.cpp", diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index a110c33e42..2fe717939b 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -128,6 +128,7 @@ static const String16 static constexpr int32_t kVendorClientScore = 200; // Matches with PROCESS_STATE_PERSISTENT_UI in ActivityManager.java static constexpr int32_t kVendorClientState = 1; +const String8 CameraService::kOfflineDevice("offline-"); Mutex CameraService::sProxyMutex; sp CameraService::sCameraServiceProxy; @@ -394,7 +395,7 @@ void CameraService::onDeviceStatusChanged(const String8& id, // to this device until the status changes updateStatus(StatusInternal::NOT_PRESENT, id); - sp clientToDisconnect; + sp clientToDisconnectOnline, clientToDisconnectOffline; { // Don't do this in updateStatus to avoid deadlock over mServiceLock Mutex::Autolock lock(mServiceLock); @@ -402,23 +403,14 @@ void CameraService::onDeviceStatusChanged(const String8& id, // Remove cached shim parameters state->setShimParams(CameraParameters()); - // Remove the client from the list of active clients, if there is one - clientToDisconnect = removeClientLocked(id); + // Remove online as well as offline client from the list of active clients, + // if they are present + clientToDisconnectOnline = removeClientLocked(id); + clientToDisconnectOffline = removeClientLocked(kOfflineDevice + id); } - // Disconnect client - if (clientToDisconnect.get() != nullptr) { - ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL", - __FUNCTION__, id.string()); - // Notify the client of disconnection - clientToDisconnect->notifyError( - hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, - CaptureResultExtras{}); - // Ensure not in binder RPC so client disconnect PID checks work correctly - LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(), - "onDeviceStatusChanged must be called from the camera service process!"); - clientToDisconnect->disconnect(); - } + disconnectClient(id, clientToDisconnectOnline); + disconnectClient(kOfflineDevice + id, clientToDisconnectOffline); removeStates(id); } else { @@ -431,6 +423,21 @@ void CameraService::onDeviceStatusChanged(const String8& id, } +void CameraService::disconnectClient(const String8& id, sp clientToDisconnect) { + if (clientToDisconnect.get() != nullptr) { + ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL", + __FUNCTION__, id.string()); + // Notify the client of disconnection + clientToDisconnect->notifyError( + hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, + CaptureResultExtras{}); + // Ensure not in binder RPC so client disconnect PID checks work correctly + LOG_ALWAYS_FATAL_IF(CameraThreadState::getCallingPid() != getpid(), + "onDeviceStatusChanged must be called from the camera service process!"); + clientToDisconnect->disconnect(); + } +} + void CameraService::onTorchStatusChanged(const String8& cameraId, TorchModeStatus newStatus) { Mutex::Autolock al(mTorchStatusMutex); @@ -1696,6 +1703,77 @@ Status CameraService::connectHelper(const sp& cameraCb, const String8& return ret; } +status_t CameraService::addOfflineClient(String8 cameraId, sp offlineClient) { + if (offlineClient.get() == nullptr) { + return BAD_VALUE; + } + + { + // Acquire mServiceLock and prevent other clients from connecting + std::unique_ptr lock = + AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS); + + if (lock == nullptr) { + ALOGE("%s: (PID %d) rejected (too many other clients connecting)." + , __FUNCTION__, offlineClient->getClientPid()); + return TIMED_OUT; + } + + auto onlineClientDesc = mActiveClientManager.get(cameraId); + if (onlineClientDesc.get() == nullptr) { + ALOGE("%s: No active online client using camera id: %s", __FUNCTION__, + cameraId.c_str()); + return BAD_VALUE; + } + + // Offline clients do not evict or conflict with other online devices. Resource sharing + // conflicts are handled by the camera provider which will either succeed or fail before + // reaching this method. + const auto& onlinePriority = onlineClientDesc->getPriority(); + auto offlineClientDesc = CameraClientManager::makeClientDescriptor( + kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0, + /*conflictingKeys*/ std::set(), onlinePriority.getScore(), + onlineClientDesc->getOwnerId(), onlinePriority.getState()); + + // Allow only one offline device per camera + auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc); + if (!incompatibleClients.empty()) { + ALOGE("%s: Incompatible offline clients present!", __FUNCTION__); + return BAD_VALUE; + } + + auto err = offlineClient->initialize(mCameraProviderManager, mMonitorTags); + if (err != OK) { + ALOGE("%s: Could not initialize offline client.", __FUNCTION__); + return err; + } + + auto evicted = mActiveClientManager.addAndEvict(offlineClientDesc); + if (evicted.size() > 0) { + for (auto& i : evicted) { + ALOGE("%s: Invalid state: Offline client for camera %s was not removed ", + __FUNCTION__, i->getKey().string()); + } + + LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, offline clients not evicted " + "properly", __FUNCTION__); + + return BAD_VALUE; + } + + logConnectedOffline(offlineClientDesc->getKey(), + static_cast(offlineClientDesc->getOwnerId()), + String8(offlineClient->getPackageName())); + + sp remoteCallback = offlineClient->getRemote(); + if (remoteCallback != nullptr) { + remoteCallback->linkToDeath(this); + } + } // lock is destroyed, allow further connect calls + + return OK; +} + Status CameraService::setTorchMode(const String16& cameraId, bool enabled, const sp& clientBinder) { Mutex::Autolock lock(mServiceLock); @@ -2300,6 +2378,13 @@ void CameraService::logDisconnected(const char* cameraId, int clientPid, clientPackage, clientPid)); } +void CameraService::logDisconnectedOffline(const char* cameraId, int clientPid, + const char* clientPackage) { + // Log the clients evicted + logEvent(String8::format("DISCONNECT offline device %s client for package %s (PID %d)", + cameraId, clientPackage, clientPid)); +} + void CameraService::logConnected(const char* cameraId, int clientPid, const char* clientPackage) { // Log the clients evicted @@ -2307,6 +2392,13 @@ void CameraService::logConnected(const char* cameraId, int clientPid, clientPackage, clientPid)); } +void CameraService::logConnectedOffline(const char* cameraId, int clientPid, + const char* clientPackage) { + // Log the clients evicted + logEvent(String8::format("CONNECT offline device %s client for package %s (PID %d)", cameraId, + clientPackage, clientPid)); +} + void CameraService::logRejected(const char* cameraId, int clientPid, const char* clientPackage, const char* reason) { // Log the client rejected @@ -2744,6 +2836,7 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16&) { if (mAppOpsManager == nullptr) { return; } + // TODO : add offline camera session case if (op != AppOpsManager::OP_CAMERA) { ALOGW("Unexpected app ops notification received: %d", op); return; @@ -2778,20 +2871,6 @@ void CameraService::BasicClient::block() { // ---------------------------------------------------------------------------- -sp CameraService::OfflineClient::sCameraService; - -status_t CameraService::OfflineClient::startCameraOps() { - // TODO - return OK; -} - -status_t CameraService::OfflineClient::finishCameraOps() { - // TODO - return OK; -} - -// ---------------------------------------------------------------------------- - void CameraService::Client::notifyError(int32_t errorCode, const CaptureResultExtras& resultExtras) { (void) resultExtras; diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index dae9c0960f..726cb0f4a1 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -68,6 +68,7 @@ class CameraService : { friend class BinderService; friend class CameraClient; + friend class CameraOfflineSessionClient; public: class Client; class BasicClient; @@ -185,6 +186,9 @@ public: // Monitored UIDs availability notification void notifyMonitoredUids(); + // Register an offline client for a given active camera id + status_t addOfflineClient(String8 cameraId, sp offlineClient); + ///////////////////////////////////////////////////////////////////// // Client functionality @@ -310,10 +314,9 @@ public: sp mRemoteBinder; // immutable after constructor // permissions management - status_t startCameraOps(); - status_t finishCameraOps(); + virtual status_t startCameraOps(); + virtual status_t finishCameraOps(); - private: std::unique_ptr mAppOpsManager = nullptr; class OpsCallback : public BnAppOpsCallback { @@ -402,87 +405,6 @@ public: int mCameraId; // All API1 clients use integer camera IDs }; // class Client - - // Client for offline session. Note that offline session client does not affect camera service's - // client arbitration logic. It is camera HAL's decision to decide whether a normal camera - // client is conflicting with existing offline client(s). - // The other distinctive difference between offline clients and normal clients is that normal - // clients are created through ICameraService binder calls, while the offline session client - // is created through ICameraDeviceUser::switchToOffline call. - class OfflineClient : public virtual RefBase { - - virtual status_t dump(int fd, const Vector& args) = 0; - - // Block the client form using the camera - virtual void block() = 0; - - // Return the package name for this client - virtual String16 getPackageName() const = 0; - - // Notify client about a fatal error - // TODO: maybe let impl notify within block? - virtual void notifyError(int32_t errorCode, - const CaptureResultExtras& resultExtras) = 0; - - // Get the UID of the application client using this - virtual uid_t getClientUid() const = 0; - - // Get the PID of the application client using this - virtual int getClientPid() const = 0; - - protected: - OfflineClient(const sp& cameraService, - const String16& clientPackageName, - const String8& cameraIdStr, - int clientPid, - uid_t clientUid, - int servicePid): mCameraIdStr(cameraIdStr), - mClientPackageName(clientPackageName), mClientPid(clientPid), - mClientUid(clientUid), mServicePid(servicePid) { - if (sCameraService == nullptr) { - sCameraService = cameraService; - } - } - - virtual ~OfflineClient() { /*TODO*/ } - - // these are initialized in the constructor. - static sp sCameraService; - const String8 mCameraIdStr; - String16 mClientPackageName; - pid_t mClientPid; - const uid_t mClientUid; - const pid_t mServicePid; - bool mDisconnected; - - // - The app-side Binder interface to receive callbacks from us - sp mRemoteBinder; // immutable after constructor - - // permissions management - status_t startCameraOps(); - status_t finishCameraOps(); - - private: - std::unique_ptr mAppOpsManager = nullptr; - - class OpsCallback : public BnAppOpsCallback { - public: - explicit OpsCallback(wp client) : mClient(client) {} - virtual void opChanged(int32_t /*op*/, const String16& /*packageName*/) { - //TODO - } - - private: - wp mClient; - - }; // class OpsCallback - - sp mOpsCallback; - - // IAppOpsCallback interface, indirected through opListener - // virtual void opChanged(int32_t op, const String16& packageName); - }; // class OfflineClient - /** * A listener class that implements the LISTENER interface for use with a ClientManager, and * implements the following methods: @@ -871,6 +793,17 @@ private: */ void logDisconnected(const char* cameraId, int clientPid, const char* clientPackage); + /** + * Add an event log message that a client has been disconnected from offline device. + */ + void logDisconnectedOffline(const char* cameraId, int clientPid, const char* clientPackage); + + /** + * Add an event log message that an offline client has been connected. + */ + void logConnectedOffline(const char* cameraId, int clientPid, + const char* clientPackage); + /** * Add an event log message that a client has been connected. */ @@ -1095,6 +1028,12 @@ private: void broadcastTorchModeStatus(const String8& cameraId, hardware::camera::common::V1_0::TorchModeStatus status); + void disconnectClient(const String8& id, sp clientToDisconnect); + + // Regular online and offline devices must not be in conflict at camera service layer. + // Use separate keys for offline devices. + static const String8 kOfflineDevice; + // TODO: right now each BasicClient holds one AppOpsManager instance. // We can refactor the code so all of clients share this instance AppOpsManager mAppOps; diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp index 28421ba90d..f618b2e764 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp @@ -1903,7 +1903,7 @@ binder::Status CameraDeviceClient::getGlobalAudioRestriction(/*out*/ int32_t* ou binder::Status CameraDeviceClient::switchToOffline( const sp& cameraCb, - const std::vector& offlineOutputs, + const std::vector& offlineOutputIds, /*out*/ sp* session) { ATRACE_CALL(); @@ -1917,7 +1917,7 @@ binder::Status CameraDeviceClient::switchToOffline( return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive"); } - if (offlineOutputs.empty()) { + if (offlineOutputIds.empty()) { String8 msg = String8::format("Offline outputs must not be empty"); ALOGE("%s: %s", __FUNCTION__, msg.string()); return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string()); @@ -1929,10 +1929,9 @@ binder::Status CameraDeviceClient::switchToOffline( return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string()); } - std::vector offlineStreamIds(offlineOutputs.size()); - for (auto& surface : offlineOutputs) { - sp binder = IInterface::asBinder(surface.graphicBufferProducer); - ssize_t index = mStreamMap.indexOfKey(binder); + std::vector offlineStreamIds(offlineOutputIds.size()); + for (const auto& streamId : offlineOutputIds) { + ssize_t index = mConfiguredOutputs.indexOfKey(streamId); if (index == NAME_NOT_FOUND) { String8 msg = String8::format("Offline output is invalid"); ALOGE("%s: %s", __FUNCTION__, msg.string()); @@ -1940,13 +1939,17 @@ binder::Status CameraDeviceClient::switchToOffline( } // TODO: Also check whether the offline output is supported by Hal for offline mode. - sp s = new Surface(surface.graphicBufferProducer); - bool isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s); - isCompositeStream |= camera3::HeicCompositeStream::isHeicCompositeStream(s); + bool isCompositeStream = false; + for (const auto& gbp : mConfiguredOutputs[streamId].getGraphicBufferProducers()) { + sp s = new Surface(gbp, false /*controlledByApp*/); + isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) | + camera3::HeicCompositeStream::isHeicCompositeStream(s); + } + if (isCompositeStream) { // TODO: Add composite specific handling } else { - offlineStreamIds.push_back(mStreamMap.valueAt(index).streamId()); + offlineStreamIds.push_back(streamId); } } @@ -1959,15 +1962,24 @@ binder::Status CameraDeviceClient::switchToOffline( } sp offlineClient = new CameraOfflineSessionClient(sCameraService, - offlineSession, cameraCb, mClientPackageName, mCameraIdStr, mClientPid, mClientUid, - mServicePid); - ret = offlineClient->initialize(); + offlineSession, cameraCb, mClientPackageName, mClientFeatureId, mCameraIdStr, + mCameraFacing, mClientPid, mClientUid, mServicePid); + ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient); if (ret == OK) { // TODO: We need to update mStreamMap, mConfiguredOutputs } else { - return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT, - "Camera %s: Failed to initilize offline session: %s (%d)", - mCameraIdStr.string(), strerror(ret), ret); + switch(ret) { + case BAD_VALUE: + return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT, + "Illegal argument to HAL module for camera \"%s\"", mCameraIdStr.c_str()); + case TIMED_OUT: + return STATUS_ERROR_FMT(CameraService::ERROR_CAMERA_IN_USE, + "Camera \"%s\" is already open", mCameraIdStr.c_str()); + default: + return STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION, + "Failed to initialize camera \"%s\": %s (%d)", mCameraIdStr.c_str(), + strerror(-ret), ret); + } } *session = offlineClient; diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h index 0a8f37777c..295ab29761 100644 --- a/services/camera/libcameraservice/api2/CameraDeviceClient.h +++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h @@ -160,7 +160,7 @@ public: virtual binder::Status switchToOffline( const sp& cameraCb, - const std::vector& offlineOutputs, + const std::vector& offlineOutputIds, /*out*/ sp* session) override; diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp new file mode 100644 index 0000000000..974e10acc2 --- /dev/null +++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2009 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CameraOfflineClient" +#define ATRACE_TAG ATRACE_TAG_CAMERA +//#define LOG_NDEBUG 0 + +#include "CameraOfflineSessionClient.h" +#include + +namespace android { + +using binder::Status; + +status_t CameraOfflineSessionClient::initialize(sp, const String8&) { + return OK; +} + +status_t CameraOfflineSessionClient::dump(int /*fd*/, const Vector& /*args*/) { + return OK; +} + +status_t CameraOfflineSessionClient::dumpClient(int /*fd*/, const Vector& /*args*/) { + return OK; +} + +binder::Status CameraOfflineSessionClient::disconnect() { + binder::Status res = Status::ok(); + if (mDisconnected) { + return res; + } + mDisconnected = true; + + sCameraService->removeByClient(this); + sCameraService->logDisconnectedOffline(mCameraIdStr, mClientPid, String8(mClientPackageName)); + + sp remote = getRemote(); + if (remote != nullptr) { + remote->unlinkToDeath(sCameraService); + } + + finishCameraOps(); + ALOGI("%s: Disconnected client for offline camera %s for PID %d", __FUNCTION__, + mCameraIdStr.string(), mClientPid); + + // client shouldn't be able to call into us anymore + mClientPid = 0; + + return res; +} + +void CameraOfflineSessionClient::notifyError(int32_t errorCode, + const CaptureResultExtras& resultExtras) { + // Thread safe. Don't bother locking. + sp remoteCb = getRemoteCallback(); + // TODO: handle composite streams + if ((remoteCb != 0)) { + remoteCb->onDeviceError(errorCode, resultExtras); + } +} + +status_t CameraOfflineSessionClient::startCameraOps() { + ATRACE_CALL(); + { + ALOGV("%s: Start camera ops, package name = %s, client UID = %d", + __FUNCTION__, String8(mClientPackageName).string(), mClientUid); + } + + if (mAppOpsManager != nullptr) { + // Notify app ops that the camera is not available + mOpsCallback = new OpsCallback(this); + int32_t res; + // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION + mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA, + mClientPackageName, mOpsCallback); + // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION + res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA, + mClientUid, mClientPackageName, /*startIfModeDefault*/ false); + + if (res == AppOpsManager::MODE_ERRORED) { + ALOGI("Offline Camera %s: Access for \"%s\" has been revoked", + mCameraIdStr.string(), String8(mClientPackageName).string()); + return PERMISSION_DENIED; + } + + if (res == AppOpsManager::MODE_IGNORED) { + ALOGI("Offline Camera %s: Access for \"%s\" has been restricted", + mCameraIdStr.string(), String8(mClientPackageName).string()); + // Return the same error as for device policy manager rejection + return -EACCES; + } + } + + mOpsActive = true; + + // Transition device state to OPEN + sCameraService->mUidPolicy->registerMonitorUid(mClientUid); + + return OK; +} + +status_t CameraOfflineSessionClient::finishCameraOps() { + ATRACE_CALL(); + + // Check if startCameraOps succeeded, and if so, finish the camera op + if (mOpsActive) { + // Notify app ops that the camera is available again + if (mAppOpsManager != nullptr) { + // TODO : possibly change this to OP_OFFLINE_CAMERA_SESSION + mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid, + mClientPackageName); + mOpsActive = false; + } + } + // Always stop watching, even if no camera op is active + if (mOpsCallback != nullptr && mAppOpsManager != nullptr) { + mAppOpsManager->stopWatchingMode(mOpsCallback); + } + mOpsCallback.clear(); + + sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid); + + return OK; +} + +// ---------------------------------------------------------------------------- +}; // namespace android diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h index cb83e2907a..0bb14008ab 100644 --- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h +++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h @@ -25,8 +25,14 @@ namespace android { using android::hardware::camera2::ICameraDeviceCallbacks; +// Client for offline session. Note that offline session client does not affect camera service's +// client arbitration logic. It is camera HAL's decision to decide whether a normal camera +// client is conflicting with existing offline client(s). +// The other distinctive difference between offline clients and normal clients is that normal +// clients are created through ICameraService binder calls, while the offline session client +// is created through ICameraDeviceUser::switchToOffline call. class CameraOfflineSessionClient : - public CameraService::OfflineClient, + public CameraService::BasicClient, public hardware::camera2::BnCameraOfflineSession // public camera2::FrameProcessorBase::FilteredListener? { @@ -36,46 +42,45 @@ public: sp session, const sp& remoteCallback, const String16& clientPackageName, - const String8& cameraIdStr, + const std::unique_ptr& clientFeatureId, + const String8& cameraIdStr, int cameraFacing, int clientPid, uid_t clientUid, int servicePid) : - CameraService::OfflineClient(cameraService, clientPackageName, - cameraIdStr, clientPid, clientUid, servicePid), - mRemoteCallback(remoteCallback), mOfflineSession(session) {} + CameraService::BasicClient( + cameraService, + IInterface::asBinder(remoteCallback), + clientPackageName, clientFeatureId, + cameraIdStr, cameraFacing, clientPid, clientUid, servicePid), + mRemoteCallback(remoteCallback), mOfflineSession(session) {} - ~CameraOfflineSessionClient() {} + virtual ~CameraOfflineSessionClient() {} - virtual binder::Status disconnect() override { return binder::Status::ok(); } - - virtual status_t dump(int /*fd*/, const Vector& /*args*/) override { - return OK; + virtual sp asBinderWrapper() override { + return IInterface::asBinder(this); } - // Block the client form using the camera - virtual void block() override {}; + virtual binder::Status disconnect() override; + + virtual status_t dump(int /*fd*/, const Vector& /*args*/) override; - // Return the package name for this client - virtual String16 getPackageName() const override { String16 ret; return ret; }; + virtual status_t dumpClient(int /*fd*/, const Vector& /*args*/) override; - // Notify client about a fatal error - // TODO: maybe let impl notify within block? virtual void notifyError(int32_t /*errorCode*/, - const CaptureResultExtras& /*resultExtras*/) override {} + const CaptureResultExtras& /*resultExtras*/) override; - // Get the UID of the application client using this - virtual uid_t getClientUid() const override { return 0; } + virtual status_t initialize(sp /*manager*/, + const String8& /*monitorTags*/) override; - // Get the PID of the application client using this - virtual int getClientPid() const override { return 0; } + // permissions management + virtual status_t startCameraOps() override; + virtual status_t finishCameraOps() override; - status_t initialize() { - // TODO: Talk to camera service to add the offline session client book keeping - return OK; - } private: - sp mSession; + + const sp& getRemoteCallback() { + return mRemoteCallback; + } sp mRemoteCallback; - // This class is responsible to convert HAL callbacks to AIDL callbacks sp mOfflineSession; };