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

Commit 464b5e34 authored by Jayant Chowdhary's avatar Jayant Chowdhary Committed by Automerger Merge Worker
Browse files

Merge "cameraserver: Allow clients to specify lower oom scores for camera...

Merge "cameraserver: Allow clients to specify lower oom scores for camera arbitration." into sc-dev am: 27c24331

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/14625405

Change-Id: Ibee80a7b38568d0a1f1810f4d5ca2f9c69a980bb
parents c526408f 27c24331
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -92,7 +92,7 @@ interface ICameraService
            String cameraId,
            String cameraId,
            String opPackageName,
            String opPackageName,
            @nullable String featureId,
            @nullable String featureId,
            int clientUid);
            int clientUid, int oomScoreOffset);


    /**
    /**
     * Add listener for changes to camera device and flashlight state.
     * Add listener for changes to camera device and flashlight state.
+1 −1
Original line number Original line Diff line number Diff line
@@ -739,7 +739,7 @@ ACameraManager::openCamera(
    // Send a zero length package name and let camera service figure it out from UID
    // Send a zero length package name and let camera service figure it out from UID
    binder::Status serviceRet = cs->connectDevice(
    binder::Status serviceRet = cs->connectDevice(
            callbacks, String16(cameraId), String16(""), {},
            callbacks, String16(cameraId), String16(""), {},
            hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
            hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0, /*out*/&deviceRemote);


    if (!serviceRet.isOk()) {
    if (!serviceRet.isOk()) {
        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
+2 −2
Original line number Original line Diff line number Diff line
@@ -378,7 +378,7 @@ TEST(CameraServiceBinderTest, CheckBinderCameraService) {
        sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
        sp<TestCameraDeviceCallbacks> callbacks(new TestCameraDeviceCallbacks());
        sp<hardware::camera2::ICameraDeviceUser> device;
        sp<hardware::camera2::ICameraDeviceUser> device;
        res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
        res = service->connectDevice(callbacks, cameraId, String16("meeeeeeeee!"),
                {}, hardware::ICameraService::USE_CALLING_UID,
                {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
                /*out*/&device);
                /*out*/&device);
        EXPECT_TRUE(res.isOk()) << res;
        EXPECT_TRUE(res.isOk()) << res;
        ASSERT_NE(nullptr, device.get());
        ASSERT_NE(nullptr, device.get());
@@ -421,7 +421,7 @@ protected:
        {
        {
            SCOPED_TRACE("openNewDevice");
            SCOPED_TRACE("openNewDevice");
            binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
            binder::Status res = service->connectDevice(callbacks, deviceId, String16("meeeeeeeee!"),
                    {}, hardware::ICameraService::USE_CALLING_UID,
                    {}, hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/ 0,
                    /*out*/&device);
                    /*out*/&device);
            EXPECT_TRUE(res.isOk()) << res;
            EXPECT_TRUE(res.isOk()) << res;
        }
        }
+54 −22
Original line number Original line Diff line number Diff line
@@ -945,7 +945,7 @@ Status CameraService::initializeShimMetadata(int cameraId) {
    if (!(ret = connectHelper<ICameraClient,Client>(
    if (!(ret = connectHelper<ICameraClient,Client>(
            sp<ICameraClient>{nullptr}, id, cameraId,
            sp<ICameraClient>{nullptr}, id, cameraId,
            internalPackageName, {}, uid, USE_CALLING_PID,
            internalPackageName, {}, uid, USE_CALLING_PID,
            API_1, /*shimUpdateOnly*/ true, /*out*/ tmp)
            API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0, /*out*/ tmp)
            ).isOk()) {
            ).isOk()) {
        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().string());
    }
    }
@@ -1217,10 +1217,12 @@ status_t CameraService::checkIfDeviceIsUsable(const String8& cameraId) const {
}
}


void CameraService::finishConnectLocked(const sp<BasicClient>& client,
void CameraService::finishConnectLocked(const sp<BasicClient>& client,
        const CameraService::DescriptorPtr& desc) {
        const CameraService::DescriptorPtr& desc, int oomScoreOffset) {


    // Make a descriptor for the incoming client
    // Make a descriptor for the incoming client
    auto clientDescriptor = CameraService::CameraClientManager::makeClientDescriptor(client, desc);
    auto clientDescriptor =
            CameraService::CameraClientManager::makeClientDescriptor(client, desc,
                    oomScoreOffset);
    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);
    auto evicted = mActiveClientManager.addAndEvict(clientDescriptor);


    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
    logConnected(desc->getKey(), static_cast<int>(desc->getOwnerId()),
@@ -1250,6 +1252,7 @@ void CameraService::finishConnectLocked(const sp<BasicClient>& client,


status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid,
        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
        int oomScoreOffset,
        /*out*/
        /*out*/
        sp<BasicClient>* client,
        sp<BasicClient>* client,
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) {
@@ -1301,7 +1304,8 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
        for (size_t i = 0; i < ownerPids.size() - 1; i++) {
            pidToPriorityMap.emplace(ownerPids[i],
            pidToPriorityMap.emplace(ownerPids[i],
                    resource_policy::ClientPriority(priorityScores[i], states[i],
                    resource_policy::ClientPriority(priorityScores[i], states[i],
                            /* isVendorClient won't get copied over*/ false));
                            /* isVendorClient won't get copied over*/ false,
                            /* oomScoreOffset won't get copied over*/ 0));
        }
        }
        mActiveClientManager.updatePriorities(pidToPriorityMap);
        mActiveClientManager.updatePriorities(pidToPriorityMap);


@@ -1314,13 +1318,16 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien
            return BAD_VALUE;
            return BAD_VALUE;
        }
        }


        // Make descriptor for incoming client
        int32_t actualScore = priorityScores[priorityScores.size() - 1];
        int32_t actualState = states[states.size() - 1];

        // Make descriptor for incoming client. We store the oomScoreOffset
        // since we might need it later on new handleEvictionsLocked and
        // ProcessInfoService would not take that into account.
        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
        clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId,
                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
                sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()),
                state->getConflicting(),
                state->getConflicting(), actualScore, clientPid, actualState,
                priorityScores[priorityScores.size() - 1],
                oomScoreOffset);
                clientPid,
                states[states.size() - 1]);


        resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();
        resource_policy::ClientPriority clientPriority = clientDescriptor->getPriority();


