1 /*
2 * Copyright (c) 2023 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 "vpn_monitor.h"
17
18 #include <cstddef>
19 #include <string>
20
21 #include <napi/native_common.h>
22 #include <uv.h>
23
24 #include "module_template.h"
25 #include "napi_utils.h"
26 #include "netmanager_ext_log.h"
27 #include "networkvpn_client.h"
28
29 namespace OHOS {
30 namespace NetManagerStandard {
31 namespace {
32 constexpr const char *CONNECT = "connect";
33 constexpr int32_t PARAM_JUST_OPTIONS = 1;
34 constexpr int32_t PARAM_OPTIONS_AND_CALLBACK = 2;
35
EventConnectCallback(uv_work_t * work,int status)36 void EventConnectCallback(uv_work_t *work, int status)
37 {
38 if (work == nullptr) {
39 NETMANAGER_EXT_LOGE("work is nullptr");
40 return;
41 }
42 auto workWrapper = reinterpret_cast<UvWorkWrapper *>(work->data);
43 if (workWrapper == nullptr) {
44 NETMANAGER_EXT_LOGE("workWrapper is nullptr");
45 delete work;
46 return;
47 }
48 bool *data = reinterpret_cast<bool *>(workWrapper->data);
49 if (data == nullptr) {
50 NETMANAGER_EXT_LOGE("isConnected is nullptr");
51 delete workWrapper;
52 delete work;
53 return;
54 }
55
56 napi_env env = workWrapper->env;
57 napi_handle_scope scope = NapiUtils::OpenScope(env);
58 napi_value isConnected = NapiUtils::GetBoolean(env, *data);
59 napi_value result = NapiUtils::CreateObject(env);
60 NapiUtils::SetNamedProperty(env, result, "isConnected", isConnected);
61 workWrapper->manager->Emit(CONNECT, std::make_pair(NapiUtils::GetUndefined(env), result));
62 NapiUtils::CloseScope(env, scope);
63 delete data;
64 delete workWrapper;
65 delete work;
66 }
67
CheckParamType(napi_env env,napi_value * params,size_t paramsCount)68 bool CheckParamType(napi_env env, napi_value *params, size_t paramsCount)
69 {
70 switch (paramsCount) {
71 case PARAM_JUST_OPTIONS:
72 return (NapiUtils::GetValueType(env, params[0]) == napi_string);
73 case PARAM_OPTIONS_AND_CALLBACK:
74 return ((NapiUtils::GetValueType(env, params[0]) == napi_string) &&
75 (NapiUtils::GetValueType(env, params[1]) == napi_function));
76 default:
77 return false;
78 }
79 }
80 } // namespace
81
OnVpnStateChanged(const bool & isConnected)82 void VpnEventCallback::OnVpnStateChanged(const bool &isConnected)
83 {
84 auto manager = VpnMonitor::GetInstance().GetManager();
85 bool *data = new bool(isConnected);
86 manager->EmitByUv(CONNECT, reinterpret_cast<void *>(data), EventConnectCallback);
87 }
88
VpnMonitor()89 VpnMonitor::VpnMonitor()
90 {
91 manager_ = new EventManager();
92 }
93
~VpnMonitor()94 VpnMonitor::~VpnMonitor()
95 {
96 if (manager_ != nullptr) {
97 delete manager_;
98 manager_ = nullptr;
99 }
100 }
101
GetInstance()102 VpnMonitor &VpnMonitor::GetInstance()
103 {
104 static VpnMonitor instance;
105 return instance;
106 }
107
On(napi_env env,napi_callback_info info)108 napi_value VpnMonitor::On(napi_env env, napi_callback_info info)
109 {
110 if (!ParseParams(env, info)) {
111 NETMANAGER_EXT_LOGE("parse failed");
112 NAPI_CALL(env, napi_throw_error(env, "0", "parse failed"));
113 return NapiUtils::GetUndefined(env);
114 }
115 Register(env);
116 return NapiUtils::GetUndefined(env);
117 }
118
Off(napi_env env,napi_callback_info info)119 napi_value VpnMonitor::Off(napi_env env, napi_callback_info info)
120 {
121 if (!ParseParams(env, info)) {
122 NETMANAGER_EXT_LOGE("parse failed");
123 NAPI_CALL(env, napi_throw_error(env, "0", "parse failed"));
124 return NapiUtils::GetUndefined(env);
125 }
126 Unregister(env);
127 return NapiUtils::GetUndefined(env);
128 }
129
ParseParams(napi_env env,napi_callback_info info)130 bool VpnMonitor::ParseParams(napi_env env, napi_callback_info info)
131 {
132 napi_value jsObject = nullptr;
133 size_t paramsCount = MAX_PARAM_NUM;
134 napi_value params[MAX_PARAM_NUM] = {nullptr};
135 NAPI_CALL_BASE(env, napi_get_cb_info(env, info, ¶msCount, params, &jsObject, nullptr), false);
136
137 if (!CheckParamType(env, params, paramsCount)) {
138 NETMANAGER_EXT_LOGE("CheckParamType failed");
139 return false;
140 }
141 if (manager_ == nullptr) {
142 NETMANAGER_EXT_LOGE("manager_ is nullptr");
143 return false;
144 }
145 const std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
146 if (CONNECT != event) {
147 NETMANAGER_EXT_LOGE("%{public}s event is error", event.c_str());
148 return false;
149 }
150 if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
151 callback_ = params[1];
152 }
153 return true;
154 }
155
Register(napi_env env)156 void VpnMonitor::Register(napi_env env)
157 {
158 if (manager_ == nullptr) {
159 NETMANAGER_EXT_LOGE("manager_ is nullptr");
160 return;
161 }
162 manager_->AddListener(env, CONNECT, callback_, false, false);
163
164 if (eventCallback_ != nullptr) {
165 NetworkVpnClient::GetInstance().UnregisterVpnEvent(eventCallback_);
166 }
167 eventCallback_ = new (std::nothrow) VpnEventCallback();
168 if (nullptr == eventCallback_) {
169 NETMANAGER_EXT_LOGE("eventCallback_ is nullptr");
170 return;
171 }
172 NetworkVpnClient::GetInstance().RegisterVpnEvent(eventCallback_);
173 }
174
Unregister(napi_env env)175 void VpnMonitor::Unregister(napi_env env)
176 {
177 if (manager_ == nullptr) {
178 NETMANAGER_EXT_LOGE("manager_ is nullptr");
179 return;
180 }
181 manager_->DeleteListener(CONNECT);
182 NetworkVpnClient::GetInstance().UnregisterVpnEvent(eventCallback_);
183 }
184 } // namespace NetManagerStandard
185 } // namespace OHOS