Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f949ddde authored by Jayant Chowdhary's avatar Jayant Chowdhary
Browse files

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: default avatarJayant Chowdhary <jchowdhary@google.com>
parent 88cc9a5f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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;


+47 −5
Original line number Diff line number Diff line
@@ -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));
            }
        });
}
+10 −1
Original line number Diff line number Diff line
@@ -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;

    /**
+25 −0
Original line number Diff line number Diff line
@@ -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<std::tuple<size_t, size_t>> *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<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) {
@@ -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()) {
+3 −0
Original line number Diff line number Diff line
@@ -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,
Loading