@@ -1463,7 +1470,7 @@ Status CameraService::connect(
    sp<Client> client = nullptr;
    sp<Client> client = nullptr;
    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
    ret = connectHelper<ICameraClient,Client>(cameraClient, id, api1CameraId,
            clientPackageName, {}, clientUid, clientPid, API_1,
            clientPackageName, {}, clientUid, clientPid, API_1,
            /*shimUpdateOnly*/ false, /*out*/client);
            /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, /*out*/client);


    if(!ret.isOk()) {
    if(!ret.isOk()) {
        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageName),
@@ -1539,7 +1546,7 @@ Status CameraService::connectDevice(
        const String16& cameraId,
        const String16& cameraId,
        const String16& clientPackageName,
        const String16& clientPackageName,
        const std::optional<String16>& clientFeatureId,
        const std::optional<String16>& clientFeatureId,
        int clientUid,
        int clientUid, int oomScoreOffset,
        /*out*/
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {
        sp<hardware::camera2::ICameraDeviceUser>* device) {


@@ -1548,19 +1555,41 @@ Status CameraService::connectDevice(
    String8 id = String8(cameraId);
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    sp<CameraDeviceClient> client = nullptr;
    String16 clientPackageNameAdj = clientPackageName;
    String16 clientPackageNameAdj = clientPackageName;
    int callingPid = CameraThreadState::getCallingPid();


    if (getCurrentServingCall() == BinderCallType::HWBINDER) {
    if (getCurrentServingCall() == BinderCallType::HWBINDER) {
        std::string vendorClient =
        std::string vendorClient =
                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
        clientPackageNameAdj = String16(vendorClient.c_str());
        clientPackageNameAdj = String16(vendorClient.c_str());
    }
    }

    if (oomScoreOffset < 0) {
        String8 msg =
                String8::format("Cannot increase the priority of a client %s pid %d for "
                        "camera id %s", String8(clientPackageNameAdj).string(), callingPid,
                        id.string());
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
    }

    // enforce system camera permissions
    if (oomScoreOffset > 0 &&
            !hasPermissionsForSystemCamera(callingPid, CameraThreadState::getCallingUid())) {
        String8 msg =
                String8::format("Cannot change the priority of a client %s pid %d for "
                        "camera id %s without SYSTEM_CAMERA permissions",
                        String8(clientPackageNameAdj).string(), callingPid, id.string());
        ALOGE("%s: %s", __FUNCTION__, msg.string());
        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.string());
    }

    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            /*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
            /*api1CameraId*/-1, clientPackageNameAdj, clientFeatureId,
            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);
            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, oomScoreOffset,
            /*out*/client);


    if(!ret.isOk()) {
    if(!ret.isOk()) {
        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
        logRejected(id, callingPid, String8(clientPackageNameAdj), ret.toString8());
                ret.toString8());
        return ret;
        return ret;
    }
    }


