diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index c1efa5fef2..69b9e7e5a2 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -7608,6 +7608,13 @@ typedef enum acamera_metadata_enum_acamera_request_available_capabilities {
*/
ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
+ /**
+ *
The camera device is capable of writing image data into a region of memory
+ * inaccessible to Android userspace or the Android kernel, and only accessible to
+ * trusted execution environments (TEE).
+ */
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13,
+
} acamera_metadata_enum_android_request_available_capabilities_t;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index c3113bf6ea..ee8d7e128b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -49,6 +49,7 @@
#include
#include "hidl/HidlCameraService.h"
#include
+#include
#include
#include
#include
@@ -226,7 +227,7 @@ void CameraService::broadcastTorchModeStatus(const String8& cameraId, TorchModeS
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 @@ Status CameraService::connectLegacy(
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& cameraCb,
const String16& cameraId,
@@ -1299,6 +1312,7 @@ Status CameraService::connectDevice(
Status ret = Status::ok();
String8 id = String8(cameraId);
sp client = nullptr;
+
ret = connectHelper(cameraCb, id,
/*api1CameraId*/-1,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
@@ -1330,6 +1344,14 @@ Status CameraService::connectHelper(const sp& cameraCb, const String8&
(halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
static_cast(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 = nullptr;
{
// Acquire mServiceLock and prevent other clients from connecting
@@ -1635,6 +1657,14 @@ Status CameraService::notifySystemEvent(int32_t eventId,
Status CameraService::addListener(const sp& listener,
/*out*/
std::vector *cameraStatuses) {
+ return addListenerHelper(listener, cameraStatuses);
+}
+
+Status CameraService::addListenerHelper(const sp& listener,
+ /*out*/
+ std::vector *cameraStatuses,
+ bool isVendorListener) {
+
ATRACE_CALL();
ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
@@ -1649,20 +1679,26 @@ Status CameraService::addListener(const sp& listener,
{
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 @@ Status CameraService::removeListener(const sp& listener)
{
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 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
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));
}
});
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a2961986b2..3af52fa54c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -173,6 +173,10 @@ public:
virtual status_t shellCommand(int in, int out, int err, const Vector& args);
+ binder::Status addListenerHelper(const sp& listener,
+ /*out*/
+ std::vector* cameraStatuses, bool isVendor = false);
+
/////////////////////////////////////////////////////////////////////
// Client functionality
@@ -615,6 +619,10 @@ private:
sp* client,
std::shared_ptr>>* partial);
+ // Should an operation attempt on a cameraId be rejected, if the camera id is
+ // advertised as a publically hidden secure camera, by the camera HAL ?
+ bool shouldRejectHiddenCameraConnection(const String8 & cameraId);
+
// Single implementation shared between the various connect calls
template
binder::Status connectHelper(const sp& cameraCb, const String8& cameraId,
@@ -781,7 +789,8 @@ private:
sp mCameraProviderManager;
// Guarded by mStatusListenerMutex
- std::vector> mListenerList;
+ std::vector>> mListenerList;
+
Mutex mStatusListenerLock;
/**
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 3059b0737d..ad4fc5f834 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -504,6 +504,17 @@ void CameraProviderManager::ProviderInfo::DeviceInfo3::queryPhysicalCameraIds()
}
}
+bool CameraProviderManager::ProviderInfo::DeviceInfo3::isPublicallyHiddenSecureCamera() {
+ camera_metadata_entry_t entryCap;
+ entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ if (entryCap.count != 1) {
+ // Do NOT hide this camera device if the capabilities specify anything more
+ // than ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA.
+ return false;
+ }
+ return entryCap.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA;
+}
+
void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedSizes(
const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
std::vector> *sizes/*out*/) {
@@ -882,6 +893,16 @@ bool CameraProviderManager::isLogicalCamera(const std::string& id,
return deviceInfo->mIsLogicalCamera;
}
+bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) {
+ std::lock_guard lock(mInterfaceMutex);
+
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) {
+ return false;
+ }
+ return deviceInfo->mIsPublicallyHiddenSecureCamera;
+}
+
bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
for (auto& provider : mProviders) {
for (auto& deviceInfo : provider->mDevices) {
@@ -1709,6 +1730,9 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
__FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
return;
}
+
+ mIsPublicallyHiddenSecureCamera = isPublicallyHiddenSecureCamera();
+
status_t res = fixupMonochromeTags();
if (OK != res) {
ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
@@ -1731,6 +1755,7 @@ CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string&
}
queryPhysicalCameraIds();
+
// Get physical camera characteristics if applicable
auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
if (!castResult.isOk()) {
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index fbd7d2e8f8..18869f53f6 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -264,6 +264,7 @@ public:
*/
bool isLogicalCamera(const std::string& id, std::vector* physicalCameraIds);
+ bool isPublicallyHiddenSecureCamera(const std::string& id);
bool isHiddenPhysicalCamera(const std::string& cameraId);
static const float kDepthARTolerance;
@@ -354,6 +355,7 @@ private:
std::vector mPhysicalIds;
hardware::CameraInfo mInfo;
sp mSavedInterface;
+ bool mIsPublicallyHiddenSecureCamera = false;
const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
@@ -471,6 +473,7 @@ private:
CameraMetadata mCameraCharacteristics;
std::unordered_map mPhysicalCameraCharacteristics;
void queryPhysicalCameraIds();
+ bool isPublicallyHiddenSecureCamera();
status_t fixupMonochromeTags();
status_t addDynamicDepthTags();
static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag,
diff --git a/services/camera/libcameraservice/hidl/HidlCameraService.cpp b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
index 48f1d374bf..74cfe4267a 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraService.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraService.cpp
@@ -182,7 +182,8 @@ Return HidlCameraService::addListener(const sp& hC
}
}
std::vector cameraStatusAndIds{};
- binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
+ binder::Status serviceRet =
+ mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
HStatus status = HStatus::NO_ERROR;
if (!serviceRet.isOk()) {
ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);