• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 package ohos;
17 
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Locale;
23 
24 import com.alibaba.fastjson.JSON;
25 import com.alibaba.fastjson.JSONObject;
26 import com.alibaba.fastjson.JSONArray;
27 import com.alibaba.fastjson.JSONException;
28 
29 /**
30  * Json Util.
31  *
32  */
33 public class JsonUtil {
34     private static final String DEVICE_TYPE = "device-type";
35     private static final String NAME = "name";
36     private static final String VALUE = "value";
37     private static final String RESOURCE = "resource";
38     private static final String MODULE_TYPE = "module-type";
39     private static final String INSTALL_FLAG = "delivery-with-install";
40     private static final String DEVICE_TYPE_NEW = "deviceType";
41     private static final String MODULE_TYPE_NEW = "moduleType";
42     private static final String INSTALL_FLAG_NEW = "deliveryWithInstall";
43     private static final String ASSETS_DIR_NAME = "assets/";
44     private static final String PROFILE = "$profile:";
45     private static final Log LOG = new Log(JsonUtil.class.toString());
46 
47     private static final String SUMMARY = "summary";
48     private static final String APP = "app";
49     private static final String VERSION = "version";
50     private static final String LEGACY_VERSION_CODE = "legacyVersionCode";
51     private static final String LEGACY_VERSION_NAME = "legacyVersionName";
52     private static final String MULTI_FRAMEWORK_BUNDLE = "multiFrameworkBundle";
53     private static final String ACTION_SYSTEM_HOME = "action.system.home";
54     private static final String ENTITY_SYSTEM_HOME = "entity.system.home";
55     private static final String MAIN_ABILITY = "mainAbility";
56     private static final String MAIN_ELEMENT = "mainElement";
57     private static final String PAGE = "page";
58     private static final String SERVICE = "service";
59     private static final String FORM = "form";
60     private static final String PACKAGES = "packages";
61     private static final String ABILITIES = "abilities";
62     private static final String WHEN = "when";
63     private static final String STRING_RESOURCE = "$string:";
64     private static final String EMPTY = "";
65     private static final String BUNDLENAME = "bundleName";
66     private static final String BUNDLE_TYPE = "bundleType";
67     private static final String VERSIONCODE = "versionCode";
68     private static final String VERSIONNAME = "versionName";
69     private static final String PATCH_VERSION_CODE = "patchVersionCode";
70     private static final String PATCH_VERSION_NAME = "patchVersionName";
71     private static final String ORIGINAL_MODULE_HASH = "originalModuleHash";
72     private static final String MODULE = "module";
73     private static final String DEVICE_TYPES = "deviceTypes";
74     private static final String TYPE = "type";
75     private static final String LABEL = "label";
76     private static final String LABEL_ID = "labelId";
77     private static final String DESCRIPTION = "description";
78     private static final String DESCRIPTION_ID = "descriptionId";
79     private static final String VERSION_CODE = "versionCode";
80     private static final String VENDOR = "vendor";
81     private static final String VERSION_NAME = "versionName";
82     private static final String MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode";
83     private static final String DEBUG = "debug";
84     private static final String MIN_API_VERSION = "minAPIVersion";
85     private static final String TARGET_API_VERSION = "targetAPIVersion";
86     private static final String API_RELEASE_TYPE = "apiReleaseType";
87     private static final String DISTRIBUTED_NOTIFICATION_ENABLED = "distributedNotificationEnabled";
88     private static final String ENTITY_TYPE = "entityType";
89     private static final String UNSPECIFIED = "unspecified";
90     private static final String SRC_ENTRANCE = "srcEntrance";
91     private static final String SRC_ENTRY = "srcEntry";
92     private static final String PROCESS = "process";
93     private static final String PHONE = "phone";
94     private static final String TABLET = "tablet";
95     private static final String TV = "tv";
96     private static final String WEARABLE = "wearable";
97     private static final String AR = "ar";
98     private static final String VR = "vr";
99     private static final String CAR = "car";
100     private static final String EARPHONES = "earphones";
101     private static final String SPEAKER = "speaker";
102     private static final String LINK_IOT = "linkIOT";
103     private static final String ROUTER = "router";
104     private static final String TWO_IN_ONE = "2in1";
105     private static final String DELIVERY_WITH_INSTALL = "deliveryWithInstall";
106     private static final String INSTALLATION_FREE = "installationFree";
107     private static final String VIRTUAL_MACHINE = "virtualMachine";
108     private static final String DEFAULT = "default";
109     private static final String HML = "hml";
110     private static final String UI_SYNTAX = "uiSyntax";
111     private static final String PAGES = "pages";
112     private static final String JSON_SUFFIX = ".json";
113     private static final String META_DATA = "metadata";
114     private static final String SRC = "src";
115     private static final String EXTENSION_ABILITIES = "extensionAbilities";
116     private static final String REQ_PERMISSIONS = "reqPermissions";
117     private static final String REQUEST_PERMISSIONS = "requestPermissions";
118     private static final String REASON = "reason";
119     private static final String REASON_ID = "reasonId";
120     private static final String USED_SCENE = "usedScene";
121     private static final String DEFINE_PERMISSIONS = "definePermissions";
122     private static final String DISTRO_FILTER = "distroFilter";
123     private static final String DISTRIBUTION_FILTER = "distributionFilter";
124     private static final String LAUNCH_TYPE = "launchType";
125     private static final String STANDARD = "standard";
126     private static final String PERMISSIONS = "permissions";
127     private static final String READ_PERMISSION = "readPermission";
128     private static final String WRITE_PERMISSION = "writePermission";
129     private static final String VISIBLE = "visible";
130     private static final String EXPORTED = "exported";
131     private static final String CONTINUABLE = "continuable";
132     private static final String SKILLS = "skills";
133     private static final String BACKGROUND_MODES = "backgroundModes";
134     private static final String URI = "uri";
135     private static final String FORMS = "forms";
136     private static final String WINDOW = "window";
137     private static final String IS_DEFAULT = "isDefault";
138     private static final String COLOR_MODE = "colorMode";
139     private static final String SUPPORT_DIMENSIONS = "supportDimensions";
140     private static final String DEFAULT_DIMENSION = "defaultDimension";
141     private static final String UPDATE_ENABLED = "updateEnabled";
142     private static final String SCHEDULE_UPDATE_TIME = "scheduledUpdateTime";
143     private static final String UPDATE_DURATION = "updateDuration";
144     private static final String FROM_CONFIG_ABILITY = "formConfigAbility";
145     private static final String FORM_VISIBLE_NOTIFY = "formVisibleNotify";
146     private static final String AUTO = "auto";
147     private static final String DOT = ".";
148     private static final String ATOMIC_SERVICE = "atomicService";
149     private static final String SPLIT = "split";
150     private static final String MAIN = "main";
151     private static final String PRELOADS = "preloads";
152     private static final String MODULE_NAME = "moduleName";
153     private static final int DEFAULT_VERSION_CODE = -1;
154     private static final String DEPENDENCY_BUNDLE_NAME = "bundleName";
155     private static final String DEPENDENCY_MODULE_NAME = "moduleName";
156     private static final String DEPENDENCIES = "dependencies";
157     private static final String COMPILE_SDK_VERSION = "compileSdkVersion";
158     private static final String COMPILE_SDK_TYPE = "compileSdkType";
159 
160 
161     /**
162      * parse hap list by device type
163      *
164      * @param deviceType target deviceType
165      * @param jsonString uncompress json String
166      * @return the parseHapList result
167      * @throws BundleException Throws this exception if the json is not standard.
168      */
parseHapList(String deviceType, String jsonString)169     static List<PackInfo> parseHapList(String deviceType, String jsonString) throws BundleException {
170         List<PackInfo> packInfos = new ArrayList<PackInfo>();
171         JSONObject jsonObject = JSONObject.parseObject(jsonString);
172         if (jsonObject == null || !jsonObject.containsKey("packages")) {
173             LOG.error("Uncompress::parseHapList exception: packages is null.");
174             throw new BundleException("Parse hap list failed, packages is null.");
175         }
176         JSONArray jsonList = JSONArray.parseArray(getJsonString(jsonObject, "packages"));
177         if (jsonList == null) {
178             LOG.error("Uncompress::parseHapList exception: packages is null.");
179             throw new BundleException("Parse hap list failed, packages is null.");
180         }
181         int jsonListSize = jsonList.size();
182         for (int i = 0; i < jsonListSize; i++) {
183             JSONObject tmpObj = jsonList.getJSONObject(i);
184             String deviceTypes = getJsonString(tmpObj, DEVICE_TYPE);
185             if (deviceTypes == null || EMPTY.equals(deviceTypes)) {
186                 deviceTypes = getJsonString(tmpObj, DEVICE_TYPE_NEW);
187             }
188             if (deviceTypes != null && deviceTypes.toLowerCase(Locale.ENGLISH).contains(
189                     deviceType.toLowerCase(Locale.ENGLISH))) {
190                 PackInfo packInfo = new PackInfo();
191                 packInfo.name = getJsonString(tmpObj, NAME);
192                 packInfo.moduleType = getJsonString(tmpObj, MODULE_TYPE);
193                 if (packInfo.moduleType == null || EMPTY.equals(packInfo.moduleType)) {
194                     packInfo.moduleType = getJsonString(tmpObj, MODULE_TYPE_NEW);
195                 }
196                 packInfo.deviceType = JSONArray.parseArray(deviceTypes, String.class);
197                 String deliveryWithInstall = getJsonString(tmpObj, INSTALL_FLAG);
198                 if (deliveryWithInstall == null || EMPTY.equals(deliveryWithInstall)) {
199                     deliveryWithInstall = getJsonString(tmpObj, INSTALL_FLAG_NEW);
200                 }
201                 packInfo.deliveryWithInstall = Boolean.parseBoolean(deliveryWithInstall);
202                 packInfos.add(packInfo);
203             }
204         }
205         return packInfos;
206     }
207 
parsePackInfos(String jsonString)208     static List<PackInfo> parsePackInfos(String jsonString) throws BundleException {
209         JSONObject jsonObject = JSONObject.parseObject(jsonString);
210         if (jsonObject == null || !jsonObject.containsKey("packages")) {
211             LOG.error("JsonUtil::parsePackInfos exception: packages is null.");
212             throw new BundleException("Parse hap list failed, packages is null.");
213         }
214         String packages = getJsonString(jsonObject, PACKAGES);
215         return JSONArray.parseArray(packages, PackInfo.class);
216     }
217 
parseShellVersionInfoToAppInfo(String packInfoJsonStr, AppInfo appInfo)218     private static boolean parseShellVersionInfoToAppInfo(String packInfoJsonStr, AppInfo appInfo)
219             throws BundleException {
220         LOG.info("Uncompress::parseShellVersionInfoToAppInfo: begin.");
221         if (!appInfo.isMultiFrameworkBundle()) {
222             LOG.info("Uncompress::parseShellVersionInfoToAppInfo: is not a multi framewok bundle.");
223             return false;
224         }
225         try {
226             JSONObject jsonObject = JSONObject.parseObject(packInfoJsonStr);
227             if (jsonObject == null) {
228                 LOG.error("Uncompress::parseShellVersionInfoToAppInfo error: summary is null.");
229                 return false;
230             }
231             JSONObject summaryJson = jsonObject.getJSONObject(SUMMARY);
232             if (summaryJson == null) {
233                 LOG.error("Uncompress::parseShellVersionInfoToAppInfo error: summary is null.");
234                 return false;
235             }
236             JSONObject appJson = summaryJson.getJSONObject(APP);
237             if (appJson == null) {
238                 LOG.error("Uncompress::parseShellVersionInfoToAppInfo error: app is null.");
239                 return false;
240             }
241             JSONObject versionJson = appJson.getJSONObject(VERSION);
242             if (versionJson == null) {
243                 LOG.error("Uncompress::parseShellVersionInfoToAppInfo error: version is null.");
244                 return false;
245             }
246             if (!versionJson.containsKey(LEGACY_VERSION_CODE) || !versionJson.containsKey(LEGACY_VERSION_NAME)) {
247                 LOG.error("Uncompress::parseShellVersionInfoToAppInfo no legacy version info.");
248                 return false;
249             }
250             appInfo.setShellVersionCode(versionJson.getString(LEGACY_VERSION_CODE));
251             appInfo.setShellVersionName(versionJson.getString(LEGACY_VERSION_NAME));
252             return true;
253         } catch (JSONException msg) {
254             LOG.error("parseShellVersionInfoToAppInfo exception.");
255             throw new BundleException("parseShellVersionInfoToAppInfo exception.");
256         }
257     }
258 
parseDeviceTypeToHapInfo(String packInfoJsonStr, HapInfo hapInfo, String hapName)259     private static void parseDeviceTypeToHapInfo(String packInfoJsonStr, HapInfo hapInfo, String hapName) {
260         LOG.info("Uncompress::parseDeviceTypeToHapInfo: begin.");
261         JSONObject jsonObject = JSONObject.parseObject(packInfoJsonStr);
262         if (jsonObject == null || !jsonObject.containsKey("packages")) {
263             LOG.error("Uncompress::parseDeviceTypeToHapInfo error: no packages.");
264             return;
265         }
266         JSONArray jsonList = JSONArray.parseArray(getJsonString(jsonObject, "packages"));
267         if (jsonList == null) {
268             LOG.error("Uncompress::parseDeviceTypeToHapInfo error: packages is null.");
269             return;
270         }
271 
272         for (int i = 0; i < jsonList.size(); i++) {
273             JSONObject tmpObj = jsonList.getJSONObject(i);
274             if (tmpObj == null) {
275                 LOG.error("Uncompress::parseDeviceTypeToHapInfo error: obj is null.");
276                 continue;
277             }
278             String name = getJsonString(tmpObj, NAME);
279             if (name != null && name.equals(hapName)) {
280                 String deviceTypes = getJsonString(tmpObj, DEVICE_TYPE_NEW);
281                 if (deviceTypes == null || deviceTypes.isEmpty()) {
282                     deviceTypes = getJsonString(tmpObj, DEVICE_TYPE);
283                 }
284                 if (deviceTypes != null && !deviceTypes.isEmpty()) {
285                     hapInfo.deviceType = JSONArray.parseArray(deviceTypes
286                         .replace(UncompressEntrance.DEVICE_TYPE_DEFAULT, UncompressEntrance.DEVICE_TYPE_PHONE),
287                         String.class);
288                 }
289                 break;
290             }
291         }
292     }
293 
294     /**
295      * parse hap profile info
296      *
297      * @param harmonyProfileJsonString uncompress json String
298      * @param data resource index data
299      * @param paclInfoJsonString pack.info json String
300      * @param hapName hap file name
301      * @return the parseProfileInfo result
302      * @throws BundleException Throws this exception if the json is not standard.
303      */
parseProfileInfo(String harmonyProfileJsonString, byte[] data, String paclInfoJsonString, String hapName)304     static ProfileInfo parseProfileInfo(String harmonyProfileJsonString, byte[] data, String paclInfoJsonString,
305         String hapName) throws BundleException {
306         ProfileInfo profileInfo = new ProfileInfo();
307         JSONObject jsonObject = JSONObject.parseObject(harmonyProfileJsonString);
308         if (jsonObject == null || !jsonObject.containsKey(APP) || !jsonObject.containsKey("deviceConfig")
309                 || !jsonObject.containsKey("module")) {
310             LOG.error("Uncompress::parseProfileInfo exception: app, deviceConfig or module is null.");
311             throw new BundleException("Parse profile info failed, app, deviceConfig or module is null.");
312         }
313         if (jsonObject.containsKey(APP)) {
314             JSONObject appJson = jsonObject.getJSONObject(APP);
315             profileInfo.appInfo = parseAppInfo(appJson, data);
316         }
317         if (jsonObject.containsKey("module")) {
318             JSONObject hapJson = jsonObject.getJSONObject("module");
319             profileInfo.hapInfo = parseHapInfo(hapJson, data);
320         }
321         parseDeviceTypeToHapInfo(paclInfoJsonString, profileInfo.hapInfo, hapName);
322         if (jsonObject.containsKey("deviceConfig")) {
323             JSONObject deviceConfigJson = jsonObject.getJSONObject("deviceConfig");
324             profileInfo.deviceConfig = parseDeviceConfigInfo(deviceConfigJson, profileInfo.hapInfo.deviceType);
325         }
326         if (!parseShellVersionInfoToAppInfo(paclInfoJsonString, profileInfo.appInfo)) {
327             profileInfo.appInfo.setDefaultShellVersion();
328         }
329         if (!profileInfo.appInfo.appName.isEmpty()) {
330             return profileInfo;
331         }
332 
333         if (profileInfo.hapInfo.abilities.size() == 1) {
334             profileInfo.appInfo.appName = profileInfo.hapInfo.abilities.get(0).label;
335             profileInfo.appInfo.appNameEN = profileInfo.hapInfo.abilities.get(0).label;
336         } else {
337             for (AbilityInfo abilityInfo : profileInfo.hapInfo.abilities) {
338                 boolean isLabel = false;
339                 for (SkillInfo skill : abilityInfo.skills) {
340                     if (skill.actions.contains("action.system.home") && skill.entities.contains("entity.system.home")) {
341                         isLabel = true;
342                         break;
343                     }
344                 }
345                 if (isLabel) {
346                     profileInfo.appInfo.appName = abilityInfo.label;
347                     profileInfo.appInfo.appNameEN = abilityInfo.label;
348                     break;
349                 }
350             }
351         }
352         return profileInfo;
353     }
354 
355     /**
356      * parse app info
357      *
358      * @param appJson global json Object
359      * @param data resource index data
360      * @return the parseAppInfo result
361      * @throws BundleException Throws this exception if the json is not standard.
362      */
parseAppInfo(JSONObject appJson, byte[] data)363     static AppInfo parseAppInfo(JSONObject appJson, byte[] data) throws BundleException {
364         AppInfo appInfo = new AppInfo();
365         if (appJson == null) {
366             LOG.error("Uncompress::parseAppInfo exception: appJson is null.");
367             throw new BundleException("Parse app info failed, appJson is null.");
368         }
369         appInfo.bundleName = getJsonString(appJson, "bundleName");
370         appInfo.setBundleType(getJsonString(appJson, BUNDLE_TYPE, APP));
371         appInfo.vendor = getJsonString(appJson, "vendor");
372         appInfo.relatedBundleName = getJsonString(appJson, "relatedBundleName");
373         if (appJson.containsKey(VERSION)) {
374             JSONObject version = appJson.getJSONObject(VERSION);
375             appInfo.versionName = getJsonString(version, "name");
376             appInfo.versionCode = getJsonString(version, "code");
377         }
378         if (appJson.containsKey("apiVersion")) {
379             JSONObject apiVersion = appJson.getJSONObject("apiVersion");
380             appInfo.compatibleApiVersion = apiVersion.getIntValue("compatible");
381             appInfo.targetApiVersion = apiVersion.getIntValue("target");
382             appInfo.releaseType = getJsonString(apiVersion, "releaseType");
383             appInfo.setCompileSdkType(getJsonString(apiVersion, COMPILE_SDK_TYPE));
384             appInfo.setCompileSdkVersion(getJsonString(apiVersion, COMPILE_SDK_VERSION));
385         }
386         String labelRes = "";
387         if (appJson.containsKey("labelId")) {
388             int labelId = appJson.getIntValue("labelId");
389             labelRes = ResourcesParser.getBaseResourceById(labelId, data);
390         }
391         if (labelRes != null && !labelRes.isEmpty()) {
392             appInfo.appName = labelRes;
393             appInfo.appNameEN = labelRes;
394         } else if (appJson.containsKey("label")) {
395             appInfo.appName = getJsonString(appJson, "label");
396             appInfo.appNameEN = getJsonString(appJson, "label");
397         }
398         appInfo.setMultiFrameworkBundle(appJson.getBooleanValue(MULTI_FRAMEWORK_BUNDLE));
399         if (appJson.containsKey(COMPILE_SDK_TYPE)) {
400             appInfo.setCompileSdkType(appJson.getString(COMPILE_SDK_TYPE));
401         }
402         if (appJson.containsKey(COMPILE_SDK_VERSION)) {
403             appInfo.setCompileSdkVersion(appJson.getString(COMPILE_SDK_VERSION));
404         }
405         return appInfo;
406     }
407 
408     /**
409      * parse module app info
410      *
411      * @param appJson global json Object
412      * @param data resource index data
413      * @return the moduleApp result
414      * @throws BundleException Throws this exception if the json is not standard.
415      */
parseModuleAppInfo(JSONObject appJson, byte[] data)416     static ModuleAppInfo parseModuleAppInfo(JSONObject appJson, byte[] data) throws BundleException {
417         ModuleAppInfo moduleAppInfo = new ModuleAppInfo();
418         if (appJson == null) {
419             LOG.error("Uncompress::parseModuleAppInfo exception: appJson is null.");
420             throw new BundleException("Parse module app info failed, appJson is null.");
421         }
422 
423         moduleAppInfo.bundleName = getJsonString(appJson, BUNDLENAME);
424         moduleAppInfo.debug = getJsonBooleanValue(appJson, DEBUG, false);
425         moduleAppInfo.icon = parseIconById(appJson, data);
426         moduleAppInfo.label = parseResourceByKey(appJson, data, LABEL, LABEL_ID);
427         moduleAppInfo.setLabels(parseResourceMapByKey(appJson, data, LABEL_ID));
428         moduleAppInfo.description = parseResourceByKey(appJson, data, DESCRIPTION, DESCRIPTION_ID);
429         moduleAppInfo.setDescriptions(parseResourceMapByKey(appJson, data, DESCRIPTION_ID));
430 
431         moduleAppInfo.vendor = getJsonString(appJson, VENDOR);
432         moduleAppInfo.versionCode = getJsonIntValue(appJson, VERSION_CODE, DEFAULT_VERSION_CODE);
433         moduleAppInfo.versionName = getJsonString(appJson, VERSION_NAME);
434 
435         if (appJson.containsKey(MIN_COMPATIBLE_VERSION_CODE)) {
436             moduleAppInfo.minCompatibleVersionCode =
437                     getJsonIntValue(appJson, MIN_COMPATIBLE_VERSION_CODE, DEFAULT_VERSION_CODE);
438         } else {
439             moduleAppInfo.minCompatibleVersionCode = getJsonIntValue(appJson, VERSION_CODE, DEFAULT_VERSION_CODE);
440         }
441         moduleAppInfo.minAPIVersion = getJsonIntValue(appJson, MIN_API_VERSION, DEFAULT_VERSION_CODE);
442         moduleAppInfo.targetAPIVersion = getJsonIntValue(appJson, TARGET_API_VERSION, DEFAULT_VERSION_CODE);
443         moduleAppInfo.apiReleaseType = getJsonString(appJson, API_RELEASE_TYPE);
444         moduleAppInfo.distributedNotificationEnabled =
445                 getJsonBooleanValue(appJson, DISTRIBUTED_NOTIFICATION_ENABLED, false);
446         moduleAppInfo.entityType = getJsonString(appJson, ENTITY_TYPE, UNSPECIFIED);
447         moduleAppInfo.setBundleType(getJsonString(appJson, BUNDLE_TYPE, APP));
448         moduleAppInfo.setCompileSdkType(getJsonString(appJson, COMPILE_SDK_TYPE, EMPTY));
449         moduleAppInfo.setCompileSdkVersion(getJsonString(appJson, COMPILE_SDK_VERSION, EMPTY));
450         // parse device type
451         parseSpecifiedDeviceType(appJson, moduleAppInfo);
452         return moduleAppInfo;
453     }
454 
parseSpecifiedDeviceType(JSONObject appJson, ModuleAppInfo moduleAppInfo)455     static void parseSpecifiedDeviceType(JSONObject appJson, ModuleAppInfo moduleAppInfo) throws BundleException {
456         if (appJson == null) {
457             LOG.error("JsonUtil::parseSpecifiedDeviceType exception: appJson is null.");
458             throw new BundleException("Parse app info failed, appJson is null.");
459         }
460         parseDeviceType(appJson, moduleAppInfo, PHONE);
461         parseDeviceType(appJson, moduleAppInfo, TABLET);
462         parseDeviceType(appJson, moduleAppInfo, TV);
463         parseDeviceType(appJson, moduleAppInfo, WEARABLE);
464         parseDeviceType(appJson, moduleAppInfo, AR);
465         parseDeviceType(appJson, moduleAppInfo, VR);
466         parseDeviceType(appJson, moduleAppInfo, CAR);
467         parseDeviceType(appJson, moduleAppInfo, EARPHONES);
468         parseDeviceType(appJson, moduleAppInfo, SPEAKER);
469         parseDeviceType(appJson, moduleAppInfo, LINK_IOT);
470         parseDeviceType(appJson, moduleAppInfo, ROUTER);
471         parseDeviceType(appJson, moduleAppInfo, TWO_IN_ONE);
472     }
473 
474     /**
475      * parse deviceType
476      *
477      * @param appJson is the json Object of app
478      * @param moduleAppInfo the app in module
479      * @param deviceName the device name in deviceType array
480      * @return the parseDeviceConfigInfo result
481      * @throws BundleException Throws this exception if the json is not standard.
482      */
parseDeviceType(JSONObject appJson, ModuleAppInfo moduleAppInfo, String deviceName)483     static ModuleDeviceType parseDeviceType(JSONObject appJson, ModuleAppInfo moduleAppInfo,
484                                             String deviceName) throws BundleException {
485         if (appJson == null) {
486             LOG.error("JsonUtil::parseDeviceType exception: appJson is null.");
487             throw new BundleException("Parse app info failed, appJson is null.");
488         }
489         ModuleDeviceType moduleDeviceType = new ModuleDeviceType();
490         if (appJson.containsKey(deviceName)) {
491             JSONObject deviceObj = appJson.getJSONObject(deviceName);
492             if (deviceObj.containsKey(MIN_API_VERSION)) {
493                 moduleDeviceType.minAPIVersion = deviceObj.getIntValue(MIN_API_VERSION);
494             } else {
495                 moduleDeviceType.minAPIVersion = moduleAppInfo.minAPIVersion;
496             }
497 
498             if (deviceObj.containsKey(DISTRIBUTED_NOTIFICATION_ENABLED)) {
499                 moduleDeviceType.distributedNotificationEnabled =
500                         deviceObj.getBoolean(DISTRIBUTED_NOTIFICATION_ENABLED);
501             } else {
502                 moduleDeviceType.distributedNotificationEnabled = moduleAppInfo.distributedNotificationEnabled;
503             }
504 
505             moduleAppInfo.deviceTypes.put(deviceName, moduleDeviceType);
506         }
507         return moduleDeviceType;
508     }
509 
510     /**
511      * parse deviceConfig infos
512      *
513      * @param deviceConfigInfoJson deviceConfig json Object
514      * @param deviceTypes the deviceTypes of the hap
515      * @return the parseDeviceConfigInfo result
516      * @throws BundleException Throws this exception if the json is not standard.
517      */
parseDeviceConfigInfo(JSONObject deviceConfigInfoJson, List<String> deviceTypes)518     static Map<String, DeviceConfig> parseDeviceConfigInfo(JSONObject deviceConfigInfoJson,
519             List<String> deviceTypes) throws BundleException {
520         Map<String, DeviceConfig> deviceConfigs = new HashMap<>();
521         if (deviceConfigInfoJson == null) {
522             return deviceConfigs;
523         }
524 
525         DeviceConfig defaultConfig = new DeviceConfig();
526         if (deviceConfigInfoJson.containsKey("default")) {
527             defaultConfig = parseDeviceConfig(deviceConfigInfoJson.getJSONObject("default"),
528                     new DeviceConfig());
529         }
530 
531         for (String deviceType : deviceTypes) {
532             getTargetDeviceConfig(deviceConfigs, deviceConfigInfoJson, defaultConfig, deviceType);
533         }
534 
535         if (deviceConfigs.isEmpty()) {
536             deviceConfigs.put(UncompressEntrance.DEVICE_TYPE_PHONE, defaultConfig);
537         }
538 
539         return deviceConfigs;
540     }
541 
542     /**
543      * parse deviceConfig infos
544      *
545      * @param deviceConfigs the parseDeviceConfigInfo result
546      * @param deviceConfigInfoJson deviceConfig json Object
547      * @param defaultConfig the default deviceConfig
548      * @param targetDeviceType the target deviceType
549      * @throws BundleException Throws this exception if the json is not standard.
550      */
getTargetDeviceConfig(Map<String, DeviceConfig> deviceConfigs, JSONObject deviceConfigInfoJson, DeviceConfig defaultConfig, String targetDeviceType)551     static void getTargetDeviceConfig(Map<String, DeviceConfig> deviceConfigs, JSONObject deviceConfigInfoJson,
552             DeviceConfig defaultConfig, String targetDeviceType) throws BundleException {
553         if (deviceConfigInfoJson.containsKey(targetDeviceType)) {
554             DeviceConfig deviceConfig = parseDeviceConfig(
555                     deviceConfigInfoJson.getJSONObject(targetDeviceType), defaultConfig);
556             deviceConfigs.put(targetDeviceType, deviceConfig);
557         } else {
558             deviceConfigs.put(targetDeviceType, defaultConfig);
559         }
560     }
561 
562     /**
563      * parse deviceConfig info
564      *
565      * @param deviceConfigJson deviceConfig json Object
566      * @param defaultConfig default deviceConfig
567      * @return the parseDeviceConfigInfo result
568      * @throws BundleException Throws this exception if the json is not standard.
569      */
parseDeviceConfig(JSONObject deviceConfigJson, DeviceConfig defaultConfig)570     static DeviceConfig parseDeviceConfig(JSONObject deviceConfigJson, DeviceConfig defaultConfig)
571             throws BundleException {
572         DeviceConfig deviceConfig = new DeviceConfig();
573         if (deviceConfigJson == null || defaultConfig == null) {
574             LOG.error("Uncompress::parseDeviceConfigInfo exception: deviceConfigJson or defaultConfig is null.");
575             throw new BundleException("Parse device config info failed, deviceConfigJson or defaultConfig is null.");
576         }
577 
578         deviceConfig.jointUserid = getJsonString(deviceConfigJson, "jointUserid", defaultConfig.jointUserid);
579         deviceConfig.process = getJsonString(deviceConfigJson, "process", defaultConfig.process);
580 
581         if (deviceConfigJson.containsKey("reqSdk")) {
582             JSONObject reqSdk = deviceConfigJson.getJSONObject("reqSdk");
583             deviceConfig.compatibleReqSdk = getJsonString(reqSdk, "compatible", defaultConfig.compatibleReqSdk);
584             deviceConfig.targetReqSdk = getJsonString(reqSdk, "target", defaultConfig.targetReqSdk);
585         }
586 
587         if (deviceConfigJson.containsKey("ark")) {
588             JSONObject ark = deviceConfigJson.getJSONObject("ark");
589             deviceConfig.arkFlag = getJsonString(ark, "flag", defaultConfig.arkFlag);
590             if (ark.containsKey("reqVersion")) {
591                 JSONObject arkVersion = ark.getJSONObject("reqVersion");
592                 deviceConfig.targetArkVersion = getJsonString(arkVersion, "target", defaultConfig.targetArkVersion);
593                 deviceConfig.compatibleArkVersion = getJsonString(arkVersion, "compatible",
594                         defaultConfig.compatibleArkVersion);
595             }
596         }
597 
598         if (deviceConfigJson.containsKey("directLaunch")) {
599             deviceConfig.directLaunch = deviceConfigJson.getBoolean("directLaunch");
600         } else {
601             deviceConfig.directLaunch = defaultConfig.directLaunch;
602         }
603 
604         return deviceConfig;
605     }
606 
607     /**
608      * parse hap info
609      *
610      * @param hapJson hap json Object
611      * @param data resource index data
612      * @return the parseHapInfo result
613      * @throws BundleException Throws this exception if the json is not standard.
614      */
parseHapInfo(JSONObject hapJson, byte[] data)615     static HapInfo parseHapInfo(JSONObject hapJson, byte[] data) throws BundleException {
616         HapInfo hapInfo = new HapInfo();
617         if (hapJson == null) {
618             LOG.error("Uncompress::parseHapInfo exception: hapJson is null.");
619             throw new BundleException("Parse hap info failed, hapJson is null.");
620         }
621         hapInfo.packageStr = getJsonString(hapJson, "package");
622         hapInfo.name = getJsonString(hapJson, "name");
623         hapInfo.description = parseResourceByKey(hapJson, data, "description", "descriptionId");
624         hapInfo.setDescriptions(parseResourceMapByKey(hapJson, data, DESCRIPTION_ID));
625 
626         if (hapJson.containsKey(MAIN_ABILITY)) {
627             hapInfo.mainElement = getJsonString(hapJson, MAIN_ABILITY);
628         }
629 
630         if (hapJson.containsKey("supportedModes")) {
631             hapInfo.supportedModes = JSONObject.parseArray(getJsonString(hapJson, "supportedModes"),
632                     String.class);
633         }
634 
635         if (hapJson.containsKey("defPermissions")) {
636             hapInfo.defPermissions = parseDefPermissions(hapJson, data);
637         }
638 
639         if (hapJson.containsKey("definePermissions")) {
640             hapInfo.definePermissions = parseDefinePermissions(hapJson, data);
641         }
642 
643         if (hapJson.containsKey("defPermissiongroups")) {
644             hapInfo.defPermissionsGroups = JSONArray.parseArray(getJsonString(hapJson, "defPermissiongroups"),
645                     DefPermissionGroup.class);
646         }
647 
648         if (hapJson.containsKey("distro")) {
649             getDistro(hapJson, hapInfo);
650         }
651 
652         if (hapJson.containsKey("reqCapabilities")) {
653             hapInfo.reqCapabilities = JSONArray.parseArray(getJsonString(hapJson, "reqCapabilities"),
654                     String.class);
655         }
656 
657         if (hapJson.containsKey("deviceType")) {
658             hapInfo.deviceType = JSONArray.parseArray(getJsonString(hapJson, "deviceType")
659                     .replace(UncompressEntrance.DEVICE_TYPE_DEFAULT, UncompressEntrance.DEVICE_TYPE_PHONE),
660                     String.class);
661         }
662 
663         if (hapJson.containsKey("metaData")) {
664             JSONObject metaDataJson = hapJson.getJSONObject("metaData");
665             hapInfo.metaData = parseMetaData(metaDataJson);
666         }
667 
668         if (hapJson.containsKey("js")) {
669             List<JsInfo> jsInfos = JSONObject.parseArray(getJsonString(hapJson, "js"), JsInfo.class);
670             if (jsInfos != null && jsInfos.size() > 0) {
671                 hapInfo.isJs = true;
672             }
673         }
674 
675         if (hapJson.containsKey("reqPermissions")) {
676             hapInfo.reqPermissions = parseFAReqPermission(hapJson, data);
677         }
678 
679         if (hapJson.containsKey("commonEvents")) {
680             hapInfo.commonEvents = JSONObject.parseArray(getJsonString(hapJson, "commonEvents"),
681                     CommonEvent.class);
682         }
683 
684         if (hapJson.containsKey("shortcuts")) {
685             hapInfo.shortcuts = parseShoruCuts(hapJson, data);
686         }
687 
688         if (hapJson.containsKey("abilities")) {
689             JSONArray abilities = hapJson.getJSONArray("abilities");
690             List<AbilityInfo> abilitieList = new ArrayList<AbilityInfo>();
691             int abilitiesSize = abilities.size();
692             for (int i = 0; i < abilitiesSize; i++) {
693                 JSONObject tmpObj = abilities.getJSONObject(i);
694                 abilitieList.add(parseAbility(tmpObj, data));
695             }
696             hapInfo.abilities = abilitieList;
697             adaptAbilityName(hapInfo.abilities, hapInfo.packageStr);
698             setFAProviderAbility(hapJson, hapInfo, hapInfo.abilities);
699         }
700 
701         if (hapJson.containsKey("distroFilter")) {
702             hapInfo.distroFilter = JSONObject.parseObject(
703                     getJsonString(hapJson, "distroFilter"), DistroFilter.class);
704         }
705         return hapInfo;
706     }
707 
parseFAReqPermission(JSONObject hapJson, byte[] data)708     static List<ReqPermission> parseFAReqPermission(JSONObject hapJson, byte[] data) throws BundleException {
709         List<ReqPermission> reqPermissions = new ArrayList<>();
710         if (!hapJson.containsKey(REQ_PERMISSIONS)) {
711             return reqPermissions;
712         }
713         JSONArray reqPermissionObjs = hapJson.getJSONArray(REQ_PERMISSIONS);
714         for (int i = 0; i < reqPermissionObjs.size(); ++i) {
715             ReqPermission reqPermission = new ReqPermission();
716             JSONObject requestPermission = reqPermissionObjs.getJSONObject(i);
717             reqPermission.name = getJsonString(requestPermission, NAME);
718             reqPermission.reason = parseResourceByKey(requestPermission, data, REASON, REASON_ID);
719             if (requestPermission.containsKey(REASON_ID)) {
720                 reqPermission.setReasons(parseResourceMapByKey(requestPermission, data, REASON_ID));
721             }
722             if (requestPermission.containsKey(USED_SCENE)) {
723                 reqPermission.usedScene = parseModuleUsedScene(requestPermission.getJSONObject(USED_SCENE));
724             }
725             reqPermissions.add(reqPermission);
726         }
727         return reqPermissions;
728     }
729 
730     /**
731      * get distro
732      *
733      * @param hapJson hapJson json
734      * @param hapInfo hapInfo json object
735      */
getDistro(JSONObject hapJson, HapInfo hapInfo)736     private static void getDistro(JSONObject hapJson, HapInfo hapInfo) {
737         JSONObject distroObj = hapJson.getJSONObject("distro");
738         Distro distro = new Distro();
739         distro.moduleName = getJsonString(distroObj, "moduleName");
740         distro.moduleType = getJsonString(distroObj, "moduleType");
741         distro.deliveryWithInstall = distroObj.getBoolean("deliveryWithInstall");
742         if (distroObj.containsKey("installationFree")) {
743             boolean isFreeInstall = distroObj.getBoolean("installationFree");
744             if (isFreeInstall) {
745                 distro.installationFree = 1;
746             }else {
747                 distro.installationFree = 0;
748             }
749         } else {
750             distro.installationFree = 2;
751         }
752         if (distroObj.containsKey("virtualMachine")) {
753             distro.virtualMachine = getJsonString(distroObj, "virtualMachine");
754         } else {
755             distro.virtualMachine = "default";
756         }
757         hapInfo.distro = distro;
758     }
759 
760     /**
761      * parse meta data
762      *
763      * @param metaDataJson meta data json
764      * @return the parseMetaData result
765      */
parseMetaData(JSONObject metaDataJson)766     private static MetaData parseMetaData(JSONObject metaDataJson) {
767         MetaData metaData = new MetaData();
768         if (metaDataJson == null) {
769             LOG.error("Uncompress::parseMetaData : metaDataJson is null");
770             return metaData;
771         }
772 
773         if (metaDataJson.containsKey("parameters")) {
774             metaData.parameters = JSONObject.parseArray(getJsonString(metaDataJson, "parameters"),
775                     MetaDataInfo.class);
776         }
777         if (metaDataJson.containsKey("results")) {
778             metaData.results = JSONObject.parseArray(getJsonString(metaDataJson, "results"),
779                     MetaDataInfo.class);
780         }
781         if (metaDataJson.containsKey("customizeData")) {
782             metaData.customizeDatas = JSONObject.parseArray(getJsonString(metaDataJson, "customizeData"),
783                     CustomizeData.class);
784         }
785         return metaData;
786     }
787 
788     /**
789      * parse ability object.
790      *
791      * @param abilityJson ability json object
792      * @param data resource index data
793      * @return the parseAbility result
794      * @throws BundleException Throws this exception if the json is not standard.
795      */
parseAbility(JSONObject abilityJson, byte[] data)796     static AbilityInfo parseAbility(JSONObject abilityJson, byte[] data) throws BundleException {
797         if (abilityJson == null) {
798             LOG.error("Uncompress::parseAbility exception: abilityJson is null.");
799             throw new BundleException("Parse ability failed, abilityJson is null.");
800         }
801         AbilityInfo ability = new AbilityInfo();
802         ability.name = getJsonString(abilityJson, "name");
803         if (abilityJson.containsKey("iconId")) {
804             int iconId = abilityJson.getIntValue("iconId");
805             String iconPath = ResourcesParser.getResourceById(iconId, data);
806             if (iconPath != null && !iconPath.isEmpty()) {
807                 ability.iconPath = ASSETS_DIR_NAME + iconPath;
808             }
809         }
810         ability.icon = ability.iconPath != null && !ability.iconPath.isEmpty() ? ability.iconPath :
811                 getJsonString(abilityJson, "icon");
812 
813         if (abilityJson.containsKey("descriptionId")) {
814             int descriptionId = abilityJson.getIntValue("descriptionId");
815             ability.descriptionRes = ResourcesParser.getBaseResourceById(descriptionId, data);
816         }
817         ability.description = ability.descriptionRes != null && !ability.descriptionRes.isEmpty() ?
818                 ability.descriptionRes : getJsonString(abilityJson, "description");
819         ability.setDescriptions(parseResourceMapByKey(abilityJson, data, DESCRIPTION_ID));
820 
821         if (abilityJson.containsKey("labelId")) {
822             int labelId = abilityJson.getIntValue("labelId");
823             ability.labelRes = ResourcesParser.getBaseResourceById(labelId, data);
824         }
825         if (ability.labelRes != null && !ability.labelRes.isEmpty()) {
826             ability.label = ability.labelRes;
827         } else if (!getJsonString(abilityJson, "label").isEmpty()) {
828             ability.label = getJsonString(abilityJson, "label");
829         } else {
830             ability.label = ability.name;
831         }
832         ability.setLabels(parseResourceMapByKey(abilityJson, data, LABEL_ID));
833 
834         ability.type = getJsonString(abilityJson, "type");
835         ability.launchType = getJsonString(abilityJson, "launchType");
836         ability.orientation = getJsonString(abilityJson, "orientation");
837         ability.uri = getJsonString(abilityJson, "uri");
838         if (abilityJson.containsKey("formsEnabled")) {
839             ability.formsEnabled = abilityJson.getBoolean("formsEnabled");
840         }
841 
842         if (abilityJson.containsKey("metaData")) {
843             JSONObject metaDataJson = abilityJson.getJSONObject("metaData");
844             ability.metaData = parseMetaData(metaDataJson);
845         }
846 
847         if (abilityJson.containsKey("skills")) {
848             ability.skills = JSONObject.parseArray(getJsonString(abilityJson, "skills"), SkillInfo.class);
849         }
850 
851         if (abilityJson.containsKey("backgroundModes")) {
852             ability.backgroundModes = JSONObject.parseArray(getJsonString(abilityJson, "backgroundModes"),
853                     String.class);
854         }
855 
856         if (abilityJson.containsKey("visible")) {
857             ability.visible = abilityJson.getBoolean("visible");
858         }
859 
860         if (abilityJson.containsKey("configChanges")) {
861             ability.configChanges = JSONObject.parseArray(
862                     getJsonString(abilityJson, "configChanges"), String.class);
863         }
864 
865         if (abilityJson.containsKey("srcLanguage")) {
866             ability.srcLanguage = getJsonString(abilityJson, "srcLanguage");
867         }
868 
869         if (abilityJson.containsKey("srcPath")) {
870             ability.srcPath = getJsonString(abilityJson, "srcPath");
871         }
872 
873         parseAbilityPermissions(abilityJson, ability);
874 
875         if (abilityJson.containsKey("forms")) {
876             JSONArray forms = abilityJson.getJSONArray("forms");
877             List<AbilityFormInfo> formList = new ArrayList<AbilityFormInfo>();
878             int formSize = forms.size();
879             for (int i = 0; i < formSize; i++) {
880                 JSONObject tmpObj = forms.getJSONObject(i);
881                 formList.add(parseAbilityFormInfo(tmpObj, data));
882             }
883             ability.formInfos = formList;
884         }
885 
886         return ability;
887     }
888 
adaptAbilityName(List<AbilityInfo> abilityInfos, String packageName)889     private static void adaptAbilityName(List<AbilityInfo> abilityInfos, String packageName) {
890         if (abilityInfos == null) {
891             return;
892         }
893         for (AbilityInfo abilityInfo : abilityInfos) {
894             if (abilityInfo.name.startsWith(DOT)) {
895                 abilityInfo.name = packageName + abilityInfo.name;
896             }
897         }
898     }
899 
900     /**
901      * parse ability object.
902      *
903      * @param abilityJson ability json object
904      * @param ability the parseAbility result
905      * @return the parseAbility Permissions result
906      * @throws BundleException Throws this exception if the json is not standard.
907      */
parseAbilityPermissions(JSONObject abilityJson, AbilityInfo ability)908     static void parseAbilityPermissions(JSONObject abilityJson, AbilityInfo ability) throws BundleException {
909         if (abilityJson == null || ability == null) {
910             LOG.error("Uncompress::parseAbilityPermissions exception: abilityJson or ability is null.");
911             throw new BundleException("Parse ability permissions failed, abilityJson or ability is null.");
912         }
913         if (abilityJson.containsKey("permissions")) {
914             ability.permissions = JSONObject.parseArray(getJsonString(abilityJson, "permissions"), String.class);
915         }
916 
917         if (abilityJson.containsKey("grantPermission")) {
918             ability.grantPermission = abilityJson.getBoolean("grantPermission");
919         }
920         ability.readPermission = getJsonString(abilityJson, "readPermission");
921         ability.writePermission = getJsonString(abilityJson, "writePermission");
922 
923         if (abilityJson.containsKey("uriPermission")) {
924             JSONObject uriPermission = abilityJson.getJSONObject("uriPermission");
925             ability.uriPermissionMode = getJsonString(uriPermission, "mode");
926             ability.uriPermissionPath = getJsonString(uriPermission, "path");
927         }
928 
929         ability.mission = getJsonString(abilityJson, "mission");
930         ability.targetAbility = getJsonString(abilityJson, "targetAbility");
931 
932         if (abilityJson.containsKey("directLaunch")) {
933             ability.directLaunch = abilityJson.getBoolean("directLaunch");
934         }
935 
936         if (abilityJson.containsKey("multiUserShared")) {
937             ability.multiUserShared = abilityJson.getBoolean("multiUserShared");
938         }
939 
940         if (abilityJson.containsKey("supportPipMode")) {
941             ability.supportPipMode = abilityJson.getBoolean("supportPipMode");
942         }
943 
944         if (abilityJson.containsKey("form")) {
945             JSONObject form = abilityJson.getJSONObject("form");
946             FormInfo formInfo = new FormInfo();
947             if (form.containsKey("formEntity")) {
948                 formInfo.formEntity = JSONObject.parseArray(getJsonString(form, "formEntity"), String.class);
949             }
950             formInfo.minWidth = getJsonString(form, "minWidth");
951             formInfo.defaultWidth = getJsonString(form, "defaultWidth");
952             formInfo.minHeight = getJsonString(form, "minHeight");
953             formInfo.defaultHeight = getJsonString(form, "defaultHeight");
954             ability.formInfo = formInfo;
955         }
956     }
957     /**
958      * parse ability forms object
959      *
960      * @param abilityFormJson ability form json object
961      * @return the ability form info result
962      */
parseAbilityFormInfo(JSONObject abilityFormJson, byte[] data)963     static AbilityFormInfo parseAbilityFormInfo(JSONObject abilityFormJson, byte[] data) throws BundleException {
964         AbilityFormInfo abilityForm = new AbilityFormInfo();
965         if (abilityFormJson == null) {
966             LOG.error("Uncompress::parseAbilityFormInfo : abilityFormJson is null");
967             return abilityForm;
968         }
969         abilityForm.name = getJsonString(abilityFormJson, "name");
970         abilityForm.type = getJsonString(abilityFormJson, "type");
971         abilityForm.description = parseResourceByKey(abilityFormJson, data, "description", "descriptionId");
972         abilityForm.setDescriptions(parseResourceMapByKey(abilityFormJson, data, DESCRIPTION_ID));
973         if (abilityFormJson.containsKey("isDefault")) {
974             abilityForm.isDefault = abilityFormJson.getBoolean("isDefault");
975         }
976         if (abilityFormJson.containsKey("colorMode")) {
977             abilityForm.colorMode = getJsonString(abilityFormJson, "colorMode");
978         }
979         if (abilityFormJson.containsKey("formConfigAbility")) {
980             abilityForm.formConfigAbility = getJsonString(abilityFormJson, "formConfigAbility");
981         }
982         if (abilityFormJson.containsKey("updateEnabled")) {
983             abilityForm.updateEnabled = abilityFormJson.getBoolean("updateEnabled");
984         }
985         abilityForm.scheduledUpdateTime = getJsonString(abilityFormJson, "scheduledUpdateTime");
986         if (abilityFormJson.containsKey("updateDuration")) {
987             abilityForm.updateDuration = abilityFormJson.getIntValue("updateDuration");
988         }
989         if (abilityFormJson.containsKey("supportDimensions")) {
990             abilityForm.supportDimensions = JSONObject.parseArray(getJsonString(abilityFormJson, "supportDimensions"),
991                     String.class);
992         }
993         abilityForm.defaultDimension = getJsonString(abilityFormJson, "defaultDimension");
994         if (abilityFormJson.containsKey("metaData")) {
995             JSONObject metaDataJson = abilityFormJson.getJSONObject("metaData");
996             abilityForm.metaData = parseMetaData(metaDataJson);
997         }
998         return abilityForm;
999     }
1000 
1001     /**
1002      * parse module hap info
1003      *
1004      * @param harmonyProfileJsonString uncompress json String
1005      * @param data resource index data
1006      * @param packInfoJsonString pack.info json String
1007      * @param hapName hap file name
1008      * @return the parseProfileInfo result
1009      * @throws BundleException Throws this exception if the json is not standard.
1010      */
parseModuleProfileInfo(String harmonyProfileJsonString, byte[] data, String packInfoJsonString, String hapName, HashMap<String, String> profileJsons)1011     static ModuleProfileInfo parseModuleProfileInfo(String harmonyProfileJsonString, byte[] data, String packInfoJsonString,
1012                                                     String hapName, HashMap<String, String> profileJsons) throws BundleException {
1013         ModuleProfileInfo moduleProfileInfo = new ModuleProfileInfo();
1014         JSONObject jsonObject = JSONObject.parseObject(harmonyProfileJsonString);
1015         if (jsonObject == null || !jsonObject.containsKey(APP) || !jsonObject.containsKey(MODULE)) {
1016             LOG.error("JsonUtil::parseModuleProfileInfo exception: app or module is null.");
1017             throw new BundleException("Parse module profile info failed, app or module is null.");
1018         }
1019 
1020         JSONObject appJson = jsonObject.getJSONObject(APP);
1021         moduleProfileInfo.moduleAppInfo = parseModuleAppInfo(appJson, data);
1022         JSONObject moduleJson = jsonObject.getJSONObject(MODULE);
1023         moduleProfileInfo.moduleInfo = parseModuleHapInfo(moduleJson, data,
1024                 moduleProfileInfo.moduleAppInfo.bundleName, profileJsons);
1025         moduleProfileInfo.moduleInfo.appModel = AppModel.STAGE;
1026         moduleProfileInfo.moduleInfo.dependenies.addAll(parseDenpendencies(appJson, moduleJson));
1027 
1028         // parse appName
1029         for (ModuleAbilityInfo abilityInfo : moduleProfileInfo.moduleInfo.abilities) {
1030             for (SkillInfo skill : abilityInfo.skills) {
1031                 if (skill.actions.contains(ACTION_SYSTEM_HOME) && skill.entities.contains(ENTITY_SYSTEM_HOME)) {
1032                     moduleProfileInfo.moduleAppInfo.appName = abilityInfo.label;
1033                     moduleProfileInfo.moduleAppInfo.appNameEN = abilityInfo.label;
1034                     break;
1035                 }
1036             }
1037         }
1038 
1039         return moduleProfileInfo;
1040     }
1041 
1042     /**
1043      * parse module hap info
1044      *
1045      * @param moduleJson Json hap json Object
1046      * @param data resource index data
1047      * @param hapName is the name of the hap
1048      * @param profileJsons is the map of profile
1049      * @return the ModuleProfileInfo result
1050      * @throws BundleException Throws this exception if the json is not standard.
1051      */
parseModuleHapInfo(JSONObject moduleJson, byte[] data, String hapName, HashMap<String, String> profileJsons)1052     static ModuleInfo parseModuleHapInfo(JSONObject moduleJson, byte[] data, String hapName,
1053                                          HashMap<String, String> profileJsons) throws BundleException {
1054         ModuleInfo moduleInfo = new ModuleInfo();
1055         if (moduleJson == null) {
1056             LOG.error("JsonUtil::parseModuleHapInfo exception: moduleJson is null.");
1057             throw new BundleException("Parse module hap info failed, moduleJson is null.");
1058         }
1059 
1060         moduleInfo.name = getJsonString(moduleJson, NAME);
1061         moduleInfo.type = getJsonString(moduleJson, TYPE);
1062         if (moduleJson.containsKey(SRC_ENTRY)) {
1063             moduleInfo.srcEntrance = getJsonString(moduleJson, SRC_ENTRY);
1064         } else {
1065             moduleInfo.srcEntrance = getJsonString(moduleJson, SRC_ENTRANCE);
1066         }
1067         moduleInfo.description = parseResourceByKey(moduleJson, data, DESCRIPTION, DESCRIPTION_ID);
1068         moduleInfo.setDescriptions(parseResourceMapByKey(moduleJson, data, DESCRIPTION_ID));
1069         if (moduleJson.containsKey(PROCESS)) {
1070             moduleInfo.process = getJsonString(moduleJson, PROCESS);
1071         } else {
1072             moduleInfo.process = hapName;
1073         }
1074         moduleInfo.mainElement = getJsonString(moduleJson, MAIN_ELEMENT);
1075         if (moduleJson.containsKey(DEVICE_TYPES)) {
1076             moduleInfo.deviceTypes = JSONObject.parseArray(getJsonString(moduleJson, DEVICE_TYPES), String.class);
1077         }
1078         moduleInfo.deliveryWithInstall = getJsonBooleanValue(moduleJson, DELIVERY_WITH_INSTALL, true);
1079         parseInstallationFree(moduleJson, moduleInfo);
1080         moduleInfo.virtualMachine = getJsonString(moduleJson, VIRTUAL_MACHINE, DEFAULT);
1081         moduleInfo.uiSyntax = getJsonString(moduleJson, UI_SYNTAX, HML);
1082         moduleInfo.pages = parseModulePages(moduleJson, profileJsons);
1083         moduleInfo.moduleMetadataInfos = parseModuleMetadataInfos(moduleJson, data, profileJsons);
1084         // parse shortcuts and distroFilter
1085         if (!moduleInfo.moduleMetadataInfos.isEmpty()) {
1086             moduleInfo.moduleShortcuts = parseModuleShortcut(moduleInfo.moduleMetadataInfos, data);
1087             moduleInfo.distroFilter = parseModuleDistrofilterFromMetadata(moduleInfo.moduleMetadataInfos);
1088         }
1089         // parse abilities
1090         parseModuleAbilityAndAddShortcut(moduleJson, moduleInfo, data, profileJsons);
1091         // parse extensionAbilities
1092         parseStageExtensionAbility(moduleJson, moduleInfo, data, profileJsons);
1093         // parse request permission
1094         moduleInfo.requestPermissions = parseReqPermission(moduleJson, data);
1095         // parse define permission
1096         moduleInfo.definePermissions = parseDefinePermissions(moduleJson, data);
1097         moduleInfo.moduleAtomicService = parseModuleAtomicService(moduleJson);
1098         return moduleInfo;
1099     }
1100 
parseDenpendencies(JSONObject appJson, JSONObject moduleJson)1101     private static List<DependencyItem> parseDenpendencies(JSONObject appJson, JSONObject moduleJson)
1102             throws BundleException {
1103         if (appJson == null || moduleJson == null) {
1104             LOG.error("JsonUtil::parseModuleHapInfo exception: moduleJson or appJson is null.");
1105             throw new BundleException("Parse module hap info failed, moduleJson or appJson is null.");
1106         }
1107         String bundleName = getJsonString(appJson, BUNDLENAME);
1108         List<DependencyItem> dependencyItemList = new ArrayList<>();
1109         if (!moduleJson.containsKey(DEPENDENCIES)) {
1110             return dependencyItemList;
1111         }
1112         JSONArray dependencyObjList = moduleJson.getJSONArray(DEPENDENCIES);
1113         for (int i = 0; i < dependencyObjList.size(); ++i) {
1114             JSONObject object = dependencyObjList.getJSONObject(i);
1115             DependencyItem item = new DependencyItem();
1116             if (object.containsKey(DEPENDENCY_BUNDLE_NAME)) {
1117                 item.setBundleName(object.getString(DEPENDENCY_BUNDLE_NAME));
1118             } else {
1119                 item.setBundleName(bundleName);
1120             }
1121             if (object.containsKey(DEPENDENCY_MODULE_NAME)) {
1122                 item.setModuleName(object.getString(DEPENDENCY_MODULE_NAME));
1123             }
1124             dependencyItemList.add(item);
1125         }
1126         return dependencyItemList;
1127     }
1128 
parseInstallationFree(JSONObject moduleJson, ModuleInfo moduleInfo)1129     private static void parseInstallationFree(JSONObject moduleJson, ModuleInfo moduleInfo) {
1130         if (moduleJson.containsKey(INSTALLATION_FREE)) {
1131             boolean isFreeInstall = moduleJson.getBoolean(INSTALLATION_FREE);
1132             if (isFreeInstall) {
1133                 moduleInfo.installationFree = 1;
1134             } else {
1135                 moduleInfo.installationFree = 0;
1136             }
1137         } else {
1138             moduleInfo.installationFree = 2;
1139         }
1140     }
1141 
1142     /**
1143      * parse module pages
1144      *
1145      * @param moduleJson is json object of modulejson
1146      * @param profileJsons is the profile map
1147      * @return the pages result
1148      */
parseModulePages( JSONObject moduleJson, HashMap<String, String> profileJsons)1149     static List<String> parseModulePages(
1150             JSONObject moduleJson, HashMap<String, String> profileJsons) throws BundleException {
1151         List<String> pages = new ArrayList<>();
1152         String pageFile = getJsonString(moduleJson, PAGES);
1153         if (pageFile.isEmpty()) {
1154             return pages;
1155         }
1156         pageFile = pageFile.replace(PROFILE, "");
1157         pageFile += JSON_SUFFIX;
1158         String fileContent = profileJsons.get(pageFile);
1159         if (fileContent != null) {
1160             JSONObject pageObj = JSONObject.parseObject(fileContent);
1161             if (pageObj != null) {
1162                 pages = JSONObject.parseArray(getJsonString(pageObj, SRC), String.class);
1163             }
1164         }
1165         return pages;
1166     }
1167 
1168     /**
1169      * parse module hap info
1170      *
1171      * @param moduleMetadataInfos metedata in moduleInfo
1172      * @return the parse result
1173      */
parseModuleDistrofilterFromMetadata(List<ModuleMetadataInfo> moduleMetadataInfos)1174     static DistroFilter parseModuleDistrofilterFromMetadata(List<ModuleMetadataInfo> moduleMetadataInfos) {
1175         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1176             String resource = moduleMetadataInfo.resource;
1177             if (resource.isEmpty()) {
1178                 continue;
1179             }
1180             JSONObject distroFilter = JSONObject.parseObject(resource);
1181             if (distroFilter.containsKey(DISTRIBUTION_FILTER)) {
1182                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRIBUTION_FILTER), DistroFilter.class);
1183             }
1184             if (distroFilter.containsKey(DISTRO_FILTER)) {
1185                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRO_FILTER), DistroFilter.class);
1186             }
1187         }
1188         return null;
1189     }
1190 
1191     /**
1192      * parse module hap info
1193      *
1194      * @param moduleJson is the json object of module object.
1195      * @param data is the resource of hap
1196      * @param profileJsons is the map of profile file name and file content
1197      * @return the parsed extensionAbilityInfos
1198      * @throws BundleException Throws this exception if the json is not standard.
1199      */
parseModuleExtensionAbilities( JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons)1200     static List<ExtensionAbilityInfo> parseModuleExtensionAbilities(
1201             JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons) throws BundleException {
1202         List<ExtensionAbilityInfo> extensionAbilityInfos = new ArrayList<>();
1203         JSONArray extensionAbilities = moduleJson.getJSONArray(EXTENSION_ABILITIES);
1204         int size = extensionAbilities.size();
1205         for (int i = 0; i < size; ++i) {
1206             JSONObject tmpObj = extensionAbilities.getJSONObject(i);
1207             extensionAbilityInfos.add(parseModuleExtensionAbility(tmpObj, data, profileJsons));
1208         }
1209         return extensionAbilityInfos;
1210     }
1211 
parseStageExtensionAbility(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data, HashMap<String, String> profileJsons)1212     private static void parseStageExtensionAbility(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data,
1213                                                    HashMap<String, String> profileJsons) throws BundleException {
1214         if (!moduleJson.containsKey(EXTENSION_ABILITIES)) {
1215             return;
1216         }
1217         // parse service providerAbility
1218         String serviceProviderAbility = parseStageServiceProvider(moduleJson, moduleInfo.abilities);
1219         moduleInfo.extensionAbilityInfos = parseModuleExtensionAbilities(moduleJson, data, profileJsons);
1220         // parse abilityform
1221         moduleInfo.abilityFormInfos = parseModuleAbilityforms(moduleInfo.extensionAbilityInfos,
1222                 data, serviceProviderAbility);
1223         // parse commonEvent
1224         moduleInfo.commonEvents = parseModuleCommonEvents(moduleInfo.extensionAbilityInfos);
1225     }
1226 
1227     /**
1228      * parse module hap info
1229      *
1230      * @param extensionAbilityJson is the json object of extension ability
1231      * @param data is the resource of hap
1232      * @param profileJsons is the map of profile file name and file content
1233      * @return the parsed extensionAbilityInfo
1234      * @throws BundleException Throws this exception if the json is not standard.
1235      */
parseModuleExtensionAbility(JSONObject extensionAbilityJson, byte[] data, HashMap<String, String> profileJsons)1236     static ExtensionAbilityInfo parseModuleExtensionAbility(JSONObject extensionAbilityJson, byte[] data,
1237                                                             HashMap<String, String> profileJsons) throws BundleException {
1238         if (extensionAbilityJson == null) {
1239             LOG.error("JsonUtil::parseModuleExtensionAbility exception: extensionAbilityJson is null.");
1240             throw new BundleException("Parse ability failed, abilityJson is null.");
1241         }
1242         ExtensionAbilityInfo moduleExtensionAbilityInfo = new ExtensionAbilityInfo();
1243         moduleExtensionAbilityInfo.name = getJsonString(extensionAbilityJson, NAME);
1244         if (extensionAbilityJson.containsKey(SRC_ENTRY)) {
1245             moduleExtensionAbilityInfo.srcEntrance = getJsonString(extensionAbilityJson, SRC_ENTRY);
1246         } else {
1247             moduleExtensionAbilityInfo.srcEntrance = getJsonString(extensionAbilityJson, SRC_ENTRANCE);
1248         }
1249         moduleExtensionAbilityInfo.icon = parseIconById(extensionAbilityJson, data);
1250         moduleExtensionAbilityInfo.label =
1251                 parseResourceByKey(extensionAbilityJson, data, LABEL, LABEL_ID);
1252         moduleExtensionAbilityInfo.setLabels(parseResourceMapByKey(extensionAbilityJson, data, LABEL_ID));
1253         moduleExtensionAbilityInfo.description =
1254                 parseResourceByKey(extensionAbilityJson, data, DESCRIPTION, DESCRIPTION_ID);
1255         moduleExtensionAbilityInfo.setDescriptions(parseResourceMapByKey(extensionAbilityJson, data, DESCRIPTION_ID));
1256         moduleExtensionAbilityInfo.type = getJsonString(extensionAbilityJson, TYPE);
1257 
1258         if (extensionAbilityJson.containsKey(PERMISSIONS)) {
1259             moduleExtensionAbilityInfo.permissions =
1260                     JSONObject.parseArray(getJsonString(extensionAbilityJson, PERMISSIONS), String.class);
1261         }
1262         moduleExtensionAbilityInfo.uri = getJsonString(extensionAbilityJson, URI);
1263         moduleExtensionAbilityInfo.readPermission = getJsonString(extensionAbilityJson, READ_PERMISSION);
1264         moduleExtensionAbilityInfo.writePermission = getJsonString(extensionAbilityJson, WRITE_PERMISSION);
1265         if (extensionAbilityJson.containsKey(SKILLS)) {
1266             moduleExtensionAbilityInfo.skills =
1267                     JSONObject.parseArray(getJsonString(extensionAbilityJson, SKILLS), SkillInfo.class);
1268         }
1269 
1270         if (extensionAbilityJson.containsKey(META_DATA)) {
1271             moduleExtensionAbilityInfo.metadataInfos =
1272                     parseModuleMetadataInfos(extensionAbilityJson, data, profileJsons);
1273             // convert to metadata
1274             ModuleAdaption adaption = new ModuleAdaption();
1275             moduleExtensionAbilityInfo.metadata = adaption.convertToMetadata(moduleExtensionAbilityInfo.metadataInfos);
1276         }
1277         if (extensionAbilityJson.containsKey(EXPORTED)) {
1278             moduleExtensionAbilityInfo.visible = getJsonBooleanValue(extensionAbilityJson, EXPORTED, false);
1279         } else {
1280             moduleExtensionAbilityInfo.visible = getJsonBooleanValue(extensionAbilityJson, VISIBLE, false);
1281         }
1282         return moduleExtensionAbilityInfo;
1283     }
1284 
1285     /**
1286      * parse abilities info
1287      *
1288      * @param moduleJson Json hap json Object
1289      * @param data resource index data
1290      * @return the List<ModuleAbilityInfo> result
1291      * @throws BundleException Throws this exception if the json is not standard.
1292      */
parseModuleAbilities(JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons)1293     static List<ModuleAbilityInfo> parseModuleAbilities(JSONObject moduleJson, byte[] data,
1294                                                         HashMap<String, String> profileJsons) throws BundleException {
1295         List<ModuleAbilityInfo> abilities = new ArrayList<>();
1296         if (!moduleJson.containsKey(ABILITIES)) {
1297             return abilities;
1298         }
1299         JSONArray abilityObjs = moduleJson.getJSONArray(ABILITIES);
1300         int size = abilityObjs.size();
1301         for (int i = 0; i < size; ++i) {
1302             JSONObject tmpObj =abilityObjs.getJSONObject(i);
1303             abilities.add(parseModuleAbility(tmpObj, data, profileJsons));
1304         }
1305         return abilities;
1306     }
1307 
parseModuleAbilityAndAddShortcut(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data, HashMap<String, String> profileJsons)1308     private static void parseModuleAbilityAndAddShortcut(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data,
1309                                                          HashMap<String, String> profileJsons) throws BundleException {
1310         moduleInfo.abilities = parseModuleAbilities(moduleJson, data, profileJsons);
1311         for (ModuleAbilityInfo abilityInfo : moduleInfo.abilities) {
1312             moduleInfo.moduleShortcuts.addAll(parseModuleShortcut(abilityInfo.metadata, data));
1313         }
1314     }
1315 
1316     /**
1317      * parse ability info
1318      *
1319      * @param abilityJson Json hap json Object
1320      * @param data resource index data
1321      * @return the ModuleAbilityInfo result
1322      * @throws BundleException Throws this exception if the json is not standard.
1323      */
parseModuleAbility(JSONObject abilityJson, byte[] data, HashMap<String, String> profileJsons)1324     static ModuleAbilityInfo parseModuleAbility(JSONObject abilityJson, byte[] data,
1325                                                 HashMap<String, String> profileJsons) throws BundleException {
1326         if (abilityJson == null) {
1327             LOG.error("Uncompress::parseModuleAbility exception: abilityJson is null.");
1328             throw new BundleException("Parse ability failed, abilityJson is null.");
1329         }
1330         ModuleAbilityInfo moduleAbilityInfo = new ModuleAbilityInfo();
1331         moduleAbilityInfo.name = getJsonString(abilityJson, NAME);
1332         if (abilityJson.containsKey(SRC_ENTRY)) {
1333             moduleAbilityInfo.srcEntrance = getJsonString(abilityJson, SRC_ENTRY);
1334         } else {
1335             moduleAbilityInfo.srcEntrance = getJsonString(abilityJson, SRC_ENTRANCE);
1336         }
1337 
1338         moduleAbilityInfo.launchType = getJsonString(abilityJson, LAUNCH_TYPE, STANDARD);
1339         moduleAbilityInfo.description = parseResourceByKey(abilityJson, data, DESCRIPTION, DESCRIPTION_ID);
1340         moduleAbilityInfo.setDescriptions(parseResourceMapByKey(abilityJson, data, DESCRIPTION_ID));
1341 
1342         moduleAbilityInfo.icon = parseIconById(abilityJson, data);
1343         moduleAbilityInfo.label = parseResourceByKey(abilityJson, data, LABEL, LABEL_ID);
1344         moduleAbilityInfo.setLabels(parseResourceMapByKey(abilityJson, data, LABEL_ID));
1345         if (abilityJson.containsKey(PERMISSIONS)) {
1346             moduleAbilityInfo.permissions = JSONObject.parseArray(
1347                 getJsonString(abilityJson, PERMISSIONS), String.class);
1348         }
1349         moduleAbilityInfo.metadata = parseModuleMetadataInfos(abilityJson, data, profileJsons);
1350         if (abilityJson.containsKey(EXPORTED)) {
1351             moduleAbilityInfo.visible = getJsonBooleanValue(abilityJson, EXPORTED, false);
1352         } else {
1353             moduleAbilityInfo.visible = getJsonBooleanValue(abilityJson, VISIBLE, false);
1354         }
1355         moduleAbilityInfo.continuable = getJsonBooleanValue(abilityJson, CONTINUABLE, false);
1356 
1357         if (abilityJson.containsKey(SKILLS)) {
1358             moduleAbilityInfo.skills = JSON.parseArray(getJsonString(abilityJson, SKILLS), SkillInfo.class);
1359         }
1360 
1361         if (abilityJson.containsKey(BACKGROUND_MODES)) {
1362             moduleAbilityInfo.backgroundModes =
1363                     JSONArray.parseArray(getJsonString(abilityJson, BACKGROUND_MODES), String.class);
1364         }
1365         return moduleAbilityInfo;
1366     }
1367 
1368     /**
1369      * parse metadata array
1370      *
1371      * @param jsonObject indicates json Object.
1372      * @param data resource index data.
1373      * @return the List<ModuleMetadataInfo> result.
1374      * @throws BundleException Throws this exception if the json is not standard.
1375      */
parseModuleMetadataInfos( JSONObject jsonObject, byte[] data, HashMap<String, String> profileJsons)1376     static List<ModuleMetadataInfo> parseModuleMetadataInfos(
1377             JSONObject jsonObject, byte[] data, HashMap<String, String> profileJsons) throws BundleException {
1378         List<ModuleMetadataInfo> moduleMetadataInfos = new ArrayList<>();
1379         if (!jsonObject.containsKey(META_DATA)) {
1380             return moduleMetadataInfos;
1381         }
1382         JSONArray metadatas = jsonObject.getJSONArray(META_DATA);
1383         for (int i = 0; i < metadatas.size(); ++i) {
1384             JSONObject metadata = metadatas.getJSONObject(i);
1385             moduleMetadataInfos.add(parseModuleMetadata(metadata, data, profileJsons));
1386         }
1387         return moduleMetadataInfos;
1388     }
1389 
1390     /**
1391      * parse metadata info
1392      *
1393      * @param jsonObject Json hap json Object
1394      * @param data resource index data
1395      * @return the ModuleMetadataInfo result
1396      * @throws BundleException Throws this exception if the json is not standard.
1397      */
parseModuleMetadata(JSONObject jsonObject, byte[] data, HashMap<String, String> profileJson)1398     static ModuleMetadataInfo parseModuleMetadata(JSONObject jsonObject, byte[] data,
1399                                                           HashMap<String, String> profileJson) throws BundleException {
1400         if (jsonObject == null) {
1401             LOG.error("JsonUtil::parseModuleMetadata exception: jsonObject is null.");
1402             throw new BundleException("Parse ModuleMetadataInfo failed, jsonObject is null.");
1403         }
1404         ModuleMetadataInfo moduleMetadataInfo = new ModuleMetadataInfo();
1405         moduleMetadataInfo.name = getJsonString(jsonObject, NAME);
1406         moduleMetadataInfo.value = getJsonString(jsonObject, VALUE);
1407 
1408         if (jsonObject.containsKey(RESOURCE)) {
1409             moduleMetadataInfo.resource = getJsonString(jsonObject, RESOURCE);
1410             String fileName = moduleMetadataInfo.resource;
1411             fileName = fileName.replace(PROFILE, "");
1412             fileName = fileName + JSON_SUFFIX;
1413             moduleMetadataInfo.resource = profileJson.get(fileName);
1414         }
1415         return moduleMetadataInfo;
1416     }
1417 
1418     /**
1419      * parse abilityform in stage module.
1420      *
1421      * @param extensionAbilityInfos is extent ability in module object.
1422      * @param data is resource byte in hap.
1423      * @return the List<AbilityFormInfo> result
1424      * @throws BundleException Throws this exception if the json is not standard.
1425      */
parseModuleAbilityforms(List<ExtensionAbilityInfo> extensionAbilityInfos, byte[] data, String serviceProviderAbility)1426     static List<AbilityFormInfo> parseModuleAbilityforms(List<ExtensionAbilityInfo> extensionAbilityInfos,
1427                                                          byte[] data, String serviceProviderAbility)
1428             throws BundleException {
1429         List<AbilityFormInfo> abilityFormInfos = new ArrayList<>();
1430         if (extensionAbilityInfos.isEmpty()) {
1431             return abilityFormInfos;
1432         }
1433         for (ExtensionAbilityInfo extensionAbilityInfo : extensionAbilityInfos) {
1434             List<AbilityFormInfo> formInfos =
1435                     parseModuleFormInfoInMetadata(data, extensionAbilityInfo.metadataInfos);
1436                 if (FORM.equals(extensionAbilityInfo.type)) {
1437                         for (AbilityFormInfo formInfo : formInfos) {
1438                     formInfo.providerAbility = serviceProviderAbility;
1439                 }
1440             }
1441             abilityFormInfos.addAll(formInfos);
1442         }
1443         return abilityFormInfos;
1444     }
1445 
1446     /**
1447      * parse commonevents info
1448      *
1449      * @param extensionAbilityInfos is the list of extensionAbility.
1450      * @return the List<CommonEvent> result
1451      */
parseModuleCommonEvents(List<ExtensionAbilityInfo> extensionAbilityInfos)1452     static List<CommonEvent> parseModuleCommonEvents(List<ExtensionAbilityInfo> extensionAbilityInfos) {
1453         List<CommonEvent> allCommonEvent = new ArrayList<>();
1454         if (extensionAbilityInfos.isEmpty()) {
1455             return allCommonEvent;
1456         }
1457         for (ExtensionAbilityInfo extensionAbilityInfo : extensionAbilityInfos) {
1458             List<CommonEvent> commonEvents =
1459                     parseCommoneventsInMetadata(extensionAbilityInfo.metadataInfos);
1460             allCommonEvent.addAll(commonEvents);
1461         }
1462         return allCommonEvent;
1463     }
1464 
1465     /**
1466      * parse commonevents info
1467      *
1468      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1469      * @return the List<CommonEvent> result
1470      */
parseCommoneventsInMetadata(List<ModuleMetadataInfo> moduleMetadataInfos)1471     static List<CommonEvent> parseCommoneventsInMetadata(List<ModuleMetadataInfo> moduleMetadataInfos) {
1472         List<CommonEvent> commonEvents = new ArrayList<>();
1473         // find common events and parse in metadata
1474         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1475             String jsonStr = moduleMetadataInfo.resource;
1476             JSONObject jsonObj = JSONObject.parseObject(jsonStr);
1477             if (jsonObj != null && jsonObj.containsKey("commonEvents")) {
1478                 commonEvents.addAll(parseModuleCommonEvents(jsonObj));
1479             }
1480         }
1481         return commonEvents;
1482     }
1483 
1484     /**
1485      * parse commonevents info
1486      *
1487      * @param jsonObject is the json  objects of commonevent.
1488      * @return the List<CommonEvent> result
1489      */
parseModuleCommonEvents(JSONObject jsonObject)1490     static List<CommonEvent> parseModuleCommonEvents(JSONObject jsonObject) {
1491         List<CommonEvent> commonEvents = new ArrayList<>();
1492         JSONArray commonEventObjs = jsonObject.getJSONArray("commonEvents");
1493         for (int i = 0; i < commonEventObjs.size(); ++i) {
1494             JSONObject commonEventObj = commonEventObjs.getJSONObject(i);
1495             CommonEvent commonEvent = new CommonEvent();
1496             if (commonEventObj.containsKey("name")) {
1497                 commonEvent.name = getJsonString(commonEventObj, "name");
1498             }
1499             if (commonEventObj.containsKey("permission")) {
1500                 commonEvent.permission = getJsonString(commonEventObj, "permission");
1501             }
1502             if (commonEventObj.containsKey("types")) {
1503                 commonEvent.type = JSON.parseArray(getJsonString(commonEventObj, "types"), String.class);
1504             }
1505             if (commonEventObj.containsKey("events")) {
1506                 commonEvent.events = JSON.parseArray(getJsonString(commonEventObj, "events"), String.class);
1507             }
1508             commonEvents.add(commonEvent);
1509         }
1510         return commonEvents;
1511     }
1512 
1513     /**
1514      * parse stage shortcuts info
1515      *
1516      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1517      * @param data is resource byte in hap
1518      * @return the List<moduleShortcut> result
1519      * @throws BundleException Throws this exception when parse failed.
1520      */
parseModuleShortcut(List<ModuleMetadataInfo> moduleMetadataInfos, byte[] data)1521     static List<ModuleShortcut> parseModuleShortcut(List<ModuleMetadataInfo> moduleMetadataInfos, byte[] data)
1522             throws BundleException {
1523         List<ModuleShortcut> shortcuts = new ArrayList<>();
1524         // find shortcut and parse in metadata
1525         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1526             String jsonStr = moduleMetadataInfo.resource;
1527             if (jsonStr.isEmpty()) {
1528                 continue;
1529             }
1530             JSONObject jsonObj = JSON.parseObject(jsonStr);
1531             if (jsonObj.containsKey("shortcuts")) {
1532                 JSONArray shortcutObjs = jsonObj.getJSONArray("shortcuts");
1533                 for (int j = 0; j < shortcutObjs.size(); ++j) {
1534                     shortcuts.add(parseModuleShortcutObj(shortcutObjs.getJSONObject(j), data));
1535                 }
1536             }
1537         }
1538         return shortcuts;
1539     }
1540 
1541     /**
1542      * parse stage shortcuts json object array
1543      *
1544      * @param shortcutObj is the objects of shortcut
1545      * @param data is resource byte in hap
1546      * @return the List<ModuleShortcuts> result
1547      * @throws BundleException Throws this exception when parse failed.
1548      */
parseModuleShortcutObj(JSONObject shortcutObj, byte[] data)1549     static ModuleShortcut parseModuleShortcutObj(JSONObject shortcutObj, byte[] data) throws BundleException {
1550         if (shortcutObj == null) {
1551             LOG.error("JsonUtil::parseModuleShortcutObj failed");
1552             throw new BundleException("JsonUtil::parseModuleShortcutObj failed");
1553         }
1554         ModuleShortcut moduleShortcut = new ModuleShortcut();
1555         if (shortcutObj.containsKey("shortcutId")) {
1556             moduleShortcut.setShortcutId(shortcutObj.getString("shortcutId"));
1557         }
1558         if (shortcutObj.containsKey("label")) {
1559             moduleShortcut.setLabel(parseResourceByStringID(data, getJsonString(shortcutObj, "label")));
1560         }
1561         moduleShortcut.setLabels(parseResourceMapByKey(shortcutObj, data, LABEL_ID));
1562 
1563         if (shortcutObj.containsKey("icon")) {
1564             String iconPath = parseResourceByStringID(data, getJsonString(shortcutObj, "icon"));
1565             moduleShortcut.setIcon(iconPath.substring(iconPath.indexOf("resources")));
1566         }
1567         if (shortcutObj.containsKey("wants")) {
1568             moduleShortcut.setWants(JSON.parseArray(getJsonString(shortcutObj, "wants"), Want.class));
1569         }
1570         return moduleShortcut;
1571     }
1572 
1573     /**
1574      * parse fa shortcuts json object array
1575      *
1576      * @param moduleJson is the object of module
1577      * @param data is resource byte in hap
1578      * @return the List<ModuleShortcuts> result
1579      * @throws BundleException Throws this exception when parse failed.
1580      */
parseShoruCuts(JSONObject moduleJson, byte[] data)1581     static List<Shortcut> parseShoruCuts(JSONObject moduleJson, byte[] data) throws BundleException {
1582         List<Shortcut> shortcuts = new ArrayList<>();
1583         if (moduleJson.containsKey("shortcuts")) {
1584             JSONArray shortcutObjs = moduleJson.getJSONArray("shortcuts");
1585             for (int i =  0; i < shortcutObjs.size(); ++i) {
1586                 shortcuts.add(parseShortObj(shortcutObjs.getJSONObject(i), data));
1587             }
1588         }
1589         return shortcuts;
1590     }
1591 
1592     /**
1593      * parse fa shortcuts json object array
1594      *
1595      * @param shortcutObj is the object of shortcut
1596      * @param data is resource byte in hap
1597      * @return the List<ModuleShortcuts> result
1598      * @throws BundleException Throws this exception when parse failed.
1599      */
parseShortObj(JSONObject shortcutObj, byte[] data)1600     static Shortcut parseShortObj(JSONObject shortcutObj, byte[] data) throws BundleException {
1601         if (shortcutObj == null) {
1602             LOG.error("JsonUtil::parseModuleShortcutObj failed");
1603             throw new BundleException("JsonUtil::parseModuleShortcutObj failed");
1604         }
1605         Shortcut shortcut = new Shortcut();
1606         if (shortcutObj.containsKey("shortcutId")) {
1607             shortcut.shortcutId = shortcutObj.getString("shortcutId");
1608         }
1609         if (shortcutObj.containsKey("label")) {
1610             shortcut.label = parseResourceByKey(shortcutObj, data, "label", "labelId");
1611         }
1612         shortcut.setLabels(parseResourceMapByKey(shortcutObj, data, LABEL_ID));
1613         if (shortcutObj.containsKey("icon")) {
1614             shortcut.icon = parseIconById(shortcutObj, data);
1615         }
1616         if (shortcutObj.containsKey("intents")) {
1617             shortcut.intents = JSON.parseArray(getJsonString(shortcutObj, "intents"), IntentInfo.class);
1618         }
1619         return shortcut;
1620     }
1621 
1622     /**
1623      * parse form info
1624      *
1625      * @param data is resource byte in hap
1626      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1627      * @return the List<AbilityFormInfo> result
1628      * @throws BundleException Throws this exception if the json is not standard.
1629      */
parseModuleFormInfoInMetadata( byte[] data, List<ModuleMetadataInfo> moduleMetadataInfos)1630     static List<AbilityFormInfo> parseModuleFormInfoInMetadata(
1631             byte[] data, List<ModuleMetadataInfo> moduleMetadataInfos) throws BundleException {
1632         List<AbilityFormInfo> abilityFormInfos = new ArrayList<>();
1633         if (moduleMetadataInfos.isEmpty()) {
1634             return abilityFormInfos;
1635         }
1636         // find form json and parse in metadata
1637         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1638             String jsonStr = moduleMetadataInfo.resource;
1639             JSONObject jsonObj = JSONObject.parseObject(jsonStr);
1640             if (jsonObj != null && jsonObj.containsKey(FORMS)) {
1641                 JSONArray jsonForms = JSONObject.parseArray(getJsonString(jsonObj, FORMS));
1642                 int size = jsonForms.size();
1643                 for (int j = 0; j < size; ++j) {
1644                     JSONObject tmpObj = jsonForms.getJSONObject(j);
1645                     abilityFormInfos.add(parseModuleForm(tmpObj, data));
1646                 }
1647             }
1648         }
1649         return abilityFormInfos;
1650     }
1651 
1652     /**
1653      * parse form object
1654      *
1655      * @param formObj is form json object
1656      * @param data is resource byte in hap
1657      * @throws BundleException Throws this exception if the json is not standard.
1658      */
parseModuleForm(JSONObject formObj, byte[] data)1659     static AbilityFormInfo parseModuleForm(JSONObject formObj, byte[] data) throws BundleException {
1660         if (formObj == null) {
1661             LOG.error("JsonUtil::parseModuleForm exception: formObj is null.");
1662             throw new BundleException("Parse parseModuleForm failed, formObj is null.");
1663         }
1664         AbilityFormInfo moduleFormInfo = new AbilityFormInfo();
1665         moduleFormInfo.name = getJsonString(formObj, NAME);
1666         moduleFormInfo.description = parseFormDescription(formObj, data);
1667         moduleFormInfo.setDescriptions(parseFormDescriptions(formObj, data));
1668         moduleFormInfo.src = getJsonString(formObj, SRC);
1669 
1670         if (formObj.containsKey(WINDOW)) {
1671             moduleFormInfo.windowInfo =
1672                     JSON.parseObject(getJsonString(formObj, WINDOW), AbilityFormInfo.ModuleWindowInfo.class);
1673         }
1674         moduleFormInfo.isDefault = getJsonBooleanValue(formObj, IS_DEFAULT, false);
1675         moduleFormInfo.colorMode = getJsonString(formObj, COLOR_MODE, AUTO);
1676         if (formObj.containsKey(SUPPORT_DIMENSIONS)) {
1677             moduleFormInfo.supportDimensions =
1678                     JSONObject.parseArray(getJsonString(formObj, SUPPORT_DIMENSIONS), String.class);
1679         }
1680         moduleFormInfo.defaultDimension = getJsonString(formObj, DEFAULT_DIMENSION);
1681         moduleFormInfo.updateEnabled = getJsonBooleanValue(formObj, UPDATE_ENABLED, false);
1682         moduleFormInfo.scheduledUpdateTime = getJsonString(formObj, SCHEDULE_UPDATE_TIME);
1683         moduleFormInfo.updateDuration = getJsonIntValue(formObj, UPDATE_DURATION, 1);
1684         moduleFormInfo.formConfigAbility = getJsonString(formObj, FROM_CONFIG_ABILITY);
1685         moduleFormInfo.formVisibleNotify = getJsonBooleanValue(formObj, FORM_VISIBLE_NOTIFY, false);
1686         return moduleFormInfo;
1687     }
1688 
parseFormDescription(JSONObject formObj, byte[] data)1689     private static String parseFormDescription(JSONObject formObj, byte[] data) throws BundleException {
1690         if (formObj.containsKey(DESCRIPTION)) {
1691             String descriptionStr = getJsonString(formObj, DESCRIPTION);
1692             if (descriptionStr.contains(STRING_RESOURCE)) {
1693                 return parseResourceByStringID(data, descriptionStr);
1694             } else {
1695                 return descriptionStr;
1696             }
1697         }
1698         return EMPTY;
1699     }
1700 
parseFormDescriptions(JSONObject formObj, byte[] data)1701     private static HashMap<String, String> parseFormDescriptions(JSONObject formObj, byte[] data) {
1702         HashMap<String, String> descriptions = new HashMap<>();
1703         if (!formObj.containsKey(DESCRIPTION)) {
1704             return descriptions;
1705         }
1706         String descriptionStr = getJsonString(formObj, DESCRIPTION);
1707         if (descriptionStr.contains(STRING_RESOURCE)) {
1708             int len = STRING_RESOURCE.length();
1709             String descriptionId = descriptionStr.substring(len);
1710             try {
1711                 int id = Integer.parseInt(descriptionId);
1712                 descriptions = ResourcesParser.getResourceMapById(id, data);
1713             } catch (NumberFormatException e) {
1714                 LOG.error("parseFormDescriptions failed: invalid descriptionId.");
1715             }
1716             return descriptions;
1717         }
1718         return descriptions;
1719     }
1720 
1721     /**
1722      * parse definepermission objects
1723      *
1724      * @param moduleJson is module json object
1725      * @param data is resource byte in hap
1726      * @throws BundleException Throws this exception if the json is not standard.
1727      */
parseDefinePermissions(JSONObject moduleJson, byte[] data)1728     static List<DefinePermission> parseDefinePermissions(JSONObject moduleJson, byte[] data) throws BundleException {
1729         List<DefinePermission> definePermissions = new ArrayList<>();
1730         if (!moduleJson.containsKey(DEFINE_PERMISSIONS)) {
1731             return definePermissions;
1732         }
1733         JSONArray definePermissionObjs = moduleJson.getJSONArray(DEFINE_PERMISSIONS);
1734         for (int i = 0; i < definePermissionObjs.size(); ++i) {
1735             definePermissions.add(parseDefinePermission(definePermissionObjs.getJSONObject(i), data));
1736         }
1737         return definePermissions;
1738     }
1739 
parseModuleAtomicService(JSONObject moduleJson)1740     static ModuleAtomicService parseModuleAtomicService(JSONObject moduleJson) {
1741         ModuleAtomicService moduleAtomicService = new ModuleAtomicService();
1742         JSONObject atomicServiceObj = null;
1743         if (!moduleJson.containsKey(ATOMIC_SERVICE)) {
1744             return moduleAtomicService;
1745         }
1746         atomicServiceObj = moduleJson.getJSONObject(ATOMIC_SERVICE);
1747         JSONArray preloadObjs = atomicServiceObj.getJSONArray(PRELOADS);
1748         List<PreloadItem> preloadItems = new ArrayList<>();
1749         for (int i = 0; i < preloadObjs.size(); ++i) {
1750             PreloadItem preloadItem = new PreloadItem();
1751             JSONObject itemObj = preloadObjs.getJSONObject(i);
1752             if (itemObj.containsKey(MODULE_NAME)) {
1753                 preloadItem.setModuleName(getJsonString(itemObj, MODULE_NAME));
1754             }
1755             preloadItems.add(preloadItem);
1756         }
1757         moduleAtomicService.setPreloadItems(preloadItems);
1758 
1759         return moduleAtomicService;
1760     }
1761 
1762     /**
1763      * parse define permission objects
1764      *
1765      * @param definePermissionObj is def permission json object
1766      * @param data is resource byte in hap
1767      * @throws BundleException Throws this exception if the json is not standard.
1768      */
parseDefinePermission(JSONObject definePermissionObj, byte[] data)1769     static DefinePermission parseDefinePermission(JSONObject definePermissionObj, byte[] data) throws BundleException {
1770         DefinePermission definePermission = new DefinePermission();
1771         definePermission.name = getJsonString(definePermissionObj, "name", definePermission.name);
1772         definePermission.grantMode = getJsonString(definePermissionObj, "grantMode", definePermission.grantMode);
1773         definePermission.availableLevel =
1774                 getJsonString(definePermissionObj, "availableLevel", definePermission.availableLevel);
1775         if (definePermissionObj.containsKey("provisionEnable")) {
1776             definePermission.provisionEnable = definePermissionObj.getBoolean("provisionEnable");
1777         }
1778         if (definePermissionObj.containsKey("distributedSceneEnable")) {
1779             definePermission.distributedSceneEnable = definePermissionObj.getBoolean("distributedSceneEnable");
1780         }
1781         definePermission.label =
1782                 parseResourceByKey(definePermissionObj, data, "label", "labelId");
1783         definePermission.setLabels(parseResourceMapByKey(definePermissionObj, data, LABEL_ID));
1784 
1785         definePermission.description =
1786                 parseResourceByKey(definePermissionObj, data, "description", "descriptionId");
1787         definePermission.setDescriptions(parseResourceMapByKey(definePermissionObj, data, DESCRIPTION_ID));
1788 
1789         return definePermission;
1790     }
1791 
1792     /**
1793      * parse defpermission objects
1794      *
1795      * @param moduleJson is module json object
1796      * @param data is resource byte in hap
1797      * @throws BundleException Throws this exception if the json is not standard.
1798      */
parseDefPermissions(JSONObject moduleJson, byte[] data)1799     static List<DefPermission> parseDefPermissions(JSONObject moduleJson, byte[] data) throws BundleException {
1800         List<DefPermission> defPermissions = new ArrayList<>();
1801         if (moduleJson.containsKey("defPermissions")) {
1802             JSONArray defPermissionObjs = moduleJson.getJSONArray("defPermissions");
1803             for (int i = 0; i < defPermissionObjs.size(); ++i) {
1804                 defPermissions.add(parseDefPermission(defPermissionObjs.getJSONObject(i), data));
1805             }
1806         }
1807         return defPermissions;
1808     }
1809 
1810     /**
1811      * parse defpermission objects
1812      *
1813      * @param defPermissionObj is def permission json object
1814      * @param data is resource byte in hap
1815      * @throws BundleException Throws this exception if the json is not standard.
1816      */
parseDefPermission(JSONObject defPermissionObj, byte[] data)1817     static DefPermission parseDefPermission(JSONObject defPermissionObj, byte[] data) throws BundleException {
1818         DefPermission defPermission = new DefPermission();
1819         if (defPermissionObj.containsKey("name")) {
1820             defPermission.name = getJsonString(defPermissionObj, "name");
1821         }
1822         if (defPermissionObj.containsKey("grantMode")) {
1823             defPermission.grantMode = getJsonString(defPermissionObj, "grantMode");
1824         }
1825         if (defPermissionObj.containsKey("availableScope")) {
1826             defPermission.availableScope =
1827                     JSONObject.parseArray(getJsonString(defPermissionObj, "availableScope"), String.class);
1828         }
1829         defPermission.label = parseResourceByKey(defPermissionObj, data, "label", "labelId");
1830         defPermission.setLabels(parseResourceMapByKey(defPermissionObj, data, LABEL_ID));
1831 
1832         defPermission.description = parseResourceByKey(defPermissionObj, data, "description", "descriptionId");
1833         defPermission.setDescriptions(parseResourceMapByKey(defPermissionObj, data, DESCRIPTION_ID));
1834 
1835         if (defPermissionObj.containsKey("group")) {
1836             defPermission.group = getJsonString(defPermissionObj, "group");
1837         }
1838         return defPermission;
1839     }
1840 
1841     /**
1842      * get resource from JSONObject by the id.
1843      *
1844      * @param data is resource byte in hap.
1845      * @param id is the resource id.
1846      * @return the result
1847      * @throws BundleException Throws this exception when parse failed.
1848      */
parseResourceByStringID(byte[] data, String id)1849     static String parseResourceByStringID(byte[] data, String id) throws BundleException {
1850         String res = "";
1851         int index = 0;
1852         while(id.charAt(index) < '0' || id.charAt(index) > '9') {
1853             index++;
1854         }
1855         try {
1856             int finalId = Integer.parseInt(id.substring(index));
1857             res = ResourcesParser.getResourceStringById(finalId, data);
1858         } catch (NumberFormatException e) {
1859             LOG.error("parseResourceByStringID failed: input invalid of " + id + ".");
1860         }
1861         return res;
1862     }
1863 
1864     /**
1865      * get resource from JSONObject by the key.
1866      *
1867      * @param jsonObject uncompress json object.
1868      * @param data is resource byte in hap.
1869      * @param key is the index of json object.
1870      * @param keyId is the index id of resource.
1871      * @return the result
1872      */
parseResourceByKey(JSONObject jsonObject, byte[] data, String key, String keyId)1873     static String parseResourceByKey(JSONObject jsonObject, byte[] data, String key, String keyId) {
1874         String res = "";
1875         if (jsonObject.containsKey(keyId)) {
1876             int resId = jsonObject.getIntValue(keyId);
1877             res = ResourcesParser.getResourceStringById(resId, data);
1878         }
1879         if (res != null && !res.isEmpty()) {
1880             return res;
1881         } else if (jsonObject.containsKey(key)) {
1882            return getJsonString(jsonObject, key);
1883         } else {
1884             return "";
1885         }
1886     }
1887 
parseResourceMapByKey(JSONObject jsonObject, byte[] data, String keyId)1888     static HashMap<String, String> parseResourceMapByKey(JSONObject jsonObject, byte[] data, String keyId) {
1889         HashMap<String, String> map = new HashMap<>();
1890         if (jsonObject.containsKey(keyId)) {
1891             int resId = jsonObject.getIntValue(keyId);
1892             map = ResourcesParser.getResourceMapById(resId, data);
1893         }
1894         return map;
1895     }
1896 
1897     /**
1898      * get icon path from resource by the key.
1899      *
1900      * @param jsonObject uncompress json object.
1901      * @param data is resource byte in hap
1902      * @return the result
1903      * @throws BundleException Throws this exception when parse failed.
1904      */
parseIconById(JSONObject jsonObject, byte[] data)1905     static String parseIconById(JSONObject jsonObject, byte[] data) throws BundleException {
1906         String iconPath = "";
1907         if (jsonObject.containsKey("iconId")) {
1908             int resId = jsonObject.getIntValue("iconId");
1909             iconPath = ResourcesParser.getBaseResourceById(resId, data);
1910             iconPath = iconPath.substring(iconPath.indexOf("resources"));
1911         }
1912         if (!iconPath.isEmpty()) {
1913             return iconPath;
1914         } else if (jsonObject.containsKey("icon")) {
1915            return getJsonString(jsonObject, "icon");
1916         } else {
1917             return "";
1918         }
1919     }
1920 
1921     /**
1922      * parse stage module reqPermissions.
1923      *
1924      * @param moduleJson module json object.
1925      * @param data is resource byte in hap.
1926      * @return the result
1927      */
parseReqPermission(JSONObject moduleJson, byte[] data)1928     static List<ReqPermission> parseReqPermission(JSONObject moduleJson, byte[] data) throws BundleException {
1929         List<ReqPermission> reqPermissions = new ArrayList<>();
1930         if (!moduleJson.containsKey(REQUEST_PERMISSIONS)) {
1931             return reqPermissions;
1932         }
1933         JSONArray requestPermissionObjs = moduleJson.getJSONArray(REQUEST_PERMISSIONS);
1934         for (int i = 0; i < requestPermissionObjs.size(); ++i) {
1935             ReqPermission reqPermission = new ReqPermission();
1936             JSONObject requestPermission = requestPermissionObjs.getJSONObject(i);
1937             reqPermission.name = getJsonString(requestPermission, NAME);
1938             reqPermission.reason = parseResourceByKey(requestPermission, data, REASON, REASON_ID);
1939             if (requestPermission.containsKey(REASON_ID)) {
1940                 reqPermission.setReasons(parseResourceMapByKey(requestPermission, data, REASON_ID));
1941             }
1942             if (requestPermission.containsKey(USED_SCENE)) {
1943                 reqPermission.usedScene = parseModuleUsedScene(requestPermission.getJSONObject(USED_SCENE));
1944             }
1945             reqPermissions.add(reqPermission);
1946         }
1947         return reqPermissions;
1948     }
1949 
parseModuleUsedScene(JSONObject usedSceneObj)1950     private static UsedScene parseModuleUsedScene(JSONObject usedSceneObj) {
1951         UsedScene usedScene = new UsedScene();
1952         if (usedSceneObj.containsKey(ABILITIES)) {
1953             usedScene.ability = JSON.parseArray(getJsonString(usedSceneObj, ABILITIES), String.class);
1954         }
1955         if (usedSceneObj.containsKey(WHEN)) {
1956             usedScene.when = getJsonString(usedSceneObj, WHEN);
1957         }
1958         return usedScene;
1959     }
1960 
1961     /**
1962      * get the String from JSONObject by the key.
1963      *
1964      * @param jsonObject uncompress json object
1965      * @param key value key
1966      * @return the result
1967      */
getJsonString(JSONObject jsonObject, String key)1968     private static String getJsonString(JSONObject jsonObject, String key) {
1969         String value = "";
1970         if (jsonObject != null && jsonObject.containsKey(key)) {
1971             value = jsonObject.get(key).toString();
1972         }
1973         return value;
1974     }
1975 
1976     /**
1977      * get the String from JSONObject by the key.
1978      *
1979      * @param jsonObject uncompress json object
1980      * @param key value key
1981      * @param defaultValue the default value
1982      * @return the result
1983      */
getJsonString(JSONObject jsonObject, String key, String defaultValue)1984     private static String getJsonString(JSONObject jsonObject, String key, String defaultValue) {
1985         String value = defaultValue;
1986         if (jsonObject != null && jsonObject.containsKey(key)) {
1987             value = jsonObject.get(key).toString();
1988         }
1989         return value;
1990     }
1991 
getJsonIntValue(JSONObject jsonObject, String key, int defaultValue)1992     private static int getJsonIntValue(JSONObject jsonObject, String key, int defaultValue) {
1993         int value = defaultValue;
1994         if (jsonObject != null && jsonObject.containsKey(key)) {
1995             value = jsonObject.getIntValue(key);
1996         }
1997         return value;
1998     }
1999 
getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue)2000     private static boolean getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue) {
2001         boolean value = defaultValue;
2002         if (jsonObject != null && jsonObject.containsKey(key)) {
2003             value = jsonObject.getBooleanValue(key);
2004         }
2005         return value;
2006     }
2007 
setFAProviderAbility(JSONObject moduleJson, HapInfo hapInfo, List<AbilityInfo> abilityInfos)2008     private static void setFAProviderAbility(JSONObject moduleJson, HapInfo hapInfo,
2009                                              List<AbilityInfo> abilityInfos) throws BundleException {
2010         if (abilityInfos.isEmpty()) {
2011             throw new BundleException("JsonUtil::setProviderAbility abilityInfo is empty.");
2012         }
2013         String serviceProviderAbility = parseFAServiceProviderAbility(moduleJson, abilityInfos);
2014         for (AbilityInfo abilityInfo : abilityInfos) {
2015             if (!abilityInfo.formInfos.isEmpty()) {
2016                 if (SERVICE.equals(abilityInfo.type)) {
2017                     setProviderAbilityForForm(abilityInfo.formInfos, serviceProviderAbility);
2018                 }
2019                 if (PAGE.equals(abilityInfo.type)) {
2020                     setProviderAbilityForForm(abilityInfo.formInfos, abilityInfo.name);
2021                 }
2022                 hapInfo.formInfos.addAll(abilityInfo.formInfos);
2023             }
2024         }
2025     }
2026 
setProviderAbilityForForm(List<AbilityFormInfo> abilityFormInfos, String providerAbility)2027     private static void setProviderAbilityForForm(List<AbilityFormInfo> abilityFormInfos, String providerAbility) {
2028         for (AbilityFormInfo abilityFormInfo : abilityFormInfos) {
2029             abilityFormInfo.providerAbility = providerAbility;
2030         }
2031     }
2032 
parseStageServiceProvider(JSONObject moduleJson, List<ModuleAbilityInfo> moduleAbilityInfos)2033     private static String parseStageServiceProvider(JSONObject moduleJson,
2034                                                     List<ModuleAbilityInfo> moduleAbilityInfos) throws BundleException {
2035         if (moduleJson.containsKey(MAIN_ELEMENT)) {
2036             return getJsonString(moduleJson, MAIN_ELEMENT);
2037         }
2038         if (!moduleAbilityInfos.isEmpty()) {
2039             for (ModuleAbilityInfo moduleAbilityInfo : moduleAbilityInfos) {
2040                 if (isSystemHomeAbility(moduleAbilityInfo.skills)) {
2041                     return moduleAbilityInfo.name;
2042                 }
2043             }
2044             return moduleAbilityInfos.get(0).name;
2045         }
2046         return "";
2047     }
2048 
parseFAServiceProviderAbility(JSONObject moduleJson, List<AbilityInfo> abilityInfos)2049     private static String parseFAServiceProviderAbility(JSONObject moduleJson,
2050                                                         List<AbilityInfo> abilityInfos) throws BundleException {
2051         if (abilityInfos.isEmpty()) {
2052             throw new BundleException("JsonUtil::parseServiceProviderAbility abilityInfos is empty.");
2053         }
2054 
2055         if (moduleJson.containsKey(MAIN_ABILITY)) {
2056             return getJsonString(moduleJson, MAIN_ABILITY);
2057         }
2058         for (AbilityInfo abilityInfo : abilityInfos) {
2059             if (isSystemHomeAbility(abilityInfo.skills)) {
2060                 return abilityInfo.name;
2061             }
2062         }
2063         for (AbilityInfo abilityInfo : abilityInfos) {
2064             if (abilityInfo.type.equals(PAGE)) {
2065                 return abilityInfo.name;
2066             }
2067         }
2068         return "";
2069     }
2070 
isSystemHomeAbility(List<SkillInfo> skills)2071     private static boolean isSystemHomeAbility(List<SkillInfo> skills) {
2072         for (SkillInfo skillInfo : skills) {
2073             if (skillInfo.entities.contains(ENTITY_SYSTEM_HOME) && skillInfo.actions.contains(ACTION_SYSTEM_HOME)) {
2074                 return true;
2075             }
2076         }
2077         return false;
2078     }
2079 
2080     /**
2081      * parse patch.json form json string.
2082      *
2083      * @param jsonString is the file path of hqf file
2084      * @return HQFVerifyInfo
2085      */
parsePatch(String jsonString)2086     static HQFInfo parsePatch(String jsonString) throws BundleException {
2087         HQFInfo hqfVerifyInfo = new HQFInfo();
2088         JSONObject jsonObject = JSON.parseObject(jsonString);
2089         JSONObject appObj = jsonObject.getJSONObject(APP);
2090         if (appObj == null) {
2091             LOG.error("parsePatch failed, input patch.json is invalid, patch.json has no app.");
2092             throw new BundleException("parsePatch failed, input patch.json is invalid.");
2093         }
2094 
2095         if (appObj.containsKey(BUNDLENAME)) {
2096             hqfVerifyInfo.setBundleName(appObj.getString(BUNDLENAME));
2097         }
2098         if (appObj.containsKey(VERSIONCODE)) {
2099             hqfVerifyInfo.setVersionCode(appObj.getIntValue(VERSIONCODE));
2100         }
2101         if (appObj.containsKey(VERSIONNAME)) {
2102             hqfVerifyInfo.setVersionName(appObj.getString(VERSIONNAME));
2103         }
2104         if (appObj.containsKey(PATCH_VERSION_CODE)) {
2105             hqfVerifyInfo.setPatchVersionCode(appObj.getIntValue(PATCH_VERSION_CODE));
2106         }
2107         if (appObj.containsKey(PATCH_VERSION_NAME)) {
2108             hqfVerifyInfo.setPatchVersionName(appObj.getString(PATCH_VERSION_NAME));
2109         }
2110         JSONObject moduleObj = jsonObject.getJSONObject(MODULE);
2111         if (moduleObj == null) {
2112             LOG.error("parse failed, input patch.json is invalid, patch.json has no module.");
2113             throw new BundleException("parse failed, input patch.json is invalid, patch.json has no module.");
2114         }
2115         if (moduleObj.containsKey(NAME)) {
2116             hqfVerifyInfo.setModuleName(moduleObj.getString(NAME));
2117         }
2118         if (moduleObj.containsKey(TYPE)) {
2119             hqfVerifyInfo.setType(moduleObj.getString(TYPE));
2120         }
2121         if (moduleObj.containsKey(DEVICE_TYPES)) {
2122             hqfVerifyInfo.setDeviceTypes(JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class));
2123         }
2124         if (moduleObj.containsKey(ORIGINAL_MODULE_HASH)) {
2125             hqfVerifyInfo.setOriginalModuleHash(moduleObj.getString(ORIGINAL_MODULE_HASH));
2126         }
2127         return hqfVerifyInfo;
2128     }
2129 }
2130