1 /*
2  * Copyright (c) 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 #include "free_install.h"
16 
17 #include <string>
18 
19 #include "app_log_wrapper.h"
20 #include "bundle_errors.h"
21 #include "bundle_mgr_interface.h"
22 #include "bundle_mgr_proxy.h"
23 #include "business_error.h"
24 #include "common_func.h"
25 #include "napi_arg.h"
26 #include "napi_constants.h"
27 
28 namespace OHOS {
29 namespace AppExecFwk {
30 namespace {
31 enum class UpgradeFlag {
32     NOT_UPGRADE = 0,
33     SINGLE_UPGRADE = 1,
34     RELATION_UPGRADE = 2,
35 };
36 const std::vector<int32_t> BUNDLE_PACK_FLAGS = {
37     BundlePackFlag::GET_PACK_INFO_ALL,
38     BundlePackFlag::GET_PACKAGES,
39     BundlePackFlag::GET_BUNDLE_SUMMARY,
40     BundlePackFlag::GET_MODULE_SUMMARY,
41 };
42 const char* RESOURCE_NAME_OF_IS_HAP_MODULE_REMOVABLE = "isHapModuleRemovable";
43 const char* RESOURCE_NAME_OF_SET_HAP_MODULE_UPGRADE_FLAG = "setHapModuleUpgradeFlag";
44 const char* RESOURCE_NAME_OF_GET_BUNDLE_PACK_INFO = "getBundlePackInfo";
45 const char* RESOURCE_NAME_OF_GET_DISPATCH_INFO = "getDispatchInfo";
46 const char* DISPATCH_INFO_VERSION = "1";
47 const char* DISPATCH_INFO_DISPATCH_API = "1.0";
48 const char* BUNDLE_NAME = "bundleName";
49 const char* MODULE_NAME = "moduleName";
50 const char* UPGRADE_FLAG = "upgradeFlag";
51 const char* BUNDLE_PACK_FLAG = "bundlePackFlag";
52 }
53 
InnerIsHapModuleRemovable(const std::string & bundleName,const std::string & moduleName,bool & isRemovable)54 static ErrCode InnerIsHapModuleRemovable(const std::string &bundleName,
55     const std::string &moduleName, bool &isRemovable)
56 {
57     auto iBundleMgr = CommonFunc::GetBundleMgr();
58     if (iBundleMgr == nullptr) {
59         APP_LOGE("can not get iBundleMgr");
60         return ERROR_BUNDLE_SERVICE_EXCEPTION;
61     }
62     auto result = iBundleMgr->IsModuleRemovable(bundleName, moduleName, isRemovable);
63     if (result != ERR_OK) {
64         APP_LOGE("InnerIsHapModuleRemovable::IsModuleRemovable failed, bundleName is %{public}s", bundleName.c_str());
65     }
66     return CommonFunc::ConvertErrCode(result);
67 }
68 
IsHapModuleRemovableExec(napi_env env,void * data)69 void IsHapModuleRemovableExec(napi_env env, void *data)
70 {
71     HapModuleRemovableCallbackInfo *asyncCallbackInfo = reinterpret_cast<HapModuleRemovableCallbackInfo*>(data);
72     if (asyncCallbackInfo == nullptr) {
73         APP_LOGE("asyncCallbackInfo is nullptr");
74         return;
75     }
76     asyncCallbackInfo->err = InnerIsHapModuleRemovable(asyncCallbackInfo->bundleName,
77         asyncCallbackInfo->moduleName, asyncCallbackInfo->result);
78 }
79 
IsHapModuleRemovableComplete(napi_env env,napi_status status,void * data)80 void IsHapModuleRemovableComplete(napi_env env, napi_status status, void *data)
81 {
82     HapModuleRemovableCallbackInfo *asyncCallbackInfo = reinterpret_cast<HapModuleRemovableCallbackInfo*>(data);
83     if (asyncCallbackInfo == nullptr) {
84         APP_LOGE("asyncCallbackInfo is null");
85         return;
86     }
87     std::unique_ptr<HapModuleRemovableCallbackInfo> callbackPtr {asyncCallbackInfo};
88     napi_value result[ARGS_SIZE_TWO] = {0};
89     if (asyncCallbackInfo->err == SUCCESS) {
90         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
91         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, asyncCallbackInfo->result, &result[ARGS_SIZE_ONE]));
92     } else {
93         result[0] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
94             RESOURCE_NAME_OF_IS_HAP_MODULE_REMOVABLE, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
95         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[ARGS_SIZE_ONE]));
96     }
97     CommonFunc::NapiReturnDeferred<HapModuleRemovableCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
98 }
99 
IsHapModuleRemovable(napi_env env,napi_callback_info info)100 napi_value IsHapModuleRemovable(napi_env env, napi_callback_info info)
101 {
102     APP_LOGD("NAPI_IsHapModuleRemovable start");
103     NapiArg args(env, info);
104     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
105         APP_LOGE("param count invalid");
106         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
107         return nullptr;
108     }
109     HapModuleRemovableCallbackInfo *asyncCallbackInfo = new (std::nothrow) HapModuleRemovableCallbackInfo(env);
110     if (asyncCallbackInfo == nullptr) {
111         APP_LOGE("asyncCallbackInfo is null");
112         return nullptr;
113     }
114     std::unique_ptr<HapModuleRemovableCallbackInfo> callbackPtr {asyncCallbackInfo};
115     if (args.GetMaxArgc() >= ARGS_SIZE_TWO) {
116         if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], asyncCallbackInfo->bundleName)) {
117             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
118             return nullptr;
119         }
120         if (!CommonFunc::ParseString(env, args[ARGS_POS_ONE], asyncCallbackInfo->moduleName)) {
121             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
122             return nullptr;
123         }
124         if (args.GetMaxArgc() == ARGS_SIZE_THREE) {
125             napi_valuetype valueType = napi_undefined;
126             napi_typeof(env, args[ARGS_POS_TWO], &valueType);
127             if (valueType == napi_function) {
128                 NAPI_CALL(env, napi_create_reference(env, args[ARGS_POS_TWO],
129                     NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
130             }
131         }
132     } else {
133         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
134         return nullptr;
135     }
136     auto promise = CommonFunc::AsyncCallNativeMethod<HapModuleRemovableCallbackInfo>(
137         env, asyncCallbackInfo, RESOURCE_NAME_OF_IS_HAP_MODULE_REMOVABLE,
138         IsHapModuleRemovableExec, IsHapModuleRemovableComplete);
139     callbackPtr.release();
140     APP_LOGD("call IsHapModuleRemovable done");
141     return promise;
142 }
143 
InnerSetHapModuleUpgradeFlag(const std::string & bundleName,const std::string & moduleName,int32_t upgradeFlag)144 static ErrCode InnerSetHapModuleUpgradeFlag(const std::string &bundleName,
145     const std::string &moduleName, int32_t upgradeFlag)
146 {
147     auto iBundleMgr = CommonFunc::GetBundleMgr();
148     if (iBundleMgr == nullptr) {
149         APP_LOGE("can not get iBundleMgr");
150         return ERROR_BUNDLE_SERVICE_EXCEPTION;
151     }
152     auto result = iBundleMgr->SetModuleUpgradeFlag(bundleName, moduleName, upgradeFlag);
153     if (result != ERR_OK) {
154         APP_LOGE("InnerSetHapModuleUpgradeFlag::SetModuleUpgradeFlag failed, bundleName is %{public}s",
155             bundleName.c_str());
156     }
157     return CommonFunc::ConvertErrCode(result);
158 }
159 
SetHapModuleUpgradeFlagExec(napi_env env,void * data)160 void SetHapModuleUpgradeFlagExec(napi_env env, void *data)
161 {
162     SetHapModuleUpgradeFlagCallbackInfo *asyncCallbackInfo =
163         reinterpret_cast<SetHapModuleUpgradeFlagCallbackInfo*>(data);
164     if (asyncCallbackInfo == nullptr) {
165         APP_LOGE("asyncCallbackInfo is nullptr");
166         return;
167     }
168     asyncCallbackInfo->err = InnerSetHapModuleUpgradeFlag(asyncCallbackInfo->bundleName,
169         asyncCallbackInfo->moduleName, asyncCallbackInfo->upgradeFlag);
170 }
171 
SetHapModuleUpgradeFlagComplete(napi_env env,napi_status status,void * data)172 void SetHapModuleUpgradeFlagComplete(napi_env env, napi_status status, void *data)
173 {
174     SetHapModuleUpgradeFlagCallbackInfo *asyncCallbackInfo =
175         reinterpret_cast<SetHapModuleUpgradeFlagCallbackInfo*>(data);
176     if (asyncCallbackInfo == nullptr) {
177         APP_LOGE("asyncCallbackInfo is null");
178         return;
179     }
180     std::unique_ptr<SetHapModuleUpgradeFlagCallbackInfo> callbackPtr {asyncCallbackInfo};
181     napi_value result[ARGS_SIZE_ONE] = {0};
182     if (asyncCallbackInfo->err == SUCCESS) {
183         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
184     } else {
185         result[0] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
186             RESOURCE_NAME_OF_SET_HAP_MODULE_UPGRADE_FLAG, Constants::PERMISSION_INSTALL_BUNDLE);
187     }
188     CommonFunc::NapiReturnDeferred<SetHapModuleUpgradeFlagCallbackInfo>(env,
189         asyncCallbackInfo, result, ARGS_SIZE_ONE);
190 }
191 
SetHapModuleUpgradeFlag(napi_env env,napi_callback_info info)192 napi_value SetHapModuleUpgradeFlag(napi_env env, napi_callback_info info)
193 {
194     APP_LOGD("NAPI_SetHapModuleUpgradeFlag start");
195     NapiArg args(env, info);
196     if (!args.Init(ARGS_SIZE_THREE, ARGS_SIZE_FOUR)) {
197         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
198         return nullptr;
199     }
200     SetHapModuleUpgradeFlagCallbackInfo *asyncCallbackInfo =
201         new (std::nothrow) SetHapModuleUpgradeFlagCallbackInfo(env);
202     if (asyncCallbackInfo == nullptr) {
203         return nullptr;
204     }
205     std::unique_ptr<SetHapModuleUpgradeFlagCallbackInfo> callbackPtr {asyncCallbackInfo};
206     if (args.GetMaxArgc() >= ARGS_SIZE_THREE) {
207         if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], asyncCallbackInfo->bundleName)) {
208             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
209             return nullptr;
210         }
211         if (!CommonFunc::ParseString(env, args[ARGS_POS_ONE], asyncCallbackInfo->moduleName)) {
212             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_STRING);
213             return nullptr;
214         }
215         if (!CommonFunc::ParseInt(env, args[ARGS_POS_TWO], asyncCallbackInfo->upgradeFlag)) {
216             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, UPGRADE_FLAG, TYPE_NUMBER);
217             return nullptr;
218         }
219         if (args.GetMaxArgc() == ARGS_SIZE_FOUR) {
220             napi_valuetype valueType = napi_undefined;
221             napi_typeof(env, args[ARGS_POS_THREE], &valueType);
222             if (valueType == napi_function) {
223                 NAPI_CALL(env, napi_create_reference(env, args[ARGS_POS_THREE],
224                     NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
225             }
226         }
227     } else {
228         APP_LOGE("parameters error");
229         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
230         return nullptr;
231     }
232 
233     auto promise = CommonFunc::AsyncCallNativeMethod<SetHapModuleUpgradeFlagCallbackInfo>(
234         env, asyncCallbackInfo, RESOURCE_NAME_OF_SET_HAP_MODULE_UPGRADE_FLAG,
235         SetHapModuleUpgradeFlagExec, SetHapModuleUpgradeFlagComplete);
236     callbackPtr.release();
237     APP_LOGD("call SetHapModuleUpgradeFlag done");
238     return promise;
239 }
240 
CreateUpgradeFlagObject(napi_env env,napi_value value)241 void CreateUpgradeFlagObject(napi_env env, napi_value value)
242 {
243     napi_value nNotUpgrade;
244     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(UpgradeFlag::NOT_UPGRADE), &nNotUpgrade));
245     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "NOT_UPGRADE", nNotUpgrade));
246 
247     napi_value nSingleUpgrade;
248     NAPI_CALL_RETURN_VOID(
249         env, napi_create_int32(env, static_cast<int32_t>(UpgradeFlag::SINGLE_UPGRADE), &nSingleUpgrade));
250     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "SINGLE_UPGRADE", nSingleUpgrade));
251 
252     napi_value nRelationUpgrade;
253     NAPI_CALL_RETURN_VOID(
254         env, napi_create_int32(env, static_cast<int32_t>(UpgradeFlag::RELATION_UPGRADE), &nRelationUpgrade));
255     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "RELATION_UPGRADE", nRelationUpgrade));
256 }
257 
CreateBundlePackFlagObject(napi_env env,napi_value value)258 void CreateBundlePackFlagObject(napi_env env, napi_value value)
259 {
260     napi_value nGetPackInfoAll;
261     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(BundlePackFlag::GET_PACK_INFO_ALL),
262         &nGetPackInfoAll));
263     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GET_PACK_INFO_ALL", nGetPackInfoAll));
264 
265     napi_value nGetPackages;
266     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(BundlePackFlag::GET_PACKAGES),
267         &nGetPackages));
268     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GET_PACKAGES", nGetPackages));
269 
270     napi_value nGetBundleSummary;
271     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(BundlePackFlag::GET_BUNDLE_SUMMARY),
272         &nGetBundleSummary));
273     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GET_BUNDLE_SUMMARY", nGetBundleSummary));
274 
275     napi_value nGetModuleSummary;
276     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(BundlePackFlag::GET_MODULE_SUMMARY),
277         &nGetModuleSummary));
278     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GET_MODULE_SUMMARY", nGetModuleSummary));
279 }
280 
ConvertSummaryApp(napi_env env,napi_value & app,const BundlePackInfo & bundlePackInfo)281 static void ConvertSummaryApp(napi_env env, napi_value &app, const BundlePackInfo &bundlePackInfo)
282 {
283     napi_value bundleName;
284     NAPI_CALL_RETURN_VOID(env,
285         napi_create_string_utf8(env, bundlePackInfo.summary.app.bundleName.c_str(), NAPI_AUTO_LENGTH, &bundleName));
286     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, app, "bundleName", bundleName));
287     napi_value version;
288     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &version));
289     napi_value versionName;
290     NAPI_CALL_RETURN_VOID(env,
291         napi_create_string_utf8(env, bundlePackInfo.summary.app.version.name.c_str(), NAPI_AUTO_LENGTH, &versionName));
292     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, version, "name", versionName));
293     napi_value versionCode;
294     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, bundlePackInfo.summary.app.version.code, &versionCode));
295     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, version, "code", versionCode));
296     napi_value minCompatibleVersionCode;
297     NAPI_CALL_RETURN_VOID(env,
298         napi_create_int32(env, bundlePackInfo.summary.app.version.minCompatibleVersionCode, &minCompatibleVersionCode));
299     NAPI_CALL_RETURN_VOID(
300         env, napi_set_named_property(env, version, "minCompatibleVersionCode", minCompatibleVersionCode));
301     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, app, "version", version));
302 }
303 
ConvertModulesApiVersion(napi_env env,napi_value & modulesObject,const OHOS::AppExecFwk::PackageModule & module)304 static void ConvertModulesApiVersion(
305     napi_env env, napi_value &modulesObject, const OHOS::AppExecFwk::PackageModule &module)
306 {
307     napi_value apiVersion;
308     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &apiVersion));
309     napi_value releaseType;
310     NAPI_CALL_RETURN_VOID(
311         env, napi_create_string_utf8(env, module.apiVersion.releaseType.c_str(), NAPI_AUTO_LENGTH, &releaseType));
312     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, apiVersion, "releaseType", releaseType));
313     napi_value compatible;
314     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, module.apiVersion.compatible, &compatible));
315     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, apiVersion, "compatible", compatible));
316     napi_value target;
317     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, module.apiVersion.target, &target));
318     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, apiVersion, "target", target));
319 
320     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, modulesObject, "apiVersion", apiVersion));
321 }
322 
ConvertDeviceType(napi_env env,napi_value & Object,std::vector<std::string> deviceTypes)323 static void ConvertDeviceType(napi_env env, napi_value &Object, std::vector<std::string> deviceTypes)
324 {
325     napi_value nDeviceTypes;
326     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &nDeviceTypes));
327     size_t typeIndex = 0;
328     for (const auto &type : deviceTypes) {
329         napi_value typeValue;
330         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, type.c_str(), NAPI_AUTO_LENGTH, &typeValue));
331         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, nDeviceTypes, typeIndex, typeValue));
332         typeIndex++;
333     }
334     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, Object, "deviceTypes", nDeviceTypes));
335 }
336 
ConvertDistro(napi_env env,napi_value & modulesObject,const PackageModule & module)337 static void ConvertDistro(napi_env env, napi_value &modulesObject, const PackageModule &module)
338 {
339     napi_value distro;
340     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &distro));
341     napi_value deliveryWithInstall;
342     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, module.distro.deliveryWithInstall, &deliveryWithInstall));
343     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, distro, "deliveryWithInstall", deliveryWithInstall));
344     napi_value installationFree;
345     NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, module.distro.installationFree, &installationFree));
346     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, distro, "installationFree", installationFree));
347     napi_value moduleName;
348     NAPI_CALL_RETURN_VOID(
349         env, napi_create_string_utf8(env, module.distro.moduleName.c_str(), NAPI_AUTO_LENGTH, &moduleName));
350     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, distro, "moduleName", moduleName));
351     napi_value moduleType;
352     NAPI_CALL_RETURN_VOID(
353         env, napi_create_string_utf8(env, module.distro.moduleType.c_str(), NAPI_AUTO_LENGTH, &moduleType));
354     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, distro, "moduleType", moduleType));
355 
356     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, modulesObject, "distro", distro));
357 }
358 
ConvertFormsInfo(napi_env env,napi_value & abilityObject,const std::vector<OHOS::AppExecFwk::AbilityFormInfo> & forms)359 static void ConvertFormsInfo(napi_env env, napi_value &abilityObject,
360     const std::vector<OHOS::AppExecFwk::AbilityFormInfo> &forms)
361 {
362     napi_value formsArray;
363     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &formsArray));
364     size_t index = 0;
365     for (const auto &form : forms) {
366         napi_value formObject;
367         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &formObject));
368         napi_value name;
369         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, form.name.c_str(), NAPI_AUTO_LENGTH, &name));
370         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "name", name));
371         napi_value type;
372         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, form.type.c_str(), NAPI_AUTO_LENGTH, &type));
373         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "type", type));
374         napi_value updateEnabled;
375         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, form.updateEnabled, &updateEnabled));
376         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "updateEnabled", updateEnabled));
377         napi_value scheduledUpdateTime;
378         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, form.scheduledUpdateTime.c_str(),
379             NAPI_AUTO_LENGTH, &scheduledUpdateTime));
380         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "scheduledUpdateTime",
381             scheduledUpdateTime));
382         napi_value updateDuration;
383         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, form.updateDuration, &updateDuration));
384         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "updateDuration", updateDuration));
385         napi_value supportDimensions;
386         NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &supportDimensions));
387         size_t indexValue = 0;
388         for (const auto &dimension : form.supportDimensions) {
389             napi_value value;
390             NAPI_CALL_RETURN_VOID(
391                 env, napi_create_string_utf8(env, dimension.c_str(), NAPI_AUTO_LENGTH, &value));
392             NAPI_CALL_RETURN_VOID(env, napi_set_element(env, supportDimensions, indexValue, value));
393             indexValue++;
394         }
395         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "supportDimensions", supportDimensions));
396         napi_value defaultDimension;
397         NAPI_CALL_RETURN_VOID(
398             env, napi_create_string_utf8(env, form.defaultDimension.c_str(), NAPI_AUTO_LENGTH, &defaultDimension));
399         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, formObject, "defaultDimension", defaultDimension));
400         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, formsArray, index, formObject));
401         index++;
402     }
403     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "forms", formsArray));
404 }
405 
ConvertAbilities(napi_env env,napi_value & modulesObject,const PackageModule & module)406 static void ConvertAbilities(napi_env env, napi_value &modulesObject, const PackageModule &module)
407 {
408     napi_value abilities;
409     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &abilities));
410     size_t index = 0;
411     for (const auto &ability : module.abilities) {
412         napi_value abilityObject;
413         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &abilityObject));
414         napi_value name;
415         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, ability.name.c_str(), NAPI_AUTO_LENGTH, &name));
416         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "name", name));
417         napi_value label;
418         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, ability.label.c_str(), NAPI_AUTO_LENGTH, &label));
419         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "label", label));
420         napi_value visible;
421         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, ability.visible, &visible));
422         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "visible", visible));
423         napi_value nExported;
424         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, ability.visible, &nExported));
425         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "exported", nExported));
426         ConvertFormsInfo(env, abilityObject, ability.forms);
427         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, abilities, index, abilityObject));
428         index++;
429     }
430     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, modulesObject, "abilities", abilities));
431 }
432 
ConvertExtensionAbilities(napi_env env,napi_value & modulesObject,const OHOS::AppExecFwk::PackageModule & module)433 static void ConvertExtensionAbilities(
434     napi_env env, napi_value &modulesObject, const OHOS::AppExecFwk::PackageModule &module)
435 {
436     napi_value extensionAbilities;
437     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &extensionAbilities));
438     size_t index = 0;
439     for (const auto &extensionAbility : module.extensionAbilities) {
440         napi_value abilityObject;
441         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &abilityObject));
442         napi_value name;
443         NAPI_CALL_RETURN_VOID(
444             env, napi_create_string_utf8(env, extensionAbility.name.c_str(), NAPI_AUTO_LENGTH, &name));
445         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, abilityObject, "name", name));
446         ConvertFormsInfo(env, abilityObject, extensionAbility.forms);
447         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, extensionAbilities, index, abilityObject));
448         index++;
449     }
450     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, modulesObject, "extensionAbilities", extensionAbilities));
451 }
452 
ConvertSummaryModules(napi_env env,napi_value & modulesArray,const BundlePackInfo & bundlePackInfo)453 static void ConvertSummaryModules(
454     napi_env env, napi_value &modulesArray, const BundlePackInfo &bundlePackInfo)
455 {
456     size_t index = 0;
457     for (const auto &module : bundlePackInfo.summary.modules) {
458         napi_value modulesObject;
459         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &modulesObject));
460         napi_value mainAbility;
461         NAPI_CALL_RETURN_VOID(
462             env, napi_create_string_utf8(env, module.mainAbility.c_str(), NAPI_AUTO_LENGTH, &mainAbility));
463         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, modulesObject, "mainAbility", mainAbility));
464         ConvertModulesApiVersion(env, modulesObject, module);
465         ConvertDeviceType(env, modulesObject, module.deviceType);
466         ConvertDistro(env, modulesObject, module);
467         ConvertAbilities(env, modulesObject, module);
468         ConvertExtensionAbilities(env, modulesObject, module);
469         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, modulesArray, index, modulesObject));
470         index++;
471     }
472 }
473 
ConvertPackageSummary(napi_env env,napi_value & jsSummary,const BundlePackInfo & bundlePackInfo)474 static void ConvertPackageSummary(
475     napi_env env, napi_value &jsSummary, const BundlePackInfo &bundlePackInfo)
476 {
477     napi_value app;
478     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &app));
479     ConvertSummaryApp(env, app, bundlePackInfo);
480     napi_value modules;
481     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &modules));
482     ConvertSummaryModules(env, modules, bundlePackInfo);
483     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, jsSummary, "app", app));
484     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, jsSummary, "modules", modules));
485 }
486 
ConvertPackages(napi_env env,napi_value & jsPackagesArray,const BundlePackInfo & bundlePackInfo)487 static void ConvertPackages(
488     napi_env env, napi_value &jsPackagesArray, const BundlePackInfo &bundlePackInfo)
489 {
490     size_t index = 0;
491     for (const auto &package : bundlePackInfo.packages) {
492         napi_value jsPackagesObject;
493         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &jsPackagesObject));
494         ConvertDeviceType(env, jsPackagesObject, package.deviceType);
495         napi_value packageName;
496         NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, package.name.c_str(), NAPI_AUTO_LENGTH, &packageName));
497         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, jsPackagesObject, "name", packageName));
498         napi_value moduleType;
499         NAPI_CALL_RETURN_VOID(
500             env, napi_create_string_utf8(env, package.moduleType.c_str(), NAPI_AUTO_LENGTH, &moduleType));
501         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, jsPackagesObject, "moduleType", moduleType));
502         napi_value deliveryWithInstall;
503         NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, package.deliveryWithInstall, &deliveryWithInstall));
504         NAPI_CALL_RETURN_VOID(
505             env, napi_set_named_property(env, jsPackagesObject, "deliveryWithInstall", deliveryWithInstall));
506         NAPI_CALL_RETURN_VOID(env, napi_set_element(env, jsPackagesArray, index, jsPackagesObject));
507         index++;
508     }
509 }
510 
ConvertBundlePackInfo(napi_env env,napi_value & result,int32_t flag,const BundlePackInfo & bundlePackInfo)511 static void ConvertBundlePackInfo(
512     napi_env env, napi_value &result, int32_t flag, const BundlePackInfo &bundlePackInfo)
513 {
514     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &result));
515     if (static_cast<uint32_t>(flag) & BundlePackFlag::GET_PACKAGES) {
516         napi_value jsPackagesArray;
517         NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &jsPackagesArray));
518         ConvertPackages(env, jsPackagesArray, bundlePackInfo);
519         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, "packages", jsPackagesArray));
520         return;
521     }
522     if (static_cast<uint32_t>(flag) & BundlePackFlag::GET_BUNDLE_SUMMARY) {
523         napi_value jsSummary;
524         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &jsSummary));
525         ConvertPackageSummary(env, jsSummary, bundlePackInfo);
526         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, "summary", jsSummary));
527         return;
528     }
529     if (static_cast<uint32_t>(flag) & BundlePackFlag::GET_MODULE_SUMMARY) {
530         napi_value jsSummary;
531         NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &jsSummary));
532         napi_value modules;
533         NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &modules));
534         ConvertSummaryModules(env, modules, bundlePackInfo);
535         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, jsSummary, "modules", modules));
536         NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, "summary", jsSummary));
537         return;
538     }
539     napi_value jsSummary;
540     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &jsSummary));
541     ConvertPackageSummary(env, jsSummary, bundlePackInfo);
542     napi_value jsPackagesArray;
543     NAPI_CALL_RETURN_VOID(env, napi_create_array(env, &jsPackagesArray));
544     ConvertPackages(env, jsPackagesArray, bundlePackInfo);
545     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, "packages", jsPackagesArray));
546     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, result, "summary", jsSummary));
547 }
548 
InnerGetBundlePackInfo(const std::string & bundleName,int32_t flags,BundlePackInfo & bundlePackInfo)549 static ErrCode InnerGetBundlePackInfo(const std::string &bundleName, int32_t flags, BundlePackInfo &bundlePackInfo)
550 {
551     auto iBundleMgr = CommonFunc::GetBundleMgr();
552     if (iBundleMgr == nullptr) {
553         APP_LOGE("can not get iBundleMgr");
554         return ERROR_BUNDLE_SERVICE_EXCEPTION;
555     }
556     auto ret = iBundleMgr->GetBundlePackInfo(bundleName, flags, bundlePackInfo);
557     if (ret != ERR_OK) {
558         APP_LOGE("InnerGetBundlePackInfo failed, bundleName is %{public}s", bundleName.c_str());
559     }
560     return CommonFunc::ConvertErrCode(ret);
561 }
562 
GetBundlePackInfoExec(napi_env env,void * data)563 void GetBundlePackInfoExec(napi_env env, void *data)
564 {
565     GetBundlePackInfoCallbackInfo *asyncCallbackInfo =
566         reinterpret_cast<GetBundlePackInfoCallbackInfo*>(data);
567     if (asyncCallbackInfo == nullptr) {
568         APP_LOGE("asyncCallbackInfo is nullptr");
569         return;
570     }
571     asyncCallbackInfo->err = InnerGetBundlePackInfo(asyncCallbackInfo->bundleName,
572         asyncCallbackInfo->bundlePackFlag, asyncCallbackInfo->bundlePackInfo);
573 }
574 
GetBundlePackInfoComplete(napi_env env,napi_status status,void * data)575 void GetBundlePackInfoComplete(napi_env env, napi_status status, void *data)
576 {
577     GetBundlePackInfoCallbackInfo *asyncCallbackInfo = reinterpret_cast<GetBundlePackInfoCallbackInfo*>(data);
578     if (asyncCallbackInfo == nullptr) {
579         APP_LOGE("asyncCallbackInfo is null");
580         return;
581     }
582     std::unique_ptr<GetBundlePackInfoCallbackInfo> callbackPtr {asyncCallbackInfo};
583     napi_value result[ARGS_SIZE_TWO] = {0};
584     if (asyncCallbackInfo->err == SUCCESS) {
585         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
586         ConvertBundlePackInfo(env, result[ARGS_SIZE_ONE],
587             asyncCallbackInfo->bundlePackFlag, asyncCallbackInfo->bundlePackInfo);
588     } else {
589         result[0] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
590             RESOURCE_NAME_OF_GET_BUNDLE_PACK_INFO, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
591         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[ARGS_SIZE_ONE]));
592     }
593     CommonFunc::NapiReturnDeferred<GetBundlePackInfoCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
594 }
595 
GetBundlePackInfo(napi_env env,napi_callback_info info)596 napi_value GetBundlePackInfo(napi_env env, napi_callback_info info)
597 {
598     APP_LOGD("NAPI_GetBundlePackInfo start");
599     NapiArg args(env, info);
600     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
601         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
602         return nullptr;
603     }
604     GetBundlePackInfoCallbackInfo *asyncCallbackInfo = new (std::nothrow) GetBundlePackInfoCallbackInfo(env);
605     if (asyncCallbackInfo == nullptr) {
606         return nullptr;
607     }
608     std::unique_ptr<GetBundlePackInfoCallbackInfo> callbackPtr {asyncCallbackInfo};
609     if (args.GetMaxArgc() >= ARGS_SIZE_TWO) {
610         if (!CommonFunc::ParseString(env, args[ARGS_POS_ZERO], asyncCallbackInfo->bundleName)) {
611             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
612             return nullptr;
613         }
614         if (!CommonFunc::ParseInt(env, args[ARGS_POS_ONE], asyncCallbackInfo->bundlePackFlag)) {
615             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_PACK_FLAG, TYPE_NUMBER);
616             return nullptr;
617         }
618         if (args.GetMaxArgc() == ARGS_SIZE_THREE) {
619             napi_valuetype valueType = napi_undefined;
620             napi_typeof(env, args[ARGS_POS_TWO], &valueType);
621             if (valueType == napi_function) {
622                 NAPI_CALL(env, napi_create_reference(env, args[ARGS_POS_TWO],
623                     NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
624             }
625         }
626     } else {
627         APP_LOGE("parameters error");
628         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
629         return nullptr;
630     }
631     if (std::find(BUNDLE_PACK_FLAGS.begin(), BUNDLE_PACK_FLAGS.end(), asyncCallbackInfo->bundlePackFlag) ==
632         BUNDLE_PACK_FLAGS.end()) {
633         BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_PACK_FLAG, "BundlePackFlag");
634         return nullptr;
635     }
636     auto promise = CommonFunc::AsyncCallNativeMethod<GetBundlePackInfoCallbackInfo>(
637         env, asyncCallbackInfo, RESOURCE_NAME_OF_GET_BUNDLE_PACK_INFO,
638         GetBundlePackInfoExec, GetBundlePackInfoComplete);
639     callbackPtr.release();
640     APP_LOGD("call GetBundlePackInfo end");
641     return promise;
642 }
643 
ConvertDispatcherVersion(napi_env env,napi_value & value,const std::string & version,const std::string & dispatchAPI)644 static void ConvertDispatcherVersion(
645     napi_env env, napi_value &value, const std::string &version, const std::string &dispatchAPI)
646 {
647     NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &value));
648     napi_value napiVersion;
649     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, version.c_str(), NAPI_AUTO_LENGTH, &napiVersion));
650     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "version", napiVersion));
651     napi_value napiDispatchAPIVersion;
652     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, dispatchAPI.c_str(), NAPI_AUTO_LENGTH,
653         &napiDispatchAPIVersion));
654     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "dispatchAPIVersion", napiDispatchAPIVersion));
655 }
656 
InnerGetDispatchInfo(std::string & version,std::string & dispatchAPI)657 static ErrCode InnerGetDispatchInfo(std::string &version, std::string &dispatchAPI)
658 {
659     auto iBundleMgr = CommonFunc::GetBundleMgr();
660     if (iBundleMgr == nullptr) {
661         APP_LOGE("can not get iBundleMgr");
662         return ERROR_BUNDLE_SERVICE_EXCEPTION;
663     }
664     if (!iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
665         APP_LOGE("non-system app calling system api");
666         return ERROR_NOT_SYSTEM_APP;
667     }
668     if (!iBundleMgr->VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
669         APP_LOGE("GetDispatchInfo failed due to permission denied");
670         return ERROR_PERMISSION_DENIED_ERROR;
671     }
672     version = DISPATCH_INFO_VERSION;
673     dispatchAPI = DISPATCH_INFO_DISPATCH_API;
674     return SUCCESS;
675 }
676 
GetDispatchInfoExec(napi_env env,void * data)677 void GetDispatchInfoExec(napi_env env, void *data)
678 {
679     GetDispatchInfoCallbackInfo *asyncCallbackInfo =
680         reinterpret_cast<GetDispatchInfoCallbackInfo*>(data);
681     if (asyncCallbackInfo == nullptr) {
682         APP_LOGE("asyncCallbackInfo is nullptr");
683         return;
684     }
685     asyncCallbackInfo->err = InnerGetDispatchInfo(asyncCallbackInfo->version, asyncCallbackInfo->dispatchAPI);
686 }
687 
GetDispatchInfoComplete(napi_env env,napi_status status,void * data)688 void GetDispatchInfoComplete(napi_env env, napi_status status, void *data)
689 {
690     GetDispatchInfoCallbackInfo *asyncCallbackInfo = reinterpret_cast<GetDispatchInfoCallbackInfo*>(data);
691     if (asyncCallbackInfo == nullptr) {
692         APP_LOGE("asyncCallbackInfo is null");
693         return;
694     }
695     std::unique_ptr<GetDispatchInfoCallbackInfo> callbackPtr {asyncCallbackInfo};
696     napi_value result[ARGS_SIZE_TWO] = {0};
697     if (asyncCallbackInfo->err == SUCCESS) {
698         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
699         ConvertDispatcherVersion(env, result[ARGS_SIZE_ONE],
700             asyncCallbackInfo->version, asyncCallbackInfo->dispatchAPI);
701     } else {
702         result[0] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
703             RESOURCE_NAME_OF_GET_DISPATCH_INFO, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED);
704         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[ARGS_SIZE_ONE]));
705     }
706     CommonFunc::NapiReturnDeferred<GetDispatchInfoCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
707 }
708 
GetDispatchInfo(napi_env env,napi_callback_info info)709 napi_value GetDispatchInfo(napi_env env, napi_callback_info info)
710 {
711     APP_LOGD("NAPI_GetDispatchInfo start");
712     NapiArg args(env, info);
713     if (!args.Init(ARGS_SIZE_ZERO, ARGS_SIZE_ONE)) {
714         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
715         return nullptr;
716     }
717     GetDispatchInfoCallbackInfo *asyncCallbackInfo = new (std::nothrow) GetDispatchInfoCallbackInfo(env);
718     if (asyncCallbackInfo == nullptr) {
719         return nullptr;
720     }
721     std::unique_ptr<GetDispatchInfoCallbackInfo> callbackPtr {asyncCallbackInfo};
722     if (args.GetMaxArgc() >= ARGS_SIZE_ONE) {
723         napi_valuetype valueType = napi_undefined;
724         napi_typeof(env, args[ARGS_POS_ZERO], &valueType);
725         if (valueType == napi_function) {
726             NAPI_CALL(env, napi_create_reference(env, args[ARGS_POS_ZERO],
727                 NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
728         }
729     }
730     auto promise = CommonFunc::AsyncCallNativeMethod<GetDispatchInfoCallbackInfo>(
731         env, asyncCallbackInfo, RESOURCE_NAME_OF_GET_DISPATCH_INFO,
732         GetDispatchInfoExec, GetDispatchInfoComplete);
733     callbackPtr.release();
734     APP_LOGD("call GetDispatchInfo end");
735     return promise;
736 }
737 } // AppExecFwk
738 } // OHOS