Loading camera/aidl/android/hardware/ICameraServiceListener.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -83,4 +83,12 @@ interface ICameraServiceListener * can retry after receiving this callback. */ oneway void onCameraAccessPrioritiesChanged(); /** * Notify registered clients about cameras being opened/closed. * Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission * will receive such callbacks. */ oneway void onCameraOpened(String cameraId, String clientPackageId); oneway void onCameraClosed(String cameraId); } camera/ndk/impl/ACameraManager.h +6 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ class CameraManagerGlobal final : public RefBase { } virtual binder::Status onCameraAccessPrioritiesChanged(); virtual binder::Status onCameraOpened(const String16&, const String16&) { return binder::Status::ok(); } virtual binder::Status onCameraClosed(const String16&) { return binder::Status::ok(); } private: const wp<CameraManagerGlobal> mCameraManager; Loading camera/tests/CameraBinderTests.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,17 @@ public: return binder::Status::ok(); } virtual binder::Status onCameraOpened(const String16& /*cameraId*/, const String16& /*clientPackageName*/) { // No op return binder::Status::ok(); } virtual binder::Status onCameraClosed(const String16& /*cameraId*/) { // No op return binder::Status::ok(); } bool waitForNumCameras(size_t num) const { Mutex::Autolock l(mLock); Loading services/camera/libcameraservice/CameraService.cpp +36 −1 Original line number Diff line number Diff line Loading @@ -118,6 +118,8 @@ static void setLogLevel(int level) { // ---------------------------------------------------------------------------- static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA"); static const String16 sCameraOpenCloseListenerPermission( "android.permission.CAMERA_OPEN_CLOSE_LISTENER"); // Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java static constexpr int32_t kVendorClientScore = 200; Loading Loading @@ -1811,7 +1813,11 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen } auto clientUid = CameraThreadState::getCallingUid(); sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid); auto clientPid = CameraThreadState::getCallingPid(); bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission, clientPid, clientUid); sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid, clientPid, openCloseCallbackAllowed); auto ret = serviceListener->initialize(); if (ret != NO_ERROR) { String8 msg = String8::format("Failed to initialize service listener: %s (%d)", Loading Loading @@ -2515,6 +2521,9 @@ status_t CameraService::BasicClient::startCameraOps() { sCameraService->mUidPolicy->registerMonitorUid(mClientUid); // Notify listeners of camera open/close status sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName); return OK; } Loading Loading @@ -2555,6 +2564,9 @@ status_t CameraService::BasicClient::finishCameraOps() { sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid); // Notify listeners of camera open/close status sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName); return OK; } Loading Loading @@ -3311,6 +3323,29 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, }); } void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open, const String16& clientPackageName) { Mutex::Autolock lock(mStatusListenerLock); for (const auto& it : mListenerList) { if (!it.second->isOpenCloseCallbackAllowed()) { continue; } binder::Status ret; String16 cameraId64(cameraId); if (open) { ret = it.second->getListener()->onCameraOpened(cameraId64, clientPackageName); } else { ret = it.second->getListener()->onCameraClosed(cameraId64); } if (!ret.isOk()) { ALOGE("%s: Failed to trigger onCameraOpened/onCameraClosed callback: %d", __FUNCTION__, ret.exceptionCode()); } } } template<class Func> void CameraService::CameraState::updateStatus(StatusInternal status, const String8& cameraId, Loading services/camera/libcameraservice/CameraService.h +14 −1 Original line number Diff line number Diff line Loading @@ -817,7 +817,9 @@ private: class ServiceListener : public virtual IBinder::DeathRecipient { public: ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener, int uid) : mParent(parent), mListener(listener), mListenerUid(uid) {} int uid, int pid, bool openCloseCallbackAllowed) : mParent(parent), mListener(listener), mListenerUid(uid), mListenerPid(pid), mOpenCloseCallbackAllowed(openCloseCallbackAllowed) {} status_t initialize() { return IInterface::asBinder(mListener)->linkToDeath(this); Loading @@ -831,12 +833,16 @@ private: } int getListenerUid() { return mListenerUid; } int getListenerPid() { return mListenerPid; } sp<hardware::ICameraServiceListener> getListener() { return mListener; } bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; } private: wp<CameraService> mParent; sp<hardware::ICameraServiceListener> mListener; int mListenerUid; int mListenerPid; bool mOpenCloseCallbackAllowed = false; }; // Guarded by mStatusListenerMutex Loading @@ -859,6 +865,13 @@ private: void updateStatus(StatusInternal status, const String8& cameraId); /** * Update the opened/closed status of the given camera id. * * This method acqiures mStatusListenerLock. */ void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName); // flashlight control sp<CameraFlashlight> mFlashlight; // guard mTorchStatusMap Loading Loading
camera/aidl/android/hardware/ICameraServiceListener.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -83,4 +83,12 @@ interface ICameraServiceListener * can retry after receiving this callback. */ oneway void onCameraAccessPrioritiesChanged(); /** * Notify registered clients about cameras being opened/closed. * Only clients with android.permission.CAMERA_OPEN_CLOSE_LISTENER permission * will receive such callbacks. */ oneway void onCameraOpened(String cameraId, String clientPackageId); oneway void onCameraClosed(String cameraId); }
camera/ndk/impl/ACameraManager.h +6 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,12 @@ class CameraManagerGlobal final : public RefBase { } virtual binder::Status onCameraAccessPrioritiesChanged(); virtual binder::Status onCameraOpened(const String16&, const String16&) { return binder::Status::ok(); } virtual binder::Status onCameraClosed(const String16&) { return binder::Status::ok(); } private: const wp<CameraManagerGlobal> mCameraManager; Loading
camera/tests/CameraBinderTests.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,17 @@ public: return binder::Status::ok(); } virtual binder::Status onCameraOpened(const String16& /*cameraId*/, const String16& /*clientPackageName*/) { // No op return binder::Status::ok(); } virtual binder::Status onCameraClosed(const String16& /*cameraId*/) { // No op return binder::Status::ok(); } bool waitForNumCameras(size_t num) const { Mutex::Autolock l(mLock); Loading
services/camera/libcameraservice/CameraService.cpp +36 −1 Original line number Diff line number Diff line Loading @@ -118,6 +118,8 @@ static void setLogLevel(int level) { // ---------------------------------------------------------------------------- static const String16 sManageCameraPermission("android.permission.MANAGE_CAMERA"); static const String16 sCameraOpenCloseListenerPermission( "android.permission.CAMERA_OPEN_CLOSE_LISTENER"); // Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java static constexpr int32_t kVendorClientScore = 200; Loading Loading @@ -1811,7 +1813,11 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen } auto clientUid = CameraThreadState::getCallingUid(); sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid); auto clientPid = CameraThreadState::getCallingPid(); bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission, clientPid, clientUid); sp<ServiceListener> serviceListener = new ServiceListener(this, listener, clientUid, clientPid, openCloseCallbackAllowed); auto ret = serviceListener->initialize(); if (ret != NO_ERROR) { String8 msg = String8::format("Failed to initialize service listener: %s (%d)", Loading Loading @@ -2515,6 +2521,9 @@ status_t CameraService::BasicClient::startCameraOps() { sCameraService->mUidPolicy->registerMonitorUid(mClientUid); // Notify listeners of camera open/close status sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName); return OK; } Loading Loading @@ -2555,6 +2564,9 @@ status_t CameraService::BasicClient::finishCameraOps() { sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid); // Notify listeners of camera open/close status sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName); return OK; } Loading Loading @@ -3311,6 +3323,29 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId, }); } void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open, const String16& clientPackageName) { Mutex::Autolock lock(mStatusListenerLock); for (const auto& it : mListenerList) { if (!it.second->isOpenCloseCallbackAllowed()) { continue; } binder::Status ret; String16 cameraId64(cameraId); if (open) { ret = it.second->getListener()->onCameraOpened(cameraId64, clientPackageName); } else { ret = it.second->getListener()->onCameraClosed(cameraId64); } if (!ret.isOk()) { ALOGE("%s: Failed to trigger onCameraOpened/onCameraClosed callback: %d", __FUNCTION__, ret.exceptionCode()); } } } template<class Func> void CameraService::CameraState::updateStatus(StatusInternal status, const String8& cameraId, Loading
services/camera/libcameraservice/CameraService.h +14 −1 Original line number Diff line number Diff line Loading @@ -817,7 +817,9 @@ private: class ServiceListener : public virtual IBinder::DeathRecipient { public: ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener, int uid) : mParent(parent), mListener(listener), mListenerUid(uid) {} int uid, int pid, bool openCloseCallbackAllowed) : mParent(parent), mListener(listener), mListenerUid(uid), mListenerPid(pid), mOpenCloseCallbackAllowed(openCloseCallbackAllowed) {} status_t initialize() { return IInterface::asBinder(mListener)->linkToDeath(this); Loading @@ -831,12 +833,16 @@ private: } int getListenerUid() { return mListenerUid; } int getListenerPid() { return mListenerPid; } sp<hardware::ICameraServiceListener> getListener() { return mListener; } bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; } private: wp<CameraService> mParent; sp<hardware::ICameraServiceListener> mListener; int mListenerUid; int mListenerPid; bool mOpenCloseCallbackAllowed = false; }; // Guarded by mStatusListenerMutex Loading @@ -859,6 +865,13 @@ private: void updateStatus(StatusInternal status, const String8& cameraId); /** * Update the opened/closed status of the given camera id. * * This method acqiures mStatusListenerLock. */ void updateOpenCloseStatus(const String8& cameraId, bool open, const String16& packageName); // flashlight control sp<CameraFlashlight> mFlashlight; // guard mTorchStatusMap Loading