1 /*
2 **
3 ** Copyright 2015, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
19 #define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
20 
21 #include <map>
22 #include <set>
23 #include <mutex>
24 #include <string>
25 #include <vector>
26 
27 #include <aidl/android/media/BnResourceManagerService.h>
28 #include <media/MediaResource.h>
29 #include <utils/Errors.h>
30 #include <utils/String8.h>
31 #include <utils/threads.h>
32 
33 #include "ResourceManagerServiceUtils.h"
34 
35 namespace android {
36 
37 class ResourceObserverService;
38 class ServiceLog;
39 struct ProcessInfoInterface;
40 class ResourceManagerMetrics;
41 
42 using Status = ::ndk::ScopedAStatus;
43 using ::aidl::android::media::IResourceManagerClient;
44 using ::aidl::android::media::BnResourceManagerService;
45 using ::aidl::android::media::MediaResourceParcel;
46 using ::aidl::android::media::MediaResourcePolicyParcel;
47 using ::aidl::android::media::ClientInfoParcel;
48 using ::aidl::android::media::ClientConfigParcel;
49 
50 class ResourceManagerService : public BnResourceManagerService {
51 public:
52     struct SystemCallbackInterface : public RefBase {
53         virtual void noteStartVideo(int uid) = 0;
54         virtual void noteStopVideo(int uid) = 0;
55         virtual void noteResetVideo() = 0;
56         virtual bool requestCpusetBoost(bool enable) = 0;
57     };
58 
getServiceName()59     static char const *getServiceName() { return "media.resource_manager"; }
60     static void instantiate();
61 
62         // Static creation methods.
63     static std::shared_ptr<ResourceManagerService> Create();
64     static std::shared_ptr<ResourceManagerService> Create(
65         const sp<ProcessInfoInterface>& processInfo,
66         const sp<SystemCallbackInterface>& systemResource);
67 
68     virtual binder_status_t dump(
69             int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
70 
71     ResourceManagerService();
72     explicit ResourceManagerService(const sp<ProcessInfoInterface> &processInfo,
73             const sp<SystemCallbackInterface> &systemResource);
74     virtual ~ResourceManagerService();
75 
76     virtual void setObserverService(
77             const std::shared_ptr<ResourceObserverService>& observerService);
78 
79     // IResourceManagerService interface
80     Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
81 
82     Status addResource(const ClientInfoParcel& clientInfo,
83                        const std::shared_ptr<IResourceManagerClient>& client,
84                        const std::vector<MediaResourceParcel>& resources) override;
85 
86     Status removeResource(const ClientInfoParcel& clientInfo,
87                           const std::vector<MediaResourceParcel>& resources) override;
88 
89     Status removeClient(const ClientInfoParcel& clientInfo) override;
90 
91     // Tries to reclaim resource from processes with lower priority than the calling process
92     // according to the requested resources.
93     // Returns true if any resource has been reclaimed, otherwise returns false.
94     Status reclaimResource(const ClientInfoParcel& clientInfo,
95                            const std::vector<MediaResourceParcel>& resources,
96                            bool* _aidl_return) override;
97 
98     Status overridePid(int32_t originalPid, int32_t newPid) override;
99 
100     Status overrideProcessInfo(const std::shared_ptr<IResourceManagerClient>& client,
101                                int32_t pid, int32_t procState, int32_t oomScore) override;
102 
103     Status markClientForPendingRemoval(const ClientInfoParcel& clientInfo) override;
104 
105     Status reclaimResourcesFromClientsPendingRemoval(int32_t pid) override;
106 
107     Status notifyClientCreated(const ClientInfoParcel& clientInfo) override;
108 
109     Status notifyClientStarted(const ClientConfigParcel& clientConfig) override;
110 
111     Status notifyClientStopped(const ClientConfigParcel& clientConfig) override;
112 
113     Status notifyClientConfigChanged(const ClientConfigParcel& clientConfig) override;
114 
115 protected:
116     // To get notifications when a resource is added for the first time.
117     void onFirstAdded(const MediaResourceParcel& res, uid_t uid);
118     // To get notifications when a resource has been removed at last.
119     void onLastRemoved(const MediaResourceParcel& res, uid_t uid);
120 
121     // Reclaims resources from |clients|. Returns true if reclaim succeeded
122     // for all clients.
123     bool reclaimUnconditionallyFrom(const std::vector<ClientInfo>& targetClients);
124 
125     // A helper function that returns true if the callingPid has higher priority than pid.
126     // Returns false otherwise.
127     bool isCallingPriorityHigher_l(int callingPid, int pid);
128 
129     // To notify the metrics about client being released.
130     void notifyClientReleased(const ClientInfoParcel& clientInfo);
131 
132     virtual Status removeResource(const ClientInfoParcel& clientInfo, bool checkValid);
133 
134 private:
135     friend class ResourceManagerServiceTest;
136     friend class ResourceManagerServiceTestBase;
137     friend class DeathNotifier;
138     friend class OverrideProcessInfoDeathNotifier;
139 
140     // Gets the client who owns biggest piece of specified resource type from pid.
141     // Returns false with no change to client if there are no clients holding resources of this
142     // type.
143     bool getBiggestClient_l(int pid, MediaResource::Type type,
144                             MediaResource::SubType subType,
145                             ClientInfo& clientsInfo,
146                             bool pendingRemovalOnly = false);
147 
148     // A helper function that gets the biggest clients of the process pid that
149     // is marked to be (pending) removed and has the needed resources.
150     bool getBiggestClientPendingRemoval_l(int pid, MediaResource::Type type,
151                                           MediaResource::SubType subType,
152                                           ClientInfo& clientsInfo);
153 
154     // From the list of clients, pick/select client(s) based on the reclaim policy.
155     void getClientForResource_l(const ResourceRequestInfo& resourceRequestInfo,
156                                 std::vector<ClientInfo>& clientsInfo);
157     // A helper function that pushes Reclaim Atom (for metric collection).
158     void pushReclaimAtom(const ClientInfoParcel& clientInfo,
159                          const std::vector<ClientInfo>& targetClients,
160                          bool reclaimed);
161 
162     // Remove the override info for the given process
163     void removeProcessInfoOverride_l(int pid);
164 
165     // Eventually we want to phase out this implementation of IResourceManagerService
166     // (ResourceManagerService) and replace that with the newer implementation
167     // (ResourceManagerServiceNew).
168     // So, marking the following methods as private virtual and for the newer implementation
169     // to override is the easiest way to maintain both implementation.
170 
171     // Initializes the internal state of the ResourceManagerService
172     virtual void init();
173 
174     // Gets the list of all the clients who own the list of specified resource type
175     // and satisfy the resource model and the reclaim policy.
176     virtual bool getTargetClients(
177         const ClientInfoParcel& clientInfo,
178         const std::vector<MediaResourceParcel>& resources,
179         std::vector<ClientInfo>& targetClients);
180 
181     // Gets the list of all the clients who own the specified resource type.
182     // Returns false if any client belongs to a process with higher priority than the
183     // calling process. The clients will remain unchanged if returns false.
184     virtual bool getAllClients_l(const ResourceRequestInfo& resourceRequestInfo,
185                                  std::vector<ClientInfo>& clientsInfo);
186 
187     // Gets the client who owns specified resource type from lowest possible priority process.
188     // Returns false if the calling process priority is not higher than the lowest process
189     // priority. The client will remain unchanged if returns false.
190     virtual bool getLowestPriorityBiggestClient_l(
191         const ResourceRequestInfo& resourceRequestInfo,
192         ClientInfo& clientInfo);
193 
194     // override the pid of given process
195     virtual bool overridePid_l(int32_t originalPid, int32_t newPid);
196 
197     // override the process info of given process
198     virtual bool overrideProcessInfo_l(const std::shared_ptr<IResourceManagerClient>& client,
199                                        int pid, int procState, int oomScore);
200 
201     // Get priority from process's pid
202     virtual bool getPriority_l(int pid, int* priority) const;
203 
204     // Gets lowest priority process that has the specified resource type.
205     // Returns false if failed. The output parameters will remain unchanged if failed.
206     virtual bool getLowestPriorityPid_l(MediaResource::Type type, MediaResource::SubType subType,
207                                         int* lowestPriorityPid, int* lowestPriority);
208 
209     // Removes the pid from the override map.
210     virtual void removeProcessInfoOverride(int pid);
211 
212     // Get the client for given pid and the clientId from the map
213     virtual std::shared_ptr<IResourceManagerClient> getClient_l(
214         int pid, const int64_t& clientId) const;
215 
216     // Remove the client for given pid and the clientId from the map
217     virtual bool removeClient_l(int pid, const int64_t& clientId);
218 
219     // Get all the resource status for dump
220     virtual void getResourceDump(std::string& resourceLog) const;
221 
222     // The following utility functions are used only for testing by ResourceManagerServiceTest
223     // START: TEST only functions
224     // Get the peak concurrent pixel count (associated with the video codecs) for the process.
225     long getPeakConcurrentPixelCount(int pid) const;
226     // Get the current concurrent pixel count (associated with the video codecs) for the process.
227     long getCurrentConcurrentPixelCount(int pid) const;
228     // To create object of type ResourceManagerServiceNew
229     static std::shared_ptr<ResourceManagerService> CreateNew(
230         const sp<ProcessInfoInterface>& processInfo,
231         const sp<SystemCallbackInterface>& systemResource);
232     // Returns a unmodifiable reference to the internal resource state as a map
getResourceMap()233     virtual const std::map<int, ResourceInfos>& getResourceMap() const {
234         return mMap;
235     }
236     // enable/disable process priority based reclaim and client importance based reclaim
setReclaimPolicy(bool processPriority,bool clientImportance)237     virtual void setReclaimPolicy(bool processPriority, bool clientImportance) {
238         // Implemented by the refactored/new RMService
239         (void)processPriority;
240         (void)clientImportance;
241     }
242     // END: TEST only functions
243 
244 protected:
245     mutable std::mutex mLock;
246     sp<ProcessInfoInterface> mProcessInfo;
247     sp<SystemCallbackInterface> mSystemCB;
248     sp<ServiceLog> mServiceLog;
249     bool mSupportsMultipleSecureCodecs;
250     bool mSupportsSecureWithNonSecureCodec;
251     int32_t mCpuBoostCount;
252 
253 private:
254     PidResourceInfosMap mMap;
255     struct ProcessInfoOverride {
256         std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
257         std::shared_ptr<IResourceManagerClient> client;
258     };
259     std::map<int, int> mOverridePidMap;
260     std::map<pid_t, ProcessInfoOverride> mProcessInfoOverrideMap;
261     std::shared_ptr<ResourceObserverService> mObserverService;
262     std::unique_ptr<ResourceManagerMetrics> mResourceManagerMetrics;
263 };
264 
265 // ----------------------------------------------------------------------------
266 } // namespace android
267 
268 #endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
269