1 /*
2  * Copyright (c) 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 #include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall_napi.h"
17 #include "advanced_ui_component/navpushpathhelper/include/hsp_silentinstall.h"
18 #include "base/log/log.h"
19 
20 using namespace std;
21 
22 namespace OHOS::NavPushPathHelper {
23 
IsHspExist(napi_env env, napi_callback_info info)24 napi_value HspSilentInstallNapi::IsHspExist(napi_env env, napi_callback_info info)
25 {
26     size_t argc = 2;
27     size_t requireArgc = 2;
28     napi_value args[2] = { nullptr };
29     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
30     NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments");
31 
32     // get first parameter:moduleName
33     napi_valuetype moduleNameType;
34     NAPI_CALL(env, napi_typeof(env, args[0], &moduleNameType));
35     NAPI_ASSERT(env, moduleNameType == napi_string, "Wrong argument type. String expected.");
36 
37     size_t maxValueLen = 1024;
38     char moduleNameValue[maxValueLen];
39     size_t moduleNameLength = 0;
40     napi_get_value_string_utf8(env, args[0], moduleNameValue, maxValueLen, &moduleNameLength);
41     std::string moduleName = moduleNameValue;
42 
43     // get second parameter:pathName
44     napi_valuetype pathNameType;
45     NAPI_CALL(env, napi_typeof(env, args[1], &pathNameType));
46     NAPI_ASSERT(env, pathNameType == napi_string, "Wrong argument type. String expected.");
47 
48     char pathNameValue[maxValueLen];
49     size_t pathNameLength = 0;
50     napi_get_value_string_utf8(env, args[1], pathNameValue, maxValueLen, &pathNameLength);
51     std::string pathName = pathNameValue;
52 
53     bool isHspExits = HspSilentInstall::IsHspExist(moduleName, pathName);
54     napi_value jsResult;
55     NAPI_CALL(env, napi_get_boolean(env, isHspExits, &jsResult));
56     return jsResult;
57 }
58 
InitRouteMap(napi_env env, napi_callback_info info)59 napi_value HspSilentInstallNapi::InitRouteMap(napi_env env, napi_callback_info info)
60 {
61     HspSilentInstall::InitRouteMap();
62     return nullptr;
63 }
64 
SilentInstall(napi_env env, napi_callback_info info)65 napi_value HspSilentInstallNapi::SilentInstall(napi_env env, napi_callback_info info)
66 {
67     napi_value result = nullptr;
68     size_t argc = 3;
69     size_t requireArgc = 3;
70     napi_value args[3] = { nullptr };
71     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
72     NAPI_ASSERT(env, argc >= requireArgc, "Wrong number of arguments");
73 
74     // get first parameter:moduleName
75     std::string moduleName;
76     getModuleName(env, args[0], moduleName);
77 
78     auto callbackData = new (std::nothrow) CallbackData();
79     if (callbackData == nullptr) {
80         return result;
81     }
82     uv_work_t *work = new (std::nothrow) uv_work_t;
83     if (work == nullptr) {
84         delete callbackData;
85         callbackData = nullptr;
86         return result;
87     }
88     int parameterNum = 1;
89     const int indexTwo = 2;
90     napi_create_reference(env, args[1], parameterNum, &(callbackData->successCallback));
91     napi_create_reference(env, args[indexTwo], parameterNum, &(callbackData->failCallback));
92     callbackData->env = env;
93 
94     auto successCallback = [callbackData, work]() {
95         uv_loop_s *loop = nullptr;
96         napi_get_uv_event_loop(callbackData->env, &loop);
97         work->data = reinterpret_cast<void *>(callbackData);
98         uv_queue_work(loop, work, [](uv_work_t *work) { (void)work; }, SendSuccessBackWork);
99     };
100 
101     auto failCallback = [callbackData, work](int32_t errorCode, const std::string& errorMessage) {
102         callbackData->errCode = errorCode;
103         callbackData->errorMessage = errorMessage;
104 
105         uv_loop_s *loop = nullptr;
106         napi_get_uv_event_loop(callbackData->env, &loop);
107         work->data = reinterpret_cast<void *>(callbackData);
108         uv_queue_work(loop, work, [](uv_work_t *work) { (void)work; }, SendFailBackWork);
109     };
110 
111     HspSilentInstall::SilentInstall(moduleName, successCallback, failCallback);
112     return result;
113 }
114 
getModuleName(napi_env env, napi_value args, std::string& moduleName)115 napi_value HspSilentInstallNapi::getModuleName(napi_env env, napi_value args, std::string& moduleName)
116 {
117     napi_valuetype moduleNameType;
118     NAPI_CALL(env, napi_typeof(env, args, &moduleNameType));
119     NAPI_ASSERT(env, moduleNameType == napi_string, "Wrong argument type. String expected.");
120 
121     napi_status status;
122     size_t maxValueLen = 1024;
123     char moduleNameValue[maxValueLen];
124     size_t moduleNameLength = 0;
125     status = napi_get_value_string_utf8(env, args, moduleNameValue, maxValueLen, &moduleNameLength);
126     NAPI_ASSERT(env, status == napi_ok, "Failed to napi_get_value_string_utf8");
127     moduleName = moduleNameValue;
128     return nullptr;
129 }
130 
SendSuccessBackWork(uv_work_t *work, int statusIn)131 void HspSilentInstallNapi::SendSuccessBackWork(uv_work_t *work, int statusIn)
132 {
133     if (work == nullptr) {
134         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> work is null");
135         return;
136     }
137     (void)statusIn;
138     napi_status status;
139     napi_handle_scope scope = nullptr;
140     CallbackData *callbackData = reinterpret_cast<CallbackData *>(work->data);
141     if (callbackData == nullptr) {
142         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> callbackData is null");
143         return;
144     }
145 
146     napi_open_handle_scope(callbackData->env, &scope);
147     if (scope == nullptr) {
148         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> scope is null");
149         return;
150     }
151 
152     napi_value callback = nullptr;
153     status = napi_get_reference_value(callbackData->env, callbackData->successCallback, &callback);
154     if (status != napi_ok) {
155         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> napi_get_reference_value error");
156         napi_close_handle_scope(callbackData->env, scope);
157         return;
158     }
159 
160     napi_value result;
161     status = napi_call_function(callbackData->env, nullptr, callback, 0, nullptr, &result);
162     if (status != napi_ok) {
163         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> napi_call_function error");
164         napi_close_handle_scope(callbackData->env, scope);
165         return;
166     }
167 
168     napi_close_handle_scope(callbackData->env, scope);
169 
170     if (callbackData != nullptr) {
171         delete callbackData;
172         callbackData = nullptr;
173     }
174 
175     if (work != nullptr) {
176         delete work;
177         work = nullptr;
178     }
179 }
180 
SendFailBackWork(uv_work_t *work, int statusIn)181 void HspSilentInstallNapi::SendFailBackWork(uv_work_t *work, int statusIn)
182 {
183     if (work == nullptr) {
184         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendSuccessBackWork -> work is null");
185         return;
186     }
187     (void)statusIn;
188     napi_status status;
189     napi_handle_scope scope = nullptr;
190     CallbackData *callbackData = reinterpret_cast<CallbackData *>(work->data);
191     if (callbackData == nullptr) {
192         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> callbackData is null");
193         return;
194     }
195 
196     napi_open_handle_scope(callbackData->env, &scope);
197     if (scope == nullptr) {
198         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> scope is null");
199         return;
200     }
201 
202     napi_value callback = nullptr;
203     status = napi_get_reference_value(callbackData->env, callbackData->failCallback, &callback);
204     if (status != napi_ok) {
205         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> napi_get_reference_value error");
206         napi_close_handle_scope(callbackData->env, scope);
207         return;
208     }
209 
210     size_t resultLength = 1;
211     napi_value resultMessage = CreateResultMessage(callbackData);
212     napi_value result[] = { resultMessage };
213     status = napi_call_function(callbackData->env, nullptr, callback, resultLength, result, nullptr);
214     if (status != napi_ok) {
215         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "SendFailBackWork -> napi_call_function error");
216         napi_close_handle_scope(callbackData->env, scope);
217         return;
218     }
219 
220     napi_close_handle_scope(callbackData->env, scope);
221 
222     if (callbackData != nullptr) {
223         delete callbackData;
224         callbackData = nullptr;
225     }
226 
227     if (work != nullptr) {
228         delete work;
229         work = nullptr;
230     }
231 }
232 
CreateResultMessage(CallbackData *callbackData)233 napi_value HspSilentInstallNapi::CreateResultMessage(CallbackData *callbackData)
234 {
235     napi_status status;
236     napi_value result = nullptr;
237     napi_value code = nullptr;
238 
239     status = napi_create_int32(callbackData->env, callbackData->errCode, &code);
240     if (status != napi_ok) {
241         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_int32 error");
242         return result;
243     }
244 
245     napi_value message = nullptr;
246     status = napi_create_string_utf8(callbackData->env, callbackData->errorMessage.c_str(),
247         NAPI_AUTO_LENGTH, &message);
248     if (status != napi_ok) {
249         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_string_utf8 error");
250         return result;
251     }
252 
253     napi_value businessError = nullptr;
254     status = napi_create_object(callbackData->env, &businessError);
255     if (status != napi_ok) {
256         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_create_object error");
257         return result;
258     }
259 
260     status = napi_set_named_property(callbackData->env, businessError, "code", code);
261     if (status != napi_ok) {
262         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_set_named_property error");
263         return result;
264     }
265 
266     status = napi_set_named_property(callbackData->env, businessError, "message", message);
267     if (status != napi_ok) {
268         TAG_LOGE(OHOS::Ace::AceLogTag::ACE_DEFAULT_DOMAIN, "CreateResultMessage -> napi_set_named_property error");
269         return result;
270     }
271     return businessError;
272 }
273 }