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

Commit fc840737 authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Android (Google) Code Review
Browse files

Merge "cameraserver: Enforce system only camera permissions in camera1 api."

parents eea0d34b 847947d8
Loading
Loading
Loading
Loading
+67 −14
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ sp<hardware::ICameraServiceProxy> CameraService::sCameraServiceProxy;
CameraService::CameraService() :
        mEventLog(DEFAULT_EVENT_LOG_LENGTH),
        mNumberOfCameras(0),
        mNumberOfCamerasWithoutSystemCamera(0),
        mSoundRef(0), mInitialized(false),
        mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
    ALOGI("CameraService started (pid=%d)", getpid());
@@ -260,11 +261,32 @@ void CameraService::onNewProviderRegistered() {
    enumerateProviders();
}

void CameraService::filterAPI1SystemCameraLocked(
        const std::vector<std::string> &normalDeviceIds) {
    mNormalDeviceIdsWithoutSystemCamera.clear();
    for (auto &deviceId : normalDeviceIds) {
        if (getSystemCameraKind(String8(deviceId.c_str())) ==
                SystemCameraKind::SYSTEM_ONLY_CAMERA) {
            // All system camera ids will necessarily come after public camera
            // device ids as per the HAL interface contract.
            break;
        }
        mNormalDeviceIdsWithoutSystemCamera.push_back(deviceId);
    }
    ALOGV("%s: number of API1 compatible public cameras is %zu", __FUNCTION__,
              mNormalDeviceIdsWithoutSystemCamera.size());
}

void CameraService::updateCameraNumAndIds() {
    Mutex::Autolock l(mServiceLock);
    mNumberOfCameras = mCameraProviderManager->getCameraCount();
    std::pair<int, int> systemAndNonSystemCameras = mCameraProviderManager->getCameraCount();
    // Excludes hidden secure cameras
    mNumberOfCameras =
            systemAndNonSystemCameras.first + systemAndNonSystemCameras.second;
    mNumberOfCamerasWithoutSystemCamera = systemAndNonSystemCameras.second;
    mNormalDeviceIds =
            mCameraProviderManager->getAPI1CompatibleCameraDeviceIds();
    filterAPI1SystemCameraLocked(mNormalDeviceIds);
}

void CameraService::addStates(const String8 id) {
@@ -446,15 +468,31 @@ void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
    broadcastTorchModeStatus(cameraId, newStatus);
}

static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
    return checkPermission(sSystemCameraPermission, callingPid, callingUid) &&
            checkPermission(sCameraPermission, callingPid, callingUid);
}

Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
    ATRACE_CALL();
    Mutex::Autolock l(mServiceLock);
    bool hasSystemCameraPermissions =
            hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
                    CameraThreadState::getCallingUid());
    switch (type) {
        case CAMERA_TYPE_BACKWARD_COMPATIBLE:
            if (hasSystemCameraPermissions) {
                *numCameras = static_cast<int>(mNormalDeviceIds.size());
            } else {
                *numCameras = static_cast<int>(mNormalDeviceIdsWithoutSystemCamera.size());
            }
            break;
        case CAMERA_TYPE_ALL:
            if (hasSystemCameraPermissions) {
                *numCameras = mNumberOfCameras;
            } else {
                *numCameras = mNumberOfCamerasWithoutSystemCamera;
            }
            break;
        default:
            ALOGW("%s: Unknown camera type %d",
@@ -469,20 +507,31 @@ Status CameraService::getCameraInfo(int cameraId,
        CameraInfo* cameraInfo) {
    ATRACE_CALL();
    Mutex::Autolock l(mServiceLock);
    std::string cameraIdStr = cameraIdIntToStrLocked(cameraId);
    if (shouldRejectSystemCameraConnection(String8(cameraIdStr.c_str()))) {
        return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera"
                "characteristics for system only device %s: ", cameraIdStr.c_str());
    }

    if (!mInitialized) {
        return STATUS_ERROR(ERROR_DISCONNECTED,
                "Camera subsystem is not available");
    }

    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
    bool hasSystemCameraPermissions =
            hasPermissionsForSystemCamera(CameraThreadState::getCallingPid(),
                    CameraThreadState::getCallingUid());
    int cameraIdBound = mNumberOfCamerasWithoutSystemCamera;
    if (hasSystemCameraPermissions) {
        cameraIdBound = mNumberOfCameras;
    }
    if (cameraId < 0 || cameraId >= cameraIdBound) {
        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT,
                "CameraId is not valid");
    }

    Status ret = Status::ok();
    status_t err = mCameraProviderManager->getCameraInfo(
            cameraIdIntToStrLocked(cameraId), cameraInfo);
            cameraIdStr.c_str(), cameraInfo);
    if (err != OK) {
        ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                "Error retrieving camera info from device %d: %s (%d)", cameraId,
@@ -493,13 +542,20 @@ Status CameraService::getCameraInfo(int cameraId,
}

std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(mNormalDeviceIds.size())) {
    const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
    auto callingPid = CameraThreadState::getCallingPid();
    auto callingUid = CameraThreadState::getCallingUid();
    if (checkPermission(sSystemCameraPermission, callingPid, callingUid) ||
            getpid() == callingPid) {
        deviceIds = &mNormalDeviceIds;
    }
    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(deviceIds->size())) {
        ALOGE("%s: input id %d invalid: valid range  (0, %zu)",
                __FUNCTION__, cameraIdInt, mNormalDeviceIds.size());
                __FUNCTION__, cameraIdInt, deviceIds->size());
        return std::string{};
    }

    return mNormalDeviceIds[cameraIdInt];
    return (*deviceIds)[cameraIdInt];
}

