blob: 7e336e398e4e902d0a737969d018bc3cff8ff30f [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>
22#include <memory>
Girish27365ed2023-10-11 20:20:55 +000023#include <vector>
Girishab17b0f2023-11-20 06:00:44 +000024
25#include <aidl/android/media/BnResourceManagerService.h>
26#include <media/MediaResource.h>
Girish27365ed2023-10-11 20:20:55 +000027#include <utils/String8.h>
28
29namespace android {
30
Girishab17b0f2023-11-20 06:00:44 +000031class ResourceManagerService;
32
33/*
34 * Death Notifier to track IResourceManagerClient's death.
35 */
36class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
37
38 // BinderDiedContext defines the cookie that is passed as DeathRecipient.
39 // Since this can maintain more context than a raw pointer, we can
40 // validate the scope of DeathNotifier, before deferencing it upon the binder death.
41 struct BinderDiedContext {
42 std::weak_ptr<DeathNotifier> mDeathNotifier;
43 };
44public:
45 static std::shared_ptr<DeathNotifier> Create(
46 const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
47 const std::weak_ptr<ResourceManagerService>& service,
48 const ::aidl::android::media::ClientInfoParcel& clientInfo,
49 bool overrideProcessInfo = false);
50
51 DeathNotifier(const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
52 const std::weak_ptr<ResourceManagerService>& service,
53 const ::aidl::android::media::ClientInfoParcel& clientInfo);
54
55 virtual ~DeathNotifier() {
56 unlink();
57 }
58
59 // Implement death recipient
60 static void BinderDiedCallback(void* cookie);
61 static void BinderUnlinkedCallback(void* cookie);
62 virtual void binderDied();
63
64private:
65 void link() {
66 // Create the context that is passed as cookie to the binder death notification.
67 // The context gets deleted at BinderUnlinkedCallback.
68 mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
69 // Register for the callbacks by linking to death notification.
70 AIBinder_linkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
71 }
72
73 void unlink() {
74 if (mClient != nullptr) {
75 // Unlink from the death notification.
76 AIBinder_unlinkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
77 mClient = nullptr;
78 }
79 }
80
81protected:
82 std::shared_ptr<::aidl::android::media::IResourceManagerClient> mClient;
83 std::weak_ptr<ResourceManagerService> mService;
84 const ::aidl::android::media::ClientInfoParcel mClientInfo;
85 BinderDiedContext* mCookie;
86 ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
87};
88
89class OverrideProcessInfoDeathNotifier : public DeathNotifier {
90public:
91 OverrideProcessInfoDeathNotifier(
92 const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
93 const std::weak_ptr<ResourceManagerService>& service,
94 const ::aidl::android::media::ClientInfoParcel& clientInfo)
95 : DeathNotifier(client, service, clientInfo) {}
96
97 virtual ~OverrideProcessInfoDeathNotifier() {}
98
99 virtual void binderDied();
100};
101
102// A map of tuple(type, sub-type, id) and the resource parcel.
103typedef std::map<std::tuple<
104 MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
105 ::aidl::android::media::MediaResourceParcel> ResourceList;
106
107// Encapsulation for Resource Info, that contains
108// - pid of the app
109// - uid of the app
110// - client id
111// - name of the client (specifically for the codec)
112// - the client associted with it
113// - death notifier for the (above) client
114// - list of resources associated with it
115// - A flag that marks whether this resource is pending to be removed.
116struct ResourceInfo {
117 pid_t pid;
118 uid_t uid;
119 int64_t clientId;
120 std::string name;
121 std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
122 std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
123 ResourceList resources;
124 bool pendingRemoval{false};
Girish88a83502023-11-23 11:23:07 +0000125 uint32_t importance = 0;
Girishab17b0f2023-11-20 06:00:44 +0000126};
127
128/*
Girish0ac5c212023-11-23 09:14:03 +0000129 * Resource Reclaim request info that encapsulates
130 * - the calling/requesting process pid.
Girish88a83502023-11-23 11:23:07 +0000131 * - the calling/requesting client's importance.
Girish0ac5c212023-11-23 09:14:03 +0000132 * - the list of resources requesting (to be reclaimed from others)
133 */
134struct ReclaimRequestInfo {
135 int mCallingPid = -1;
Girish88a83502023-11-23 11:23:07 +0000136 uint32_t mCallingClientImportance = 0;
Girish0ac5c212023-11-23 09:14:03 +0000137 const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
138};
139
140/*
Girishab17b0f2023-11-20 06:00:44 +0000141 * Resource request info that encapsulates
142 * - the calling/requesting process pid.
143 * - the resource requesting (to be reclaimed from others)
144 */
145struct ResourceRequestInfo {
146 // pid of the calling/requesting process.
147 int mCallingPid = -1;
148 // resources requested.
149 const ::aidl::android::media::MediaResourceParcel* mResource;
150};
151
152/*
153 * Structure that defines the Client - a possible target to relcaim from.
154 * This encapsulates pid, uid of the process and the client id
155 * based on the reclaim policy.
156 */
157struct ClientInfo {
158 // pid of the process.
159 pid_t mPid = -1;
160 // uid of the process.
161 uid_t mUid = -1;
162 // Client Id.
163 int64_t mClientId = -1;
164 ClientInfo(pid_t pid = -1, uid_t uid = -1, const int64_t& clientId = -1)
165 : mPid(pid), mUid(uid), mClientId(clientId) {}
166};
167
168// Map of Resource information index through the client id.
169typedef std::map<int64_t, ResourceInfo> ResourceInfos;
170
171// Map of Resource information indexed through the process id.
172typedef std::map<int, ResourceInfos> PidResourceInfosMap;
173
Girish27365ed2023-10-11 20:20:55 +0000174// templated function to stringify the given vector of items.
175template <typename T>
176String8 getString(const std::vector<T>& items) {
177 String8 itemsStr;
178 for (size_t i = 0; i < items.size(); ++i) {
179 itemsStr.appendFormat("%s ", toString(items[i]).c_str());
180 }
181 return itemsStr;
182}
183
184// Bunch of utility functions that looks for a specific Resource.
185
186//Check whether a given resource (of type and subtype) is found in given resource parcel.
187bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girish6a6044d2023-11-22 21:23:14 +0000188 const ::aidl::android::media::MediaResourceParcel& resource);
Girish27365ed2023-10-11 20:20:55 +0000189
190//Check whether a given resource (of type and subtype) is found in given resource list.
191bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girishab17b0f2023-11-20 06:00:44 +0000192 const ResourceList& resources);
Girish27365ed2023-10-11 20:20:55 +0000193
194//Check whether a given resource (of type and subtype) is found in given resource info list.
195bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
Girishab17b0f2023-11-20 06:00:44 +0000196 const ResourceInfos& infos);
Girish27365ed2023-10-11 20:20:55 +0000197
198// Return modifiable list of ResourceInfo for a given process (look up by pid)
199// from the map of ResourceInfos.
200ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map);
201
202// Return modifiable ResourceInfo for a given process (look up by pid)
203// from the map of ResourceInfos.
204// If the item is not in the map, create one and add it to the map.
Girishab17b0f2023-11-20 06:00:44 +0000205ResourceInfo& getResourceInfoForEdit(
206 const aidl::android::media::ClientInfoParcel& clientInfo,
207 const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
208 ResourceInfos& infos);
209
210// Merge resources from r2 into r1.
Girish6a6044d2023-11-22 21:23:14 +0000211void mergeResources(::aidl::android::media::MediaResourceParcel& r1,
212 const ::aidl::android::media::MediaResourceParcel& r2);
213
214// To notify the media_resource_monitor about the resource being granted.
215void notifyResourceGranted(
216 int pid,
217 const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
Girish27365ed2023-10-11 20:20:55 +0000218
219} // namespace android
220
221#endif //ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_