cameraserver: Add support for hiding secure cameras.
Bug: 123046494
Test: Sanity -> GCA
Test: Hardcode all cameras hidden, AImageReaderVendorTest passes, GCA
cannot find cameras.
Change-Id: I7780751101c660e47d84627ec191f43d268f1aa9
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c3113bf..ee8d7e1 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -49,6 +49,7 @@
#include <hardware/hardware.h>
#include "hidl/HidlCameraService.h"
#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/IPCThreadState.h>
#include <memunreachable/memunreachable.h>
#include <media/AudioSystem.h>
#include <media/IMediaHTTPService.h>
@@ -226,7 +227,7 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto& i : mListenerList) {
- i->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
+ i.second->onTorchStatusChanged(mapToInterface(status), String16{cameraId});
}
}
@@ -1287,6 +1288,18 @@
return ret;
}
+bool CameraService::shouldRejectHiddenCameraConnection(const String8 & cameraId) {
+ // If the thread serving this call is not a hwbinder thread and the caller
+ // isn't the cameraserver itself, and the camera id being requested is to be
+ // publically hidden, we should reject the connection.
+ if (!hardware::IPCThreadState::self()->isServingCall() &&
+ CameraThreadState::getCallingPid() != getpid() &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+ return true;
+ }
+ return false;
+}
+
Status CameraService::connectDevice(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
@@ -1299,6 +1312,7 @@
Status ret = Status::ok();
String8 id = String8(cameraId);
sp<CameraDeviceClient> client = nullptr;
+
ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
/*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
@@ -1330,6 +1344,14 @@
(halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
static_cast<int>(effectiveApiLevel));
+ if (shouldRejectHiddenCameraConnection(cameraId)) {
+ ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
+ cameraId.c_str());
+ return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
+ "No camera device with ID \"%s\" currently available",
+ cameraId.string());
+
+ }
sp<CLIENT> client = nullptr;
{
// Acquire mServiceLock and prevent other clients from connecting
@@ -1635,6 +1657,14 @@
Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
/*out*/
std::vector<hardware::CameraStatus> *cameraStatuses) {
+ return addListenerHelper(listener, cameraStatuses);
+}
+
+Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listener,
+ /*out*/
+ std::vector<hardware::CameraStatus> *cameraStatuses,
+ bool isVendorListener) {
+
ATRACE_CALL();
ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
@@ -1649,20 +1679,26 @@
{
Mutex::Autolock lock(mStatusListenerLock);
for (auto& it : mListenerList) {
- if (IInterface::asBinder(it) == IInterface::asBinder(listener)) {
+ if (IInterface::asBinder(it.second) == IInterface::asBinder(listener)) {
ALOGW("%s: Tried to add listener %p which was already subscribed",
__FUNCTION__, listener.get());
return STATUS_ERROR(ERROR_ALREADY_EXISTS, "Listener already registered");
}
}
- mListenerList.push_back(listener);
+ mListenerList.emplace_back(isVendorListener, listener);
}
/* Collect current devices and status */
{
Mutex::Autolock lock(mCameraStatesLock);
for (auto& i : mCameraStates) {
+ if (!isVendorListener &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(i.first.c_str())) {
+ ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
+ i.first.c_str(), CameraThreadState::getCallingPid());
+ continue;
+ }
cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
}
}
@@ -1697,7 +1733,7 @@
{
Mutex::Autolock lock(mStatusListenerLock);
for (auto it = mListenerList.begin(); it != mListenerList.end(); it++) {
- if (IInterface::asBinder(*it) == IInterface::asBinder(listener)) {
+ if (IInterface::asBinder(it->second) == IInterface::asBinder(listener)) {
mListenerList.erase(it);
return Status::ok();
}
@@ -3033,7 +3069,13 @@
Mutex::Autolock lock(mStatusListenerLock);
for (auto& listener : mListenerList) {
- listener->onStatusChanged(mapToInterface(status), String16(cameraId));
+ if (!listener.first &&
+ mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
+ ALOGV("Skipping camera discovery callback for system-only camera %s",
+ cameraId.c_str());
+ continue;
+ }
+ listener.second->onStatusChanged(mapToInterface(status), String16(cameraId));
}
});
}