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