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

Commit 5dd97493 authored by Girish's avatar Girish
Browse files

resourcemanager: handle updated resources

Allow clients (in this case MediaCodec) to update the resources
on already added resources to ensure right amount of resources
are tracked by the resource manager service.

Bug: 399521069
Flags: EXEMPT bugfix
Test: atest android.media.misc.cts.ResourceManagerTest
      atest android.media.misc.cts.ResourceManagerMultiTest
      /data/nativetest64/ResourceManagerService_test/ResourceManagerService_test
      /data/nativetest64/ResourceObserverService_test/ResourceObserverService_test
Change-Id: I60d4406b2b7e0b12b691513119855049b82f012c
parent 61863f7e
Loading
Loading
Loading
Loading
+71 −16
Original line number Diff line number Diff line
@@ -419,6 +419,7 @@ struct MediaCodec::ResourceManagerServiceProxy :
    status_t init();
    void addResource(const MediaResourceParcel &resource);
    void addResource(const std::vector<MediaResourceParcel>& resources);
    void updateResource(const std::vector<MediaResourceParcel>& resources);
    void removeResource(const MediaResourceParcel &resource);
    void removeResource(const std::vector<MediaResourceParcel>& resources);
    void removeClient();
@@ -650,6 +651,17 @@ void MediaCodec::ResourceManagerServiceProxy::addResource(
              std::inserter(mMediaResourceParcel, mMediaResourceParcel.end()));
}

void MediaCodec::ResourceManagerServiceProxy::updateResource(
        const std::vector<MediaResourceParcel>& resources) {
    std::scoped_lock lock{mLock};
    std::shared_ptr<IResourceManagerService> service = getService_l();
    if (service == nullptr) {
        ALOGW("Service isn't available");
        return;
    }
    service->updateResource(getClientInfo(), resources);
}

