• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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