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