blob: e8f15158e14b6f40595cb019bdfe266ca437895c [file] [log] [blame]
Girish27365ed2023-10-11 20:20:55 +00001/*
2**
3** Copyright 2023, 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_RESOURCEMANAGERSERVICEUTILS_H_
19#define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
20
Girish0ac5c212023-11-23 09:14:03 +000021#include <map>
Girishd11a03a2023-11-30 21:17:51 +000022#include <set>
Girish0ac5c212023-11-23 09:14:03 +000023#include <memory>
Girish27365ed2023-10-11 20:20:55 +000024#include <vector>
Girishab17b0f2023-11-20 06:00:44 +000025
26#include <aidl/android/media/BnResourceManagerService.h>
27#include <media/MediaResource.h>
Girish27365ed2023-10-11 20:20:55 +000028#include <utils/String8.h>
29
30namespace android {
31
Girishab17b0f2023-11-20 06:00:44 +000032class ResourceManagerService;
33
34/*
35 * Death Notifier to track IResourceManagerClient's death.
36 */
37class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
38
39 // BinderDiedContext defines the cookie that is passed as DeathRecipient.
40 // Since this can maintain more context than a raw pointer, we can
41 // validate the scope of DeathNotifier, before deferencing it upon the binder death.
42 struct BinderDiedContext {
43 std::weak_ptr<DeathNotifier> mDeathNotifier;
44 };
45public:
46 static std::shared_ptr<DeathNotifier> Create(
47 const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
48 const std::weak_ptr<ResourceManagerService>& service,
49 const ::aidl::android::media::ClientInfoParcel& clientInfo,
50 bool overrideProcessInfo = false);
51
52 DeathNotifier(const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
53 const std::weak_ptr<ResourceManagerService>& service,
54 const ::aidl::android::media::ClientInfoParcel& clientInfo);
55
56 virtual ~DeathNotifier() {
57 unlink();
58 }
59
60 // Implement death recipient
61 static void BinderDiedCallback(void* cookie);
62 static void BinderUnlinkedCallback(void* cookie);
63 virtual void binderDied();
64
65private:
66 void link() {
67 // Create the context that is passed as cookie to the binder death notification.
68 // The context gets deleted at BinderUnlinkedCallback.
69 mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
70 // Register for the callbacks by linking to death notification.
71 AIBinder_linkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
72 }
73
74 void unlink() {
75 if (mClient != nullptr) {
76 // Unlink from the death notification.
77 AIBinder_unlinkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
78 mClient = nullptr;
79 }
80 }
81
82protected:
83 std::shared_ptr<::aidl::android::media::IResourceManagerClient> mClient;
84 std::weak_ptr<ResourceManagerService> mService;
85 const ::aidl::android::media::ClientInfoParcel mClientInfo;
86 BinderDiedContext* mCookie;
87 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
88};
89
90class OverrideProcessInfoDeathNotifier : public DeathNotifier {
91public:
92 OverrideProcessInfoDeathNotifier(
93 const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
94 const std::weak_ptr<ResourceManagerService>& service,
95 const ::aidl::android::media::ClientInfoParcel& clientInfo)
96 : DeathNotifier(client, service, clientInfo) {}
97
98 virtual ~OverrideProcessInfoDeathNotifier() {}
99
100 virtual void binderDied();
101};
102
Girishd11a03a2023-11-30 21:17:51 +0000103// Encapsulate Resource List as vector of resources instead of map.
104// Since the number of resource is very limited, maintaining it as
105// std::vector helps with both performance and memory requiremnts.
106struct ResourceList {
107 // Add or Update an entry into ResourceList.
108 // If a new entry is added, isNewEntry will be set to true upon return
109 // returns true on successful update, false otherwise.
110 bool add(const ::aidl::android::media::MediaResourceParcel& res, bool* isNewEntry = nullptr);
111
112 // reduce the resource usage by subtracting the resource value.
113 // If the resource value is 0 after reducing the resource usage,
114 // that entry will be removed and removedEntryValue is set to the
115 // value before it was removed upon return otherwise it will be set to -1.
116 // returns true on successful removal of the resource, false otherwise.
117 bool remove(const ::aidl::android::media::MediaResourceParcel& res,
118 long* removedEntryValue = nullptr);
119
120 // Returns true if there aren't any resource entries.
121 bool empty() const {
122 return mResourceList.empty();
123 }
124
125 // Returns resource list as a non-modifiable vectors
126 const std::vector<::aidl::android::media::MediaResourceParcel>& getResources() const {
127 return mResourceList;
128 }
129
130 // Converts resource list into string format
131 std::string toString() const;
132
133 // BEGIN: Test only function
134 // Check if two resource lists are the same.
135 bool operator==(const ResourceList& rhs) const;
136
137 // Add or Update an entry into ResourceList.
138 void addOrUpdate(const ::aidl::android::media::MediaResourceParcel& res);
139 // END: Test only function
140
141private:
142 std::vector<::aidl::android::media::MediaResourceParcel> mResourceList;
143};
Girishab17b0f2023-11-20 06:00:44 +0000144
145// Encapsulation for Resource Info, that contains
146// - pid of the app
147// - uid of the app
148// - client id
149// - name of the client (specifically for the codec)
150// - the client associted with it
151// - death notifier for the (above) client
152// - list of resources associated with it
153// - A flag that marks whether this resource is pending to be removed.
154struct ResourceInfo {
155 pid_t pid;
156 uid_t uid;
157 int64_t clientId;
158 std::string name;
159 std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
160 std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
161 ResourceList resources;
162 bool pendingRemoval{false};
Girish88a83502023-11-23 11:23:07 +0000163 uint32_t importance = 0;
Girishab17b0f2023-11-20 06:00:44 +0000164};
165
166/*
Girish0ac5c212023-11-23 09:14:03 +0000167 * Resource Reclaim request info that encapsulates
168 * - the calling/requesting process pid.
Girish1c682402024-01-31 21:03:51 +0000169 * - id of the client that made reclaim request.
Girish88a83502023-11-23 11:23:07 +0000170 * - the calling/requesting client's importance.
Girish0ac5c212023-11-23 09:14:03 +0000171 * - the list of resources requesting (to be reclaimed from others)
172 */
173struct ReclaimRequestInfo {
174 int mCallingPid = -1;
Girish1c682402024-01-31 21:03:51 +0000175 int64_t mClientId = 0;
Girish88a83502023-11-23 11:23:07 +0000176 uint32_t mCallingClientImportance = 0;
Girish0ac5c212023-11-23 09:14:03 +0000177 const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
178};
179
180/*
Girishab17b0f2023-11-20 06:00:44 +0000181 * Resource request info that encapsulates
182 * - the calling/requesting process pid.
Girish1c682402024-01-31 21:03:51 +0000183 * - the calling/requesting client's id.
Girishab17b0f2023-11-20 06:00:44 +0000184 * - the resource requesting (to be reclaimed from others)
185 */
186struct ResourceRequestInfo {
187 // pid of the calling/requesting process.
188 int mCallingPid = -1;
Girish1c682402024-01-31 21:03:51 +0000189 // id of the calling/requesting client.
190 int64_t mClientId = 0;
Girishab17b0f2023-11-20 06:00:44 +0000191 // resources requested.
192 const ::aidl::android::media::MediaResourceParcel* mResource;
193};
194
195/*
196 * Structure that defines the Client - a possible target to relcaim from.
197 * This encapsulates pid, uid of the process and the client id
198 * based on the reclaim policy.
199 */
200struct ClientInfo {
201 // pid of the process.
202 pid_t mPid = -1;
203 // uid of the process.
204 uid_t mUid = -1;
205 // Client Id.
206 int64_t mClientId = -1;
207 ClientInfo(pid_t pid = -1, uid_t uid = -1, const int64_t& clientId = -1)
208 : mPid(pid), mUid(uid), mClientId(clientId) {}
209};
210
211// Map of Resource information index through the client id.
212typedef std::map<int64_t, ResourceInfo> ResourceInfos;
213
214// Map of Resource information indexed through the process id.
215typedef std::map<int, ResourceInfos> PidResourceInfosMap;
216
Girish27365ed2023-10-11 20:20:55 +0000217// templated function to stringify the given vector of items.
218template <typename T>
219String8 getString(const std::vector<T>& items) {
220 String8 itemsStr;
221 for (size_t i = 0; i < items.size(); ++i) {
222 itemsStr.appendFormat("%s ", toString(items[i]).c_str());
223 }
224 return itemsStr;
225}
226
227// Bunch of utility functions that looks for a specific Resource.
228
229//Check whether a given resource (of type and subtype) is found in given resource parcel.
230bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girish6a6044d2023-11-22 21:23:14 +0000231 const ::aidl::android::media::MediaResourceParcel& resource);
Girish27365ed2023-10-11 20:20:55 +0000232
233//Check whether a given resource (of type and subtype) is found in given resource list.
234bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girishab17b0f2023-11-20 06:00:44 +0000235 const ResourceList& resources);
Girish27365ed2023-10-11 20:20:55 +0000236
237//Check whether a given resource (of type and subtype) is found in given resource info list.
238bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girishab17b0f2023-11-20 06:00:44 +0000239 const ResourceInfos& infos);
Girish27365ed2023-10-11 20:20:55 +0000240
241// Return modifiable list of ResourceInfo for a given process (look up by pid)
242// from the map of ResourceInfos.
243ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map);
244
245// Return modifiable ResourceInfo for a given process (look up by pid)
246// from the map of ResourceInfos.
247// If the item is not in the map, create one and add it to the map.
Girishab17b0f2023-11-20 06:00:44 +0000248ResourceInfo& getResourceInfoForEdit(
249 const aidl::android::media::ClientInfoParcel& clientInfo,
250 const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
251 ResourceInfos& infos);
252
253// Merge resources from r2 into r1.
Girish6a6044d2023-11-22 21:23:14 +0000254void mergeResources(::aidl::android::media::MediaResourceParcel& r1,
255 const ::aidl::android::media::MediaResourceParcel& r2);
256
257// To notify the media_resource_monitor about the resource being granted.
258void notifyResourceGranted(
259 int pid,
260 const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
Girish27365ed2023-10-11 20:20:55 +0000261
262} // namespace android
263
264#endif //ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_