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 if (listener.MatchType(type)) {
123 auto workWrapper = new UvWorkWrapper(data, listener.GetEnv(), type, this);
124 listener.EmitByUv(type, workWrapper, Handler);
125 }
126 });
127 }
128
HasEventListener(const std::string & type)129 bool EventManager::HasEventListener(const std::string &type)
130 {
131 std::lock_guard lock(mutexForListenersAndEmitByUv_);
132 return std::any_of(listeners_.begin(), listeners_.end(),
133 [&type](const EventListener &listener) -> bool { return listener.MatchType(type); });
134 }
135
DeleteListener(const std::string & type)136 void EventManager::DeleteListener(const std::string &type)
137 {
138 std::lock_guard lock(mutexForListenersAndEmitByUv_);
139 auto it = std::remove_if(listeners_.begin(), listeners_.end(),
140 [type](const EventListener &listener) -> bool { return listener.MatchType(type); });
141 listeners_.erase(it, listeners_.end());
142 }
143
144 std::unordered_set<EventManager *> EventManager::validManager_;
145 std::mutex EventManager::mutexForManager_;
146
SetInvalid(EventManager * manager)147 void EventManager::SetInvalid(EventManager *manager)
148 {
149 std::lock_guard lock(mutexForManager_);
150 auto pos = validManager_.find(manager);
151 if (pos == validManager_.end()) {
152 NETSTACK_LOGE("The manager is not in the unordered_set");
153 return;
154 }
155 validManager_.erase(pos);
156 delete manager;
157 manager = nullptr;
158 }
159
IsManagerValid(EventManager * manager)160 bool EventManager::IsManagerValid(EventManager *manager)
161 {
162 std::lock_guard lock(mutexForManager_);
163 return validManager_.find(manager) != validManager_.end();
164 }
165
SetValid(EventManager * manager)166 void EventManager::SetValid(EventManager *manager)
167 {
168 std::lock_guard lock(mutexForManager_);
169 validManager_.emplace(manager);
170 }
171
172 #ifdef ENABLE_EVENT_HANDLER
InitNetstackEventHandler()173 bool EventManager::InitNetstackEventHandler()
174 {
175 if (eventRunner_ == nullptr) {
176 NETSTACK_LOGI("event handler is null, create handler.");
177 eventRunner_ = AppExecFwk::EventRunner::Create();
178 if (!eventRunner_) {
179 NETSTACK_LOGE("create event runner failed");
180 return false;
181 }
182 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventRunner_);
183 return true;
184 }
185 return true;
186 }
187
GetNetstackEventHandler()188 std::shared_ptr<AppExecFwk::EventHandler> EventManager::GetNetstackEventHandler()
189 {
190 return eventHandler_;
191 }
192 #endif
193
CreateEventReference(napi_env env,napi_value value)194 void EventManager::CreateEventReference(napi_env env, napi_value value)
195 {
196 if (env != nullptr && value != nullptr) {
197 eventRef_ = NapiUtils::CreateReference(env, value);
198 }
199 }
200
DeleteEventReference(napi_env env)201 void EventManager::DeleteEventReference(napi_env env)
202 {
203 if (env != nullptr && eventRef_ != nullptr) {
204 NapiUtils::DeleteReference(env, eventRef_);
205 }
206 }
207
SetEventDestroy(bool flag)208 void EventManager::SetEventDestroy(bool flag)
209 {
210 isDestroy_.store(flag);
211 }
212
IsEventDestroy()213 bool EventManager::IsEventDestroy()
214 {
215 return isDestroy_.load();
216 }
217
GetWebSocketTextData()218 const std::string &EventManager::GetWebSocketTextData()
219 {
220 return webSocketTextData_;
221 }
222
AppendWebSocketTextData(void * data,size_t length)223 void EventManager::AppendWebSocketTextData(void *data, size_t length)
224 {
225 webSocketTextData_.append(reinterpret_cast<char *>(data), length);
226 }
227
GetWebSocketBinaryData()228 const std::string &EventManager::GetWebSocketBinaryData()
229 {
230 return webSocketBinaryData_;
231 }
232
AppendWebSocketBinaryData(void * data,size_t length)233 void EventManager::AppendWebSocketBinaryData(void *data, size_t length)
234 {
235 webSocketBinaryData_.append(reinterpret_cast<char *>(data), length);
236 }
237
ClearWebSocketTextData()238 void EventManager::ClearWebSocketTextData()
239 {
240 webSocketTextData_.clear();
241 }
242
ClearWebSocketBinaryData()243 void EventManager::ClearWebSocketBinaryData()
244 {
245 webSocketBinaryData_.clear();
246 }
247
UvWorkWrapper(void * theData,napi_env theEnv,std::string eventType,EventManager * eventManager)248 UvWorkWrapper::UvWorkWrapper(void *theData, napi_env theEnv, std::string eventType, EventManager *eventManager)
249 : data(theData), env(theEnv), type(std::move(eventType)), manager(eventManager)
250 {
251 }
252 } // namespace OHOS::NetStack
253