/* ** ** Copyright 2015, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H #include #include #include #include #include #include #include #include #include #include namespace android { class DeathNotifier; class ResourceManagerService; class ResourceObserverService; class ServiceLog; struct ProcessInfoInterface; using Status = ::ndk::ScopedAStatus; using ::aidl::android::media::IResourceManagerClient; using ::aidl::android::media::BnResourceManagerService; using ::aidl::android::media::MediaResourceParcel; using ::aidl::android::media::MediaResourcePolicyParcel; typedef std::map>, MediaResourceParcel> ResourceList; struct ResourceInfo { int64_t clientId; uid_t uid; std::shared_ptr client; uintptr_t cookie{0}; ResourceList resources; bool pendingRemoval{false}; }; // TODO: convert these to std::map typedef KeyedVector ResourceInfos; typedef KeyedVector PidResourceInfosMap; class ResourceManagerService : public BnResourceManagerService { public: struct SystemCallbackInterface : public RefBase { virtual void noteStartVideo(int uid) = 0; virtual void noteStopVideo(int uid) = 0; virtual void noteResetVideo() = 0; virtual bool requestCpusetBoost(bool enable) = 0; }; static char const *getServiceName() { return "media.resource_manager"; } static void instantiate(); virtual inline binder_status_t dump( int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/); ResourceManagerService(); explicit ResourceManagerService(const sp &processInfo, const sp &systemResource); virtual ~ResourceManagerService(); void setObserverService(const std::shared_ptr& observerService); // IResourceManagerService interface Status config(const std::vector& policies) override; Status addResource(int32_t pid, int32_t uid, int64_t clientId, const std::shared_ptr& client, const std::vector& resources) override; Status removeResource(int32_t pid, int64_t clientId, const std::vector& resources) override; Status removeClient(int32_t pid, int64_t clientId) override; // 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& resources, bool* _aidl_return) override; Status overridePid(int originalPid, int newPid) override; Status overrideProcessInfo(const std::shared_ptr& client, int pid, int procState, int oomScore) override; Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override; Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override; Status removeResource(int pid, int64_t clientId, bool checkValid); private: friend class ResourceManagerServiceTest; friend class DeathNotifier; friend class OverrideProcessInfoDeathNotifier; // Reclaims resources from |clients|. Returns true if reclaim succeeded // for all clients. bool reclaimUnconditionallyFrom(const Vector> &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, MediaResource::SubType subType, Vector> *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, MediaResource::SubType subType, std::shared_ptr *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, MediaResource::SubType subType, int *pid, int *priority); // Gets the client who owns biggest piece of specified resource type from pid. // 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 *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 *client); bool isCallingPriorityHigher_l(int callingPid, int pid); // A helper function basically calls getLowestPriorityBiggestClient_l and add // the result client to the given Vector. void getClientForResource_l(int callingPid, const MediaResourceParcel *res, Vector> *clients); void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo); void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo); // Merge r2 into r1 void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2); // Get priority from process's pid bool getPriority_l(int pid, int* priority); void removeProcessInfoOverride(int pid); void removeProcessInfoOverride_l(int pid); uintptr_t addCookieAndLink_l(const std::shared_ptr& client, const sp& notifier); void removeCookieAndUnlink_l(const std::shared_ptr& client, uintptr_t cookie); mutable Mutex mLock; sp mProcessInfo; sp mSystemCB; sp mServiceLog; PidResourceInfosMap mMap; bool mSupportsMultipleSecureCodecs; bool mSupportsSecureWithNonSecureCodec; int32_t mCpuBoostCount; ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient; struct ProcessInfoOverride { uintptr_t cookie; std::shared_ptr client; }; std::map mOverridePidMap; std::map mProcessInfoOverrideMap; static std::mutex sCookieLock; static uintptr_t sCookieCounter GUARDED_BY(sCookieLock); static std::map > sCookieToDeathNotifierMap GUARDED_BY(sCookieLock); std::shared_ptr mObserverService; }; // ---------------------------------------------------------------------------- } // namespace android #endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H