1 /*
2 * Copyright (c) 2021-2022 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_manager.h"
17
18 #include <algorithm>
19 #include "netstack_log.h"
20 #include "napi_utils.h"
21
22 namespace OHOS::NetStack {
23 static constexpr const int CALLBACK_PARAM_NUM = 1;
24
25 static constexpr const int ASYNC_CALLBACK_PARAM_NUM = 2;
26
EventManager()27 EventManager::EventManager() : data_(nullptr), eventRef_(nullptr), isDestroy_(false) {}
28
~EventManager()29 EventManager::~EventManager()
30 {
31 NETSTACK_LOGD("EventManager is destructed by the destructor");
32 }
33
AddListener(napi_env env,const std::string & type,napi_value callback,bool once,bool asyncCallback)34 void EventManager::AddListener(napi_env env, const std::string &type, napi_value callback, bool once,
35 bool asyncCallback)
36 {
37 std::lock_guard lock(mutexForListenersAndEmitByUv_);
38 auto it = std::remove_if(listeners_.begin(), listeners_.end(),
39 [type](const EventListener &listener) -> bool { return listener.MatchType(type); });
40 if (it != listeners_.end()) {
41 listeners_.erase(it, listeners_.end());
42 }
43
44 listeners_.emplace_back(EventListener(env, type, callback, once, asyncCallback));
45 }
46
DeleteListener(const std::string & type,napi_value callback)47 void EventManager::DeleteListener(const std::string &type, napi_value callback)
48 {
49 std::lock_guard lock(mutexForListenersAndEmitByUv_);
50 auto it =
51 std::remove_if(listeners_.begin(), listeners_.end(), [type, callback](const EventListener &listener) -> bool {
52 return listener.Match(type, callback);
53 });
54 listeners_.erase(it, listeners_.end());
55 }
56
Emit(const std::string & type,const std::pair<napi_value,napi_value> & argv)57 void EventManager::Emit(const std::string &type, const std::pair<napi_value, napi_value> &argv)
58 {
59 std::lock_guard lock(mutexForEmitAndEmitByUv_);
60 std::for_each(listeners_.begin(), listeners_.end(), [type, argv](const EventListener &listener) {
61 if (listener.IsAsyncCallback()) {
62 /* AsyncCallback(BusinessError error, T data) */
63 napi_value arg[ASYNC_CALLBACK_PARAM_NUM] = {argv.first, argv.second};
64 listener.Emit(type, ASYNC_CALLBACK_PARAM_NUM, arg);
65 } else {
66 /* Callback(T data) */
67 napi_value arg[CALLBACK_PARAM_NUM] = {argv.second};
68 listener.Emit(type, CALLBACK_PARAM_NUM, arg);
69 }
70 });
71
72 auto it = std::remove_if(listeners_.begin(), listeners_.end(),
73 [type](const EventListener &listener) -> bool { return listener.MatchOnce(type); });
74 listeners_.erase(it, listeners_.end());
75 }
76
SetData(void * data)77 void EventManager::SetData(void *data)
78 {
79 std::lock_guard<std::mutex> lock(dataMutex_);
80 data_ = data;
81 }
82
GetData()83 void *EventManager::GetData()
84 {
85 std::lock_guard<std::mutex> lock(dataMutex_);
86 return data_;
87 }
88
SetQueueData(void * data)89 void EventManager::SetQueueData(void *data)
90 {
91 std::lock_guard<std::mutex> lock(dataQueueMutex_);
92 dataQueue_.push(data);
93 }
94
GetQueueData()95 void *EventManager::GetQueueData()
96 {
97 std::lock_guard<std::mutex> lock(dataQueueMutex_);
98 if (!dataQueue_.empty()) {
99 return dataQueue_.front();
100 }
101 NETSTACK_LOGE("eventManager data queue is empty");
102 return nullptr;
103 }
104
PopQueueData()105 void EventManager::PopQueueData()
106 {
107 std::lock_guard<std::mutex> lock(dataQueueMutex_);
108 if (!dataQueue_.empty()) {
109 dataQueue_.pop();
110 }
111 }
112
EmitByUv(const std::string & type,void * data,void (Handler)(uv_work_t *,int status))113 void EventManager::EmitByUv(const std::string &type, void *data, void(Handler)(uv_work_t *, int status))
114 {
115 std::lock_guard lock1(mutexForEmitAndEmitByUv_);
116 std::lock_guard lock2(mutexForListenersAndEmitByUv_);
117 if (!EventManager::IsManagerValid(this)) {
118 return;
119 }
120
121 std::for_each(listeners_.begin(), listeners_.end(), [type, data, Handler, this](const EventListener &listener) {
122 auto workWrapper = new UvWorkWrapper(data, listener.GetEnv(), type, this);
123 listener.EmitByUv(type, workWrapper, Handler);
124 });
125 }
126
HasEventListener(const std::string & type)127 bool EventManager::HasEventListener(const std::string &type)
128 {
129 std::lock_guard lock(mutexForListenersAndEmitByUv_);
130 return std::any_of(listeners_.begin(), listeners_.end(),
131 [&type](const EventListener &listener) -> bool { return listener.MatchType(type); });
132 }
133
DeleteListener(const std::string & type)134 void EventManager::DeleteListener(const std::string &type)
135 {
136 std::lock_guard lock(mutexForListenersAndEmitByUv_);
137 auto it = std::remove_if(listeners_.begin(), listeners_.end(),
138 [type](const EventListener &listener) -> bool { return listener.MatchType(type); });
139 listeners_.erase(it, listeners_.end());
140 }
141
142 std::unordered_set<EventManager *> EventManager::validManager_;
143 std::mutex EventManager::mutexForManager_;
144
SetInvalid(EventManager * manager)145 void EventManager::SetInvalid(EventManager *manager)
146 {
147 std::lock_guard lock(mutexForManager_);
148 auto pos = validManager_.find(manager);
149 if (pos == validManager_.end()) {
150 NETSTACK_LOGE("The manager is not in the unordered_set");
151 return;
152 }
153 validManager_.erase(pos);
154 delete manager;
155 manager = nullptr;
156 }
157
IsManagerValid(EventManager * manager)158 bool EventManager::IsManagerValid(EventManager *manager)
159 {
160 std::lock_guard lock(mutexForManager_);
161 return validManager_.find(manager) != validManager_.end();
162 }
163
SetValid(EventManager * manager)164 void EventManager::SetValid(EventManager *manager)
165 {
166 std::lock_guard lock(mutexForManager_);
167 validManager_.emplace(manager);
168 }
169
170 #ifdef ENABLE_EVENT_HANDLER
InitNetstackEventHandler()171 bool EventManager::InitNetstackEventHandler()
172 {
173 if (eventRunner_ == nullptr) {
174 NETSTACK_LOGI("event handler is null, create handler.");
175 eventRunner_ = AppExecFwk::EventRunner::Create();
176 if (!eventRunner_) {
177 NETSTACK_LOGE("create event runner failed");
178 return false;
179 }
180 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventRunner_);
181 return true;
182 }
183 return true;
184 }
185
GetNetstackEventHandler()186 std::shared_ptr<AppExecFwk::EventHandler> EventManager::GetNetstackEventHandler()
187 {
188 return eventHandler_;
189 }
190 #endif
191
CreateEventReference(napi_env env,napi_value value)192 void EventManager::CreateEventReference(napi_env env, napi_value value)
193 {
194 if (env != nullptr && value != nullptr) {
195 eventRef_ = NapiUtils::CreateReference(env, value);
196 }
197 }
198
DeleteEventReference(napi_env env)199 void EventManager::DeleteEventReference(napi_env env)
200 {
201 if (env != nullptr && eventRef_ != nullptr) {
202 NapiUtils::DeleteReference(env, eventRef_);
203 }
204 }
205
SetEventDestroy(bool flag)206 void EventManager::SetEventDestroy(bool flag)
207 {
208 isDestroy_.store(flag);
209 }
210
IsEventDestroy()211 bool EventManager::IsEventDestroy()
212 {
213 return isDestroy_.load();
214 }
215
UvWorkWrapper(void * theData,napi_env theEnv,std::string eventType,EventManager * eventManager)216 UvWorkWrapper::UvWorkWrapper(void *theData, napi_env theEnv, std::string eventType, EventManager *eventManager)
217 : data(theData), env(theEnv), type(std::move(eventType)), manager(eventManager)
218 {
219 }
220 } // namespace OHOS::NetStack
221