Camera: Add onCameraOpened/onCameraClosed callbacks
The onCameraOpened/onCameraClosed callbacks are used to notify camera
service client with CAMERA_OPEN_CLOSE_LISTENER permission that a certain
camera device has been opened/closed.
Test: Manually check callbacks are received in SystemUI app
Bug: 150540299
Change-Id: If6f3624c43927c30afef7df0a780eafe3ae4c527
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 453984e..e0884f4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -126,6 +126,8 @@
static const String16 sSystemCameraPermission("android.permission.SYSTEM_CAMERA");
static const String16
sCameraSendSystemEventsPermission("android.permission.CAMERA_SEND_SYSTEM_EVENTS");
+static const String16 sCameraOpenCloseListenerPermission(
+ "android.permission.CAMERA_OPEN_CLOSE_LISTENER");
// Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java
static constexpr int32_t kVendorClientScore = 200;
@@ -2146,6 +2148,8 @@
auto clientUid = CameraThreadState::getCallingUid();
auto clientPid = CameraThreadState::getCallingPid();
+ bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
+ clientPid, clientUid);
Mutex::Autolock lock(mServiceLock);
@@ -2160,7 +2164,8 @@
}
sp<ServiceListener> serviceListener =
- new ServiceListener(this, listener, clientUid, clientPid, isVendorListener);
+ new ServiceListener(this, listener, clientUid, clientPid, isVendorListener,
+ openCloseCallbackAllowed);
auto ret = serviceListener->initialize();
if (ret != NO_ERROR) {
String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
@@ -2923,6 +2928,9 @@
sCameraService->mUidPolicy->registerMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, true/*open*/, mClientPackageName);
+
return OK;
}
@@ -2963,6 +2971,9 @@
sCameraService->mUidPolicy->unregisterMonitorUid(mClientUid);
+ // Notify listeners of camera open/close status
+ sCameraService->updateOpenCloseStatus(mCameraIdStr, false/*open*/, mClientPackageName);
+
return OK;
}
@@ -3759,6 +3770,29 @@
});
}
+void CameraService::updateOpenCloseStatus(const String8& cameraId, bool open,
+ const String16& clientPackageName) {
+ Mutex::Autolock lock(mStatusListenerLock);
+
+ for (const auto& it : mListenerList) {
+ if (!it->isOpenCloseCallbackAllowed()) {
+ continue;
+ }
+
+ binder::Status ret;
+ String16 cameraId64(cameraId);
+ if (open) {
+ ret = it->getListener()->onCameraOpened(cameraId64, clientPackageName);
+ } else {
+ ret = it->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,
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 265a572..f12b4cc 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -912,9 +912,10 @@
class ServiceListener : public virtual IBinder::DeathRecipient {
public:
ServiceListener(sp<CameraService> parent, sp<hardware::ICameraServiceListener> listener,
- int uid, int pid, bool isVendorClient)
+ int uid, int pid, bool isVendorClient, bool openCloseCallbackAllowed)
: mParent(parent), mListener(listener), mListenerUid(uid), mListenerPid(pid),
- mIsVendorListener(isVendorClient) { }
+ mIsVendorListener(isVendorClient),
+ mOpenCloseCallbackAllowed(openCloseCallbackAllowed) { }
status_t initialize() {
return IInterface::asBinder(mListener)->linkToDeath(this);
@@ -931,6 +932,7 @@
int getListenerPid() { return mListenerPid; }
sp<hardware::ICameraServiceListener> getListener() { return mListener; }
bool isVendorListener() { return mIsVendorListener; }
+ bool isOpenCloseCallbackAllowed() { return mOpenCloseCallbackAllowed; }
private:
wp<CameraService> mParent;
@@ -938,6 +940,7 @@
int mListenerUid = -1;
int mListenerPid = -1;
bool mIsVendorListener = false;
+ bool mOpenCloseCallbackAllowed = false;
};
// Guarded by mStatusListenerMutex
@@ -960,6 +963,13 @@
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
diff --git a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
index 95493a1..7148035 100644
--- a/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
+++ b/services/camera/libcameraservice/hidl/AidlCameraServiceListener.h
@@ -58,6 +58,15 @@
// TODO: no implementation yet.
return binder::Status::ok();
}
+ virtual binder::Status onCameraOpened(const ::android::String16& /*cameraId*/,
+ const ::android::String16& /*clientPackageId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
+ virtual binder::Status onCameraClosed(const ::android::String16& /*cameraId*/) {
+ // empty implementation
+ return binder::Status::ok();
+ }
};
} // implementation