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
20using namespace std;
21
22namespace OHOS::NavPushPathHelper {
23
24napi_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
59napi_value HspSilentInstallNapi::InitRouteMap(napi_env env, napi_callback_info info)
60{
61    HspSilentInstall::InitRouteMap();
62    return nullptr;
63}
64
65napi_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
115napi_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
131void 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
181void 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
233napi_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}