1 /*
2 * Copyright (c) 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
16 #include "event_listener_mgr.h"
17
18 #include "accesstoken_kit.h"
19 #include "ipc_skeleton.h"
20 #include "app_mgr_constants.h"
21 #include "parameters.h"
22 #include "res_sched_log.h"
23 #include "res_sched_common_death_recipient.h"
24 #include "res_sched_event_listener_proxy.h"
25
26 namespace OHOS {
27 namespace ResourceSchedule {
28 IMPLEMENT_SINGLE_INSTANCE(EventListenerMgr);
29
~EventListenerMgr()30 EventListenerMgr::~EventListenerMgr()
31 {
32 std::lock_guard<std::mutex> autoLock(mutex_);
33 eventListenerMap_.clear();
34 }
35
Init()36 void EventListenerMgr::Init()
37 {
38 if (initialized_) {
39 RESSCHED_LOGE("EventListenerMgr has been initialized");
40 return;
41 }
42 eventListenerDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(
43 new (std::nothrow) ResSchedCommonDeathRecipient(
44 std::bind(&EventListenerMgr::OnRemoteListenerDied, this, std::placeholders::_1)));
45 eventSenderQueue_ = std::make_shared<ffrt::queue>("EventSenderQueue");
46 initialized_ = true;
47 }
48
Deinit()49 void EventListenerMgr::Deinit()
50 {
51 eventSenderQueue_.reset();
52 }
53
RegisterEventListener(int32_t callingPid,const sptr<IRemoteObject> & listener,uint32_t eventType,uint32_t listenerGroup)54 void EventListenerMgr::RegisterEventListener(int32_t callingPid,
55 const sptr<IRemoteObject>& listener, uint32_t eventType, uint32_t listenerGroup)
56 {
57 RESSCHED_LOGD("%{public}s:called, pid = %{public}d.", __func__, callingPid);
58 if (listener == nullptr) {
59 RESSCHED_LOGE("%{public}s:listener is null", __func__);
60 return;
61 }
62 if (eventListenerDeathRecipient_ == nullptr) {
63 RESSCHED_LOGE("%{public}s:error due to eventListenerDeathRecipient_ null", __func__);
64 return;
65 }
66 std::lock_guard<std::mutex> autoLock(mutex_);
67 auto iter = eventListenerMap_.find(eventType);
68 if (iter != eventListenerMap_.end() && iter->second.find((pid_t)callingPid) != iter->second.end()) {
69 if (iter->second[(pid_t)callingPid].groups.count(listenerGroup) == 0) {
70 iter->second[(pid_t)callingPid].groups.emplace(listenerGroup);
71 RESSCHED_LOGI("%{public}s:pid = %{public}d register eventType %{public}d group %{public}d succeed.",
72 __func__, callingPid, eventType, listenerGroup);
73 } else {
74 RESSCHED_LOGE("%{public}s:pid %{public}d has benn registered eventType %{public}d group %{public}d",
75 __func__, callingPid, eventType, listenerGroup);
76 }
77 return;
78 }
79 EventListenerInfo info;
80 info.listener = listener;
81 info.pid = (pid_t)callingPid;
82 info.groups.emplace(listenerGroup);
83 eventListenerMap_[eventType][info.pid] = info;
84 listener->AddDeathRecipient(eventListenerDeathRecipient_);
85 RESSCHED_LOGI("%{public}s:pid = %{public}d register eventType %{public}d group %{public}d succeed.",
86 __func__, callingPid, eventType, listenerGroup);
87 }
88
UnRegisterEventListener(int32_t callingPid,uint32_t eventType,uint32_t listenerGroup)89 void EventListenerMgr::UnRegisterEventListener(int32_t callingPid, uint32_t eventType, uint32_t listenerGroup)
90 {
91 RESSCHED_LOGD("%{public}s: called", __func__);
92 std::lock_guard<std::mutex> autoLock(mutex_);
93 auto iter = eventListenerMap_.find(eventType);
94 if (iter != eventListenerMap_.end()) {
95 auto listenerItem = iter->second.find(callingPid);
96 if (listenerItem != iter->second.end()) {
97 listenerItem->second.groups.erase(listenerGroup);
98 if (listenerItem->second.groups.size() != 0) {
99 return;
100 }
101 listenerItem->second.listener->RemoveDeathRecipient(eventListenerDeathRecipient_);
102 iter->second.erase(callingPid);
103 if (iter->second.empty()) {
104 eventListenerMap_.erase(eventType);
105 }
106 RESSCHED_LOGI("%{public}s: pid:%{public}d unregister eventType %{public}d succeed",
107 __func__, callingPid, eventType);
108 }
109 }
110 }
111
OnRemoteListenerDied(const sptr<IRemoteObject> & listener)112 void EventListenerMgr::OnRemoteListenerDied(const sptr<IRemoteObject>& listener)
113 {
114 RESSCHED_LOGD("%{public}s:called", __func__);
115 if (listener == nullptr) {
116 RESSCHED_LOGW("remote listener null");
117 return;
118 }
119 RemoveListenerLock(listener);
120 }
121
SendEvent(uint32_t eventType,uint32_t eventValue,const nlohmann::json & extInfo,uint32_t listenerGroup)122 void EventListenerMgr::SendEvent(uint32_t eventType, uint32_t eventValue, const nlohmann::json &extInfo,
123 uint32_t listenerGroup)
124 {
125 RESSCHED_LOGD("%{public}s:called", __func__);
126 if (eventType < ResType::EventType::EVENT_START ||
127 eventType > ResType::EventType::EVENT_END) {
128 RESSCHED_LOGW("invalid eventType:%{public}d", eventType);
129 return;
130 }
131 if (eventSenderQueue_ == nullptr) {
132 RESSCHED_LOGE("%{public}s:error due to eventSenderQueue_ null.", __func__);
133 return;
134 }
135 SendEventLock(eventType, eventValue, extInfo, listenerGroup);
136 }
137
RemoveListenerLock(const sptr<IRemoteObject> & listener)138 void EventListenerMgr::RemoveListenerLock(const sptr<IRemoteObject>& listener)
139 {
140 RESSCHED_LOGD("%{public}s:called", __func__);
141 std::lock_guard<std::mutex> autoLock(mutex_);
142 for (auto& listeners : eventListenerMap_) {
143 for (auto& listenerInfoItem : listeners.second) {
144 if (listenerInfoItem.second.listener != listener) {
145 continue;
146 }
147 listenerInfoItem.second.listener->RemoveDeathRecipient(eventListenerDeathRecipient_);
148 listeners.second.erase(listenerInfoItem.first);
149 break;
150 }
151 }
152 }
153
SendEventLock(uint32_t eventType,uint32_t eventValue,const nlohmann::json & extInfo,uint32_t listenerGroup)154 void EventListenerMgr::SendEventLock(uint32_t eventType, uint32_t eventValue, const nlohmann::json& extInfo,
155 uint32_t listenerGroup)
156 {
157 std::vector<sptr<IRemoteObject>> listenerArray;
158 {
159 std::lock_guard<std::mutex> autoLock(mutex_);
160 auto listeners = eventListenerMap_.find(eventType);
161 if (listeners == eventListenerMap_.end()) {
162 RESSCHED_LOGD("eventType:%{public}d no listener.", eventType);
163 return;
164 }
165 for (auto& listenerItem : listeners->second) {
166 if (listenerItem.second.groups.count(listenerGroup) == 1) {
167 listenerArray.push_back(listenerItem.second.listener);
168 }
169 }
170 }
171 HandleSendEvent(listenerArray, eventType, eventValue, extInfo, listenerGroup);
172 }
173
DumpRegisterInfo()174 std::unordered_map<int32_t, std::vector<pid_t>> EventListenerMgr::DumpRegisterInfo()
175 {
176 std::unordered_map<int32_t, std::vector<pid_t>> ret;
177 {
178 std::lock_guard<std::mutex> autoLock(mutex_);
179 for (auto& listenerItem : eventListenerMap_) {
180 ret[listenerItem.first] = {};
181 for (auto listener : listenerItem.second) {
182 ret[listenerItem.first].emplace_back(listener.second.pid);
183 }
184 }
185 }
186 return ret;
187 }
188
HandleSendEvent(std::vector<sptr<IRemoteObject>> & listenerVec,uint32_t eventType,uint32_t eventValue,const nlohmann::json & extInfo,uint32_t listenerGroup)189 void EventListenerMgr::HandleSendEvent(std::vector<sptr<IRemoteObject>>& listenerVec,
190 uint32_t eventType, uint32_t eventValue, const nlohmann::json &extInfo, uint32_t listenerGroup)
191 {
192 auto func = [listenerVec, eventType, eventValue, extInfo, listenerGroup] () {
193 for (auto& listener : listenerVec) {
194 if (listener == nullptr) {
195 continue;
196 }
197 auto proxy = std::make_unique<ResSchedEventListenerProxy>(listener);
198 proxy->OnReceiveEvent(eventType, eventValue, listenerGroup,
199 extInfo.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace));
200 }
201 };
202 eventSenderQueue_->submit(func);
203 }
204 } // ResourceSchedule
205 } // OHOS