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