Loading media/libmedia/include/media/MediaResource.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ inline static const char *asString(MediaResource::SubType i, const char *def = " case MediaResource::SubType::kUnspecifiedSubType: return "unspecified"; case MediaResource::SubType::kAudioCodec: return "audio-codec"; case MediaResource::SubType::kVideoCodec: return "video-codec"; case MediaResource::SubType::kImageCodec: return "image-codec"; default: return def; } } Loading services/mediaresourcemanager/IMediaResourceMonitor.h +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public: enum { TYPE_VIDEO_CODEC = 0, TYPE_AUDIO_CODEC = 1, TYPE_IMAGE_CODEC = 2, }; virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0; Loading services/mediaresourcemanager/ResourceManagerService.cpp +131 −89 Original line number Diff line number Diff line Loading @@ -51,8 +51,8 @@ std::map<uintptr_t, sp<DeathNotifier> > ResourceManagerService::sCookieToDeathNo class DeathNotifier : public RefBase { public: DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid, int64_t clientId); DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid, int64_t clientId); virtual ~DeathNotifier() {} Loading Loading @@ -130,27 +130,48 @@ static String8 getString(const std::vector<T> &items) { return itemsStr; } static bool hasResourceType(MediaResource::Type type, const ResourceList& resources) { static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, MediaResourceParcel resource) { if (type != resource.type) { return false; } switch (type) { // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so // compare the subtypes as well. case MediaResource::Type::kSecureCodec: case MediaResource::Type::kNonSecureCodec: if (resource.subType == subType) { return true; } break; // Non-codec resources are not segregated by the subtype (e.g. video vs. audio). default: return true; } return false; } static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, const ResourceList& resources) { for (auto it = resources.begin(); it != resources.end(); it++) { if (it->second.type == type) { if (hasResourceType(type, subType, it->second)) { return true; } } return false; } static bool hasResourceType(MediaResource::Type type, const ResourceInfos& infos) { static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, const ResourceInfos& infos) { for (size_t i = 0; i < infos.size(); ++i) { if (hasResourceType(type, infos[i].resources)) { if (hasResourceType(type, subType, infos[i].resources)) { return true; } } return false; } static ResourceInfos& getResourceInfosForEdit( int pid, PidResourceInfosMap& map) { static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) { ssize_t index = map.indexOfKey(pid); if (index < 0) { // new pid Loading @@ -161,11 +182,8 @@ static ResourceInfos& getResourceInfosForEdit( return map.editValueFor(pid); } static ResourceInfo& getResourceInfoForEdit( uid_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) { static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) { ssize_t index = infos.indexOfKey(clientId); if (index < 0) { Loading @@ -188,17 +206,24 @@ static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel if (binder != NULL) { sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder); for (size_t i = 0; i < resources.size(); ++i) { if (resources[i].subType == MediaResource::SubType::kAudioCodec) { switch (resources[i].subType) { case MediaResource::SubType::kAudioCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC); } else if (resources[i].subType == MediaResource::SubType::kVideoCodec) { break; case MediaResource::SubType::kVideoCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC); break; case MediaResource::SubType::kImageCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC); break; case MediaResource::SubType::kUnspecifiedSubType: break; } } } } binder_status_t ResourceManagerService::dump( int fd, const char** /*args*/, uint32_t /*numArgs*/) { binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) { String8 result; if (checkCallingPermission(String16("android.permission.DUMP")) == false) { Loading Loading @@ -275,8 +300,7 @@ binder_status_t ResourceManagerService::dump( return OK; } struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { SystemCallbackImpl() : mClientToken(new BBinder()) {} virtual void noteStartVideo(int uid) override { Loading @@ -303,8 +327,7 @@ private: ResourceManagerService::ResourceManagerService() : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {} ResourceManagerService::ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, ResourceManagerService::ResourceManagerService(const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource) : mProcessInfo(processInfo), mSystemCB(systemResource), Loading Loading @@ -362,8 +385,8 @@ Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParce return Status::ok(); } void ResourceManagerService::onFirstAdded( const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { // first time added if (resource.type == MediaResource::Type::kCpuBoost && resource.subType == MediaResource::SubType::kUnspecifiedSubType) { Loading @@ -380,8 +403,8 @@ void ResourceManagerService::onFirstAdded( } } void ResourceManagerService::onLastRemoved( const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { if (resource.type == MediaResource::Type::kCpuBoost && resource.subType == MediaResource::SubType::kUnspecifiedSubType && mCpuBoostCount > 0) { Loading @@ -394,8 +417,8 @@ void ResourceManagerService::onLastRemoved( } } void ResourceManagerService::mergeResources( MediaResourceParcel& r1, const MediaResourceParcel& r2) { void ResourceManagerService::mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2) { // The resource entry on record is maintained to be in [0,INT64_MAX]. // Clamp if merging in the new resource value causes it to go out of bound. // Note that the new resource value could be negative, eg.DrmSession, the Loading @@ -411,10 +434,7 @@ void ResourceManagerService::mergeResources( } } Status ResourceManagerService::addResource( int32_t pid, int32_t uid, int64_t clientId, Status ResourceManagerService::addResource(int32_t pid, int32_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, const std::vector<MediaResourceParcel>& resources) { String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)", Loading Loading @@ -473,8 +493,7 @@ Status ResourceManagerService::addResource( return Status::ok(); } Status ResourceManagerService::removeResource( int32_t pid, int64_t clientId, Status ResourceManagerService::removeResource(int32_t pid, int64_t clientId, const std::vector<MediaResourceParcel>& resources) { String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)", pid, (long long) clientId, getString(resources).string()); Loading Loading @@ -583,22 +602,19 @@ Status ResourceManagerService::removeResource(int pid, int64_t clientId, bool ch return Status::ok(); } void ResourceManagerService::getClientForResource_l( int callingPid, const MediaResourceParcel *res, void ResourceManagerService::getClientForResource_l(int callingPid, const MediaResourceParcel *res, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { if (res == NULL) { return; } std::shared_ptr<IResourceManagerClient> client; if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) { if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, &client)) { clients->push_back(client); } } Status ResourceManagerService::reclaimResource( int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) { Status ResourceManagerService::reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) { String8 log = String8::format("reclaimResource(callingPid %d, resources %s)", callingPid, getString(resources).string()); mServiceLog->add(log); Loading @@ -618,34 +634,43 @@ Status ResourceManagerService::reclaimResource( const MediaResourceParcel *graphicMemory = NULL; const MediaResourceParcel *drmSession = NULL; for (size_t i = 0; i < resources.size(); ++i) { MediaResource::Type type = resources[i].type; if (resources[i].type == MediaResource::Type::kSecureCodec) { switch (resources[i].type) { case MediaResource::Type::kSecureCodec: secureCodec = &resources[i]; } else if (type == MediaResource::Type::kNonSecureCodec) { break; case MediaResource::Type::kNonSecureCodec: nonSecureCodec = &resources[i]; } else if (type == MediaResource::Type::kGraphicMemory) { break; case MediaResource::Type::kGraphicMemory: graphicMemory = &resources[i]; } else if (type == MediaResource::Type::kDrmSession) { break; case MediaResource::Type::kDrmSession: drmSession = &resources[i]; break; default: break; } } // first pass to handle secure/non-secure codec conflict if (secureCodec != NULL) { if (!mSupportsMultipleSecureCodecs) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, secureCodec->subType, &clients)) { return Status::ok(); } } if (!mSupportsSecureWithNonSecureCodec) { if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, secureCodec->subType, &clients)) { return Status::ok(); } } } if (nonSecureCodec != NULL) { if (!mSupportsSecureWithNonSecureCodec) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, nonSecureCodec->subType, &clients)) { return Status::ok(); } } Loading Loading @@ -681,11 +706,11 @@ Status ResourceManagerService::reclaimResource( } } *_aidl_return = reclaimInternal(clients); *_aidl_return = reclaimUnconditionallyFrom(clients); return Status::ok(); } bool ResourceManagerService::reclaimInternal( bool ResourceManagerService::reclaimUnconditionallyFrom( const Vector<std::shared_ptr<IResourceManagerClient>> &clients) { if (clients.size() == 0) { return false; Loading Loading @@ -732,9 +757,7 @@ bool ResourceManagerService::reclaimInternal( return false; } Status ResourceManagerService::overridePid( int originalPid, int newPid) { Status ResourceManagerService::overridePid(int originalPid, int newPid) { String8 log = String8::format("overridePid(originalPid %d, newPid %d)", originalPid, newPid); mServiceLog->add(log); Loading Loading @@ -763,9 +786,7 @@ Status ResourceManagerService::overridePid( } Status ResourceManagerService::overrideProcessInfo( const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) { String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)", pid, procState, oomScore); Loading Loading @@ -799,8 +820,8 @@ Status ResourceManagerService::overrideProcessInfo( return Status::ok(); } uintptr_t ResourceManagerService::addCookieAndLink_l( ::ndk::SpAIBinder binder, const sp<DeathNotifier>& notifier) { uintptr_t ResourceManagerService::addCookieAndLink_l(::ndk::SpAIBinder binder, const sp<DeathNotifier>& notifier) { std::scoped_lock lock{sCookieLock}; uintptr_t cookie; Loading @@ -813,8 +834,7 @@ uintptr_t ResourceManagerService::addCookieAndLink_l( return cookie; } void ResourceManagerService::removeCookieAndUnlink_l( ::ndk::SpAIBinder binder, uintptr_t cookie) { void ResourceManagerService::removeCookieAndUnlink_l(::ndk::SpAIBinder binder, uintptr_t cookie) { std::scoped_lock lock{sCookieLock}; AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), (void*)cookie); sCookieToDeathNotifierMap.erase(cookie); Loading Loading @@ -889,16 +909,34 @@ Status ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(int32_t MediaResource::Type::kNonSecureCodec, MediaResource::Type::kGraphicMemory, MediaResource::Type::kDrmSession}) { switch (type) { // Codec resources are segregated by audio, video and image domains. case MediaResource::Type::kSecureCodec: case MediaResource::Type::kNonSecureCodec: for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec, MediaResource::SubType::kVideoCodec, MediaResource::SubType::kImageCodec}) { std::shared_ptr<IResourceManagerClient> client; if (getBiggestClient_l(pid, type, &client, true /* pendingRemovalOnly */)) { if (getBiggestClientPendingRemoval_l(pid, type, subType, &client)) { clients.add(client); continue; } } break; // Non-codec resources are shared by audio, video and image codecs (no subtype). default: std::shared_ptr<IResourceManagerClient> client; if (getBiggestClientPendingRemoval_l(pid, type, MediaResource::SubType::kUnspecifiedSubType, &client)) { clients.add(client); } break; } } } if (!clients.empty()) { reclaimInternal(clients); reclaimUnconditionallyFrom(clients); } return Status::ok(); } Loading @@ -915,14 +953,13 @@ bool ResourceManagerService::getPriority_l(int pid, int* priority) { return mProcessInfo->getPriority(newPid, priority); } bool ResourceManagerService::getAllClients_l( int callingPid, MediaResource::Type type, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { Vector<std::shared_ptr<IResourceManagerClient>> temp; for (size_t i = 0; i < mMap.size(); ++i) { ResourceInfos &infos = mMap.editValueAt(i); for (size_t j = 0; j < infos.size(); ++j) { if (hasResourceType(type, infos[j].resources)) { if (hasResourceType(type, subType, infos[j].resources)) { if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) { // some higher/equal priority process owns the resource, // this request can't be fulfilled. Loading @@ -942,8 +979,8 @@ bool ResourceManagerService::getAllClients_l( return true; } bool ResourceManagerService::getLowestPriorityBiggestClient_l( int callingPid, MediaResource::Type type, bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) { int lowestPriorityPid; int lowestPriority; Loading @@ -951,7 +988,7 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( // Before looking into other processes, check if we have clients marked for // pending removal in the same process. if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) { if (getBiggestClientPendingRemoval_l(callingPid, type, subType, client)) { return true; } if (!getPriority_l(callingPid, &callingPriority)) { Loading @@ -959,7 +996,7 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( callingPid); return false; } if (!getLowestPriorityPid_l(type, &lowestPriorityPid, &lowestPriority)) { if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) { return false; } if (lowestPriority <= callingPriority) { Loading @@ -968,14 +1005,14 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( return false; } if (!getBiggestClient_l(lowestPriorityPid, type, client)) { if (!getBiggestClient_l(lowestPriorityPid, type, subType, client)) { return false; } return true; } bool ResourceManagerService::getLowestPriorityPid_l( MediaResource::Type type, int *lowestPriorityPid, int *lowestPriority) { bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) { int pid = -1; int priority = -1; for (size_t i = 0; i < mMap.size(); ++i) { Loading @@ -983,7 +1020,7 @@ bool ResourceManagerService::getLowestPriorityPid_l( // no client on this process. continue; } if (!hasResourceType(type, mMap.valueAt(i))) { if (!hasResourceType(type, subType, mMap.valueAt(i))) { // doesn't have the requested resource type continue; } Loading Loading @@ -1021,8 +1058,13 @@ bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) return (callingPidPriority < priority); } bool ResourceManagerService::getBiggestClient_l( int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client, bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) { return getBiggestClient_l(pid, type, subType, client, true /* pendingRemovalOnly */); } bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly) { ssize_t index = mMap.indexOfKey(pid); if (index < 0) { Loading @@ -1041,7 +1083,7 @@ bool ResourceManagerService::getBiggestClient_l( } for (auto it = resources.begin(); it != resources.end(); it++) { const MediaResourceParcel &resource = it->second; if (resource.type == type) { if (hasResourceType(type, subType, resource)) { if (resource.value > largestValue) { largestValue = resource.value; clientTemp = infos[i].client; Loading @@ -1052,8 +1094,8 @@ bool ResourceManagerService::getBiggestClient_l( if (clientTemp == NULL) { ALOGE_IF(!pendingRemovalOnly, "getBiggestClient_l: can't find resource type %s for pid %d", asString(type), pid); "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d", asString(type), asString(subType), pid); return false; } Loading services/mediaresourcemanager/ResourceManagerService.h +19 −29 Original line number Diff line number Diff line Loading @@ -77,26 +77,19 @@ public: int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/); ResourceManagerService(); explicit ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, explicit ResourceManagerService(const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource); virtual ~ResourceManagerService(); void setObserverService( const std::shared_ptr<ResourceObserverService>& observerService); void setObserverService(const std::shared_ptr<ResourceObserverService>& observerService); // IResourceManagerService interface Status config(const std::vector<MediaResourcePolicyParcel>& policies) override; Status addResource( int32_t pid, int32_t uid, int64_t clientId, Status addResource(int32_t pid, int32_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, const std::vector<MediaResourceParcel>& resources) override; Status removeResource( int32_t pid, int64_t clientId, Status removeResource(int32_t pid, int64_t clientId, const std::vector<MediaResourceParcel>& resources) override; Status removeClient(int32_t pid, int64_t clientId) override; Loading @@ -104,20 +97,13 @@ public: // Tries to reclaim resource from processes with lower priority than the calling process // according to the requested resources. // Returns true if any resource has been reclaimed, otherwise returns false. Status reclaimResource( int32_t callingPid, const std::vector<MediaResourceParcel>& resources, Status reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) override; Status overridePid( int originalPid, int newPid) override; Status overridePid(int originalPid, int newPid) override; Status overrideProcessInfo( const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) override; Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) override; Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override; Loading @@ -132,30 +118,34 @@ private: // Reclaims resources from |clients|. Returns true if reclaim succeeded // for all clients. bool reclaimInternal( const Vector<std::shared_ptr<IResourceManagerClient>> &clients); bool reclaimUnconditionallyFrom(const Vector<std::shared_ptr<IResourceManagerClient>> &clients); // Gets the list of all the clients who own the specified resource type. // Returns false if any client belongs to a process with higher priority than the // calling process. The clients will remain unchanged if returns false. bool getAllClients_l(int callingPid, MediaResource::Type type, bool getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients); // Gets the client who owns specified resource type from lowest possible priority process. // Returns false if the calling process priority is not higher than the lowest process // priority. The client will remain unchanged if returns false. bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client); MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client); // Gets lowest priority process that has the specified resource type. // Returns false if failed. The output parameters will remain unchanged if failed. bool getLowestPriorityPid_l(MediaResource::Type type, int *pid, int *priority); bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType, int *pid, int *priority); // Gets the client who owns biggest piece of specified resource type from pid. // Returns false if failed. The client will remain unchanged if failed. bool getBiggestClient_l(int pid, MediaResource::Type type, // Returns false with no change to client if there are no clients holdiing resources of thisi // type. bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly = false); // Same method as above, but with pendingRemovalOnly as true. bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client); bool isCallingPriorityHigher_l(int callingPid, int pid); Loading services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,5 @@ enum MediaResourceSubType { kUnspecifiedSubType = 0, kAudioCodec = 1, kVideoCodec = 2, kImageCodec = 3, } Loading
media/libmedia/include/media/MediaResource.h +1 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ inline static const char *asString(MediaResource::SubType i, const char *def = " case MediaResource::SubType::kUnspecifiedSubType: return "unspecified"; case MediaResource::SubType::kAudioCodec: return "audio-codec"; case MediaResource::SubType::kVideoCodec: return "video-codec"; case MediaResource::SubType::kImageCodec: return "image-codec"; default: return def; } } Loading
services/mediaresourcemanager/IMediaResourceMonitor.h +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public: enum { TYPE_VIDEO_CODEC = 0, TYPE_AUDIO_CODEC = 1, TYPE_IMAGE_CODEC = 2, }; virtual void notifyResourceGranted(/*in*/ int32_t pid, /*in*/ const int32_t type) = 0; Loading
services/mediaresourcemanager/ResourceManagerService.cpp +131 −89 Original line number Diff line number Diff line Loading @@ -51,8 +51,8 @@ std::map<uintptr_t, sp<DeathNotifier> > ResourceManagerService::sCookieToDeathNo class DeathNotifier : public RefBase { public: DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid, int64_t clientId); DeathNotifier(const std::shared_ptr<ResourceManagerService> &service, int pid, int64_t clientId); virtual ~DeathNotifier() {} Loading Loading @@ -130,27 +130,48 @@ static String8 getString(const std::vector<T> &items) { return itemsStr; } static bool hasResourceType(MediaResource::Type type, const ResourceList& resources) { static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, MediaResourceParcel resource) { if (type != resource.type) { return false; } switch (type) { // Codec subtypes (e.g. video vs. audio) are each considered separate resources, so // compare the subtypes as well. case MediaResource::Type::kSecureCodec: case MediaResource::Type::kNonSecureCodec: if (resource.subType == subType) { return true; } break; // Non-codec resources are not segregated by the subtype (e.g. video vs. audio). default: return true; } return false; } static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, const ResourceList& resources) { for (auto it = resources.begin(); it != resources.end(); it++) { if (it->second.type == type) { if (hasResourceType(type, subType, it->second)) { return true; } } return false; } static bool hasResourceType(MediaResource::Type type, const ResourceInfos& infos) { static bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType, const ResourceInfos& infos) { for (size_t i = 0; i < infos.size(); ++i) { if (hasResourceType(type, infos[i].resources)) { if (hasResourceType(type, subType, infos[i].resources)) { return true; } } return false; } static ResourceInfos& getResourceInfosForEdit( int pid, PidResourceInfosMap& map) { static ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map) { ssize_t index = map.indexOfKey(pid); if (index < 0) { // new pid Loading @@ -161,11 +182,8 @@ static ResourceInfos& getResourceInfosForEdit( return map.editValueFor(pid); } static ResourceInfo& getResourceInfoForEdit( uid_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) { static ResourceInfo& getResourceInfoForEdit(uid_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, ResourceInfos& infos) { ssize_t index = infos.indexOfKey(clientId); if (index < 0) { Loading @@ -188,17 +206,24 @@ static void notifyResourceGranted(int pid, const std::vector<MediaResourceParcel if (binder != NULL) { sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder); for (size_t i = 0; i < resources.size(); ++i) { if (resources[i].subType == MediaResource::SubType::kAudioCodec) { switch (resources[i].subType) { case MediaResource::SubType::kAudioCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC); } else if (resources[i].subType == MediaResource::SubType::kVideoCodec) { break; case MediaResource::SubType::kVideoCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC); break; case MediaResource::SubType::kImageCodec: service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_IMAGE_CODEC); break; case MediaResource::SubType::kUnspecifiedSubType: break; } } } } binder_status_t ResourceManagerService::dump( int fd, const char** /*args*/, uint32_t /*numArgs*/) { binder_status_t ResourceManagerService::dump(int fd, const char** /*args*/, uint32_t /*numArgs*/) { String8 result; if (checkCallingPermission(String16("android.permission.DUMP")) == false) { Loading Loading @@ -275,8 +300,7 @@ binder_status_t ResourceManagerService::dump( return OK; } struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { struct SystemCallbackImpl : public ResourceManagerService::SystemCallbackInterface { SystemCallbackImpl() : mClientToken(new BBinder()) {} virtual void noteStartVideo(int uid) override { Loading @@ -303,8 +327,7 @@ private: ResourceManagerService::ResourceManagerService() : ResourceManagerService(new ProcessInfo(), new SystemCallbackImpl()) {} ResourceManagerService::ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, ResourceManagerService::ResourceManagerService(const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource) : mProcessInfo(processInfo), mSystemCB(systemResource), Loading Loading @@ -362,8 +385,8 @@ Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParce return Status::ok(); } void ResourceManagerService::onFirstAdded( const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { void ResourceManagerService::onFirstAdded(const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { // first time added if (resource.type == MediaResource::Type::kCpuBoost && resource.subType == MediaResource::SubType::kUnspecifiedSubType) { Loading @@ -380,8 +403,8 @@ void ResourceManagerService::onFirstAdded( } } void ResourceManagerService::onLastRemoved( const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { void ResourceManagerService::onLastRemoved(const MediaResourceParcel& resource, const ResourceInfo& clientInfo) { if (resource.type == MediaResource::Type::kCpuBoost && resource.subType == MediaResource::SubType::kUnspecifiedSubType && mCpuBoostCount > 0) { Loading @@ -394,8 +417,8 @@ void ResourceManagerService::onLastRemoved( } } void ResourceManagerService::mergeResources( MediaResourceParcel& r1, const MediaResourceParcel& r2) { void ResourceManagerService::mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2) { // The resource entry on record is maintained to be in [0,INT64_MAX]. // Clamp if merging in the new resource value causes it to go out of bound. // Note that the new resource value could be negative, eg.DrmSession, the Loading @@ -411,10 +434,7 @@ void ResourceManagerService::mergeResources( } } Status ResourceManagerService::addResource( int32_t pid, int32_t uid, int64_t clientId, Status ResourceManagerService::addResource(int32_t pid, int32_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, const std::vector<MediaResourceParcel>& resources) { String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)", Loading Loading @@ -473,8 +493,7 @@ Status ResourceManagerService::addResource( return Status::ok(); } Status ResourceManagerService::removeResource( int32_t pid, int64_t clientId, Status ResourceManagerService::removeResource(int32_t pid, int64_t clientId, const std::vector<MediaResourceParcel>& resources) { String8 log = String8::format("removeResource(pid %d, clientId %lld, resources %s)", pid, (long long) clientId, getString(resources).string()); Loading Loading @@ -583,22 +602,19 @@ Status ResourceManagerService::removeResource(int pid, int64_t clientId, bool ch return Status::ok(); } void ResourceManagerService::getClientForResource_l( int callingPid, const MediaResourceParcel *res, void ResourceManagerService::getClientForResource_l(int callingPid, const MediaResourceParcel *res, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { if (res == NULL) { return; } std::shared_ptr<IResourceManagerClient> client; if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) { if (getLowestPriorityBiggestClient_l(callingPid, res->type, res->subType, &client)) { clients->push_back(client); } } Status ResourceManagerService::reclaimResource( int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) { Status ResourceManagerService::reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) { String8 log = String8::format("reclaimResource(callingPid %d, resources %s)", callingPid, getString(resources).string()); mServiceLog->add(log); Loading @@ -618,34 +634,43 @@ Status ResourceManagerService::reclaimResource( const MediaResourceParcel *graphicMemory = NULL; const MediaResourceParcel *drmSession = NULL; for (size_t i = 0; i < resources.size(); ++i) { MediaResource::Type type = resources[i].type; if (resources[i].type == MediaResource::Type::kSecureCodec) { switch (resources[i].type) { case MediaResource::Type::kSecureCodec: secureCodec = &resources[i]; } else if (type == MediaResource::Type::kNonSecureCodec) { break; case MediaResource::Type::kNonSecureCodec: nonSecureCodec = &resources[i]; } else if (type == MediaResource::Type::kGraphicMemory) { break; case MediaResource::Type::kGraphicMemory: graphicMemory = &resources[i]; } else if (type == MediaResource::Type::kDrmSession) { break; case MediaResource::Type::kDrmSession: drmSession = &resources[i]; break; default: break; } } // first pass to handle secure/non-secure codec conflict if (secureCodec != NULL) { if (!mSupportsMultipleSecureCodecs) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, secureCodec->subType, &clients)) { return Status::ok(); } } if (!mSupportsSecureWithNonSecureCodec) { if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kNonSecureCodec, secureCodec->subType, &clients)) { return Status::ok(); } } } if (nonSecureCodec != NULL) { if (!mSupportsSecureWithNonSecureCodec) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, &clients)) { if (!getAllClients_l(callingPid, MediaResource::Type::kSecureCodec, nonSecureCodec->subType, &clients)) { return Status::ok(); } } Loading Loading @@ -681,11 +706,11 @@ Status ResourceManagerService::reclaimResource( } } *_aidl_return = reclaimInternal(clients); *_aidl_return = reclaimUnconditionallyFrom(clients); return Status::ok(); } bool ResourceManagerService::reclaimInternal( bool ResourceManagerService::reclaimUnconditionallyFrom( const Vector<std::shared_ptr<IResourceManagerClient>> &clients) { if (clients.size() == 0) { return false; Loading Loading @@ -732,9 +757,7 @@ bool ResourceManagerService::reclaimInternal( return false; } Status ResourceManagerService::overridePid( int originalPid, int newPid) { Status ResourceManagerService::overridePid(int originalPid, int newPid) { String8 log = String8::format("overridePid(originalPid %d, newPid %d)", originalPid, newPid); mServiceLog->add(log); Loading Loading @@ -763,9 +786,7 @@ Status ResourceManagerService::overridePid( } Status ResourceManagerService::overrideProcessInfo( const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) { String8 log = String8::format("overrideProcessInfo(pid %d, procState %d, oomScore %d)", pid, procState, oomScore); Loading Loading @@ -799,8 +820,8 @@ Status ResourceManagerService::overrideProcessInfo( return Status::ok(); } uintptr_t ResourceManagerService::addCookieAndLink_l( ::ndk::SpAIBinder binder, const sp<DeathNotifier>& notifier) { uintptr_t ResourceManagerService::addCookieAndLink_l(::ndk::SpAIBinder binder, const sp<DeathNotifier>& notifier) { std::scoped_lock lock{sCookieLock}; uintptr_t cookie; Loading @@ -813,8 +834,7 @@ uintptr_t ResourceManagerService::addCookieAndLink_l( return cookie; } void ResourceManagerService::removeCookieAndUnlink_l( ::ndk::SpAIBinder binder, uintptr_t cookie) { void ResourceManagerService::removeCookieAndUnlink_l(::ndk::SpAIBinder binder, uintptr_t cookie) { std::scoped_lock lock{sCookieLock}; AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), (void*)cookie); sCookieToDeathNotifierMap.erase(cookie); Loading Loading @@ -889,16 +909,34 @@ Status ResourceManagerService::reclaimResourcesFromClientsPendingRemoval(int32_t MediaResource::Type::kNonSecureCodec, MediaResource::Type::kGraphicMemory, MediaResource::Type::kDrmSession}) { switch (type) { // Codec resources are segregated by audio, video and image domains. case MediaResource::Type::kSecureCodec: case MediaResource::Type::kNonSecureCodec: for (MediaResource::SubType subType : {MediaResource::SubType::kAudioCodec, MediaResource::SubType::kVideoCodec, MediaResource::SubType::kImageCodec}) { std::shared_ptr<IResourceManagerClient> client; if (getBiggestClient_l(pid, type, &client, true /* pendingRemovalOnly */)) { if (getBiggestClientPendingRemoval_l(pid, type, subType, &client)) { clients.add(client); continue; } } break; // Non-codec resources are shared by audio, video and image codecs (no subtype). default: std::shared_ptr<IResourceManagerClient> client; if (getBiggestClientPendingRemoval_l(pid, type, MediaResource::SubType::kUnspecifiedSubType, &client)) { clients.add(client); } break; } } } if (!clients.empty()) { reclaimInternal(clients); reclaimUnconditionallyFrom(clients); } return Status::ok(); } Loading @@ -915,14 +953,13 @@ bool ResourceManagerService::getPriority_l(int pid, int* priority) { return mProcessInfo->getPriority(newPid, priority); } bool ResourceManagerService::getAllClients_l( int callingPid, MediaResource::Type type, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { bool ResourceManagerService::getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients) { Vector<std::shared_ptr<IResourceManagerClient>> temp; for (size_t i = 0; i < mMap.size(); ++i) { ResourceInfos &infos = mMap.editValueAt(i); for (size_t j = 0; j < infos.size(); ++j) { if (hasResourceType(type, infos[j].resources)) { if (hasResourceType(type, subType, infos[j].resources)) { if (!isCallingPriorityHigher_l(callingPid, mMap.keyAt(i))) { // some higher/equal priority process owns the resource, // this request can't be fulfilled. Loading @@ -942,8 +979,8 @@ bool ResourceManagerService::getAllClients_l( return true; } bool ResourceManagerService::getLowestPriorityBiggestClient_l( int callingPid, MediaResource::Type type, bool ResourceManagerService::getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) { int lowestPriorityPid; int lowestPriority; Loading @@ -951,7 +988,7 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( // Before looking into other processes, check if we have clients marked for // pending removal in the same process. if (getBiggestClient_l(callingPid, type, client, true /* pendingRemovalOnly */)) { if (getBiggestClientPendingRemoval_l(callingPid, type, subType, client)) { return true; } if (!getPriority_l(callingPid, &callingPriority)) { Loading @@ -959,7 +996,7 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( callingPid); return false; } if (!getLowestPriorityPid_l(type, &lowestPriorityPid, &lowestPriority)) { if (!getLowestPriorityPid_l(type, subType, &lowestPriorityPid, &lowestPriority)) { return false; } if (lowestPriority <= callingPriority) { Loading @@ -968,14 +1005,14 @@ bool ResourceManagerService::getLowestPriorityBiggestClient_l( return false; } if (!getBiggestClient_l(lowestPriorityPid, type, client)) { if (!getBiggestClient_l(lowestPriorityPid, type, subType, client)) { return false; } return true; } bool ResourceManagerService::getLowestPriorityPid_l( MediaResource::Type type, int *lowestPriorityPid, int *lowestPriority) { bool ResourceManagerService::getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType, int *lowestPriorityPid, int *lowestPriority) { int pid = -1; int priority = -1; for (size_t i = 0; i < mMap.size(); ++i) { Loading @@ -983,7 +1020,7 @@ bool ResourceManagerService::getLowestPriorityPid_l( // no client on this process. continue; } if (!hasResourceType(type, mMap.valueAt(i))) { if (!hasResourceType(type, subType, mMap.valueAt(i))) { // doesn't have the requested resource type continue; } Loading Loading @@ -1021,8 +1058,13 @@ bool ResourceManagerService::isCallingPriorityHigher_l(int callingPid, int pid) return (callingPidPriority < priority); } bool ResourceManagerService::getBiggestClient_l( int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client, bool ResourceManagerService::getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client) { return getBiggestClient_l(pid, type, subType, client, true /* pendingRemovalOnly */); } bool ResourceManagerService::getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly) { ssize_t index = mMap.indexOfKey(pid); if (index < 0) { Loading @@ -1041,7 +1083,7 @@ bool ResourceManagerService::getBiggestClient_l( } for (auto it = resources.begin(); it != resources.end(); it++) { const MediaResourceParcel &resource = it->second; if (resource.type == type) { if (hasResourceType(type, subType, resource)) { if (resource.value > largestValue) { largestValue = resource.value; clientTemp = infos[i].client; Loading @@ -1052,8 +1094,8 @@ bool ResourceManagerService::getBiggestClient_l( if (clientTemp == NULL) { ALOGE_IF(!pendingRemovalOnly, "getBiggestClient_l: can't find resource type %s for pid %d", asString(type), pid); "getBiggestClient_l: can't find resource type %s and subtype %s for pid %d", asString(type), asString(subType), pid); return false; } Loading
services/mediaresourcemanager/ResourceManagerService.h +19 −29 Original line number Diff line number Diff line Loading @@ -77,26 +77,19 @@ public: int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/); ResourceManagerService(); explicit ResourceManagerService( const sp<ProcessInfoInterface> &processInfo, explicit ResourceManagerService(const sp<ProcessInfoInterface> &processInfo, const sp<SystemCallbackInterface> &systemResource); virtual ~ResourceManagerService(); void setObserverService( const std::shared_ptr<ResourceObserverService>& observerService); void setObserverService(const std::shared_ptr<ResourceObserverService>& observerService); // IResourceManagerService interface Status config(const std::vector<MediaResourcePolicyParcel>& policies) override; Status addResource( int32_t pid, int32_t uid, int64_t clientId, Status addResource(int32_t pid, int32_t uid, int64_t clientId, const std::shared_ptr<IResourceManagerClient>& client, const std::vector<MediaResourceParcel>& resources) override; Status removeResource( int32_t pid, int64_t clientId, Status removeResource(int32_t pid, int64_t clientId, const std::vector<MediaResourceParcel>& resources) override; Status removeClient(int32_t pid, int64_t clientId) override; Loading @@ -104,20 +97,13 @@ public: // Tries to reclaim resource from processes with lower priority than the calling process // according to the requested resources. // Returns true if any resource has been reclaimed, otherwise returns false. Status reclaimResource( int32_t callingPid, const std::vector<MediaResourceParcel>& resources, Status reclaimResource(int32_t callingPid, const std::vector<MediaResourceParcel>& resources, bool* _aidl_return) override; Status overridePid( int originalPid, int newPid) override; Status overridePid(int originalPid, int newPid) override; Status overrideProcessInfo( const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) override; Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client, int pid, int procState, int oomScore) override; Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override; Loading @@ -132,30 +118,34 @@ private: // Reclaims resources from |clients|. Returns true if reclaim succeeded // for all clients. bool reclaimInternal( const Vector<std::shared_ptr<IResourceManagerClient>> &clients); bool reclaimUnconditionallyFrom(const Vector<std::shared_ptr<IResourceManagerClient>> &clients); // Gets the list of all the clients who own the specified resource type. // Returns false if any client belongs to a process with higher priority than the // calling process. The clients will remain unchanged if returns false. bool getAllClients_l(int callingPid, MediaResource::Type type, bool getAllClients_l(int callingPid, MediaResource::Type type, MediaResource::SubType subType, Vector<std::shared_ptr<IResourceManagerClient>> *clients); // Gets the client who owns specified resource type from lowest possible priority process. // Returns false if the calling process priority is not higher than the lowest process // priority. The client will remain unchanged if returns false. bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client); MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client); // Gets lowest priority process that has the specified resource type. // Returns false if failed. The output parameters will remain unchanged if failed. bool getLowestPriorityPid_l(MediaResource::Type type, int *pid, int *priority); bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType, int *pid, int *priority); // Gets the client who owns biggest piece of specified resource type from pid. // Returns false if failed. The client will remain unchanged if failed. bool getBiggestClient_l(int pid, MediaResource::Type type, // Returns false with no change to client if there are no clients holdiing resources of thisi // type. bool getBiggestClient_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client, bool pendingRemovalOnly = false); // Same method as above, but with pendingRemovalOnly as true. bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type, MediaResource::SubType subType, std::shared_ptr<IResourceManagerClient> *client); bool isCallingPriorityHigher_l(int callingPid, int pid); Loading
services/mediaresourcemanager/aidl/android/media/MediaResourceSubType.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,5 @@ enum MediaResourceSubType { kUnspecifiedSubType = 0, kAudioCodec = 1, kVideoCodec = 2, kImageCodec = 3, }