String8 CameraService::cameraIdIntToStr(int cameraIdInt) {
@@ -1348,11 +1404,6 @@ Status CameraService::connectLegacy(
    return ret;
}

static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
    return checkPermission(sSystemCameraPermission, callingPid, callingUid) &&
            checkPermission(sCameraPermission, callingPid, callingUid);
}

bool CameraService::shouldSkipStatusUpdates(const String8& cameraId, bool isVendorListener,
        int clientPid, int clientUid) const {
    SystemCameraKind systemCameraKind = getSystemCameraKind(cameraId);
@@ -3151,6 +3202,8 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
    dprintf(fd, "\n== Service global info: ==\n\n");
    dprintf(fd, "Number of camera devices: %d\n", mNumberOfCameras);
    dprintf(fd, "Number of normal camera devices: %zu\n", mNormalDeviceIds.size());
    dprintf(fd, "Number of public camera devices visible to API1: %zu\n",
            mNormalDeviceIdsWithoutSystemCamera.size());
    for (size_t i = 0; i < mNormalDeviceIds.size(); i++) {
        dprintf(fd, "    Device %zu maps to \"%s\"\n", i, mNormalDeviceIds[i].c_str());
    }
+12 −0
Original line number Diff line number Diff line
@@ -667,6 +667,13 @@ private:
        return mCameraProviderManager->getSystemCameraKind(cameraId.c_str());
    }

    // Update the set of API1Compatible camera devices without including system
    // cameras and secure cameras. This is used for hiding system only cameras
    // from clients using camera1 api and not having android.permission.SYSTEM_CAMERA.
    // This function expects @param normalDeviceIds, to have normalDeviceIds
    // sorted in alpha-numeric order.
    void filterAPI1SystemCameraLocked(const std::vector<std::string> &normalDeviceIds);

    // Single implementation shared between the various connect calls
    template<class CALLBACK, class CLIENT>
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
@@ -821,9 +828,14 @@ private:
     */
    void updateCameraNumAndIds();

    // Number of camera devices (excluding hidden secure cameras)
    int                 mNumberOfCameras;
    // Number of camera devices (excluding hidden secure cameras and
    // system cameras)
    int                 mNumberOfCamerasWithoutSystemCamera;

    std::vector<std::string> mNormalDeviceIds;
    std::vector<std::string> mNormalDeviceIdsWithoutSystemCamera;

    // sounds
    sp<MediaPlayer>     newMediaPlayer(const char *file);
+49 −11
Original line number Diff line number Diff line
@@ -104,13 +104,25 @@ status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListe
    return OK;
}

int CameraProviderManager::getCameraCount() const {
std::pair<int, int> CameraProviderManager::getCameraCount() const {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    int count = 0;
    int systemCameraCount = 0;
    int publicCameraCount = 0;
    for (auto& provider : mProviders) {
        count += provider->mUniqueCameraIds.size();
        for (auto &id : provider->mUniqueCameraIds) {
            switch(getSystemCameraKindLocked(id)) {
                case SystemCameraKind::PUBLIC:
                    publicCameraCount++;
                    break;
                case SystemCameraKind::SYSTEM_ONLY_CAMERA:
                    systemCameraCount++;
                    break;
                default:
                    break;
            }
    return count;
        }
    }
    return std::make_pair(systemCameraCount, publicCameraCount);
}

std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
@@ -124,21 +136,38 @@ std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
    return deviceIds;
}