@@ -1572,7 +1601,7 @@ template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, const String16& clientPackageName,
        int api1CameraId, const String16& clientPackageName,
        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
        const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool shimUpdateOnly,
        apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset,
        /*out*/sp<CLIENT>& device) {
        /*out*/sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();
    binder::Status ret = binder::Status::ok();


@@ -1623,7 +1652,7 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
        sp<BasicClient> clientTmp = nullptr;
        sp<BasicClient> clientTmp = nullptr;
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
                IInterface::asBinder(cameraCb), clientName8, oomScoreOffset, /*out*/&clientTmp,
                /*out*/&partial)) != NO_ERROR) {
                /*out*/&partial)) != NO_ERROR) {
            switch (err) {
            switch (err) {
                case -ENODEV:
                case -ENODEV:
@@ -1741,7 +1770,7 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&
            mServiceLock.lock();
            mServiceLock.lock();
        } else {
        } else {
            // Otherwise, add client to active clients list
            // Otherwise, add client to active clients list
            finishConnectLocked(client, partial);
            finishConnectLocked(client, partial, oomScoreOffset);
        }
        }


        client->setImageDumpMask(mImageDumpMask);
        client->setImageDumpMask(mImageDumpMask);
@@ -1788,7 +1817,8 @@ status_t CameraService::addOfflineClient(String8 cameraId, sp<BasicClient> offli
        auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
        auto offlineClientDesc = CameraClientManager::makeClientDescriptor(
                kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
                kOfflineDevice + onlineClientDesc->getKey(), offlineClient, /*cost*/ 0,
                /*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
                /*conflictingKeys*/ std::set<String8>(), onlinePriority.getScore(),
                onlineClientDesc->getOwnerId(), onlinePriority.getState());
                onlineClientDesc->getOwnerId(), onlinePriority.getState(),
                /*ommScoreOffset*/ 0);


        // Allow only one offline device per camera
        // Allow only one offline device per camera
        auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
        auto incompatibleClients = mActiveClientManager.getIncompatibleClients(offlineClientDesc);
@@ -3662,21 +3692,23 @@ String8 CameraService::CameraClientManager::toString() const {
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
        const String8& key, const sp<BasicClient>& value, int32_t cost,
        const String8& key, const sp<BasicClient>& value, int32_t cost,
        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
        const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId,
        int32_t state) {
        int32_t state, int32_t oomScoreOffset) {


    bool isVendorClient = getCurrentServingCall() == BinderCallType::HWBINDER;
    bool isVendorClient = getCurrentServingCall() == BinderCallType::HWBINDER;
    int32_t score_adj = isVendorClient ? kVendorClientScore : score;
    int32_t score_adj = isVendorClient ? kVendorClientScore : score;
    int32_t state_adj = isVendorClient ? kVendorClientState: state;
    int32_t state_adj = isVendorClient ? kVendorClientState: state;


    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
    return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>(
            key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient);
            key, value, cost, conflictingKeys, score_adj, ownerId, state_adj, isVendorClient,
            oomScoreOffset);
}
}


CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor(
        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) {
        const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial,
        int32_t oomScoreOffset) {
    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
    return makeClientDescriptor(partial->getKey(), value, partial->getCost(),
            partial->getConflicting(), partial->getPriority().getScore(),
            partial->getConflicting(), partial->getPriority().getScore(),
            partial->getOwnerId(), partial->getPriority().getState());
            partial->getOwnerId(), partial->getPriority().getState(), oomScoreOffset);
}
}


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
+8 −5
Original line number Original line Diff line number Diff line
@@ -138,7 +138,7 @@ public:
    virtual binder::Status     connectDevice(
    virtual binder::Status     connectDevice(
            const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
            const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb, const String16& cameraId,
            const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
            const String16& clientPackageName, const std::optional<String16>& clientFeatureId,
            int32_t clientUid,
            int32_t clientUid, int scoreOffset,
            /*out*/
            /*out*/
            sp<hardware::camera2::ICameraDeviceUser>* device);
            sp<hardware::camera2::ICameraDeviceUser>* device);


@@ -510,14 +510,14 @@ public:
         */
         */
        static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
        static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value,
                int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
                int32_t cost, const std::set<String8>& conflictingKeys, int32_t score,
                int32_t ownerId, int32_t state);
                int32_t ownerId, int32_t state, int oomScoreOffset);


        /**
        /**
         * Make a ClientDescriptor object wrapping the given BasicClient strong pointer with
         * Make a ClientDescriptor object wrapping the given BasicClient strong pointer with
         * values intialized from a prior ClientDescriptor.
         * values intialized from a prior ClientDescriptor.
         */
         */
        static DescriptorPtr makeClientDescriptor(const sp<BasicClient>& value,
        static DescriptorPtr makeClientDescriptor(const sp<BasicClient>& value,
                const CameraService::DescriptorPtr& partial);
                const CameraService::DescriptorPtr& partial, int oomScoreOffset);


    }; // class CameraClientManager
    }; // class CameraClientManager


@@ -739,6 +739,7 @@ private:
    // Only call with with mServiceLock held.
    // Only call with with mServiceLock held.
    status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
    status_t handleEvictionsLocked(const String8& cameraId, int clientPid,
        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
        apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName,
        int scoreOffset,
        /*out*/
        /*out*/
        sp<BasicClient>* client,
        sp<BasicClient>* client,
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial);
@@ -772,7 +773,8 @@ private:
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
            int api1CameraId, const String16& clientPackageName,
            int api1CameraId, const String16& clientPackageName,
            const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
            const std::optional<String16>& clientFeatureId, int clientUid, int clientPid,
            apiLevel effectiveApiLevel, bool shimUpdateOnly, /*out*/sp<CLIENT>& device);
            apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset,
            /*out*/sp<CLIENT>& device);


    // Lock guarding camera service state
    // Lock guarding camera service state
    Mutex               mServiceLock;
    Mutex               mServiceLock;
@@ -831,7 +833,8 @@ private:
     *
     *
     * This method must be called with mServiceLock held.
     * This method must be called with mServiceLock held.
     */
     */
    void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc);
    void finishConnectLocked(const sp<BasicClient>& client, const DescriptorPtr& desc,
            int oomScoreOffset);


    /**
    /**
     * Returns the underlying camera Id string mapped to a camera id int
     * Returns the underlying camera Id string mapped to a camera id int
Loading