1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "res_sched_client.h"
16 #include <string> // for to_string
17 #include <unistd.h> // for getpid
18 #include <new> // for nothrow, operator new
19 #include <unordered_map> // for unordered_map, __hash_map_con...
20 #include <utility> // for pair
21 #include "if_system_ability_manager.h" // for ISystemAbilityManager
22 #include "iremote_broker.h" // for iface_cast
23 #include "iservice_registry.h" // for SystemAbilityManagerClient
24 #include "res_sched_errors.h" // for GET_RES_SCHED_SERVICE_FAILED
25 #include "res_sched_log.h" // for RESSCHED_LOGE, RESSCHED_LOGD
26 #include "system_ability_definition.h" // for RES_SCHED_SYS_ABILITY_ID
27 #include "ffrt_inner.h" // for future
28
29 namespace OHOS {
30 namespace ResourceSchedule {
31 namespace {
32 bool g_isDestroyed = false;
33 constexpr int32_t CHECK_MUTEX_TIMEOUT = 500; // 500ms
34 }
GetInstance()35 ResSchedClient& ResSchedClient::GetInstance()
36 {
37 static ResSchedClient instance;
38 return instance;
39 }
~ResSchedClient()40 ResSchedClient::~ResSchedClient()
41 {
42 std::lock_guard<std::mutex> lock(mutex_);
43 g_isDestroyed = true;
44 if (rss_ && rss_->AsObject()) {
45 rss_->AsObject()->RemoveDeathRecipient(recipient_);
46 }
47 rss_ = nullptr;
48 systemloadCbRegistered_ = false;
49 }
50
ReportData(uint32_t resType,int64_t value,const std::unordered_map<std::string,std::string> & mapPayload)51 void ResSchedClient::ReportData(uint32_t resType, int64_t value,
52 const std::unordered_map<std::string, std::string>& mapPayload)
53 {
54 if (TryConnect() != ERR_OK) {
55 return;
56 }
57 RESSCHED_LOGD("ResSchedClient::ReportData receive resType = %{public}u, value = %{public}lld.",
58 resType, (long long)value);
59 nlohmann::json payload;
60 for (auto it = mapPayload.begin(); it != mapPayload.end(); ++it) {
61 payload[it->first] = it->second;
62 }
63 std::lock_guard<std::mutex> lock(mutex_);
64 if (rss_ == nullptr) {
65 RESSCHED_LOGD("ResSchedClient::ReportData fail to get resource schedule service.");
66 return;
67 }
68 rss_->ReportData(resType, value, payload);
69 }
70
ReportSyncEvent(const uint32_t resType,const int64_t value,const nlohmann::json & payload,nlohmann::json & reply)71 int32_t ResSchedClient::ReportSyncEvent(const uint32_t resType, const int64_t value, const nlohmann::json& payload,
72 nlohmann::json& reply)
73 {
74 RESSCHED_LOGD("%{public}s: resType=%{public}u, value=%{public}lld.", __func__, resType, (long long)value);
75
76 sptr<IResSchedService> proxy = GetProxy();
77 if (proxy == nullptr) {
78 RESSCHED_LOGD("%{public}s: fail to get rss.", __func__);
79 return RES_SCHED_CONNECT_FAIL;
80 }
81 if (resType == ResType::SYNC_RES_TYPE_CHECK_MUTEX_BEFORE_START) {
82 ffrt::future<std::pair<int32_t, nlohmann::json>> fut = ffrt::async([resType, value, payload, proxy] {
83 nlohmann::json ffrtReply;
84 if (proxy == nullptr) {
85 return std::pair<int32_t, nlohmann::json>(RES_SCHED_CONNECT_FAIL, ffrtReply);
86 }
87 int32_t ret = proxy->ReportSyncEvent(resType, value, payload, ffrtReply);
88 return std::pair<int32_t, nlohmann::json>(ret, ffrtReply);
89 });
90
91 ffrt::future_status status = fut.wait_for(std::chrono::milliseconds(CHECK_MUTEX_TIMEOUT));
92 if (status == ffrt::future_status::ready) {
93 auto result = fut.get();
94 reply = std::move(result.second);
95 return result.first;
96 }
97 RESSCHED_LOGW("%{public}s: sync time out", __func__);
98 return RES_SCHED_REQUEST_FAIL;
99 } else {
100 return proxy->ReportSyncEvent(resType, value, payload, reply);
101 }
102 }
103
KillProcess(const std::unordered_map<std::string,std::string> & mapPayload)104 int32_t ResSchedClient::KillProcess(const std::unordered_map<std::string, std::string>& mapPayload)
105 {
106 RESSCHED_LOGD("ResSchedClient::KillProcess receive mission.");
107 nlohmann::json payload;
108 for (auto it = mapPayload.begin(); it != mapPayload.end(); ++it) {
109 payload[it->first] = it->second;
110 }
111 sptr<IResSchedService> proxy = GetProxy();
112 if (proxy == nullptr) {
113 RESSCHED_LOGD("ResSchedClient::KillProcess fail to get resource schedule service.");
114 return RES_SCHED_KILL_PROCESS_FAIL;
115 }
116 return proxy->KillProcess(payload);
117 }
118
RegisterSystemloadNotifier(const sptr<ResSchedSystemloadNotifierClient> & callbackObj)119 void ResSchedClient::RegisterSystemloadNotifier(const sptr<ResSchedSystemloadNotifierClient>& callbackObj)
120 {
121 RESSCHED_LOGD("ResSchedClient::RegisterSystemloadNotifier receive mission.");
122 std::lock_guard<std::mutex> lock(mutex_);
123 if (InitSystemloadListenersLocked() != ERR_OK) {
124 RESSCHED_LOGE("ResSchedClient::RegisterSystemloadNotifier init listener failed.");
125 return;
126 }
127 systemloadLevelListener_->RegisterSystemloadLevelCb(callbackObj);
128 if (!systemloadCbRegistered_ && !systemloadLevelListener_->IsSystemloadCbArrayEmpty() && rss_) {
129 rss_->RegisterSystemloadNotifier(systemloadLevelListener_);
130 systemloadCbRegistered_ = true;
131 }
132 AddResSaListenerLocked();
133 }
134
UnRegisterSystemloadNotifier(const sptr<ResSchedSystemloadNotifierClient> & callbackObj)135 void ResSchedClient::UnRegisterSystemloadNotifier(const sptr<ResSchedSystemloadNotifierClient>& callbackObj)
136 {
137 RESSCHED_LOGD("ResSchedClient::UnRegisterSystemloadNotifier receive mission.");
138 std::lock_guard<std::mutex> lock(mutex_);
139 if (systemloadLevelListener_ == nullptr) {
140 RESSCHED_LOGE("ResSchedClient::UnRegisterSystemloadNotifier systemloadLevelListener is null.");
141 return;
142 }
143 systemloadLevelListener_->UnRegisterSystemloadLevelCb(callbackObj);
144 UnRegisterSystemloadListenersLocked();
145 }
146
RegisterEventListener(const sptr<ResSchedEventListener> & eventListener,uint32_t eventType,uint32_t listenerGroup)147 void ResSchedClient::RegisterEventListener(const sptr<ResSchedEventListener>& eventListener,
148 uint32_t eventType, uint32_t listenerGroup)
149 {
150 RESSCHED_LOGD("%{public}s:receive mission.", __func__);
151 std::lock_guard<std::mutex> lock(mutex_);
152 if (InitInnerEventListenerLocked() != ERR_OK) {
153 RESSCHED_LOGE("ResSchedClient::RegisterEventListener init listener failed.");
154 return;
155 }
156 innerEventListener_->RegisterEventListener(eventListener, eventType, listenerGroup);
157 auto item = registeredInnerEvents.find(eventType);
158 if ((item == registeredInnerEvents.end() || item->second.count(listenerGroup) == 0) &&
159 !innerEventListener_->IsInnerEventMapEmpty(eventType, listenerGroup) && rss_) {
160 rss_->RegisterEventListener(innerEventListener_, eventType, listenerGroup);
161 if (item == registeredInnerEvents.end()) {
162 registeredInnerEvents.emplace(eventType, std::unordered_set<uint32_t>());
163 }
164 registeredInnerEvents[eventType].insert(listenerGroup);
165 }
166 AddResSaListenerLocked();
167 }
168
UnRegisterEventListener(const sptr<ResSchedEventListener> & eventListener,uint32_t eventType,uint32_t listenerGroup)169 void ResSchedClient::UnRegisterEventListener(const sptr<ResSchedEventListener>& eventListener,
170 uint32_t eventType, uint32_t listenerGroup)
171 {
172 RESSCHED_LOGD("%{public}s:receive mission.", __func__);
173 std::lock_guard<std::mutex> lock(mutex_);
174 if (innerEventListener_ == nullptr) {
175 RESSCHED_LOGE("%{public}s: innerEventListener_ is null.", __func__);
176 return;
177 }
178 innerEventListener_->UnRegisterEventListener(eventListener, eventType, listenerGroup);
179 UnRegisterEventListenerLocked(eventType, listenerGroup);
180 }
181
GetSystemloadLevel()182 int32_t ResSchedClient::GetSystemloadLevel()
183 {
184 if (TryConnect() != ERR_OK) {
185 return RES_SCHED_CONNECT_FAIL;
186 }
187 RESSCHED_LOGD("ResSchedClient::GetSystemloadLevel receive mission.");
188
189 std::lock_guard<std::mutex> lock(mutex_);
190 if (rss_ == nullptr) {
191 RESSCHED_LOGE("ResSchedClient::GetSystemloadLevel fail to get resource schedule service.");
192 return RES_SCHED_CONNECT_FAIL;
193 }
194 return rss_->GetSystemloadLevel();
195 }
196
IsAllowedAppPreload(const std::string & bundleName,int32_t preloadMode)197 bool ResSchedClient::IsAllowedAppPreload(const std::string& bundleName, int32_t preloadMode)
198 {
199 if (TryConnect() != ERR_OK) {
200 return false;
201 }
202
203 std::lock_guard<std::mutex> lock(mutex_);
204 if (rss_ == nullptr) {
205 RESSCHED_LOGE("ResSchedClient::IsAllowedAppPreload fail to get resource schedule service.");
206 return false;
207 }
208
209 RESSCHED_LOGD("App preload bundleName %{public}s, preloadMode %{public}d", bundleName.c_str(), preloadMode);
210 return rss_->IsAllowedAppPreload(bundleName, preloadMode);
211 }
212
GetProxy()213 sptr<IResSchedService> ResSchedClient::GetProxy()
214 {
215 if (TryConnect() == ERR_OK) {
216 std::lock_guard<std::mutex> lock(mutex_);
217 return rss_;
218 }
219 return nullptr;
220 }
221
TryConnect()222 ErrCode ResSchedClient::TryConnect()
223 {
224 std::lock_guard<std::mutex> lock(mutex_);
225 if (g_isDestroyed) {
226 return GET_RES_SCHED_SERVICE_FAILED;
227 }
228 if (rss_) {
229 return ERR_OK;
230 }
231
232 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
233 if (!systemManager) {
234 RESSCHED_LOGE("ResSchedClient::Fail to get registry.");
235 return GET_RES_SCHED_SERVICE_FAILED;
236 }
237
238 remoteObject_ = systemManager->CheckSystemAbility(RES_SCHED_SYS_ABILITY_ID);
239 if (!remoteObject_) {
240 RESSCHED_LOGE("ResSchedClient::Fail to connect resource schedule service.");
241 return GET_RES_SCHED_SERVICE_FAILED;
242 }
243
244 rss_ = iface_cast<IResSchedService>(remoteObject_);
245 if (!rss_) {
246 return GET_RES_SCHED_SERVICE_FAILED;
247 }
248 recipient_ = new (std::nothrow) ResSchedDeathRecipient(*this);
249 if (!recipient_) {
250 RESSCHED_LOGE("ResSchedClient::New ResSchedDeathRecipient failed.");
251 return GET_RES_SCHED_SERVICE_FAILED;
252 }
253 rss_->AsObject()->AddDeathRecipient(recipient_);
254 AddResSaListenerLocked();
255 RESSCHED_LOGD("ResSchedClient::Connect resource schedule service success.");
256 return ERR_OK;
257 }
258
StopRemoteObject()259 void ResSchedClient::StopRemoteObject()
260 {
261 std::lock_guard<std::mutex> lock(mutex_);
262 if (rss_ && rss_->AsObject()) {
263 rss_->AsObject()->RemoveDeathRecipient(recipient_);
264 }
265 rss_ = nullptr;
266 systemloadCbRegistered_ = false;
267 registeredInnerEvents.clear();
268 }
269
AddResSaListenerLocked()270 void ResSchedClient::AddResSaListenerLocked()
271 {
272 if (resSchedSvcStatusListener_ != nullptr) {
273 return;
274 }
275 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
276 if (!systemManager) {
277 RESSCHED_LOGE("ResSchedClient::Fail to get sa mgr client.");
278 return;
279 }
280 resSchedSvcStatusListener_ = new (std::nothrow) ResSchedSvcStatusChange;
281 if (resSchedSvcStatusListener_ == nullptr) {
282 RESSCHED_LOGE("ResSchedClient::Fail to new res svc listener.");
283 return;
284 }
285 int32_t ret = systemManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, resSchedSvcStatusListener_);
286 if (ret != ERR_OK) {
287 RESSCHED_LOGE("ResSchedClient::Register sa status change failed.");
288 resSchedSvcStatusListener_ = nullptr;
289 }
290 }
291
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)292 void ResSchedClient::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
293 {
294 if (systemAbilityId != RES_SCHED_SYS_ABILITY_ID) {
295 RESSCHED_LOGE("ResSchedClient::OnAddSystemAbility is not res sa id.");
296 return;
297 }
298 if (TryConnect() != ERR_OK) {
299 return;
300 }
301 std::lock_guard<std::mutex> lock(mutex_);
302 if (InitInnerEventListenerLocked() != ERR_OK) {
303 RESSCHED_LOGE("ResSchedClient::OnAddSystemAbility init event listener failed.");
304 } else if (innerEventListener_ && rss_) {
305 RecoverEventListener();
306 }
307 if (InitSystemloadListenersLocked() != ERR_OK) {
308 RESSCHED_LOGE("ResSchedClient::OnAddSystemAbility init listener failed.");
309 return;
310 }
311 if (!systemloadCbRegistered_ && !systemloadLevelListener_->IsSystemloadCbArrayEmpty() && rss_) {
312 rss_->RegisterSystemloadNotifier(systemloadLevelListener_);
313 systemloadCbRegistered_ = true;
314 }
315 }
316
RecoverEventListener()317 void ResSchedClient::RecoverEventListener()
318 {
319 for (auto typeAndGroup : innerEventListener_->GetRegisteredTypesAndGroup()) {
320 auto type = typeAndGroup.first;
321 for (auto group : typeAndGroup.second) {
322 if (!rss_) {
323 return;
324 }
325 rss_->RegisterEventListener(innerEventListener_, type, group);
326 if (registeredInnerEvents.find(type) == registeredInnerEvents.end()) {
327 registeredInnerEvents.emplace(type, std::unordered_set<uint32_t>());
328 }
329 registeredInnerEvents[type].insert(group);
330 }
331 }
332 }
333
InitSystemloadListenersLocked()334 int32_t ResSchedClient::InitSystemloadListenersLocked()
335 {
336 if (systemloadLevelListener_ != nullptr) {
337 return ERR_OK;
338 }
339 systemloadLevelListener_ = new (std::nothrow) SystemloadLevelListener;
340 if (systemloadLevelListener_ == nullptr) {
341 RESSCHED_LOGW("ResSchedClient::InitSystemloadListenersLocked new listener error.");
342 return RES_SCHED_DATA_ERROR;
343 }
344 return ERR_OK;
345 }
346
InitInnerEventListenerLocked()347 int32_t ResSchedClient::InitInnerEventListenerLocked()
348 {
349 if (innerEventListener_ != nullptr) {
350 return ERR_OK;
351 }
352 innerEventListener_ = new (std::nothrow) InnerEventListener;
353 if (innerEventListener_ == nullptr) {
354 RESSCHED_LOGW("ResSchedClient::InitInnerEventListenerLocked new listener error.");
355 return RES_SCHED_DATA_ERROR;
356 }
357 return ERR_OK;
358 }
359
UnRegisterEventListenerLocked(uint32_t eventType,uint32_t listenerGroup)360 void ResSchedClient::UnRegisterEventListenerLocked(uint32_t eventType, uint32_t listenerGroup)
361 {
362 if (innerEventListener_->IsInnerEventMapEmpty(eventType, listenerGroup) && rss_) {
363 rss_->UnRegisterEventListener(eventType, listenerGroup);
364 auto item = registeredInnerEvents.find(eventType);
365 if (item != registeredInnerEvents.end()) {
366 item->second.erase(listenerGroup);
367 }
368 }
369 }
370
371
UnRegisterSystemloadListenersLocked()372 void ResSchedClient::UnRegisterSystemloadListenersLocked()
373 {
374 if (systemloadLevelListener_->IsSystemloadCbArrayEmpty() && rss_) {
375 rss_->UnRegisterSystemloadNotifier();
376 systemloadCbRegistered_ = false;
377 }
378 }
379
ResSchedDeathRecipient(ResSchedClient & resSchedClient)380 ResSchedClient::ResSchedDeathRecipient::ResSchedDeathRecipient(ResSchedClient &resSchedClient)
381 : resSchedClient_(resSchedClient) {}
382
~ResSchedDeathRecipient()383 ResSchedClient::ResSchedDeathRecipient::~ResSchedDeathRecipient() {}
384
OnRemoteDied(const wptr<IRemoteObject> & remote)385 void ResSchedClient::ResSchedDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
386 {
387 resSchedClient_.StopRemoteObject();
388 }
389
~SystemloadLevelListener()390 ResSchedClient::SystemloadLevelListener::~SystemloadLevelListener()
391 {
392 std::lock_guard<std::mutex> lock(listMutex_);
393 systemloadLevelCbs_.clear();
394 }
395
RegisterSystemloadLevelCb(const sptr<ResSchedSystemloadNotifierClient> & callbackObj)396 void ResSchedClient::SystemloadLevelListener::RegisterSystemloadLevelCb(
397 const sptr<ResSchedSystemloadNotifierClient>& callbackObj)
398 {
399 std::lock_guard<std::mutex> lock(listMutex_);
400 if (callbackObj != nullptr) {
401 for (auto& iter : systemloadLevelCbs_) {
402 if (iter == callbackObj) {
403 RESSCHED_LOGE("ResSchedClient register an exist callback object.");
404 return;
405 }
406 }
407 systemloadLevelCbs_.emplace_back(callbackObj);
408 }
409 RESSCHED_LOGD("Client has registered %{public}d listeners.", static_cast<int32_t>(systemloadLevelCbs_.size()));
410 }
411
UnRegisterSystemloadLevelCb(const sptr<ResSchedSystemloadNotifierClient> & callbackObj)412 void ResSchedClient::SystemloadLevelListener::UnRegisterSystemloadLevelCb(
413 const sptr<ResSchedSystemloadNotifierClient>& callbackObj)
414 {
415 std::lock_guard<std::mutex> lock(listMutex_);
416 systemloadLevelCbs_.remove(callbackObj);
417 RESSCHED_LOGD(
418 "Client left %{public}d systemload level listeners.", static_cast<int32_t>(systemloadLevelCbs_.size()));
419 }
420
IsSystemloadCbArrayEmpty()421 bool ResSchedClient::SystemloadLevelListener::IsSystemloadCbArrayEmpty()
422 {
423 std::lock_guard<std::mutex> lock(listMutex_);
424 return systemloadLevelCbs_.empty();
425 }
426
OnSystemloadLevel(int32_t level)427 void ResSchedClient::SystemloadLevelListener::OnSystemloadLevel(int32_t level)
428 {
429 std::list<sptr<ResSchedSystemloadNotifierClient>> notifyList;
430 {
431 std::lock_guard<std::mutex> lock(listMutex_);
432 for (auto& iter : systemloadLevelCbs_) {
433 notifyList.push_back(iter);
434 }
435 }
436 // copy notifiers from systemloadLevelCbs_ to revent dead lock
437 for (auto& notifier : notifyList) {
438 if (notifier != nullptr) {
439 notifier->OnSystemloadLevel(level);
440 }
441 }
442 }
443
~InnerEventListener()444 ResSchedClient::InnerEventListener::~InnerEventListener()
445 {
446 std::lock_guard<std::mutex> lock(eventMutex_);
447 eventListeners_.clear();
448 }
449
RegisterEventListener(const sptr<ResSchedEventListener> & eventListener,uint32_t eventType,uint32_t listenerGroup)450 void ResSchedClient::InnerEventListener::RegisterEventListener(const sptr<ResSchedEventListener>& eventListener,
451 uint32_t eventType, uint32_t listenerGroup)
452 {
453 std::lock_guard<std::mutex> lock(eventMutex_);
454 if (eventListener == nullptr) {
455 RESSCHED_LOGE("ResSchedClient register an null eventListener object.");
456 return;
457 }
458 auto item = eventListeners_.find(eventType);
459 if (item == eventListeners_.end()) {
460 eventListeners_.emplace(eventType, std::unordered_map<uint32_t, std::list<sptr<ResSchedEventListener>>>());
461 eventListeners_[eventType].emplace(listenerGroup, std::list<sptr<ResSchedEventListener>>());
462 eventListeners_[eventType][listenerGroup].emplace_back(eventListener);
463 } else {
464 auto listenerItem = item->second.find(listenerGroup);
465 if (listenerItem == item->second.end()) {
466 item->second.emplace(listenerGroup, std::list<sptr<ResSchedEventListener>>());
467 }
468 for (auto& iter : listenerItem->second) {
469 if (iter == eventListener) {
470 RESSCHED_LOGE("ResSchedClient register an exist eventListener object.");
471 return;
472 }
473 }
474 item->second[listenerGroup].emplace_back(eventListener);
475 }
476 RESSCHED_LOGD("Client has registered %{public}d eventListener with type:%{public}d.",
477 static_cast<int32_t>(eventListeners_[eventType].size()), eventType);
478 }
479
UnRegisterEventListener(const sptr<ResSchedEventListener> & eventListener,uint32_t eventType,uint32_t listenerGroup)480 void ResSchedClient::InnerEventListener::UnRegisterEventListener(const sptr<ResSchedEventListener>& eventListener,
481 uint32_t eventType, uint32_t listenerGroup)
482 {
483 std::lock_guard<std::mutex> lock(eventMutex_);
484 auto item = eventListeners_.find(eventType);
485 if (item == eventListeners_.end()) {
486 RESSCHED_LOGE("eventListener not registered");
487 return;
488 }
489 auto listenerItem = item->second.find(listenerGroup);
490 if (listenerItem == item->second.end()) {
491 return;
492 }
493 listenerItem->second.remove(eventListener);
494 if (listenerItem->second.size() == 0) {
495 item->second.erase(listenerGroup);
496 RESSCHED_LOGD("Client left 0 listeners with type %{public}d group %{public}d", eventType, listenerGroup);
497 }
498 if (item->second.size() == 0) {
499 eventListeners_.erase(eventType);
500 RESSCHED_LOGD("Client left 0 listeners with type %{public}d.", eventType);
501 return;
502 }
503 RESSCHED_LOGD("Client left %{public}d listeners with type %{public}d.",
504 static_cast<int32_t>(item->second.size()), eventType);
505 }
506
OnReceiveEvent(uint32_t eventType,uint32_t eventValue,uint32_t listenerGroup,const nlohmann::json & extInfo)507 void ResSchedClient::InnerEventListener::OnReceiveEvent(uint32_t eventType, uint32_t eventValue, uint32_t listenerGroup,
508 const nlohmann::json& extInfo)
509 {
510 std::unordered_map<std::string, std::string> extInfoMap;
511 for (auto it = extInfo.begin(); it != extInfo.end(); ++it) {
512 extInfoMap[it.key()] = it.value().get<std::string>();
513 }
514 std::list<sptr<ResSchedEventListener>> listenerList;
515 {
516 std::lock_guard<std::mutex> lock(eventMutex_);
517 auto item = eventListeners_.find(eventType);
518 if (item == eventListeners_.end()) {
519 return;
520 }
521 auto listenerItem = item->second.find(listenerGroup);
522 for (auto& iter : listenerItem->second) {
523 listenerList.push_back(iter);
524 }
525 }
526 // copy notifiers from systemloadLevelCbs_ to revent dead lock
527 for (auto& listener : listenerList) {
528 if (listener != nullptr) {
529 listener->OnReceiveEvent(eventType, eventValue, extInfoMap);
530 }
531 }
532 }
533
IsInnerEventMapEmpty(uint32_t eventType,uint32_t listenerGroup)534 bool ResSchedClient::InnerEventListener::IsInnerEventMapEmpty(uint32_t eventType, uint32_t listenerGroup)
535 {
536 std::lock_guard<std::mutex> lock(eventMutex_);
537 auto item = eventListeners_.find(eventType);
538 if (item == eventListeners_.end()) {
539 return true;
540 }
541 auto listenerItem = item->second.find(listenerGroup);
542 return listenerItem == item->second.end() || listenerItem->second.empty();
543 }
544
GetRegisteredTypesAndGroup()545 std::unordered_map<uint32_t, std::list<uint32_t>> ResSchedClient::InnerEventListener::GetRegisteredTypesAndGroup()
546 {
547 std::unordered_map<uint32_t, std::list<uint32_t>> ret;
548 std::lock_guard<std::mutex> lock(eventMutex_);
549 for (auto item : eventListeners_) {
550 ret.emplace(item.first, std::list<uint32_t>());
551 for (auto listenerItem : item.second) {
552 ret[item.first].emplace_back(listenerItem.first);
553 }
554 }
555 return ret;
556 }
557
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)558 void ResSchedSvcStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
559 {
560 RESSCHED_LOGD("ResSchedSvcStatusChange::OnAddSystemAbility called, said : %{public}d.", systemAbilityId);
561 ResSchedClient::GetInstance().OnAddSystemAbility(systemAbilityId, deviceId);
562 }
563
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)564 void ResSchedSvcStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
565 {
566 RESSCHED_LOGD("ResSchedSvcStatusChange::OnRemoveSystemAbility called.");
567 }
568
ReportData(uint32_t resType,int64_t value,const std::unordered_map<std::string,std::string> & mapPayload)569 extern "C" void ReportData(uint32_t resType, int64_t value,
570 const std::unordered_map<std::string, std::string>& mapPayload)
571 {
572 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
573 }
574
KillProcess(const std::unordered_map<std::string,std::string> & mapPayload)575 extern "C" void KillProcess(const std::unordered_map<std::string, std::string>& mapPayload)
576 {
577 ResSchedClient::GetInstance().KillProcess(mapPayload);
578 }
579 } // namespace ResourceSchedule
580 } // namespace OHOS
581