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