Merge "cameraserver: Add support for hiding secure cameras."

gugelfrei
Jayant Chowdhary 5 years ago committed by Android (Google) Code Review
commit 988393f760

@ -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;

@ -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 @@ 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<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const String16& cameraId,
@ -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,
@ -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
@ -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());
@ -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()));
}
}
@ -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();
}
@ -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));
}
});
}

@ -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
@ -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,
@ -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;
/**

@ -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*/) {
@ -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) {
@ -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)",
@ -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()) {

@ -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;
@ -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;
@ -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,

@ -182,7 +182,8 @@ Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hC
}
}
std::vector<hardware::CameraStatus> 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__);

Loading…
Cancel
Save