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