xref: /aosp_15_r20/frameworks/av/services/mediaresourcemanager/ResourceManagerServiceUtils.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker **
3*ec779b8eSAndroid Build Coastguard Worker ** Copyright 2023, The Android Open Source Project
4*ec779b8eSAndroid Build Coastguard Worker **
5*ec779b8eSAndroid Build Coastguard Worker ** Licensed under the Apache License, Version 2.0 (the "License");
6*ec779b8eSAndroid Build Coastguard Worker ** you may not use this file except in compliance with the License.
7*ec779b8eSAndroid Build Coastguard Worker ** You may obtain a copy of the License at
8*ec779b8eSAndroid Build Coastguard Worker **
9*ec779b8eSAndroid Build Coastguard Worker **     http://www.apache.org/licenses/LICENSE-2.0
10*ec779b8eSAndroid Build Coastguard Worker **
11*ec779b8eSAndroid Build Coastguard Worker ** Unless required by applicable law or agreed to in writing, software
12*ec779b8eSAndroid Build Coastguard Worker ** distributed under the License is distributed on an "AS IS" BASIS,
13*ec779b8eSAndroid Build Coastguard Worker ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*ec779b8eSAndroid Build Coastguard Worker ** See the License for the specific language governing permissions and
15*ec779b8eSAndroid Build Coastguard Worker ** limitations under the License.
16*ec779b8eSAndroid Build Coastguard Worker */
17*ec779b8eSAndroid Build Coastguard Worker 
18*ec779b8eSAndroid Build Coastguard Worker #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
19*ec779b8eSAndroid Build Coastguard Worker #define ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <map>
22*ec779b8eSAndroid Build Coastguard Worker #include <set>
23*ec779b8eSAndroid Build Coastguard Worker #include <memory>
24*ec779b8eSAndroid Build Coastguard Worker #include <vector>
25*ec779b8eSAndroid Build Coastguard Worker 
26*ec779b8eSAndroid Build Coastguard Worker #include <aidl/android/media/BnResourceManagerService.h>
27*ec779b8eSAndroid Build Coastguard Worker #include <media/MediaResource.h>
28*ec779b8eSAndroid Build Coastguard Worker #include <utils/String8.h>
29*ec779b8eSAndroid Build Coastguard Worker 
30*ec779b8eSAndroid Build Coastguard Worker namespace android {
31*ec779b8eSAndroid Build Coastguard Worker 
32*ec779b8eSAndroid Build Coastguard Worker class ResourceManagerService;
33*ec779b8eSAndroid Build Coastguard Worker 
34*ec779b8eSAndroid Build Coastguard Worker /*
35*ec779b8eSAndroid Build Coastguard Worker  * Death Notifier to track IResourceManagerClient's death.
36*ec779b8eSAndroid Build Coastguard Worker  */
37*ec779b8eSAndroid Build Coastguard Worker class DeathNotifier : public std::enable_shared_from_this<DeathNotifier> {
38*ec779b8eSAndroid Build Coastguard Worker 
39*ec779b8eSAndroid Build Coastguard Worker     // BinderDiedContext defines the cookie that is passed as DeathRecipient.
40*ec779b8eSAndroid Build Coastguard Worker     // Since this can maintain more context than a raw pointer, we can
41*ec779b8eSAndroid Build Coastguard Worker     // validate the scope of DeathNotifier, before deferencing it upon the binder death.
42*ec779b8eSAndroid Build Coastguard Worker     struct BinderDiedContext {
43*ec779b8eSAndroid Build Coastguard Worker         std::weak_ptr<DeathNotifier> mDeathNotifier;
44*ec779b8eSAndroid Build Coastguard Worker     };
45*ec779b8eSAndroid Build Coastguard Worker public:
46*ec779b8eSAndroid Build Coastguard Worker     static std::shared_ptr<DeathNotifier> Create(
47*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
48*ec779b8eSAndroid Build Coastguard Worker         const std::weak_ptr<ResourceManagerService>& service,
49*ec779b8eSAndroid Build Coastguard Worker         const ::aidl::android::media::ClientInfoParcel& clientInfo,
50*ec779b8eSAndroid Build Coastguard Worker         bool overrideProcessInfo = false);
51*ec779b8eSAndroid Build Coastguard Worker 
52*ec779b8eSAndroid Build Coastguard Worker     DeathNotifier(const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
53*ec779b8eSAndroid Build Coastguard Worker                   const std::weak_ptr<ResourceManagerService>& service,
54*ec779b8eSAndroid Build Coastguard Worker                   const ::aidl::android::media::ClientInfoParcel& clientInfo);
55*ec779b8eSAndroid Build Coastguard Worker 
~DeathNotifier()56*ec779b8eSAndroid Build Coastguard Worker     virtual ~DeathNotifier() {
57*ec779b8eSAndroid Build Coastguard Worker         unlink();
58*ec779b8eSAndroid Build Coastguard Worker     }
59*ec779b8eSAndroid Build Coastguard Worker 
60*ec779b8eSAndroid Build Coastguard Worker     // Implement death recipient
61*ec779b8eSAndroid Build Coastguard Worker     static void BinderDiedCallback(void* cookie);
62*ec779b8eSAndroid Build Coastguard Worker     static void BinderUnlinkedCallback(void* cookie);
63*ec779b8eSAndroid Build Coastguard Worker     virtual void binderDied();
64*ec779b8eSAndroid Build Coastguard Worker 
65*ec779b8eSAndroid Build Coastguard Worker private:
link()66*ec779b8eSAndroid Build Coastguard Worker     void link() {
67*ec779b8eSAndroid Build Coastguard Worker         // Create the context that is passed as cookie to the binder death notification.
68*ec779b8eSAndroid Build Coastguard Worker         // The context gets deleted at BinderUnlinkedCallback.
69*ec779b8eSAndroid Build Coastguard Worker         mCookie = new BinderDiedContext{.mDeathNotifier = weak_from_this()};
70*ec779b8eSAndroid Build Coastguard Worker         // Register for the callbacks by linking to death notification.
71*ec779b8eSAndroid Build Coastguard Worker         AIBinder_linkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
72*ec779b8eSAndroid Build Coastguard Worker     }
73*ec779b8eSAndroid Build Coastguard Worker 
unlink()74*ec779b8eSAndroid Build Coastguard Worker     void unlink() {
75*ec779b8eSAndroid Build Coastguard Worker         if (mClient != nullptr) {
76*ec779b8eSAndroid Build Coastguard Worker             // Unlink from the death notification.
77*ec779b8eSAndroid Build Coastguard Worker             AIBinder_unlinkToDeath(mClient->asBinder().get(), mDeathRecipient.get(), mCookie);
78*ec779b8eSAndroid Build Coastguard Worker             mClient = nullptr;
79*ec779b8eSAndroid Build Coastguard Worker         }
80*ec779b8eSAndroid Build Coastguard Worker     }
81*ec779b8eSAndroid Build Coastguard Worker 
82*ec779b8eSAndroid Build Coastguard Worker protected:
83*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<::aidl::android::media::IResourceManagerClient> mClient;
84*ec779b8eSAndroid Build Coastguard Worker     std::weak_ptr<ResourceManagerService> mService;
85*ec779b8eSAndroid Build Coastguard Worker     const ::aidl::android::media::ClientInfoParcel mClientInfo;
86*ec779b8eSAndroid Build Coastguard Worker     BinderDiedContext* mCookie;
87*ec779b8eSAndroid Build Coastguard Worker     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
88*ec779b8eSAndroid Build Coastguard Worker };
89*ec779b8eSAndroid Build Coastguard Worker 
90*ec779b8eSAndroid Build Coastguard Worker class OverrideProcessInfoDeathNotifier : public DeathNotifier {
91*ec779b8eSAndroid Build Coastguard Worker public:
OverrideProcessInfoDeathNotifier(const std::shared_ptr<::aidl::android::media::IResourceManagerClient> & client,const std::weak_ptr<ResourceManagerService> & service,const::aidl::android::media::ClientInfoParcel & clientInfo)92*ec779b8eSAndroid Build Coastguard Worker     OverrideProcessInfoDeathNotifier(
93*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<::aidl::android::media::IResourceManagerClient>& client,
94*ec779b8eSAndroid Build Coastguard Worker         const std::weak_ptr<ResourceManagerService>& service,
95*ec779b8eSAndroid Build Coastguard Worker         const ::aidl::android::media::ClientInfoParcel& clientInfo)
96*ec779b8eSAndroid Build Coastguard Worker             : DeathNotifier(client, service, clientInfo) {}
97*ec779b8eSAndroid Build Coastguard Worker 
~OverrideProcessInfoDeathNotifier()98*ec779b8eSAndroid Build Coastguard Worker     virtual ~OverrideProcessInfoDeathNotifier() {}
99*ec779b8eSAndroid Build Coastguard Worker 
100*ec779b8eSAndroid Build Coastguard Worker     virtual void binderDied();
101*ec779b8eSAndroid Build Coastguard Worker };
102*ec779b8eSAndroid Build Coastguard Worker 
103*ec779b8eSAndroid Build Coastguard Worker // Encapsulate Resource List as vector of resources instead of map.
104*ec779b8eSAndroid Build Coastguard Worker // Since the number of resource is very limited, maintaining it as
105*ec779b8eSAndroid Build Coastguard Worker // std::vector helps with both performance and memory requiremnts.
106*ec779b8eSAndroid Build Coastguard Worker struct ResourceList {
107*ec779b8eSAndroid Build Coastguard Worker     // Add or Update an entry into ResourceList.
108*ec779b8eSAndroid Build Coastguard Worker     // If a new entry is added, isNewEntry will be set to true upon return
109*ec779b8eSAndroid Build Coastguard Worker     // returns true on successful update, false otherwise.
110*ec779b8eSAndroid Build Coastguard Worker     bool add(const ::aidl::android::media::MediaResourceParcel& res, bool* isNewEntry = nullptr);
111*ec779b8eSAndroid Build Coastguard Worker 
112*ec779b8eSAndroid Build Coastguard Worker     // reduce the resource usage by subtracting the resource value.
113*ec779b8eSAndroid Build Coastguard Worker     // If the resource value is 0 after reducing the resource usage,
114*ec779b8eSAndroid Build Coastguard Worker     // that entry will be removed and removedEntryValue is set to the
115*ec779b8eSAndroid Build Coastguard Worker     // value before it was removed upon return otherwise it will be set to -1.
116*ec779b8eSAndroid Build Coastguard Worker     // returns true on successful removal of the resource, false otherwise.
117*ec779b8eSAndroid Build Coastguard Worker     bool remove(const ::aidl::android::media::MediaResourceParcel& res,
118*ec779b8eSAndroid Build Coastguard Worker                 long* removedEntryValue = nullptr);
119*ec779b8eSAndroid Build Coastguard Worker 
120*ec779b8eSAndroid Build Coastguard Worker     // Returns true if there aren't any resource entries.
emptyResourceList121*ec779b8eSAndroid Build Coastguard Worker     bool empty() const {
122*ec779b8eSAndroid Build Coastguard Worker         return mResourceList.empty();
123*ec779b8eSAndroid Build Coastguard Worker     }
124*ec779b8eSAndroid Build Coastguard Worker 
125*ec779b8eSAndroid Build Coastguard Worker     // Returns resource list as a non-modifiable vectors
getResourcesResourceList126*ec779b8eSAndroid Build Coastguard Worker     const std::vector<::aidl::android::media::MediaResourceParcel>& getResources() const {
127*ec779b8eSAndroid Build Coastguard Worker         return mResourceList;
128*ec779b8eSAndroid Build Coastguard Worker     }
129*ec779b8eSAndroid Build Coastguard Worker 
130*ec779b8eSAndroid Build Coastguard Worker     // Converts resource list into string format
131*ec779b8eSAndroid Build Coastguard Worker     std::string toString() const;
132*ec779b8eSAndroid Build Coastguard Worker 
133*ec779b8eSAndroid Build Coastguard Worker     // BEGIN: Test only function
134*ec779b8eSAndroid Build Coastguard Worker     // Check if two resource lists are the same.
135*ec779b8eSAndroid Build Coastguard Worker     bool operator==(const ResourceList& rhs) const;
136*ec779b8eSAndroid Build Coastguard Worker 
137*ec779b8eSAndroid Build Coastguard Worker     // Add or Update an entry into ResourceList.
138*ec779b8eSAndroid Build Coastguard Worker     void addOrUpdate(const ::aidl::android::media::MediaResourceParcel& res);
139*ec779b8eSAndroid Build Coastguard Worker     // END: Test only function
140*ec779b8eSAndroid Build Coastguard Worker 
141*ec779b8eSAndroid Build Coastguard Worker private:
142*ec779b8eSAndroid Build Coastguard Worker     std::vector<::aidl::android::media::MediaResourceParcel> mResourceList;
143*ec779b8eSAndroid Build Coastguard Worker };
144*ec779b8eSAndroid Build Coastguard Worker 
145*ec779b8eSAndroid Build Coastguard Worker // Encapsulation for Resource Info, that contains
146*ec779b8eSAndroid Build Coastguard Worker // - pid of the app
147*ec779b8eSAndroid Build Coastguard Worker // - uid of the app
148*ec779b8eSAndroid Build Coastguard Worker // - client id
149*ec779b8eSAndroid Build Coastguard Worker // - name of the client (specifically for the codec)
150*ec779b8eSAndroid Build Coastguard Worker // - the client associted with it
151*ec779b8eSAndroid Build Coastguard Worker // - death notifier for the (above) client
152*ec779b8eSAndroid Build Coastguard Worker // - list of resources associated with it
153*ec779b8eSAndroid Build Coastguard Worker // - A flag that marks whether this resource is pending to be removed.
154*ec779b8eSAndroid Build Coastguard Worker struct ResourceInfo {
155*ec779b8eSAndroid Build Coastguard Worker     pid_t pid;
156*ec779b8eSAndroid Build Coastguard Worker     uid_t uid;
157*ec779b8eSAndroid Build Coastguard Worker     int64_t clientId;
158*ec779b8eSAndroid Build Coastguard Worker     std::string name;
159*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<::aidl::android::media::IResourceManagerClient> client;
160*ec779b8eSAndroid Build Coastguard Worker     std::shared_ptr<DeathNotifier> deathNotifier = nullptr;
161*ec779b8eSAndroid Build Coastguard Worker     ResourceList resources;
162*ec779b8eSAndroid Build Coastguard Worker     bool pendingRemoval{false};
163*ec779b8eSAndroid Build Coastguard Worker     uint32_t importance = 0;
164*ec779b8eSAndroid Build Coastguard Worker };
165*ec779b8eSAndroid Build Coastguard Worker 
166*ec779b8eSAndroid Build Coastguard Worker /*
167*ec779b8eSAndroid Build Coastguard Worker  * Resource Reclaim request info that encapsulates
168*ec779b8eSAndroid Build Coastguard Worker  *  - the calling/requesting process pid.
169*ec779b8eSAndroid Build Coastguard Worker  *  - id of the client that made reclaim request.
170*ec779b8eSAndroid Build Coastguard Worker  *  - the calling/requesting client's importance.
171*ec779b8eSAndroid Build Coastguard Worker  *  - the list of resources requesting (to be reclaimed from others)
172*ec779b8eSAndroid Build Coastguard Worker  */
173*ec779b8eSAndroid Build Coastguard Worker struct ReclaimRequestInfo {
174*ec779b8eSAndroid Build Coastguard Worker     int mCallingPid = -1;
175*ec779b8eSAndroid Build Coastguard Worker     int64_t mClientId = 0;
176*ec779b8eSAndroid Build Coastguard Worker     uint32_t mCallingClientImportance = 0;
177*ec779b8eSAndroid Build Coastguard Worker     const std::vector<::aidl::android::media::MediaResourceParcel>& mResources;
178*ec779b8eSAndroid Build Coastguard Worker };
179*ec779b8eSAndroid Build Coastguard Worker 
180*ec779b8eSAndroid Build Coastguard Worker /*
181*ec779b8eSAndroid Build Coastguard Worker  * Resource request info that encapsulates
182*ec779b8eSAndroid Build Coastguard Worker  *  - the calling/requesting process pid.
183*ec779b8eSAndroid Build Coastguard Worker  *  - the calling/requesting client's id.
184*ec779b8eSAndroid Build Coastguard Worker  *  - the resource requesting (to be reclaimed from others)
185*ec779b8eSAndroid Build Coastguard Worker  */
186*ec779b8eSAndroid Build Coastguard Worker struct ResourceRequestInfo {
187*ec779b8eSAndroid Build Coastguard Worker     // pid of the calling/requesting process.
188*ec779b8eSAndroid Build Coastguard Worker     int mCallingPid = -1;
189*ec779b8eSAndroid Build Coastguard Worker     // id of the calling/requesting client.
190*ec779b8eSAndroid Build Coastguard Worker     int64_t mClientId = 0;
191*ec779b8eSAndroid Build Coastguard Worker     // resources requested.
192*ec779b8eSAndroid Build Coastguard Worker     const ::aidl::android::media::MediaResourceParcel* mResource;
193*ec779b8eSAndroid Build Coastguard Worker };
194*ec779b8eSAndroid Build Coastguard Worker 
195*ec779b8eSAndroid Build Coastguard Worker /*
196*ec779b8eSAndroid Build Coastguard Worker  * Structure that defines the Client - a possible target to relcaim from.
197*ec779b8eSAndroid Build Coastguard Worker  * This encapsulates pid, uid of the process and the client id
198*ec779b8eSAndroid Build Coastguard Worker  * based on the reclaim policy.
199*ec779b8eSAndroid Build Coastguard Worker  */
200*ec779b8eSAndroid Build Coastguard Worker struct ClientInfo {
201*ec779b8eSAndroid Build Coastguard Worker     // pid of the process.
202*ec779b8eSAndroid Build Coastguard Worker     pid_t mPid = -1;
203*ec779b8eSAndroid Build Coastguard Worker     // uid of the process.
204*ec779b8eSAndroid Build Coastguard Worker     uid_t mUid = -1;
205*ec779b8eSAndroid Build Coastguard Worker     // Client Id.
206*ec779b8eSAndroid Build Coastguard Worker     int64_t mClientId = -1;
207*ec779b8eSAndroid Build Coastguard Worker     ClientInfo(pid_t pid = -1, uid_t uid = -1, const int64_t& clientId = -1)
mPidClientInfo208*ec779b8eSAndroid Build Coastguard Worker         : mPid(pid), mUid(uid), mClientId(clientId) {}
209*ec779b8eSAndroid Build Coastguard Worker };
210*ec779b8eSAndroid Build Coastguard Worker 
211*ec779b8eSAndroid Build Coastguard Worker // Map of Resource information index through the client id.
212*ec779b8eSAndroid Build Coastguard Worker typedef std::map<int64_t, ResourceInfo> ResourceInfos;
213*ec779b8eSAndroid Build Coastguard Worker 
214*ec779b8eSAndroid Build Coastguard Worker // Map of Resource information indexed through the process id.
215*ec779b8eSAndroid Build Coastguard Worker typedef std::map<int, ResourceInfos> PidResourceInfosMap;
216*ec779b8eSAndroid Build Coastguard Worker 
217*ec779b8eSAndroid Build Coastguard Worker // templated function to stringify the given vector of items.
218*ec779b8eSAndroid Build Coastguard Worker template <typename T>
getString(const std::vector<T> & items)219*ec779b8eSAndroid Build Coastguard Worker String8 getString(const std::vector<T>& items) {
220*ec779b8eSAndroid Build Coastguard Worker     String8 itemsStr;
221*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < items.size(); ++i) {
222*ec779b8eSAndroid Build Coastguard Worker         itemsStr.appendFormat("%s ", toString(items[i]).c_str());
223*ec779b8eSAndroid Build Coastguard Worker     }
224*ec779b8eSAndroid Build Coastguard Worker     return itemsStr;
225*ec779b8eSAndroid Build Coastguard Worker }
226*ec779b8eSAndroid Build Coastguard Worker 
227*ec779b8eSAndroid Build Coastguard Worker // Bunch of utility functions that looks for a specific Resource.
228*ec779b8eSAndroid Build Coastguard Worker 
229*ec779b8eSAndroid Build Coastguard Worker //Check whether a given resource (of type and subtype) is found in given resource parcel.
230*ec779b8eSAndroid Build Coastguard Worker bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
231*ec779b8eSAndroid Build Coastguard Worker                      const ::aidl::android::media::MediaResourceParcel& resource);
232*ec779b8eSAndroid Build Coastguard Worker 
233*ec779b8eSAndroid Build Coastguard Worker //Check whether a given resource (of type and subtype) is found in given resource list.
234*ec779b8eSAndroid Build Coastguard Worker bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
235*ec779b8eSAndroid Build Coastguard Worker                      const ResourceList& resources);
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker //Check whether a given resource (of type and subtype) is found in given resource info list.
238*ec779b8eSAndroid Build Coastguard Worker bool hasResourceType(MediaResource::Type type, MediaResource::SubType subType,
239*ec779b8eSAndroid Build Coastguard Worker                      const ResourceInfos& infos);
240*ec779b8eSAndroid Build Coastguard Worker 
241*ec779b8eSAndroid Build Coastguard Worker // Return modifiable list of ResourceInfo for a given process (look up by pid)
242*ec779b8eSAndroid Build Coastguard Worker // from the map of ResourceInfos.
243*ec779b8eSAndroid Build Coastguard Worker ResourceInfos& getResourceInfosForEdit(int pid, PidResourceInfosMap& map);
244*ec779b8eSAndroid Build Coastguard Worker 
245*ec779b8eSAndroid Build Coastguard Worker // Return modifiable ResourceInfo for a given process (look up by pid)
246*ec779b8eSAndroid Build Coastguard Worker // from the map of ResourceInfos.
247*ec779b8eSAndroid Build Coastguard Worker // If the item is not in the map, create one and add it to the map.
248*ec779b8eSAndroid Build Coastguard Worker ResourceInfo& getResourceInfoForEdit(
249*ec779b8eSAndroid Build Coastguard Worker         const aidl::android::media::ClientInfoParcel& clientInfo,
250*ec779b8eSAndroid Build Coastguard Worker         const std::shared_ptr<aidl::android::media::IResourceManagerClient>& client,
251*ec779b8eSAndroid Build Coastguard Worker         ResourceInfos& infos);
252*ec779b8eSAndroid Build Coastguard Worker 
253*ec779b8eSAndroid Build Coastguard Worker // Merge resources from r2 into r1.
254*ec779b8eSAndroid Build Coastguard Worker void mergeResources(::aidl::android::media::MediaResourceParcel& r1,
255*ec779b8eSAndroid Build Coastguard Worker                     const ::aidl::android::media::MediaResourceParcel& r2);
256*ec779b8eSAndroid Build Coastguard Worker 
257*ec779b8eSAndroid Build Coastguard Worker // To notify the media_resource_monitor about the resource being granted.
258*ec779b8eSAndroid Build Coastguard Worker void notifyResourceGranted(
259*ec779b8eSAndroid Build Coastguard Worker         int pid,
260*ec779b8eSAndroid Build Coastguard Worker         const std::vector<::aidl::android::media::MediaResourceParcel>& resources);
261*ec779b8eSAndroid Build Coastguard Worker 
262*ec779b8eSAndroid Build Coastguard Worker } // namespace android
263*ec779b8eSAndroid Build Coastguard Worker 
264*ec779b8eSAndroid Build Coastguard Worker #endif //ANDROID_MEDIA_RESOURCEMANAGERSERVICEUTILS_H_
265