Loading camera/ndk/include/camera/NdkCameraMetadataTags.h +7 −0 Original line number Diff line number Diff line Loading @@ -7608,6 +7608,13 @@ typedef enum acamera_metadata_enum_acamera_request_available_capabilities { */ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12, /** * <p>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).</p> */ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13, } acamera_metadata_enum_android_request_available_capabilities_t; Loading services/camera/libcameraservice/CameraService.cpp +47 −5 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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}); } } Loading Loading @@ -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<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId, Loading @@ -1299,6 +1312,7 @@ Status CameraService::connectDevice( 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, Loading Loading @@ -1330,6 +1344,14 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& (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 Loading Loading @@ -1635,6 +1657,14 @@ Status CameraService::notifySystemEvent(int32_t eventId, 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()); Loading @@ -1649,20 +1679,26 @@ Status CameraService::addListener(const sp<ICameraServiceListener>& 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())); } } Loading Loading @@ -1697,7 +1733,7 @@ Status CameraService::removeListener(const sp<ICameraServiceListener>& 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(); } Loading Loading @@ -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)); } }); } Loading services/camera/libcameraservice/CameraService.h +10 −1 Original line number Diff line number Diff line Loading @@ -173,6 +173,10 @@ public: virtual status_t shellCommand(int in, int out, int err, const Vector<String16>& args); binder::Status addListenerHelper(const sp<hardware::ICameraServiceListener>& listener, /*out*/ std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false); ///////////////////////////////////////////////////////////////////// // Client functionality Loading Loading @@ -615,6 +619,10 @@ private: sp<BasicClient>* client, std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* 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<class CALLBACK, class CLIENT> binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, Loading Loading @@ -781,7 +789,8 @@ private: sp<CameraProviderManager> mCameraProviderManager; // Guarded by mStatusListenerMutex std::vector<sp<hardware::ICameraServiceListener>> mListenerList; std::vector<std::pair<bool, sp<hardware::ICameraServiceListener>>> mListenerList; Mutex mStatusListenerLock; /** Loading services/camera/libcameraservice/common/CameraProviderManager.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -499,6 +499,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<std::tuple<size_t, size_t>> *sizes/*out*/) { Loading Loading @@ -877,6 +888,16 @@ bool CameraProviderManager::isLogicalCamera(const std::string& id, return deviceInfo->mIsLogicalCamera; } bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) { std::lock_guard<std::mutex> 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) { Loading Loading @@ -1704,6 +1725,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)", Loading @@ -1726,6 +1750,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()) { Loading services/camera/libcameraservice/common/CameraProviderManager.h +3 −0 Original line number Diff line number Diff line Loading @@ -264,6 +264,7 @@ public: */ bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds); bool isPublicallyHiddenSecureCamera(const std::string& id); bool isHiddenPhysicalCamera(const std::string& cameraId); static const float kDepthARTolerance; Loading Loading @@ -354,6 +355,7 @@ private: std::vector<std::string> mPhysicalIds; hardware::CameraInfo mInfo; sp<IBase> mSavedInterface; bool mIsPublicallyHiddenSecureCamera = false; const hardware::camera::common::V1_0::CameraResourceCost mResourceCost; Loading Loading @@ -471,6 +473,7 @@ private: CameraMetadata mCameraCharacteristics; std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics; void queryPhysicalCameraIds(); bool isPublicallyHiddenSecureCamera(); status_t fixupMonochromeTags(); status_t addDynamicDepthTags(); static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag, Loading Loading
camera/ndk/include/camera/NdkCameraMetadataTags.h +7 −0 Original line number Diff line number Diff line Loading @@ -7608,6 +7608,13 @@ typedef enum acamera_metadata_enum_acamera_request_available_capabilities { */ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12, /** * <p>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).</p> */ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA = 13, } acamera_metadata_enum_android_request_available_capabilities_t; Loading
services/camera/libcameraservice/CameraService.cpp +47 −5 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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}); } } Loading Loading @@ -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<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId, Loading @@ -1299,6 +1312,7 @@ Status CameraService::connectDevice( 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, Loading Loading @@ -1330,6 +1344,14 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& (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 Loading Loading @@ -1635,6 +1657,14 @@ Status CameraService::notifySystemEvent(int32_t eventId, 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()); Loading @@ -1649,20 +1679,26 @@ Status CameraService::addListener(const sp<ICameraServiceListener>& 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())); } } Loading Loading @@ -1697,7 +1733,7 @@ Status CameraService::removeListener(const sp<ICameraServiceListener>& 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(); } Loading Loading @@ -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)); } }); } Loading
services/camera/libcameraservice/CameraService.h +10 −1 Original line number Diff line number Diff line Loading @@ -173,6 +173,10 @@ public: virtual status_t shellCommand(int in, int out, int err, const Vector<String16>& args); binder::Status addListenerHelper(const sp<hardware::ICameraServiceListener>& listener, /*out*/ std::vector<hardware::CameraStatus>* cameraStatuses, bool isVendor = false); ///////////////////////////////////////////////////////////////////// // Client functionality Loading Loading @@ -615,6 +619,10 @@ private: sp<BasicClient>* client, std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* 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<class CALLBACK, class CLIENT> binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, Loading Loading @@ -781,7 +789,8 @@ private: sp<CameraProviderManager> mCameraProviderManager; // Guarded by mStatusListenerMutex std::vector<sp<hardware::ICameraServiceListener>> mListenerList; std::vector<std::pair<bool, sp<hardware::ICameraServiceListener>>> mListenerList; Mutex mStatusListenerLock; /** Loading
services/camera/libcameraservice/common/CameraProviderManager.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -499,6 +499,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<std::tuple<size_t, size_t>> *sizes/*out*/) { Loading Loading @@ -877,6 +888,16 @@ bool CameraProviderManager::isLogicalCamera(const std::string& id, return deviceInfo->mIsLogicalCamera; } bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id) { std::lock_guard<std::mutex> 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) { Loading Loading @@ -1704,6 +1725,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)", Loading @@ -1726,6 +1750,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()) { Loading
services/camera/libcameraservice/common/CameraProviderManager.h +3 −0 Original line number Diff line number Diff line Loading @@ -264,6 +264,7 @@ public: */ bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds); bool isPublicallyHiddenSecureCamera(const std::string& id); bool isHiddenPhysicalCamera(const std::string& cameraId); static const float kDepthARTolerance; Loading Loading @@ -354,6 +355,7 @@ private: std::vector<std::string> mPhysicalIds; hardware::CameraInfo mInfo; sp<IBase> mSavedInterface; bool mIsPublicallyHiddenSecureCamera = false; const hardware::camera::common::V1_0::CameraResourceCost mResourceCost; Loading Loading @@ -471,6 +473,7 @@ private: CameraMetadata mCameraCharacteristics; std::unordered_map<std::string, CameraMetadata> mPhysicalCameraCharacteristics; void queryPhysicalCameraIds(); bool isPublicallyHiddenSecureCamera(); status_t fixupMonochromeTags(); status_t addDynamicDepthTags(); static void getSupportedSizes(const CameraMetadata& ch, uint32_t tag, Loading