void MediaCodec::ResourceManagerServiceProxy::removeResource(
        const MediaResourceParcel &resource) {
    std::vector<MediaResourceParcel> resources;
@@ -1290,20 +1302,71 @@ static float getOperatingFrameRate(const sp<AMessage>& format,
    return frameRate;
}

inline MediaResourceParcel getMediaResourceParcel(const InstanceResourceInfo& resourceInfo) {
    MediaResourceParcel resource;
    resource.type = getResourceType(resourceInfo.mName);
    resource.value = resourceInfo.mStaticCount;
    return resource;
}

void MediaCodec::updateResourceUsage(
        const std::vector<InstanceResourceInfo>& oldResources,
        const std::vector<InstanceResourceInfo>& newResources) {
    std::vector<MediaResourceParcel> resources;

    // Add all the new resources first.
    for (const InstanceResourceInfo& resource : newResources) {
        resources.push_back(getMediaResourceParcel(resource));
    }

    // Look for resources that aren't required anymore.
    for (const InstanceResourceInfo& oldRes : oldResources) {
        auto found = std::find_if(newResources.begin(),
                                  newResources.end(),
                                  [oldRes](const InstanceResourceInfo& newRes) {
                                      return oldRes.mName == newRes.mName; });

        // If this old resource isn't found in updated resources, that means its
        // not required anymore.
        // Set the count to 0, so that it will be removed from the RM.
        if (found == newResources.end()) {
            MediaResourceParcel res = getMediaResourceParcel(oldRes);
            res.value = 0;
            resources.push_back(res);
        }
    }

    // update/notify the RM about change in resource usage.
    if (!resources.empty()) {
        mResourceManagerProxy->updateResource(resources);
    }
}

bool MediaCodec::getRequiredSystemResources() {
    bool success = false;
    std::vector<InstanceResourceInfo> oldResources;
    std::vector<InstanceResourceInfo> newResources;

    if (android::media::codec::codec_availability() &&
        android::media::codec::codec_availability_support()) {
        // Get the required system resources now.
        Mutexed<std::vector<InstanceResourceInfo>>::Locked resourcesLocked(
                mRequiredResourceInfo);
        *resourcesLocked = mCodec->getRequiredSystemResources();
        // Make a copy of the previous required resources, if there were any.
        oldResources = *resourcesLocked;
        // Get the required system resources now.
        newResources = mCodec->getRequiredSystemResources();
        // Update the dynamic resource usage with the current operating frame-rate.
        *resourcesLocked = computeDynamicResources(*resourcesLocked);

        return !(*resourcesLocked).empty();
        newResources = computeDynamicResources(newResources);
        *resourcesLocked = newResources;
        success  = !newResources.empty();
    }

    return false;
    // Since the required resources has been updated/changed,
    // we should update/notify the RM with the updated usage.
    if (!oldResources.empty()) {
        updateResourceUsage(oldResources, newResources);
    }
    return success;
}

/**
@@ -4236,16 +4299,6 @@ inline void MediaCodec::initClientConfigParcel(ClientConfigParcel& clientConfig)
    clientConfig.id = mCodecId;
}

inline MediaResourceParcel getMediaResourceParcel(const InstanceResourceInfo& resourceInfo) {
    MediaResourceParcel resource;
    resource.type = getResourceType(resourceInfo.mName);
    resource.value = resourceInfo.mStaticCount;
    // TODO: How do we use this info and pass it on to RM to track?
    //resource.value = resourceInfo.mPerFrameCount;

    return resource;
}

void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
    switch (msg->what()) {
        case kWhatCodecNotify:
@@ -5024,7 +5077,9 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        for (const InstanceResourceInfo& resource : *resourcesLocked) {
                            resources.push_back(getMediaResourceParcel(resource));
                        }
                        (*resourcesLocked).clear();
                    }
                    // Notify the RM to remove those resources.
                    if (!resources.empty()) {
                        mResourceManagerProxy->removeResource(resources);
                    }
+2 −0
Original line number Diff line number Diff line
@@ -387,6 +387,8 @@ private:
    // constant resource counts.
    std::vector<InstanceResourceInfo> computeDynamicResources(
            const std::vector<InstanceResourceInfo>& resources);
    void updateResourceUsage(const std::vector<InstanceResourceInfo>& oldResources,
                             const std::vector<InstanceResourceInfo>& newResources);

private:
    enum State {
+9 −0
Original line number Diff line number Diff line
@@ -1114,6 +1114,15 @@ Status ResourceManagerService::getMediaResourceUsageReport(
    return Status::ok();
}

Status ResourceManagerService::updateResource(const ClientInfoParcel& clientInfo,
                                              const std::vector<MediaResourceParcel>& resources) {
    (void)clientInfo;
    (void)resources;

    // Not implemented
    return Status::ok();
}

long ResourceManagerService::getPeakConcurrentPixelCount(int pid) const {
    return mResourceManagerMetrics->getPeakConcurrentPixelCount(pid);
}
+3 −0
Original line number Diff line number Diff line
@@ -83,6 +83,9 @@ public:
                       const std::shared_ptr<IResourceManagerClient>& client,
                       const std::vector<MediaResourceParcel>& resources) override;

    Status updateResource(const ClientInfoParcel& clientInfo,
                          const std::vector<MediaResourceParcel>& resources) override;

    Status removeResource(const ClientInfoParcel& clientInfo,
                          const std::vector<MediaResourceParcel>& resources) override;

+17 −1
Original line number Diff line number Diff line
@@ -220,7 +220,7 @@ Status ResourceManagerServiceNew::notifyClientConfigChanged(
    {
        // Update the ResourceTracker about the change in the configuration.
        std::scoped_lock lock{mLock};
        mResourceTracker->updateResource(clientConfig.clientInfo);
        mResourceTracker->updateClientImportance(clientConfig.clientInfo);
    }
    return ResourceManagerService::notifyClientConfigChanged(clientConfig);
}
@@ -243,6 +243,22 @@ Status ResourceManagerServiceNew::getMediaResourceUsageReport(
    return Status::ok();
}

Status ResourceManagerServiceNew::updateResource(
        const ClientInfoParcel& clientInfo,
        const std::vector<MediaResourceParcel>& resources) {
    int32_t pid = clientInfo.pid;
    int32_t uid = clientInfo.uid;
    int64_t clientId = clientInfo.id;
    String8 log = String8::format("updateResource(pid %d, uid %d clientId %lld, resources %s)",
            pid, uid, (long long) clientId, getString(resources).c_str());
    mServiceLog->add(log);

    std::scoped_lock lock{mLock};
    mResourceTracker->updateResource(clientInfo, resources);

    return Status::ok();
}

void ResourceManagerServiceNew::getResourceDump(std::string& resourceLog) const {
    std::scoped_lock lock{mLock};
    mResourceTracker->dump(resourceLog);
Loading