void CameraProviderManager::collectDeviceIdsLocked(const std::vector<std::string> deviceIds,
        std::vector<std::string>& publicDeviceIds,
        std::vector<std::string>& systemDeviceIds) const {
    for (auto &deviceId : deviceIds) {
        if (getSystemCameraKindLocked(deviceId) == SystemCameraKind::SYSTEM_ONLY_CAMERA) {
            systemDeviceIds.push_back(deviceId);
        } else {
            publicDeviceIds.push_back(deviceId);
        }
    }
}

std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    std::vector<std::string> publicDeviceIds;
    std::vector<std::string> systemDeviceIds;
    std::vector<std::string> deviceIds;
    for (auto& provider : mProviders) {
        std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;

        // Secure cameras should not be exposed through camera 1 api
        providerDeviceIds.erase(std::remove_if(providerDeviceIds.begin(), providerDeviceIds.end(),
                [this](const std::string& s) {
                bool rem = this->getSystemCameraKindLocked(s) ==
                        SystemCameraKind::HIDDEN_SECURE_CAMERA;
                return rem;}), providerDeviceIds.end());
        // API1 app doesn't handle logical and physical camera devices well. So
        // for each camera facing, only take the first id advertised by HAL in
        // all [logical, physical1, physical2, ...] id combos, and filter out the rest.
        filterLogicalCameraIdsLocked(providerDeviceIds);

        deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
        collectDeviceIdsLocked(providerDeviceIds, publicDeviceIds, systemDeviceIds);
    }

    std::sort(deviceIds.begin(), deviceIds.end(),
    auto sortFunc =
            [](const std::string& a, const std::string& b) -> bool {
                uint32_t aUint = 0, bUint = 0;
                bool aIsUint = base::ParseUint(a, &aUint);
@@ -154,7 +183,13 @@ std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds
                }
                // Simple string compare if both id are not uint
                return a < b;
            });
            };
    // We put device ids for system cameras at the end since they will be pared
    // off for processes not having system camera permissions.
    std::sort(publicDeviceIds.begin(), publicDeviceIds.end(), sortFunc);
    std::sort(systemDeviceIds.begin(), systemDeviceIds.end(), sortFunc);
    deviceIds.insert(deviceIds.end(), publicDeviceIds.begin(), publicDeviceIds.end());
    deviceIds.insert(deviceIds.end(), systemDeviceIds.begin(), systemDeviceIds.end());
    return deviceIds;
}

@@ -1054,9 +1089,12 @@ bool CameraProviderManager::isLogicalCamera(const std::string& id,
    return deviceInfo->mIsLogicalCamera;
}

SystemCameraKind CameraProviderManager::getSystemCameraKind(const std::string& id) {
SystemCameraKind CameraProviderManager::getSystemCameraKind(const std::string& id) const {
    std::lock_guard<std::mutex> lock(mInterfaceMutex);
    return getSystemCameraKindLocked(id);
}

SystemCameraKind CameraProviderManager::getSystemCameraKindLocked(const std::string& id) const {
    auto deviceInfo = findDeviceInfoLocked(id);
    if (deviceInfo == nullptr) {
        return SystemCameraKind::PUBLIC;
+10 −4
Original line number Diff line number Diff line
@@ -152,10 +152,10 @@ public:
            ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);

    /**
     * Retrieve the total number of available cameras. This value may change dynamically as cameras
     * are added or removed.
     * Retrieve the total number of available cameras.
     * This value may change dynamically as cameras are added or removed.
     */
    int getCameraCount() const;
    std::pair<int, int> getCameraCount() const;

    std::vector<std::string> getCameraDeviceIds() const;

@@ -292,7 +292,7 @@ public:
     */
    bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);

    SystemCameraKind getSystemCameraKind(const std::string& id);
    SystemCameraKind getSystemCameraKind(const std::string& id) const;
    bool isHiddenPhysicalCamera(const std::string& cameraId);

    static const float kDepthARTolerance;
@@ -615,6 +615,12 @@ private:
    status_t getCameraCharacteristicsLocked(const std::string &id,
            CameraMetadata* characteristics) const;
    void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;

    SystemCameraKind getSystemCameraKindLocked(const std::string& id) const;

    void collectDeviceIdsLocked(const std::vector<std::string> deviceIds,
            std::vector<std::string>& normalDeviceIds,
            std::vector<std::string>& systemCameraDeviceIds) const;
};

} // namespace android