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 
23 #include <aidl/android/media/BnResourceManagerService.h>
24 #include <arpa/inet.h>
25 #include <media/MediaResource.h>
26 #include <utils/Errors.h>
27 #include <utils/KeyedVector.h>
28 #include <utils/String8.h>
29 #include <utils/threads.h>
30 #include <utils/Vector.h>
31 
32 namespace android {
33 
34 class DeathNotifier;
35 class ResourceManagerService;
36 class ServiceLog;
37 struct ProcessInfoInterface;
38 
39 using Status = ::ndk::ScopedAStatus;
40 using ::aidl::android::media::IResourceManagerClient;
41 using ::aidl::android::media::BnResourceManagerService;
42 using ::aidl::android::media::MediaResourceParcel;
43 using ::aidl::android::media::MediaResourcePolicyParcel;
44 
45 typedef std::map<std::tuple<
46         MediaResource::Type, MediaResource::SubType, std::vector<int8_t>>,
47         MediaResourceParcel> ResourceList;
48 
49 struct ResourceInfo {
50     int64_t clientId;
51     uid_t uid;
52     std::shared_ptr<IResourceManagerClient> client;
53     sp<DeathNotifier> deathNotifier;
54     ResourceList resources;
55     bool pendingRemoval{false};
56 };
57 
58 // TODO: convert these to std::map
59 typedef KeyedVector<int64_t, ResourceInfo> ResourceInfos;
60 typedef KeyedVector<int, ResourceInfos> PidResourceInfosMap;
61 
62 class DeathNotifier : public RefBase {
63 public:
64     DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
65             int pid, int64_t clientId);
66 
~DeathNotifier()67     ~DeathNotifier() {}
68 
69     // Implement death recipient
70     static void BinderDiedCallback(void* cookie);
71     void binderDied();
72 
73 private:
74     std::weak_ptr<ResourceManagerService> mService;
75     int mPid;
76     int64_t mClientId;
77 };
78 class ResourceManagerService : public BnResourceManagerService {
79 public:
80     struct SystemCallbackInterface : public RefBase {
81         virtual void noteStartVideo(int uid) = 0;
82         virtual void noteStopVideo(int uid) = 0;
83         virtual void noteResetVideo() = 0;
84         virtual bool requestCpusetBoost(bool enable) = 0;
85     };
86 
getServiceName()87     static char const *getServiceName() { return "media.resource_manager"; }
88     static void instantiate();
89 
90     virtual inline binder_status_t dump(
91             int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
92 
93     ResourceManagerService();
94     explicit ResourceManagerService(
95             const sp<ProcessInfoInterface> &processInfo,
96             const sp<SystemCallbackInterface> &systemResource);
97     virtual ~ResourceManagerService();
98 
99     // IResourceManagerService interface
100     Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
101 
102     Status addResource(
103             int32_t pid,
104             int32_t uid,
105             int64_t clientId,
106             const std::shared_ptr<IResourceManagerClient>& client,
107             const std::vector<MediaResourceParcel>& resources) override;
108 
109     Status removeResource(
110             int32_t pid,
111             int64_t clientId,
112             const std::vector<MediaResourceParcel>& resources) override;
113 
114     Status removeClient(int32_t pid, int64_t clientId) override;
115 
116     // Tries to reclaim resource from processes with lower priority than the calling process
117     // according to the requested resources.
118     // Returns true if any resource has been reclaimed, otherwise returns false.
119     Status reclaimResource(
120             int32_t callingPid,
121             const std::vector<MediaResourceParcel>& resources,
122             bool* _aidl_return) override;
123 
124     Status overridePid(
125             int originalPid,
126             int newPid) override;
127 
128     Status markClientForPendingRemoval(int32_t pid, int64_t clientId) override;
129 
130     Status removeResource(int pid, int64_t clientId, bool checkValid);
131 
132 private:
133     friend class ResourceManagerServiceTest;
134 
135     // Gets the list of all the clients who own the specified resource type.
136     // Returns false if any client belongs to a process with higher priority than the
137     // calling process. The clients will remain unchanged if returns false.
138     bool getAllClients_l(int callingPid, MediaResource::Type type,
139             Vector<std::shared_ptr<IResourceManagerClient>> *clients);
140 
141     // Gets the client who owns specified resource type from lowest possible priority process.
142     // Returns false if the calling process priority is not higher than the lowest process
143     // priority. The client will remain unchanged if returns false.
144     bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type,
145             std::shared_ptr<IResourceManagerClient> *client);
146 
147     // Gets lowest priority process that has the specified resource type.
148     // Returns false if failed. The output parameters will remain unchanged if failed.
149     bool getLowestPriorityPid_l(MediaResource::Type type, int *pid, int *priority);
150 
151     // Gets the client who owns biggest piece of specified resource type from pid.
152     // Returns false if failed. The client will remain unchanged if failed.
153     bool getBiggestClient_l(int pid, MediaResource::Type type,
154             std::shared_ptr<IResourceManagerClient> *client,
155             bool pendingRemovalOnly = false);
156 
157     bool isCallingPriorityHigher_l(int callingPid, int pid);
158 
159     // A helper function basically calls getLowestPriorityBiggestClient_l and add
160     // the result client to the given Vector.
161     void getClientForResource_l(int callingPid, const MediaResourceParcel *res,
162             Vector<std::shared_ptr<IResourceManagerClient>> *clients);
163 
164     void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
165     void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
166 
167     // Merge r2 into r1
168     void mergeResources(MediaResourceParcel& r1, const MediaResourceParcel& r2);
169 
170     // Get priority from process's pid
171     bool getPriority_l(int pid, int* priority);
172 
173     mutable Mutex mLock;
174     sp<ProcessInfoInterface> mProcessInfo;
175     sp<SystemCallbackInterface> mSystemCB;
176     sp<ServiceLog> mServiceLog;
177     PidResourceInfosMap mMap;
178     bool mSupportsMultipleSecureCodecs;
179     bool mSupportsSecureWithNonSecureCodec;
180     int32_t mCpuBoostCount;
181     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
182     std::map<int, int> mOverridePidMap;
183 };
184 
185 // ----------------------------------------------------------------------------
186 } // namespace android
187 
188 #endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
189