• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <pthread.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <unistd.h>
20 
21 #include "app_log_wrapper.h"
22 #include "bundle_status_callback.h"
23 #include "js_launcher_mgr.h"
24 #include "launcher_service.h"
25 #include "napi/native_api.h"
26 #include "napi/native_node_api.h"
27 
28 using namespace OHOS::AppExecFwk;
29 namespace {
30 const std::string REGISTERCALLBACK = "BundleStatusChange";
31 const std::string UNREGISTERCALLBACK = "BundleStatusChange";
32 constexpr int32_t NAPI_RETURN_ZERO = 0;
33 constexpr int32_t OPERATION_SUCESS = 0;
34 constexpr int32_t OPERATION_FAILED = 1;
35 constexpr int32_t OPERATION_TYPE_MIAMATCH = 2;
36 constexpr int32_t INDEX_ONE = 1;
37 constexpr int32_t INDEX_TWO = 2;
38 constexpr int32_t INDEX_THREE = 3;
39 constexpr int32_t NAPI_RETURN_ONE = 1;
40 }
41 
42 struct AsyncHandleBundleContext {
43     napi_env env = nullptr;
44     napi_async_work asyncWork = nullptr;
45     napi_deferred deferred = nullptr;
46     napi_ref callbackRef = 0;
47     OHOS::sptr<BundleStatusCallback> bundleStatusCallback = nullptr;
48     std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> launcherAbilityInfos;
49     std::vector<OHOS::AppExecFwk::ShortcutInfo> shortcutInfos;
50     std::string bundleName;
51     int32_t userId = 0;
52     bool ret = false;
53     uint32_t err = 0;
54     std::string message;
55 };
56 
GetLauncherService()57 static OHOS::sptr<OHOS::AppExecFwk::LauncherService> GetLauncherService()
58 {
59     return OHOS::AppExecFwk::JSLauncherMgr::GetLauncherService();
60 }
61 
ParseString(napi_env env,napi_value value,std::string & result)62 static void ParseString(napi_env env, napi_value value, std::string& result)
63 {
64     size_t size = 0;
65 
66     if (napi_get_value_string_utf8(env, value, nullptr, NAPI_RETURN_ZERO, &size) != napi_ok) {
67         APP_LOGE("can not get string size");
68         return;
69     }
70 
71     result.reserve(size + NAPI_RETURN_ONE);
72     result.resize(size);
73     if (napi_get_value_string_utf8(env, value, result.data(), (size + NAPI_RETURN_ONE), &size) != napi_ok) {
74         APP_LOGE("can not get string value");
75         return;
76     }
77 }
78 
ParseBundleStatusCallback(napi_env env,OHOS::sptr<BundleStatusCallback> & bundleStatusCallback,napi_value args)79 static bool ParseBundleStatusCallback(napi_env env,
80     OHOS::sptr<BundleStatusCallback>& bundleStatusCallback, napi_value args)
81 {
82     APP_LOGD("parse bundleStatusCallback begin");
83     napi_status status;
84     napi_valuetype valueType;
85     NAPI_CALL_BASE(env, napi_typeof(env, args, &valueType), false);
86     if (valueType != napi_object) {
87         APP_LOGE("param type mismatch!");
88         return false;
89     }
90 
91     // parse added callback
92     napi_ref addCallback = nullptr;
93     napi_value addValue = nullptr;
94     status = napi_get_named_property(env, args, "add", &addValue);
95     NAPI_ASSERT_BASE(env, status == napi_ok, "property name incorrect!", false);
96     napi_typeof(env, addValue, &valueType);
97     if (valueType != napi_function) {
98         APP_LOGE("add param type mismatch!");
99         return false;
100     }
101     napi_create_reference(env, addValue, NAPI_RETURN_ONE, &addCallback);
102 
103     // parse updated callback
104     napi_ref updateCallback = nullptr;
105     napi_value updateValue = nullptr;
106     status = napi_get_named_property(env, args, "update", &updateValue);
107     NAPI_ASSERT_BASE(env, status == napi_ok, "property name incorrect!", false);
108     napi_typeof(env, updateValue, &valueType);
109     if (valueType != napi_function) {
110         APP_LOGE("update param type mismatch!");
111         return false;
112     }
113     napi_create_reference(env, updateValue, NAPI_RETURN_ONE, &updateCallback);
114 
115     // parse remove callback
116     napi_ref removeCallback = nullptr;
117     napi_value removeValue = nullptr;
118     status = napi_get_named_property(env, args, "remove", &removeValue);
119     NAPI_ASSERT_BASE(env, status == napi_ok, "property name incorrect!", false);
120     napi_typeof(env, removeValue, &valueType);
121     if (valueType != napi_function) {
122         APP_LOGE("remove param type mismatch!");
123         return false;
124     }
125     napi_create_reference(env, removeValue, NAPI_RETURN_ONE, &removeCallback);
126 
127     bundleStatusCallback = new BundleStatusCallback(env, addCallback, updateCallback, removeCallback);
128     APP_LOGD("parse bundleStatusCallback end");
129     return true;
130 }
131 
ConvertApplicationInfo(napi_env env,napi_value objAppInfo,const OHOS::AppExecFwk::ApplicationInfo & appInfo)132 static void ConvertApplicationInfo(napi_env env, napi_value objAppInfo,
133     const OHOS::AppExecFwk::ApplicationInfo &appInfo)
134 {
135     napi_value nName;
136     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, appInfo.name.c_str(), NAPI_AUTO_LENGTH, &nName));
137     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "name", nName));
138 
139     napi_value nDescription;
140     NAPI_CALL_RETURN_VOID(
141         env, napi_create_string_utf8(env, appInfo.description.c_str(), NAPI_AUTO_LENGTH, &nDescription));
142     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "description", nDescription));
143 
144     napi_value nDescriptionId;
145     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, appInfo.descriptionId, &nDescriptionId));
146     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "descriptionId", nDescriptionId));
147 
148     napi_value nIsSystemApp;
149     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, appInfo.isSystemApp, &nIsSystemApp));
150     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "systemApp", nIsSystemApp));
151 
152     napi_value nEnabled;
153     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, appInfo.enabled, &nEnabled));
154     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "enabled", nEnabled));
155 
156     napi_value nRemovable;
157     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, appInfo.removable, &nRemovable));
158     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "removable", nRemovable));
159 
160     napi_value nLabel;
161     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, appInfo.label.c_str(), NAPI_AUTO_LENGTH, &nLabel));
162     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "label", nLabel));
163 
164     napi_value nLabelId;
165     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, appInfo.labelId, &nLabelId));
166     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "labelId", nLabelId));
167 
168     napi_value nIconPath;
169     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, appInfo.iconPath.c_str(), NAPI_AUTO_LENGTH, &nIconPath));
170     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "icon", nIconPath));
171 
172     napi_value nIconId;
173     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, appInfo.iconId, &nIconId));
174     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "iconId", nIconId));
175 
176     napi_value nSupportedModes;
177     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, appInfo.supportedModes, &nSupportedModes));
178     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "supportedModes", nSupportedModes));
179 
180     napi_value nProcess;
181     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, appInfo.process.c_str(), NAPI_AUTO_LENGTH, &nProcess));
182     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "process", nProcess));
183 
184     napi_value nModuleSourceDirs;
185     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &nModuleSourceDirs));
186     for (size_t idx = 0; idx < appInfo.moduleSourceDirs.size(); idx++) {
187         napi_value nModuleSourceDir;
188         NAPI_CALL_RETURN_VOID(env,
189             napi_create_string_utf8(env, appInfo.moduleSourceDirs[idx].c_str(),
190                                     NAPI_AUTO_LENGTH, &nModuleSourceDir));
191         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, nModuleSourceDirs, idx, nModuleSourceDir));
192     }
193     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "moduleSourceDirs", nModuleSourceDirs));
194 
195     napi_value nPermissions;
196     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &nPermissions));
197     for (size_t idx = 0; idx < appInfo.permissions.size(); idx++) {
198         napi_value nPermission;
199         NAPI_CALL_RETURN_VOID(
200             env, napi_create_string_utf8(env, appInfo.permissions[idx].c_str(), NAPI_AUTO_LENGTH, &nPermission));
201         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, nPermissions, idx, nPermission));
202     }
203     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "permissions", nPermissions));
204 
205     napi_value nModuleInfos;
206     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &nModuleInfos));
207     for (size_t idx = 0; idx < appInfo.moduleInfos.size(); idx++) {
208         napi_value objModuleInfos;
209         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &objModuleInfos));
210 
211         napi_value nModuleName;
212         NAPI_CALL_RETURN_VOID(
213             env, napi_create_string_utf8(env,
214                                          appInfo.moduleInfos[idx].moduleName.c_str(),
215                                          NAPI_AUTO_LENGTH, &nModuleName));
216         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objModuleInfos, "moduleName", nModuleName));
217 
218         napi_value nModuleSourceDir;
219         NAPI_CALL_RETURN_VOID(
220             env, napi_create_string_utf8(env,
221                                          appInfo.moduleInfos[idx].moduleSourceDir.c_str(),
222                                          NAPI_AUTO_LENGTH, &nModuleSourceDir));
223         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objModuleInfos, "moduleSourceDir", nModuleSourceDir));
224 
225         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, nModuleInfos, idx, objModuleInfos));
226     }
227     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "moduleInfos", nModuleInfos));
228 
229     napi_value nEntryDir;
230     NAPI_CALL_RETURN_VOID(
231         env, napi_create_string_utf8(env, appInfo.entryDir.c_str(), NAPI_AUTO_LENGTH, &nEntryDir));
232     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "entryDir", nEntryDir));
233 
234     napi_value nFlags;
235     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, appInfo.flags, &nFlags));
236     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAppInfo, "flags", nFlags));
237 
238     APP_LOGI("ConvertApplicationInfo entryDir=%{public}s.", appInfo.entryDir.c_str());
239 }
240 
ConvertElementName(napi_env env,napi_value elementInfo,const OHOS::AppExecFwk::ElementName & elementName)241 static void ConvertElementName(napi_env env, napi_value elementInfo, const OHOS::AppExecFwk::ElementName &elementName)
242 {
243     // wrap deviceId
244     napi_value deviceId;
245     NAPI_CALL_RETURN_VOID(
246         env, napi_create_string_utf8(env, elementName.GetDeviceID().c_str(), NAPI_AUTO_LENGTH, &deviceId));
247     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, elementInfo, "deviceId", deviceId));
248 
249     // wrap bundleName
250     napi_value bundleName;
251     NAPI_CALL_RETURN_VOID(
252         env, napi_create_string_utf8(env, elementName.GetBundleName().c_str(), NAPI_AUTO_LENGTH, &bundleName));
253     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, elementInfo, "bundleName", bundleName));
254 
255     // wrap moduleName
256     napi_value moduleName;
257     NAPI_CALL_RETURN_VOID(
258         env, napi_create_string_utf8(env, elementName.GetModuleName().c_str(), NAPI_AUTO_LENGTH, &moduleName));
259     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, elementInfo, "moduleName", moduleName));
260 
261     // wrap abilityName
262     napi_value abilityName;
263     NAPI_CALL_RETURN_VOID(
264         env, napi_create_string_utf8(env, elementName.GetAbilityName().c_str(), NAPI_AUTO_LENGTH, &abilityName));
265     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, elementInfo, "abilityName", abilityName));
266 }
267 
ConvertLauncherAbilityInfo(napi_env env,napi_value objAbilityInfo,const OHOS::AppExecFwk::LauncherAbilityInfo & launcherAbilityInfo)268 static void ConvertLauncherAbilityInfo(napi_env env, napi_value objAbilityInfo,
269     const OHOS::AppExecFwk::LauncherAbilityInfo &launcherAbilityInfo)
270 {
271     // wrap labelId
272     napi_value labelId;
273     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, launcherAbilityInfo.labelId, &labelId));
274     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "labelId", labelId));
275 
276     // wrap iconId
277     napi_value iconId;
278     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, launcherAbilityInfo.iconId, &iconId));
279     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "iconId", iconId));
280 
281     // wrap userId
282     napi_value userId;
283     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, launcherAbilityInfo.userId, &userId));
284     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "userId", userId));
285 
286     // wrap installTime
287     napi_value installTime;
288     NAPI_CALL_RETURN_VOID(env, napi_create_int64(env, launcherAbilityInfo.installTime, &installTime));
289     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "installTime", installTime));
290 
291     // wrap elementName
292     napi_value elementName;
293     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &elementName));
294     ConvertElementName(env, elementName, launcherAbilityInfo.elementName);
295     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "elementName", elementName));
296 
297     // wrap application
298     napi_value appInfo;
299     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &appInfo));
300     ConvertApplicationInfo(env, appInfo, launcherAbilityInfo.applicationInfo);
301     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objAbilityInfo, "applicationInfo", appInfo));
302 }
303 
ParseLauncherAbilityInfo(napi_env env,napi_value result,const std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> & launcherAbilityInfos)304 static bool ParseLauncherAbilityInfo(
305     napi_env env, napi_value result,
306     const std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> &launcherAbilityInfos)
307 {
308     if (launcherAbilityInfos.empty()) {
309         return false;
310     }
311     size_t index = 0;
312     for (const auto& abilityInfo : launcherAbilityInfos) {
313         napi_value objAbilityInfo = nullptr;
314         napi_create_object(env, &objAbilityInfo);
315         ConvertLauncherAbilityInfo(env, objAbilityInfo, abilityInfo);
316         napi_set_element(env, result, index, objAbilityInfo);
317         index++;
318     }
319     return true;
320 }
321 
ConvertShortcutIntent(napi_env env,napi_value objShortcutInfo,const OHOS::AppExecFwk::ShortcutIntent & shortcutIntent)322 static void ConvertShortcutIntent(napi_env env, napi_value objShortcutInfo,
323                                   const OHOS::AppExecFwk::ShortcutIntent &shortcutIntent)
324 {
325     napi_value nTargetBundle;
326     NAPI_CALL_RETURN_VOID(
327         env, napi_create_string_utf8(env, shortcutIntent.targetBundle.c_str(), NAPI_AUTO_LENGTH, &nTargetBundle));
328     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "targetBundle", nTargetBundle));
329 
330     napi_value nTargetModule;
331     NAPI_CALL_RETURN_VOID(
332         env, napi_create_string_utf8(env, shortcutIntent.targetModule.c_str(), NAPI_AUTO_LENGTH, &nTargetModule));
333     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "targetModule", nTargetModule));
334 
335     napi_value nTargetClass;
336     NAPI_CALL_RETURN_VOID(
337         env, napi_create_string_utf8(env, shortcutIntent.targetClass.c_str(), NAPI_AUTO_LENGTH, &nTargetClass));
338     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "targetClass", nTargetClass));
339 }
340 
ConvertShortcutInfo(napi_env env,napi_value objShortcutInfo,const OHOS::AppExecFwk::ShortcutInfo & shortcutInfo)341 static void ConvertShortcutInfo(
342     napi_env env, napi_value objShortcutInfo,
343     const OHOS::AppExecFwk::ShortcutInfo &shortcutInfo)
344 {
345     // wrap id
346     napi_value shortId;
347     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env,
348                                                        shortcutInfo.id.c_str(), NAPI_AUTO_LENGTH, &shortId));
349     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "id", shortId));
350 
351     // wrap bundleName
352     napi_value bundleName;
353     NAPI_CALL_RETURN_VOID(
354         env, napi_create_string_utf8(env, shortcutInfo.bundleName.c_str(), NAPI_AUTO_LENGTH, &bundleName));
355     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "bundleName", bundleName));
356 
357     // wrap moduleName
358     napi_value moduleName;
359     NAPI_CALL_RETURN_VOID(
360         env, napi_create_string_utf8(env, shortcutInfo.moduleName.c_str(), NAPI_AUTO_LENGTH, &moduleName));
361     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "moduleName", moduleName));
362 
363     // wrap hostAbility
364     napi_value hostAbility;
365     NAPI_CALL_RETURN_VOID(
366         env, napi_create_string_utf8(env, shortcutInfo.hostAbility.c_str(), NAPI_AUTO_LENGTH, &hostAbility));
367     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "hostAbility", hostAbility));
368 
369     // wrap icon
370     napi_value icon;
371     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, shortcutInfo.icon.c_str(), NAPI_AUTO_LENGTH, &icon));
372     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "icon", icon));
373 
374     // wrap iconId
375     napi_value iconId;
376     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, shortcutInfo.iconId, &iconId));
377     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "iconId", iconId));
378 
379     // wrap label
380     napi_value label;
381     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, shortcutInfo.label.c_str(), NAPI_AUTO_LENGTH, &label));
382     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "label", label));
383 
384     // wrap labelId
385     napi_value labelId;
386     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, shortcutInfo.labelId, &labelId));
387     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "labelId", labelId));
388 
389     // wrap disableMessage
390     napi_value disableMessage;
391     NAPI_CALL_RETURN_VOID(
392         env, napi_create_string_utf8(env, shortcutInfo.disableMessage.c_str(), NAPI_AUTO_LENGTH, &disableMessage));
393     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "disableMessage", disableMessage));
394 
395     // wrap wants
396     napi_value intents;
397     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &intents));
398     for (size_t index = 0; index < shortcutInfo.intents.size(); ++index) {
399         napi_value intent;
400         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &intent));
401         ConvertShortcutIntent(env, intent, shortcutInfo.intents[index]);
402         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, intents, index, intent));
403     }
404     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "wants", intents));
405 
406     // wrap isStatic
407     napi_value isStatic;
408     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, shortcutInfo.isStatic, &isStatic));
409     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "isStatic", isStatic));
410 
411     // wrap isHomeShortcut
412     napi_value isHomeShortcut;
413     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, shortcutInfo.isHomeShortcut, &isHomeShortcut));
414     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "isHomeShortcut", isHomeShortcut));
415 
416     // wrap isEnabled
417     napi_value isEnabled;
418     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, shortcutInfo.isEnables, &isEnabled));
419     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, objShortcutInfo, "isEnabled", isEnabled));
420 }
421 
ParseShortcutInfo(napi_env env,napi_value result,const std::vector<OHOS::AppExecFwk::ShortcutInfo> & shortcutInfos)422 static void ParseShortcutInfo(napi_env env, napi_value result,
423                               const std::vector<OHOS::AppExecFwk::ShortcutInfo> &shortcutInfos)
424 {
425     if (shortcutInfos.empty()) {
426         APP_LOGE("launcher shortcut info is empty");
427         return;
428     }
429     size_t index = 0;
430     for (const auto& item : shortcutInfos) {
431         napi_value objShortcutInfo;
432         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &objShortcutInfo));
433         ConvertShortcutInfo(env, objShortcutInfo, item);
434         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, result, index, objShortcutInfo));
435         index++;
436     }
437     return;
438 }
439 
440 
InnerJSLauncherServiceOn(napi_env env,OHOS::sptr<BundleStatusCallback> callbackRef)441 static bool InnerJSLauncherServiceOn(napi_env env, OHOS::sptr<BundleStatusCallback> callbackRef)
442 {
443     if (callbackRef == nullptr) {
444         APP_LOGE("Input null BundleStatusCallback");
445     }
446     auto launcher = GetLauncherService();
447     if (launcher == nullptr) {
448         APP_LOGE("can not get launcher");
449         return false;
450     }
451 
452     auto result = launcher->RegisterCallback(callbackRef);
453     if (!result) {
454         APP_LOGE("RegisterBundleStatusCallback call error");
455         return false;
456     }
457     return true;
458 }
459 
JSLauncherServiceOn(napi_env env,napi_callback_info info)460 static napi_value JSLauncherServiceOn(napi_env env, napi_callback_info info)
461 {
462     size_t requireArgc = 2;
463     size_t argc = 3;
464     napi_value argv[3] = { 0 };
465     napi_value thisArg = nullptr;
466     void *data = nullptr;
467 
468     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
469     NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
470     std::string command;
471 
472     AsyncHandleBundleContext *asyncCallbackInfo = new AsyncHandleBundleContext();
473     if (asyncCallbackInfo == nullptr) {
474         return nullptr;
475     }
476     asyncCallbackInfo->env = env;
477     for (size_t i = 0; i < argc; ++i) {
478         napi_valuetype valueType = napi_undefined;
479         napi_typeof(env, argv[i], &valueType);
480         if ((i == 0) && (valueType == napi_string)) {
481             ParseString(env, argv[i], command);
482         } else if ((i == INDEX_ONE) && (valueType == napi_object)) {
483             bool res = ParseBundleStatusCallback(env, asyncCallbackInfo->bundleStatusCallback, argv[i]);
484             if (!res) {
485                 asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
486                 asyncCallbackInfo->message = "type mismatch";
487             }
488         } else if ((i == INDEX_TWO) && (valueType == napi_function))  {
489             napi_create_reference(env, argv[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callbackRef);
490             break;
491         } else {
492             asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
493             asyncCallbackInfo->message = "type mismatch";
494         }
495     }
496 
497     napi_value promise = nullptr;
498     if (command != REGISTERCALLBACK) {
499         APP_LOGE("Input wrong command");
500         delete asyncCallbackInfo;
501         asyncCallbackInfo = nullptr;
502         return promise;
503     }
504 
505     if (asyncCallbackInfo->callbackRef == nullptr) {
506         napi_create_promise(env, &asyncCallbackInfo->deferred, &promise);
507     } else {
508         napi_get_undefined(env,  &promise);
509     }
510 
511     napi_value resource = nullptr;
512     napi_create_string_utf8(env, "JSLauncherServiceOn", NAPI_AUTO_LENGTH, &resource);
513 
514     napi_create_async_work(
515         env, nullptr, resource,
516         [](napi_env env, void* data) {
517         },
518         [](napi_env env, napi_status status, void* data) {
519             AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext *>(data);
520             if (!asyncCallbackInfo->err) {
521                 asyncCallbackInfo->ret = InnerJSLauncherServiceOn(env, asyncCallbackInfo->bundleStatusCallback);
522             }
523             napi_value result[2] = { 0 };
524             // wrap result
525             if (asyncCallbackInfo->err) {
526                 napi_create_uint32(env, asyncCallbackInfo->err, &result[0]);
527                 napi_create_string_utf8(env, asyncCallbackInfo->message.c_str(), NAPI_AUTO_LENGTH, &result[1]);
528             } else {
529                 if (asyncCallbackInfo->ret) {
530                     napi_create_uint32(env, OPERATION_SUCESS, &result[0]);
531                     napi_create_string_utf8(env, "register success", NAPI_AUTO_LENGTH, &result[1]);
532                 } else {
533                     napi_create_uint32(env, OPERATION_FAILED, &result[0]);
534                     napi_create_string_utf8(env, "register failed", NAPI_AUTO_LENGTH, &result[1]);
535                 }
536             }
537             // callback or promise return
538             if (asyncCallbackInfo->deferred) {
539                 if (asyncCallbackInfo->ret) {
540                     napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]);
541                 } else {
542                     napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]);
543                 }
544             } else {
545                 napi_value callback = nullptr;
546                 napi_value placeHolder = nullptr;
547                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
548                 napi_call_function(env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
549                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
550             }
551             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
552             delete asyncCallbackInfo;
553             asyncCallbackInfo = nullptr;
554         },
555         reinterpret_cast<void*>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
556     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
557 
558     return promise;
559 }
560 
InnerJSLauncherServiceOff()561 static bool InnerJSLauncherServiceOff()
562 {
563     auto launcher = GetLauncherService();
564     if (launcher == nullptr) {
565         APP_LOGE("can not get launcher");
566         return false;
567     }
568 
569     auto result = launcher->UnRegisterCallback();
570     if (!result) {
571         APP_LOGE("RegisterBundleStatusCallback call error");
572         return false;
573     }
574     return true;
575 }
576 
LauncherServiceOffComplete(napi_env env,napi_status status,void * data)577 static void LauncherServiceOffComplete(napi_env env, napi_status status, void* data)
578 {
579     AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
580     if (!asyncCallbackInfo->err) {
581         asyncCallbackInfo->ret = InnerJSLauncherServiceOff();
582     }
583     napi_value result[INDEX_TWO] = { 0 };
584     if (asyncCallbackInfo->ret) {
585         napi_create_uint32(env, 0, &result[0]);
586         napi_create_string_utf8(env, "unregister success", NAPI_AUTO_LENGTH, &result[INDEX_ONE]);
587     } else {
588         napi_create_uint32(env, INDEX_ONE, &result[0]);
589         napi_create_string_utf8(env, "unregister failed", NAPI_AUTO_LENGTH, &result[INDEX_ONE]);
590     }
591     if (asyncCallbackInfo->deferred) {
592         if (asyncCallbackInfo->ret) {
593             napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[INDEX_ONE]);
594         } else {
595             napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]);
596         }
597     } else {
598         napi_value callback = nullptr;
599         napi_value placeHolder = nullptr;
600         napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
601         napi_call_function(env, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
602         napi_delete_reference(env, asyncCallbackInfo->callbackRef);
603     }
604     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
605     delete asyncCallbackInfo;
606     asyncCallbackInfo = nullptr;
607 }
608 
JSLauncherServiceOff(napi_env env,napi_callback_info info)609 static napi_value JSLauncherServiceOff(napi_env env, napi_callback_info info)
610 {
611     size_t requireArgc = INDEX_ONE;
612     size_t argc = INDEX_TWO;
613     napi_value argv[INDEX_TWO] = { 0 };
614     napi_value thisArg = nullptr;
615     void *data = nullptr;
616 
617     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
618     NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter");
619     std::string command;
620     AsyncHandleBundleContext *asyncCallbackInfo = new AsyncHandleBundleContext();
621     if (asyncCallbackInfo == nullptr) {
622         return nullptr;
623     }
624     asyncCallbackInfo->env = env;
625     for (size_t i = 0; i < argc; ++i) {
626         napi_valuetype valueType = napi_undefined;
627         napi_typeof(env, argv[i], &valueType);
628         if ((i == 0) && (valueType == napi_string)) {
629             ParseString(env, argv[i], command);
630         } else if ((i == INDEX_ONE) && (valueType == napi_function))  {
631             napi_create_reference(env, argv[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callbackRef);
632         } else {
633             asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
634             asyncCallbackInfo->message = "type mismatch";
635         }
636     }
637     napi_value promise = nullptr;
638     if (command != UNREGISTERCALLBACK) {
639         APP_LOGE("Input wrong command");
640         delete asyncCallbackInfo;
641         asyncCallbackInfo = nullptr;
642         return promise;
643     }
644     if (asyncCallbackInfo->callbackRef == nullptr) {
645         napi_create_promise(env, &asyncCallbackInfo->deferred, &promise);
646     } else {
647         napi_get_undefined(env,  &promise);
648     }
649     napi_value resource = nullptr;
650     napi_create_string_utf8(env, "JSLauncherServiceOn", NAPI_AUTO_LENGTH, &resource);
651     napi_create_async_work(
652         env, nullptr, resource, [](napi_env env, void* data) {}, LauncherServiceOffComplete,
653         reinterpret_cast<void*>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
654     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
655     return promise;
656 }
657 
InnerJSGetAllLauncherAbilityInfos(napi_env env,uint32_t userId,std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> & launcherAbilityInfos)658 static bool InnerJSGetAllLauncherAbilityInfos(napi_env env, uint32_t userId,
659     std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> &launcherAbilityInfos)
660 {
661     auto launcher = GetLauncherService();
662     if (launcher == nullptr) {
663         APP_LOGE("can not get launcher");
664         return false;
665     }
666 
667     auto result = launcher->GetAllLauncherAbilityInfos(userId, launcherAbilityInfos);
668     if (!result) {
669         APP_LOGE("GetAllLauncherAbilityInfos call error");
670         return false;
671     }
672     return true;
673 }
674 
JSGetAllLauncherAbilityInfos(napi_env env,napi_callback_info info)675 static napi_value JSGetAllLauncherAbilityInfos(napi_env env, napi_callback_info info)
676 {
677     size_t argc = INDEX_TWO;
678     napi_value argv[INDEX_TWO] = { 0 };
679     size_t requireArgc = INDEX_ONE;
680     napi_value thisArg = nullptr;
681     void *data = nullptr;
682 
683     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
684     NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter");
685     AsyncHandleBundleContext *asyncCallbackInfo = new AsyncHandleBundleContext();
686     asyncCallbackInfo->env = env;
687     for (size_t i = 0; i < argc; ++i) {
688         napi_valuetype valueType = napi_undefined;
689         napi_typeof(env, argv[i], &valueType);
690         if ((i == 0) && (valueType == napi_number)) {
691             napi_get_value_int32(env, argv[i], &asyncCallbackInfo->userId);
692         } else if ((i == INDEX_ONE) && (valueType == napi_function))  {
693             napi_create_reference(env, argv[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callbackRef);
694             break;
695         } else {
696             asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
697             asyncCallbackInfo->message = "type mismatch";
698         }
699     }
700     napi_value promise = nullptr;
701     if (asyncCallbackInfo->callbackRef == nullptr) {
702         napi_create_promise(env, &asyncCallbackInfo->deferred, &promise);
703     } else {
704         napi_get_undefined(env,  &promise);
705     }
706     napi_value resource = nullptr;
707     napi_create_string_utf8(env, "JSGetAllLauncherAbilityInfos", NAPI_AUTO_LENGTH, &resource);
708 
709     napi_create_async_work(
710         env, nullptr, resource,
711         [](napi_env env, void* data) {
712             AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
713             if (!asyncCallbackInfo->err) {
714                 asyncCallbackInfo->ret = InnerJSGetAllLauncherAbilityInfos(asyncCallbackInfo->env,
715                                                                            asyncCallbackInfo->userId,
716                                                                            asyncCallbackInfo->launcherAbilityInfos);
717             }
718         },
719         [](napi_env env, napi_status status, void* data) {
720           AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
721           napi_value result[INDEX_TWO] = { 0 };
722           // wrap result
723           if (asyncCallbackInfo->err) {
724               napi_create_int32(env, asyncCallbackInfo->err, &result[0]);
725               napi_get_undefined(env, &result[INDEX_ONE]);
726           } else {
727               if (asyncCallbackInfo->ret) {
728                   napi_create_int32(env, OPERATION_SUCESS, &result[0]);
729                   napi_create_array(env, &result[INDEX_ONE]);
730                   ParseLauncherAbilityInfo(env, result[INDEX_ONE], asyncCallbackInfo->launcherAbilityInfos);
731               } else {
732                   napi_create_int32(env, OPERATION_FAILED, &result[0]);
733                   napi_get_undefined(env, &result[INDEX_ONE]);
734               }
735           }
736           // return callback or promise
737           if (asyncCallbackInfo->deferred) {
738               if (asyncCallbackInfo->ret) {
739                   napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[INDEX_ONE]);
740               } else {
741                   napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]);
742               }
743           } else {
744               napi_value callback = nullptr;
745               napi_value callResult = 0;
746               napi_value undefined = 0;
747               napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
748               napi_call_function(env, undefined, callback, sizeof(result) / sizeof(result[0]), result, &callResult);
749               napi_delete_reference(env, asyncCallbackInfo->callbackRef);
750           }
751           napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
752           delete asyncCallbackInfo;
753           asyncCallbackInfo = nullptr;
754         },
755         reinterpret_cast<void*>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
756     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
757 
758     return promise;
759 }
760 
InnerJSGetLauncherAbilityInfos(napi_env env,std::string & bundleName,uint32_t userId,std::vector<OHOS::AppExecFwk::LauncherAbilityInfo> & launcherAbilityInfos)761 static bool InnerJSGetLauncherAbilityInfos(napi_env env, std::string& bundleName,
762     uint32_t userId, std::vector<OHOS::AppExecFwk::LauncherAbilityInfo>& launcherAbilityInfos)
763 {
764     auto launcher = GetLauncherService();
765     if (launcher == nullptr) {
766         APP_LOGE("can not get launcher");
767         return false;
768     }
769 
770     auto result = launcher->GetAbilityList(bundleName, userId, launcherAbilityInfos);
771     if (!result) {
772         APP_LOGE("GetAbilityList call error, bundlename is %{public}s, userId is %{public}d",
773             bundleName.c_str(), userId);
774         return false;
775     }
776     return true;
777 }
778 
JSGetLauncherAbilityInfos(napi_env env,napi_callback_info info)779 static napi_value JSGetLauncherAbilityInfos(napi_env env, napi_callback_info info)
780 {
781     size_t argc = INDEX_THREE;
782     napi_value argv[INDEX_THREE] = { 0 };
783     size_t requireArgc = INDEX_TWO;
784     napi_value thisArg = nullptr;
785     void *data = nullptr;
786     std::string bundleName;
787 
788     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
789     NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
790     AsyncHandleBundleContext *asyncCallbackInfo = new AsyncHandleBundleContext();
791     asyncCallbackInfo->env = env;
792 
793     for (size_t i = 0; i < argc; ++i) {
794         napi_valuetype valueType = napi_undefined;
795         napi_typeof(env, argv[i], &valueType);
796         if ((i == 0) && (valueType == napi_string)) {
797             ParseString(env, argv[i], asyncCallbackInfo->bundleName);
798         } else if ((i == INDEX_ONE) && (valueType == napi_number)) {
799             napi_get_value_int32(env, argv[i], &asyncCallbackInfo->userId);
800         } else if ((i == INDEX_TWO) && (valueType == napi_function)) {
801             napi_create_reference(env, argv[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callbackRef);
802             break;
803         } else {
804             asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
805             asyncCallbackInfo->message = "type mismatch";
806         }
807     }
808 
809     napi_value promise = nullptr;
810     if (asyncCallbackInfo->callbackRef == nullptr) {
811         napi_create_promise(env, &asyncCallbackInfo->deferred, &promise);
812     } else {
813         napi_get_undefined(env,  &promise);
814     }
815 
816     napi_value resource = nullptr;
817     napi_create_string_utf8(env, "JSGetLauncherAbilityInfos", NAPI_AUTO_LENGTH, &resource);
818     napi_create_async_work(
819         env, nullptr, resource,
820         [](napi_env env, void* data) {
821             AsyncHandleBundleContext* asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
822             if (!asyncCallbackInfo->err) {
823               asyncCallbackInfo->ret = InnerJSGetLauncherAbilityInfos(asyncCallbackInfo->env,
824                                                                       asyncCallbackInfo->bundleName,
825                                                                       asyncCallbackInfo->userId,
826                                                                       asyncCallbackInfo->launcherAbilityInfos);
827             }
828         },
829         [](napi_env env, napi_status status, void* data) {
830             AsyncHandleBundleContext* asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
831             napi_value result[INDEX_TWO] = { 0 };
832             // wrap result
833             if (asyncCallbackInfo->err) {
834                 napi_create_int32(env, asyncCallbackInfo->err, &result[0]);
835                 napi_get_undefined(env, &result[INDEX_ONE]);
836             } else {
837                 if (asyncCallbackInfo->ret) {
838                   napi_create_uint32(env, OPERATION_SUCESS, &result[0]);
839                   napi_create_array(env, &result[INDEX_ONE]);
840                   ParseLauncherAbilityInfo(env, result[INDEX_ONE], asyncCallbackInfo->launcherAbilityInfos);
841                 } else {
842                   napi_create_uint32(env, OPERATION_FAILED, &result[0]);
843                   napi_get_undefined(env, &result[INDEX_ONE]);
844                 }
845             }
846             // return callback or promise
847             if (asyncCallbackInfo->deferred) {
848               if (asyncCallbackInfo->ret) {
849                   napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[INDEX_ONE]);
850               } else {
851                   napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]);
852               }
853             } else {
854                 napi_value callback = nullptr;
855                 napi_value callResult = 0;
856                 napi_value undefined = 0;
857                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
858                 napi_call_function(env, undefined, callback, sizeof(result) / sizeof(result[0]), result, &callResult);
859                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
860             }
861             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
862             delete asyncCallbackInfo;
863             asyncCallbackInfo = nullptr;
864         },
865         reinterpret_cast<void*>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
866     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
867     return promise;
868 }
869 
InnerJSGetShortcutInfos(napi_env env,const std::string & bundleName,std::vector<OHOS::AppExecFwk::ShortcutInfo> & shortcutInfos)870 static bool InnerJSGetShortcutInfos(napi_env env, const std::string& bundleName,
871     std::vector<OHOS::AppExecFwk::ShortcutInfo>& shortcutInfos)
872 {
873     auto launcher = GetLauncherService();
874     if (launcher == nullptr) {
875         APP_LOGE("can not get launcher");
876         return false;
877     }
878     auto result = launcher->GetShortcutInfos(bundleName, shortcutInfos);
879     if (!result) {
880         APP_LOGE("GetShortcutInfos call error");
881         return false;
882     }
883     return true;
884 }
885 
JSGetShortcutInfos(napi_env env,napi_callback_info info)886 static napi_value JSGetShortcutInfos(napi_env env, napi_callback_info info)
887 {
888     size_t argc = INDEX_TWO;
889     napi_value argv[INDEX_TWO] = { 0 };
890     size_t requireArgc = INDEX_ONE;
891     napi_value thisArg = nullptr;
892     void *data = nullptr;
893 
894     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
895     NAPI_ASSERT(env, argc >= requireArgc, "requires 1 parameter");
896     AsyncHandleBundleContext *asyncCallbackInfo = new AsyncHandleBundleContext();
897     asyncCallbackInfo->env = env;
898 
899     for (size_t i = 0; i < argc; ++i) {
900         napi_valuetype valueType = napi_undefined;
901         napi_typeof(env, argv[i], &valueType);
902         if ((i == 0) && (valueType == napi_string)) {
903             ParseString(env, argv[i], asyncCallbackInfo->bundleName);
904         } else if ((i == INDEX_ONE) && (valueType == napi_function)) {
905             napi_create_reference(env, argv[i], NAPI_RETURN_ONE, &asyncCallbackInfo->callbackRef);
906             break;
907         } else {
908             asyncCallbackInfo->err = OPERATION_TYPE_MIAMATCH;
909             asyncCallbackInfo->message = "type mismatch";
910         }
911     }
912     napi_value promise = nullptr;
913     if (asyncCallbackInfo->callbackRef == nullptr) {
914         napi_create_promise(env, &asyncCallbackInfo->deferred, &promise);
915     } else {
916         napi_get_undefined(env,  &promise);
917     }
918     napi_value resource = nullptr;
919     napi_create_string_utf8(env, "JSGetShortcutInfos", NAPI_AUTO_LENGTH, &resource);
920 
921     napi_create_async_work(
922         env, nullptr, resource,
923         [](napi_env env, void* data) {
924             AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
925             if (!asyncCallbackInfo->err) {
926                 asyncCallbackInfo->ret = InnerJSGetShortcutInfos(asyncCallbackInfo->env,
927                                                                  asyncCallbackInfo->bundleName,
928                                                                  asyncCallbackInfo->shortcutInfos);
929             }
930         },
931         [](napi_env env, napi_status status, void* data) {
932             AsyncHandleBundleContext *asyncCallbackInfo = reinterpret_cast<AsyncHandleBundleContext*>(data);
933             napi_value result[INDEX_TWO] = { 0 };
934             // wrap result
935             if (asyncCallbackInfo->err) {
936                 napi_create_int32(env, asyncCallbackInfo->err, &result[0]);
937                 napi_get_undefined(env, &result[INDEX_ONE]);
938             } else {
939                 if (asyncCallbackInfo->ret) {
940                     napi_create_uint32(env, OPERATION_SUCESS, &result[0]);
941                     napi_create_array(env, &result[INDEX_ONE]);
942                     ParseShortcutInfo(env, result[INDEX_ONE], asyncCallbackInfo->shortcutInfos);
943                 } else {
944                     napi_create_uint32(env, OPERATION_FAILED, &result[0]);
945                     napi_get_undefined(env, &result[INDEX_ONE]);
946                 }
947             }
948             // return callback or promise
949             if (asyncCallbackInfo->deferred) {
950                 if (asyncCallbackInfo->ret) {
951                     napi_resolve_deferred(env, asyncCallbackInfo->deferred, result[1]);
952                 } else {
953                     napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]);
954                 }
955             } else {
956                 napi_value callback = nullptr;
957                 napi_value callResult = 0;
958                 napi_value undefined = 0;
959                 napi_get_reference_value(env, asyncCallbackInfo->callbackRef, &callback);
960                 napi_call_function(env, undefined, callback, sizeof(result) / sizeof(result[0]), result, &callResult);
961                 napi_delete_reference(env, asyncCallbackInfo->callbackRef);
962             }
963             napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
964             delete asyncCallbackInfo;
965             asyncCallbackInfo = nullptr;
966         },
967         reinterpret_cast<void*>(asyncCallbackInfo), &asyncCallbackInfo->asyncWork);
968     napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
969 
970     return promise;
971 }
972 
LauncherServiceExport(napi_env env,napi_value exports)973 static napi_value LauncherServiceExport(napi_env env, napi_value exports)
974 {
975     static napi_property_descriptor launcherDesc[] = {
976         DECLARE_NAPI_FUNCTION("on", JSLauncherServiceOn),
977         DECLARE_NAPI_FUNCTION("off", JSLauncherServiceOff),
978         DECLARE_NAPI_FUNCTION("getAllLauncherAbilityInfos", JSGetAllLauncherAbilityInfos),
979         DECLARE_NAPI_FUNCTION("getLauncherAbilityInfos", JSGetLauncherAbilityInfos),
980         DECLARE_NAPI_FUNCTION("getShortcutInfos", JSGetShortcutInfos),
981     };
982 
983     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(launcherDesc) / sizeof(launcherDesc[0]), launcherDesc));
984     return exports;
985 }
986 
987 static napi_module launcherServiceModule = {
988     .nm_version = 1,
989     .nm_flags = 0,
990     .nm_filename = nullptr,
991     .nm_register_func = LauncherServiceExport,
992     .nm_modname = "bundle.innerBundleManager",
993     .nm_priv = ((void*)0),
994     .reserved = { 0 },
995 };
996 
LauncherServiceRegister()997 extern "C" __attribute__((constructor)) void LauncherServiceRegister()
998 {
999     napi_module_register(&launcherServiceModule);
1000 }
1001 
1002