1 /*
2 * Copyright (c) 2021-2024 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 #if HAS_NETMANAGER_BASE
17 #include "ffrt.h"
18 #include <syscall.h>
19 #include <unistd.h>
20 #endif
21
22 #include "event_listener.h"
23
24 #include "napi/native_api.h"
25 #include "napi/native_common.h"
26 #include "napi_utils.h"
27 #include "netstack_log.h"
28
29 namespace OHOS::NetStack {
EventListener(long tid,napi_env env,std::string type,napi_value callback,bool once,bool asyncCallback)30 EventListener::EventListener(long tid, napi_env env, std::string type, napi_value callback, bool once,
31 bool asyncCallback)
32 : env_(env),
33 type_(std::move(type)),
34 once_(once),
35 callbackRef_(NapiUtils::CreateReference(env, callback)),
36 asyncCallback_(asyncCallback),
37 tid_(tid)
38 {
39 }
40
EventListener(const EventListener & listener)41 EventListener::EventListener(const EventListener &listener)
42 {
43 env_ = listener.env_;
44 type_ = listener.type_;
45 once_ = listener.once_;
46 asyncCallback_ = listener.asyncCallback_;
47 tid_ = listener.tid_;
48
49 if (listener.callbackRef_ == nullptr) {
50 callbackRef_ = nullptr;
51 return;
52 }
53 napi_value callback = NapiUtils::GetReference(listener.env_, listener.callbackRef_);
54 callbackRef_ = NapiUtils::CreateReference(env_, callback);
55 }
56
~EventListener()57 EventListener::~EventListener()
58 {
59 if (GetCurrentThreadId() == tid_ && callbackRef_ != nullptr) {
60 NapiUtils::DeleteReference(env_, callbackRef_);
61 }
62 callbackRef_ = nullptr;
63 }
64
operator =(const EventListener & listener)65 EventListener &EventListener::operator=(const EventListener &listener)
66 {
67 env_ = listener.env_;
68 type_ = listener.type_;
69 once_ = listener.once_;
70 asyncCallback_ = listener.asyncCallback_;
71 tid_ = listener.tid_;
72
73 if (callbackRef_ != nullptr) {
74 NapiUtils::DeleteReference(env_, callbackRef_);
75 }
76 if (listener.callbackRef_ == nullptr) {
77 callbackRef_ = nullptr;
78 return *this;
79 }
80
81 napi_value callback = NapiUtils::GetReference(listener.env_, listener.callbackRef_);
82 callbackRef_ = NapiUtils::CreateReference(env_, callback);
83 return *this;
84 }
85
Emit(const std::string & eventType,size_t argc,napi_value * argv) const86 void EventListener::Emit(const std::string &eventType, size_t argc, napi_value *argv) const
87 {
88 if (GetCurrentThreadId() != tid_) {
89 return;
90 }
91 if (type_ != eventType) {
92 return;
93 }
94
95 if (callbackRef_ == nullptr) {
96 return;
97 }
98 napi_value callback = NapiUtils::GetReference(env_, callbackRef_);
99 if (NapiUtils::GetValueType(env_, callback) == napi_function) {
100 (void)NapiUtils::CallFunction(env_, NapiUtils::GetUndefined(env_), callback, argc, argv);
101 }
102 }
103
Match(const std::string & type,napi_value callback) const104 bool EventListener::Match(const std::string &type, napi_value callback) const
105 {
106 if (GetCurrentThreadId() != tid_) {
107 return false;
108 }
109 if (type_ != type) {
110 return false;
111 }
112
113 napi_value callback1 = NapiUtils::GetReference(env_, callbackRef_);
114 bool ret = false;
115 NAPI_CALL_BASE(env_, napi_strict_equals(env_, callback1, callback, &ret), false);
116 return ret;
117 }
118
MatchOnce(const std::string & type) const119 bool EventListener::MatchOnce(const std::string &type) const
120 {
121 if (type_ != type) {
122 return false;
123 }
124 return once_;
125 }
126
MatchType(const std::string & type) const127 bool EventListener::MatchType(const std::string &type) const
128 {
129 return type_ == type;
130 }
131
IsAsyncCallback() const132 bool EventListener::IsAsyncCallback() const
133 {
134 return asyncCallback_;
135 }
136
EmitByUv(const std::string & type,void * data,void (Handler)(uv_work_t *,int status)) const137 void EventListener::EmitByUv(const std::string &type, void *data, void(Handler)(uv_work_t *, int status)) const
138 {
139 if (type_ != type) {
140 NETSTACK_LOGE("event type does not match");
141 return;
142 }
143
144 if (callbackRef_ == nullptr) {
145 NETSTACK_LOGE("callback reference is nullptr");
146 return;
147 }
148
149 NapiUtils::CreateUvQueueWork(env_, data, Handler);
150 }
151
GetEnv() const152 napi_env EventListener::GetEnv() const
153 {
154 return env_;
155 }
156
GetCallbackRef() const157 napi_ref EventListener::GetCallbackRef() const
158 {
159 return callbackRef_;
160 }
161
GetCurrentThreadId()162 uint64_t GetCurrentThreadId()
163 {
164 #if HAS_NETMANAGER_BASE
165 auto tid = ffrt_this_task_get_id();
166 if (tid == 0) {
167 tid = static_cast<uint64_t>(syscall(SYS_gettid));
168 }
169 return tid;
170 #else
171 return 0;
172 #endif
173 }
174 } // namespace OHOS::NetStack
175