• 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         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