• 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: " + msg.getMessage());
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             if (object.containsKey(VERSION_CODE)) {
1125                 item.setVersionCode(object.getIntValue(VERSION_CODE));
1126             }
1127             dependencyItemList.add(item);
1128         }
1129         return dependencyItemList;
1130     }
1131 
parseInstallationFree(JSONObject moduleJson, ModuleInfo moduleInfo)1132     private static void parseInstallationFree(JSONObject moduleJson, ModuleInfo moduleInfo) {
1133         if (moduleJson.containsKey(INSTALLATION_FREE)) {
1134             boolean isFreeInstall = moduleJson.getBoolean(INSTALLATION_FREE);
1135             if (isFreeInstall) {
1136                 moduleInfo.installationFree = 1;
1137             } else {
1138                 moduleInfo.installationFree = 0;
1139             }
1140         } else {
1141             moduleInfo.installationFree = 2;
1142         }
1143     }
1144 
1145     /**
1146      * parse module pages
1147      *
1148      * @param moduleJson is json object of modulejson
1149      * @param profileJsons is the profile map
1150      * @return the pages result
1151      */
parseModulePages( JSONObject moduleJson, HashMap<String, String> profileJsons)1152     static List<String> parseModulePages(
1153             JSONObject moduleJson, HashMap<String, String> profileJsons) throws BundleException {
1154         List<String> pages = new ArrayList<>();
1155         String pageFile = getJsonString(moduleJson, PAGES);
1156         if (pageFile.isEmpty()) {
1157             return pages;
1158         }
1159         pageFile = pageFile.replace(PROFILE, "");
1160         pageFile += JSON_SUFFIX;
1161         String fileContent = profileJsons.get(pageFile);
1162         if (fileContent != null) {
1163             JSONObject pageObj = JSONObject.parseObject(fileContent);
1164             if (pageObj != null) {
1165                 pages = JSONObject.parseArray(getJsonString(pageObj, SRC), String.class);
1166             }
1167         }
1168         return pages;
1169     }
1170 
1171     /**
1172      * parse module hap info
1173      *
1174      * @param moduleMetadataInfos metedata in moduleInfo
1175      * @return the parse result
1176      */
parseModuleDistrofilterFromMetadata(List<ModuleMetadataInfo> moduleMetadataInfos)1177     static DistroFilter parseModuleDistrofilterFromMetadata(List<ModuleMetadataInfo> moduleMetadataInfos) {
1178         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1179             String resource = moduleMetadataInfo.resource;
1180             if (resource.isEmpty()) {
1181                 continue;
1182             }
1183             JSONObject distroFilter = JSONObject.parseObject(resource);
1184             if (distroFilter.containsKey(DISTRIBUTION_FILTER)) {
1185                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRIBUTION_FILTER), DistroFilter.class);
1186             }
1187             if (distroFilter.containsKey(DISTRO_FILTER)) {
1188                 return JSONObject.parseObject(getJsonString(distroFilter, DISTRO_FILTER), DistroFilter.class);
1189             }
1190         }
1191         return null;
1192     }
1193 
1194     /**
1195      * parse module hap info
1196      *
1197      * @param moduleJson is the json object of module object.
1198      * @param data is the resource of hap
1199      * @param profileJsons is the map of profile file name and file content
1200      * @return the parsed extensionAbilityInfos
1201      * @throws BundleException Throws this exception if the json is not standard.
1202      */
parseModuleExtensionAbilities( JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons)1203     static List<ExtensionAbilityInfo> parseModuleExtensionAbilities(
1204             JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons) throws BundleException {
1205         List<ExtensionAbilityInfo> extensionAbilityInfos = new ArrayList<>();
1206         JSONArray extensionAbilities = moduleJson.getJSONArray(EXTENSION_ABILITIES);
1207         int size = extensionAbilities.size();
1208         for (int i = 0; i < size; ++i) {
1209             JSONObject tmpObj = extensionAbilities.getJSONObject(i);
1210             extensionAbilityInfos.add(parseModuleExtensionAbility(tmpObj, data, profileJsons));
1211         }
1212         return extensionAbilityInfos;
1213     }
1214 
parseStageExtensionAbility(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data, HashMap<String, String> profileJsons)1215     private static void parseStageExtensionAbility(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data,
1216                                                    HashMap<String, String> profileJsons) throws BundleException {
1217         if (!moduleJson.containsKey(EXTENSION_ABILITIES)) {
1218             return;
1219         }
1220         // parse service providerAbility
1221         String serviceProviderAbility = parseStageServiceProvider(moduleJson, moduleInfo.abilities);
1222         moduleInfo.extensionAbilityInfos = parseModuleExtensionAbilities(moduleJson, data, profileJsons);
1223         // parse abilityform
1224         moduleInfo.abilityFormInfos = parseModuleAbilityforms(moduleInfo.extensionAbilityInfos,
1225                 data, serviceProviderAbility);
1226         // parse commonEvent
1227         moduleInfo.commonEvents = parseModuleCommonEvents(moduleInfo.extensionAbilityInfos);
1228     }
1229 
1230     /**
1231      * parse module hap info
1232      *
1233      * @param extensionAbilityJson is the json object of extension ability
1234      * @param data is the resource of hap
1235      * @param profileJsons is the map of profile file name and file content
1236      * @return the parsed extensionAbilityInfo
1237      * @throws BundleException Throws this exception if the json is not standard.
1238      */
parseModuleExtensionAbility(JSONObject extensionAbilityJson, byte[] data, HashMap<String, String> profileJsons)1239     static ExtensionAbilityInfo parseModuleExtensionAbility(JSONObject extensionAbilityJson, byte[] data,
1240                                                             HashMap<String, String> profileJsons) throws BundleException {
1241         if (extensionAbilityJson == null) {
1242             LOG.error("JsonUtil::parseModuleExtensionAbility exception: extensionAbilityJson is null.");
1243             throw new BundleException("Parse ability failed, abilityJson is null.");
1244         }
1245         ExtensionAbilityInfo moduleExtensionAbilityInfo = new ExtensionAbilityInfo();
1246         moduleExtensionAbilityInfo.name = getJsonString(extensionAbilityJson, NAME);
1247         if (extensionAbilityJson.containsKey(SRC_ENTRY)) {
1248             moduleExtensionAbilityInfo.srcEntrance = getJsonString(extensionAbilityJson, SRC_ENTRY);
1249         } else {
1250             moduleExtensionAbilityInfo.srcEntrance = getJsonString(extensionAbilityJson, SRC_ENTRANCE);
1251         }
1252         moduleExtensionAbilityInfo.icon = parseIconById(extensionAbilityJson, data);
1253         moduleExtensionAbilityInfo.label =
1254                 parseResourceByKey(extensionAbilityJson, data, LABEL, LABEL_ID);
1255         moduleExtensionAbilityInfo.setLabels(parseResourceMapByKey(extensionAbilityJson, data, LABEL_ID));
1256         moduleExtensionAbilityInfo.description =
1257                 parseResourceByKey(extensionAbilityJson, data, DESCRIPTION, DESCRIPTION_ID);
1258         moduleExtensionAbilityInfo.setDescriptions(parseResourceMapByKey(extensionAbilityJson, data, DESCRIPTION_ID));
1259         moduleExtensionAbilityInfo.type = getJsonString(extensionAbilityJson, TYPE);
1260 
1261         if (extensionAbilityJson.containsKey(PERMISSIONS)) {
1262             moduleExtensionAbilityInfo.permissions =
1263                     JSONObject.parseArray(getJsonString(extensionAbilityJson, PERMISSIONS), String.class);
1264         }
1265         moduleExtensionAbilityInfo.uri = getJsonString(extensionAbilityJson, URI);
1266         moduleExtensionAbilityInfo.readPermission = getJsonString(extensionAbilityJson, READ_PERMISSION);
1267         moduleExtensionAbilityInfo.writePermission = getJsonString(extensionAbilityJson, WRITE_PERMISSION);
1268         if (extensionAbilityJson.containsKey(SKILLS)) {
1269             moduleExtensionAbilityInfo.skills =
1270                     JSONObject.parseArray(getJsonString(extensionAbilityJson, SKILLS), SkillInfo.class);
1271         }
1272 
1273         if (extensionAbilityJson.containsKey(META_DATA)) {
1274             moduleExtensionAbilityInfo.metadataInfos =
1275                     parseModuleMetadataInfos(extensionAbilityJson, data, profileJsons);
1276             // convert to metadata
1277             ModuleAdaption adaption = new ModuleAdaption();
1278             moduleExtensionAbilityInfo.metadata = adaption.convertToMetadata(moduleExtensionAbilityInfo.metadataInfos);
1279         }
1280         if (extensionAbilityJson.containsKey(EXPORTED)) {
1281             moduleExtensionAbilityInfo.visible = getJsonBooleanValue(extensionAbilityJson, EXPORTED, false);
1282         } else {
1283             moduleExtensionAbilityInfo.visible = getJsonBooleanValue(extensionAbilityJson, VISIBLE, false);
1284         }
1285         return moduleExtensionAbilityInfo;
1286     }
1287 
1288     /**
1289      * parse abilities info
1290      *
1291      * @param moduleJson Json hap json Object
1292      * @param data resource index data
1293      * @return the List<ModuleAbilityInfo> result
1294      * @throws BundleException Throws this exception if the json is not standard.
1295      */
parseModuleAbilities(JSONObject moduleJson, byte[] data, HashMap<String, String> profileJsons)1296     static List<ModuleAbilityInfo> parseModuleAbilities(JSONObject moduleJson, byte[] data,
1297                                                         HashMap<String, String> profileJsons) throws BundleException {
1298         List<ModuleAbilityInfo> abilities = new ArrayList<>();
1299         if (!moduleJson.containsKey(ABILITIES)) {
1300             return abilities;
1301         }
1302         JSONArray abilityObjs = moduleJson.getJSONArray(ABILITIES);
1303         int size = abilityObjs.size();
1304         for (int i = 0; i < size; ++i) {
1305             JSONObject tmpObj =abilityObjs.getJSONObject(i);
1306             abilities.add(parseModuleAbility(tmpObj, data, profileJsons));
1307         }
1308         return abilities;
1309     }
1310 
parseModuleAbilityAndAddShortcut(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data, HashMap<String, String> profileJsons)1311     private static void parseModuleAbilityAndAddShortcut(JSONObject moduleJson, ModuleInfo moduleInfo, byte[] data,
1312                                                          HashMap<String, String> profileJsons) throws BundleException {
1313         moduleInfo.abilities = parseModuleAbilities(moduleJson, data, profileJsons);
1314         for (ModuleAbilityInfo abilityInfo : moduleInfo.abilities) {
1315             moduleInfo.moduleShortcuts.addAll(parseModuleShortcut(abilityInfo.metadata, data));
1316         }
1317     }
1318 
1319     /**
1320      * parse ability info
1321      *
1322      * @param abilityJson Json hap json Object
1323      * @param data resource index data
1324      * @return the ModuleAbilityInfo result
1325      * @throws BundleException Throws this exception if the json is not standard.
1326      */
parseModuleAbility(JSONObject abilityJson, byte[] data, HashMap<String, String> profileJsons)1327     static ModuleAbilityInfo parseModuleAbility(JSONObject abilityJson, byte[] data,
1328                                                 HashMap<String, String> profileJsons) throws BundleException {
1329         if (abilityJson == null) {
1330             LOG.error("Uncompress::parseModuleAbility exception: abilityJson is null.");
1331             throw new BundleException("Parse ability failed, abilityJson is null.");
1332         }
1333         ModuleAbilityInfo moduleAbilityInfo = new ModuleAbilityInfo();
1334         moduleAbilityInfo.name = getJsonString(abilityJson, NAME);
1335         if (abilityJson.containsKey(SRC_ENTRY)) {
1336             moduleAbilityInfo.srcEntrance = getJsonString(abilityJson, SRC_ENTRY);
1337         } else {
1338             moduleAbilityInfo.srcEntrance = getJsonString(abilityJson, SRC_ENTRANCE);
1339         }
1340 
1341         moduleAbilityInfo.launchType = getJsonString(abilityJson, LAUNCH_TYPE, STANDARD);
1342         moduleAbilityInfo.description = parseResourceByKey(abilityJson, data, DESCRIPTION, DESCRIPTION_ID);
1343         moduleAbilityInfo.setDescriptions(parseResourceMapByKey(abilityJson, data, DESCRIPTION_ID));
1344 
1345         moduleAbilityInfo.icon = parseIconById(abilityJson, data);
1346         moduleAbilityInfo.label = parseResourceByKey(abilityJson, data, LABEL, LABEL_ID);
1347         moduleAbilityInfo.setLabels(parseResourceMapByKey(abilityJson, data, LABEL_ID));
1348         if (abilityJson.containsKey(PERMISSIONS)) {
1349             moduleAbilityInfo.permissions = JSONObject.parseArray(
1350                     getJsonString(abilityJson, PERMISSIONS), String.class);
1351         }
1352         moduleAbilityInfo.metadata = parseModuleMetadataInfos(abilityJson, data, profileJsons);
1353         if (abilityJson.containsKey(EXPORTED)) {
1354             moduleAbilityInfo.visible = getJsonBooleanValue(abilityJson, EXPORTED, false);
1355         } else {
1356             moduleAbilityInfo.visible = getJsonBooleanValue(abilityJson, VISIBLE, false);
1357         }
1358         moduleAbilityInfo.continuable = getJsonBooleanValue(abilityJson, CONTINUABLE, false);
1359 
1360         if (abilityJson.containsKey(SKILLS)) {
1361             moduleAbilityInfo.skills = JSON.parseArray(getJsonString(abilityJson, SKILLS), SkillInfo.class);
1362         }
1363 
1364         if (abilityJson.containsKey(BACKGROUND_MODES)) {
1365             moduleAbilityInfo.backgroundModes =
1366                     JSONArray.parseArray(getJsonString(abilityJson, BACKGROUND_MODES), String.class);
1367         }
1368         return moduleAbilityInfo;
1369     }
1370 
1371     /**
1372      * parse metadata array
1373      *
1374      * @param jsonObject indicates json Object.
1375      * @param data resource index data.
1376      * @return the List<ModuleMetadataInfo> result.
1377      * @throws BundleException Throws this exception if the json is not standard.
1378      */
parseModuleMetadataInfos( JSONObject jsonObject, byte[] data, HashMap<String, String> profileJsons)1379     static List<ModuleMetadataInfo> parseModuleMetadataInfos(
1380             JSONObject jsonObject, byte[] data, HashMap<String, String> profileJsons) throws BundleException {
1381         List<ModuleMetadataInfo> moduleMetadataInfos = new ArrayList<>();
1382         if (!jsonObject.containsKey(META_DATA)) {
1383             return moduleMetadataInfos;
1384         }
1385         try {
1386             JSONArray metadatas = jsonObject.getJSONArray(META_DATA);
1387             for (int i = 0; i < metadatas.size(); ++i) {
1388                 JSONObject metadata = metadatas.getJSONObject(i);
1389                 moduleMetadataInfos.add(parseModuleMetadata(metadata, data, profileJsons));
1390             }
1391         } catch (JSONException | NullPointerException ex) {
1392             LOG.warning("JsonUtil::parseModuleMetadataInfos err: " + ex.getMessage());
1393         }
1394         return moduleMetadataInfos;
1395     }
1396 
1397     /**
1398      * parse metadata info
1399      *
1400      * @param jsonObject Json hap json Object
1401      * @param data resource index data
1402      * @return the ModuleMetadataInfo result
1403      * @throws BundleException Throws this exception if the json is not standard.
1404      */
parseModuleMetadata(JSONObject jsonObject, byte[] data, HashMap<String, String> profileJson)1405     static ModuleMetadataInfo parseModuleMetadata(JSONObject jsonObject, byte[] data,
1406                                                   HashMap<String, String> profileJson) throws BundleException {
1407         if (jsonObject == null) {
1408             LOG.error("JsonUtil::parseModuleMetadata exception: jsonObject is null.");
1409             throw new BundleException("Parse ModuleMetadataInfo failed, jsonObject is null.");
1410         }
1411         ModuleMetadataInfo moduleMetadataInfo = new ModuleMetadataInfo();
1412         moduleMetadataInfo.name = getJsonString(jsonObject, NAME);
1413         moduleMetadataInfo.value = getJsonString(jsonObject, VALUE);
1414 
1415         if (jsonObject.containsKey(RESOURCE)) {
1416             moduleMetadataInfo.resource = getJsonString(jsonObject, RESOURCE);
1417             String fileName = moduleMetadataInfo.resource;
1418             fileName = fileName.replace(PROFILE, "");
1419             fileName = fileName + JSON_SUFFIX;
1420             String resourceValue = profileJson.get(fileName);
1421             if (resourceValue == null) {
1422                 LOG.warning("JsonUtil::parseModuleMetadata : metadata.resource value is null");
1423                 moduleMetadataInfo.resource = "";
1424             } else {
1425                 moduleMetadataInfo.resource = profileJson.get(fileName);
1426             }
1427         }
1428         return moduleMetadataInfo;
1429     }
1430 
1431     /**
1432      * parse abilityform in stage module.
1433      *
1434      * @param extensionAbilityInfos is extent ability in module object.
1435      * @param data is resource byte in hap.
1436      * @return the List<AbilityFormInfo> result
1437      * @throws BundleException Throws this exception if the json is not standard.
1438      */
parseModuleAbilityforms(List<ExtensionAbilityInfo> extensionAbilityInfos, byte[] data, String serviceProviderAbility)1439     static List<AbilityFormInfo> parseModuleAbilityforms(List<ExtensionAbilityInfo> extensionAbilityInfos,
1440                                                          byte[] data, String serviceProviderAbility)
1441             throws BundleException {
1442         List<AbilityFormInfo> abilityFormInfos = new ArrayList<>();
1443         if (extensionAbilityInfos.isEmpty()) {
1444             return abilityFormInfos;
1445         }
1446         for (ExtensionAbilityInfo extensionAbilityInfo : extensionAbilityInfos) {
1447             List<AbilityFormInfo> formInfos =
1448                     parseModuleFormInfoInMetadata(data, extensionAbilityInfo.metadataInfos);
1449             if (FORM.equals(extensionAbilityInfo.type)) {
1450                 for (AbilityFormInfo formInfo : formInfos) {
1451                     formInfo.providerAbility = serviceProviderAbility;
1452                     formInfo.setFormExtensionAbilityName(extensionAbilityInfo.name);
1453                 }
1454             }
1455             abilityFormInfos.addAll(formInfos);
1456         }
1457         return abilityFormInfos;
1458     }
1459 
1460     /**
1461      * parse commonevents info
1462      *
1463      * @param extensionAbilityInfos is the list of extensionAbility.
1464      * @return the List<CommonEvent> result
1465      */
parseModuleCommonEvents(List<ExtensionAbilityInfo> extensionAbilityInfos)1466     static List<CommonEvent> parseModuleCommonEvents(List<ExtensionAbilityInfo> extensionAbilityInfos) {
1467         List<CommonEvent> allCommonEvent = new ArrayList<>();
1468         if (extensionAbilityInfos.isEmpty()) {
1469             return allCommonEvent;
1470         }
1471         for (ExtensionAbilityInfo extensionAbilityInfo : extensionAbilityInfos) {
1472             List<CommonEvent> commonEvents =
1473                     parseCommoneventsInMetadata(extensionAbilityInfo.metadataInfos);
1474             allCommonEvent.addAll(commonEvents);
1475         }
1476         return allCommonEvent;
1477     }
1478 
1479     /**
1480      * parse commonevents info
1481      *
1482      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1483      * @return the List<CommonEvent> result
1484      */
parseCommoneventsInMetadata(List<ModuleMetadataInfo> moduleMetadataInfos)1485     static List<CommonEvent> parseCommoneventsInMetadata(List<ModuleMetadataInfo> moduleMetadataInfos) {
1486         List<CommonEvent> commonEvents = new ArrayList<>();
1487         // find common events and parse in metadata
1488         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1489             String jsonStr = moduleMetadataInfo.resource;
1490             JSONObject jsonObj = JSONObject.parseObject(jsonStr);
1491             if (jsonObj != null && jsonObj.containsKey("commonEvents")) {
1492                 commonEvents.addAll(parseModuleCommonEvents(jsonObj));
1493             }
1494         }
1495         return commonEvents;
1496     }
1497 
1498     /**
1499      * parse commonevents info
1500      *
1501      * @param jsonObject is the json  objects of commonevent.
1502      * @return the List<CommonEvent> result
1503      */
parseModuleCommonEvents(JSONObject jsonObject)1504     static List<CommonEvent> parseModuleCommonEvents(JSONObject jsonObject) {
1505         List<CommonEvent> commonEvents = new ArrayList<>();
1506         try {
1507             JSONArray commonEventObjs = jsonObject.getJSONArray("commonEvents");
1508             for (int i = 0; i < commonEventObjs.size(); ++i) {
1509                 JSONObject commonEventObj = commonEventObjs.getJSONObject(i);
1510                 CommonEvent commonEvent = new CommonEvent();
1511                 if (commonEventObj.containsKey("name")) {
1512                     commonEvent.name = getJsonString(commonEventObj, "name");
1513                 }
1514                 if (commonEventObj.containsKey("permission")) {
1515                     commonEvent.permission = getJsonString(commonEventObj, "permission");
1516                 }
1517                 if (commonEventObj.containsKey("types")) {
1518                     commonEvent.type = JSON.parseArray(getJsonString(commonEventObj, "types"), String.class);
1519                 }
1520                 if (commonEventObj.containsKey("events")) {
1521                     commonEvent.events = JSON.parseArray(getJsonString(commonEventObj, "events"), String.class);
1522                 }
1523                 commonEvents.add(commonEvent);
1524             }
1525         } catch (JSONException | NullPointerException ex) {
1526             LOG.warning("JsonUtil::parseModuleCommonEvents err: " + ex.getMessage());
1527         }
1528         return commonEvents;
1529     }
1530 
1531     /**
1532      * parse stage shortcuts info
1533      *
1534      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1535      * @param data is resource byte in hap
1536      * @return the List<moduleShortcut> result
1537      * @throws BundleException Throws this exception when parse failed.
1538      */
parseModuleShortcut(List<ModuleMetadataInfo> moduleMetadataInfos, byte[] data)1539     static List<ModuleShortcut> parseModuleShortcut(List<ModuleMetadataInfo> moduleMetadataInfos, byte[] data)
1540             throws BundleException {
1541         List<ModuleShortcut> shortcuts = new ArrayList<>();
1542         // find shortcut and parse in metadata
1543         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1544             String jsonStr = moduleMetadataInfo.resource;
1545             if (jsonStr == null || jsonStr.isEmpty()) {
1546                 continue;
1547             }
1548             try {
1549                 JSONObject jsonObj = JSON.parseObject(jsonStr);
1550                 if (jsonObj.containsKey("shortcuts")) {
1551                     JSONArray shortcutObjs = jsonObj.getJSONArray("shortcuts");
1552                     for (int j = 0; j < shortcutObjs.size(); ++j) {
1553                         shortcuts.add(parseModuleShortcutObj(shortcutObjs.getJSONObject(j), data));
1554                     }
1555                 }
1556             } catch (JSONException ignore) {
1557                 LOG.warning("ignored metadata: " + moduleMetadataInfo.name);
1558             }
1559         }
1560         return shortcuts;
1561     }
1562 
1563     /**
1564      * parse stage shortcuts json object array
1565      *
1566      * @param shortcutObj is the objects of shortcut
1567      * @param data is resource byte in hap
1568      * @return the List<ModuleShortcuts> result
1569      * @throws BundleException Throws this exception when parse failed.
1570      */
parseModuleShortcutObj(JSONObject shortcutObj, byte[] data)1571     static ModuleShortcut parseModuleShortcutObj(JSONObject shortcutObj, byte[] data) throws BundleException {
1572         if (shortcutObj == null) {
1573             LOG.error("JsonUtil::parseModuleShortcutObj failed");
1574             throw new BundleException("JsonUtil::parseModuleShortcutObj failed");
1575         }
1576         ModuleShortcut moduleShortcut = new ModuleShortcut();
1577         if (shortcutObj.containsKey("shortcutId")) {
1578             moduleShortcut.setShortcutId(shortcutObj.getString("shortcutId"));
1579         }
1580         if (shortcutObj.containsKey("label")) {
1581             moduleShortcut.setLabel(parseResourceByStringID(data, getJsonString(shortcutObj, "label")));
1582         }
1583         moduleShortcut.setLabels(parseResourceMapByKey(shortcutObj, data, LABEL_ID));
1584 
1585         if (shortcutObj.containsKey("icon")) {
1586             String iconPath = parseResourceByStringID(data, getJsonString(shortcutObj, "icon"));
1587             moduleShortcut.setIcon(iconPath.substring(iconPath.indexOf("resources")));
1588         }
1589         if (shortcutObj.containsKey("wants")) {
1590             moduleShortcut.setWants(JSON.parseArray(getJsonString(shortcutObj, "wants"), Want.class));
1591         }
1592         return moduleShortcut;
1593     }
1594 
1595     /**
1596      * parse fa shortcuts json object array
1597      *
1598      * @param moduleJson is the object of module
1599      * @param data is resource byte in hap
1600      * @return the List<ModuleShortcuts> result
1601      * @throws BundleException Throws this exception when parse failed.
1602      */
parseShoruCuts(JSONObject moduleJson, byte[] data)1603     static List<Shortcut> parseShoruCuts(JSONObject moduleJson, byte[] data) throws BundleException {
1604         List<Shortcut> shortcuts = new ArrayList<>();
1605         if (moduleJson.containsKey("shortcuts")) {
1606             JSONArray shortcutObjs = moduleJson.getJSONArray("shortcuts");
1607             for (int i =  0; i < shortcutObjs.size(); ++i) {
1608                 shortcuts.add(parseShortObj(shortcutObjs.getJSONObject(i), data));
1609             }
1610         }
1611         return shortcuts;
1612     }
1613 
1614     /**
1615      * parse fa shortcuts json object array
1616      *
1617      * @param shortcutObj is the object of shortcut
1618      * @param data is resource byte in hap
1619      * @return the List<ModuleShortcuts> result
1620      * @throws BundleException Throws this exception when parse failed.
1621      */
parseShortObj(JSONObject shortcutObj, byte[] data)1622     static Shortcut parseShortObj(JSONObject shortcutObj, byte[] data) throws BundleException {
1623         if (shortcutObj == null) {
1624             LOG.error("JsonUtil::parseModuleShortcutObj failed");
1625             throw new BundleException("JsonUtil::parseModuleShortcutObj failed");
1626         }
1627         Shortcut shortcut = new Shortcut();
1628         if (shortcutObj.containsKey("shortcutId")) {
1629             shortcut.shortcutId = shortcutObj.getString("shortcutId");
1630         }
1631         if (shortcutObj.containsKey("label")) {
1632             shortcut.label = parseResourceByKey(shortcutObj, data, "label", "labelId");
1633         }
1634         shortcut.setLabels(parseResourceMapByKey(shortcutObj, data, LABEL_ID));
1635         if (shortcutObj.containsKey("icon")) {
1636             shortcut.icon = parseIconById(shortcutObj, data);
1637         }
1638         if (shortcutObj.containsKey("intents")) {
1639             shortcut.intents = JSON.parseArray(getJsonString(shortcutObj, "intents"), IntentInfo.class);
1640         }
1641         return shortcut;
1642     }
1643 
1644     /**
1645      * parse form info
1646      *
1647      * @param data is resource byte in hap
1648      * @param moduleMetadataInfos is the list of ModuleMetadataInfo
1649      * @return the List<AbilityFormInfo> result
1650      * @throws BundleException Throws this exception if the json is not standard.
1651      */
parseModuleFormInfoInMetadata( byte[] data, List<ModuleMetadataInfo> moduleMetadataInfos)1652     static List<AbilityFormInfo> parseModuleFormInfoInMetadata(
1653             byte[] data, List<ModuleMetadataInfo> moduleMetadataInfos) throws BundleException {
1654         List<AbilityFormInfo> abilityFormInfos = new ArrayList<>();
1655         if (moduleMetadataInfos.isEmpty()) {
1656             return abilityFormInfos;
1657         }
1658         // find form json and parse in metadata
1659         for (ModuleMetadataInfo moduleMetadataInfo : moduleMetadataInfos) {
1660             String jsonStr = moduleMetadataInfo.resource;
1661             JSONObject jsonObj = JSONObject.parseObject(jsonStr);
1662             if (jsonObj != null && jsonObj.containsKey(FORMS)) {
1663                 JSONArray jsonForms = JSONObject.parseArray(getJsonString(jsonObj, FORMS));
1664                 int size = jsonForms.size();
1665                 for (int j = 0; j < size; ++j) {
1666                     JSONObject tmpObj = jsonForms.getJSONObject(j);
1667                     abilityFormInfos.add(parseModuleForm(tmpObj, data));
1668                 }
1669             }
1670         }
1671         return abilityFormInfos;
1672     }
1673 
1674     /**
1675      * parse form object
1676      *
1677      * @param formObj is form json object
1678      * @param data is resource byte in hap
1679      * @throws BundleException Throws this exception if the json is not standard.
1680      */
parseModuleForm(JSONObject formObj, byte[] data)1681     static AbilityFormInfo parseModuleForm(JSONObject formObj, byte[] data) throws BundleException {
1682         if (formObj == null) {
1683             LOG.error("JsonUtil::parseModuleForm exception: formObj is null.");
1684             throw new BundleException("Parse parseModuleForm failed, formObj is null.");
1685         }
1686         AbilityFormInfo moduleFormInfo = new AbilityFormInfo();
1687         moduleFormInfo.name = getJsonString(formObj, NAME);
1688         moduleFormInfo.description = parseFormDescription(formObj, data);
1689         moduleFormInfo.setDescriptions(parseFormDescriptions(formObj, data));
1690         moduleFormInfo.src = getJsonString(formObj, SRC);
1691 
1692         if (formObj.containsKey(WINDOW)) {
1693             moduleFormInfo.windowInfo =
1694                     JSON.parseObject(getJsonString(formObj, WINDOW), AbilityFormInfo.ModuleWindowInfo.class);
1695         }
1696         moduleFormInfo.isDefault = getJsonBooleanValue(formObj, IS_DEFAULT, false);
1697         moduleFormInfo.colorMode = getJsonString(formObj, COLOR_MODE, AUTO);
1698         if (formObj.containsKey(SUPPORT_DIMENSIONS)) {
1699             moduleFormInfo.supportDimensions =
1700                     JSONObject.parseArray(getJsonString(formObj, SUPPORT_DIMENSIONS), String.class);
1701         }
1702         moduleFormInfo.defaultDimension = getJsonString(formObj, DEFAULT_DIMENSION);
1703         moduleFormInfo.updateEnabled = getJsonBooleanValue(formObj, UPDATE_ENABLED, false);
1704         moduleFormInfo.scheduledUpdateTime = getJsonString(formObj, SCHEDULE_UPDATE_TIME);
1705         moduleFormInfo.updateDuration = getJsonIntValue(formObj, UPDATE_DURATION, 1);
1706         moduleFormInfo.formConfigAbility = getJsonString(formObj, FROM_CONFIG_ABILITY);
1707         moduleFormInfo.formVisibleNotify = getJsonBooleanValue(formObj, FORM_VISIBLE_NOTIFY, false);
1708         return moduleFormInfo;
1709     }
1710 
parseFormDescription(JSONObject formObj, byte[] data)1711     private static String parseFormDescription(JSONObject formObj, byte[] data) throws BundleException {
1712         if (formObj.containsKey(DESCRIPTION)) {
1713             String descriptionStr = getJsonString(formObj, DESCRIPTION);
1714             if (descriptionStr.contains(STRING_RESOURCE)) {
1715                 return parseResourceByStringID(data, descriptionStr);
1716             } else {
1717                 return descriptionStr;
1718             }
1719         }
1720         return EMPTY;
1721     }
1722 
parseFormDescriptions(JSONObject formObj, byte[] data)1723     private static HashMap<String, String> parseFormDescriptions(JSONObject formObj, byte[] data) {
1724         HashMap<String, String> descriptions = new HashMap<>();
1725         if (!formObj.containsKey(DESCRIPTION)) {
1726             return descriptions;
1727         }
1728         String descriptionStr = getJsonString(formObj, DESCRIPTION);
1729         if (descriptionStr.contains(STRING_RESOURCE)) {
1730             int len = STRING_RESOURCE.length();
1731             String descriptionId = descriptionStr.substring(len);
1732             try {
1733                 int id = Integer.parseInt(descriptionId);
1734                 descriptions = ResourcesParser.getResourceMapById(id, data);
1735             } catch (NumberFormatException e) {
1736                 LOG.error("parseFormDescriptions failed: invalid descriptionId: " + descriptionId);
1737             }
1738             return descriptions;
1739         }
1740         return descriptions;
1741     }
1742 
1743     /**
1744      * parse definepermission objects
1745      *
1746      * @param moduleJson is module json object
1747      * @param data is resource byte in hap
1748      * @throws BundleException Throws this exception if the json is not standard.
1749      */
parseDefinePermissions(JSONObject moduleJson, byte[] data)1750     static List<DefinePermission> parseDefinePermissions(JSONObject moduleJson, byte[] data) throws BundleException {
1751         List<DefinePermission> definePermissions = new ArrayList<>();
1752         if (!moduleJson.containsKey(DEFINE_PERMISSIONS)) {
1753             return definePermissions;
1754         }
1755         try {
1756             JSONArray definePermissionObjs = moduleJson.getJSONArray(DEFINE_PERMISSIONS);
1757             for (int i = 0; i < definePermissionObjs.size(); ++i) {
1758                 definePermissions.add(parseDefinePermission(definePermissionObjs.getJSONObject(i), data));
1759             }
1760         } catch (JSONException | NullPointerException ex) {
1761             LOG.warning("JsonUtil::parseDefinePermissions err: " + ex.getMessage());
1762         }
1763         return definePermissions;
1764     }
1765 
parseModuleAtomicService(JSONObject moduleJson)1766     static ModuleAtomicService parseModuleAtomicService(JSONObject moduleJson) {
1767         ModuleAtomicService moduleAtomicService = new ModuleAtomicService();
1768         try {
1769             JSONObject atomicServiceObj = null;
1770             if (!moduleJson.containsKey(ATOMIC_SERVICE)) {
1771                 return moduleAtomicService;
1772             }
1773             atomicServiceObj = moduleJson.getJSONObject(ATOMIC_SERVICE);
1774             JSONArray preloadObjs = atomicServiceObj.getJSONArray(PRELOADS);
1775             List<PreloadItem> preloadItems = new ArrayList<>();
1776             for (int i = 0; i < preloadObjs.size(); ++i) {
1777                 PreloadItem preloadItem = new PreloadItem();
1778                 JSONObject itemObj = preloadObjs.getJSONObject(i);
1779                 if (itemObj.containsKey(MODULE_NAME)) {
1780                     preloadItem.setModuleName(getJsonString(itemObj, MODULE_NAME));
1781                 }
1782                 preloadItems.add(preloadItem);
1783             }
1784             moduleAtomicService.setPreloadItems(preloadItems);
1785         } catch (JSONException | NullPointerException ex) {
1786             LOG.warning("JsonUtil::parseModuleAtomicService err: " + ex.getMessage());
1787         }
1788 
1789         return moduleAtomicService;
1790     }
1791 
1792     /**
1793      * parse define permission objects
1794      *
1795      * @param definePermissionObj is def permission json object
1796      * @param data is resource byte in hap
1797      * @throws BundleException Throws this exception if the json is not standard.
1798      */
parseDefinePermission(JSONObject definePermissionObj, byte[] data)1799     static DefinePermission parseDefinePermission(JSONObject definePermissionObj, byte[] data) throws BundleException {
1800         DefinePermission definePermission = new DefinePermission();
1801         definePermission.name = getJsonString(definePermissionObj, "name", definePermission.name);
1802         definePermission.grantMode = getJsonString(definePermissionObj, "grantMode", definePermission.grantMode);
1803         definePermission.availableLevel =
1804                 getJsonString(definePermissionObj, "availableLevel", definePermission.availableLevel);
1805         if (definePermissionObj.containsKey("provisionEnable")) {
1806             definePermission.provisionEnable = definePermissionObj.getBoolean("provisionEnable");
1807         }
1808         if (definePermissionObj.containsKey("distributedSceneEnable")) {
1809             definePermission.distributedSceneEnable = definePermissionObj.getBoolean("distributedSceneEnable");
1810         }
1811         definePermission.label =
1812                 parseResourceByKey(definePermissionObj, data, "label", "labelId");
1813         definePermission.setLabels(parseResourceMapByKey(definePermissionObj, data, LABEL_ID));
1814 
1815         definePermission.description =
1816                 parseResourceByKey(definePermissionObj, data, "description", "descriptionId");
1817         definePermission.setDescriptions(parseResourceMapByKey(definePermissionObj, data, DESCRIPTION_ID));
1818 
1819         return definePermission;
1820     }
1821 
1822     /**
1823      * parse defpermission objects
1824      *
1825      * @param moduleJson is module json object
1826      * @param data is resource byte in hap
1827      * @throws BundleException Throws this exception if the json is not standard.
1828      */
parseDefPermissions(JSONObject moduleJson, byte[] data)1829     static List<DefPermission> parseDefPermissions(JSONObject moduleJson, byte[] data) throws BundleException {
1830         List<DefPermission> defPermissions = new ArrayList<>();
1831         if (moduleJson.containsKey("defPermissions")) {
1832             JSONArray defPermissionObjs = moduleJson.getJSONArray("defPermissions");
1833             for (int i = 0; i < defPermissionObjs.size(); ++i) {
1834                 defPermissions.add(parseDefPermission(defPermissionObjs.getJSONObject(i), data));
1835             }
1836         }
1837         return defPermissions;
1838     }
1839 
1840     /**
1841      * parse defpermission objects
1842      *
1843      * @param defPermissionObj is def permission json object
1844      * @param data is resource byte in hap
1845      * @throws BundleException Throws this exception if the json is not standard.
1846      */
parseDefPermission(JSONObject defPermissionObj, byte[] data)1847     static DefPermission parseDefPermission(JSONObject defPermissionObj, byte[] data) throws BundleException {
1848         DefPermission defPermission = new DefPermission();
1849         if (defPermissionObj.containsKey("name")) {
1850             defPermission.name = getJsonString(defPermissionObj, "name");
1851         }
1852         if (defPermissionObj.containsKey("grantMode")) {
1853             defPermission.grantMode = getJsonString(defPermissionObj, "grantMode");
1854         }
1855         if (defPermissionObj.containsKey("availableScope")) {
1856             defPermission.availableScope =
1857                     JSONObject.parseArray(getJsonString(defPermissionObj, "availableScope"), String.class);
1858         }
1859         defPermission.label = parseResourceByKey(defPermissionObj, data, "label", "labelId");
1860         defPermission.setLabels(parseResourceMapByKey(defPermissionObj, data, LABEL_ID));
1861 
1862         defPermission.description = parseResourceByKey(defPermissionObj, data, "description", "descriptionId");
1863         defPermission.setDescriptions(parseResourceMapByKey(defPermissionObj, data, DESCRIPTION_ID));
1864 
1865         if (defPermissionObj.containsKey("group")) {
1866             defPermission.group = getJsonString(defPermissionObj, "group");
1867         }
1868         return defPermission;
1869     }
1870 
1871     /**
1872      * get resource from JSONObject by the id.
1873      *
1874      * @param data is resource byte in hap.
1875      * @param id is the resource id.
1876      * @return the result
1877      * @throws BundleException Throws this exception when parse failed.
1878      */
parseResourceByStringID(byte[] data, String id)1879     static String parseResourceByStringID(byte[] data, String id) throws BundleException {
1880         String res = "";
1881         int index = 0;
1882         while(id.charAt(index) < '0' || id.charAt(index) > '9') {
1883             index++;
1884         }
1885         try {
1886             int finalId = Integer.parseInt(id.substring(index));
1887             res = ResourcesParser.getResourceStringById(finalId, data);
1888         } catch (NumberFormatException e) {
1889             LOG.error("parseResourceByStringID failed: input invalid of " + id + ".");
1890         }
1891         return res;
1892     }
1893 
1894     /**
1895      * get resource from JSONObject by the key.
1896      *
1897      * @param jsonObject uncompress json object.
1898      * @param data is resource byte in hap.
1899      * @param key is the index of json object.
1900      * @param keyId is the index id of resource.
1901      * @return the result
1902      */
parseResourceByKey(JSONObject jsonObject, byte[] data, String key, String keyId)1903     static String parseResourceByKey(JSONObject jsonObject, byte[] data, String key, String keyId) {
1904         String res = "";
1905         if (jsonObject.containsKey(keyId)) {
1906             int resId = jsonObject.getIntValue(keyId);
1907             res = ResourcesParser.getResourceStringById(resId, data);
1908         }
1909         if (res != null && !res.isEmpty()) {
1910             return res;
1911         } else if (jsonObject.containsKey(key)) {
1912             return getJsonString(jsonObject, key);
1913         } else {
1914             return "";
1915         }
1916     }
1917 
parseResourceMapByKey(JSONObject jsonObject, byte[] data, String keyId)1918     static HashMap<String, String> parseResourceMapByKey(JSONObject jsonObject, byte[] data, String keyId) {
1919         HashMap<String, String> map = new HashMap<>();
1920         if (jsonObject.containsKey(keyId)) {
1921             int resId = jsonObject.getIntValue(keyId);
1922             map = ResourcesParser.getResourceMapById(resId, data);
1923         }
1924         return map;
1925     }
1926 
1927     /**
1928      * get icon path from resource by the key.
1929      *
1930      * @param jsonObject uncompress json object.
1931      * @param data is resource byte in hap
1932      * @return the result
1933      * @throws BundleException Throws this exception when parse failed.
1934      */
parseIconById(JSONObject jsonObject, byte[] data)1935     static String parseIconById(JSONObject jsonObject, byte[] data) throws BundleException {
1936         String iconPath = "";
1937         if (jsonObject.containsKey("iconId")) {
1938             int resId = jsonObject.getIntValue("iconId");
1939             iconPath = ResourcesParser.getBaseResourceById(resId, data);
1940             if (iconPath.isEmpty()) {
1941                 iconPath = ResourcesParser.getResourceById(resId, data);
1942             }
1943             if (iconPath.contains("resources")) {
1944                 iconPath = iconPath.substring(iconPath.indexOf("resources"));
1945             } else {
1946                 LOG.warning("JsonUtil::parseIconById not found: " + resId);
1947             }
1948         }
1949         if (!iconPath.isEmpty()) {
1950             return iconPath;
1951         } else if (jsonObject.containsKey("icon")) {
1952             return getJsonString(jsonObject, "icon");
1953         } else {
1954             return "";
1955         }
1956     }
1957 
1958     /**
1959      * parse stage module reqPermissions.
1960      *
1961      * @param moduleJson module json object.
1962      * @param data is resource byte in hap.
1963      * @return the result
1964      */
parseReqPermission(JSONObject moduleJson, byte[] data)1965     static List<ReqPermission> parseReqPermission(JSONObject moduleJson, byte[] data) throws BundleException {
1966         List<ReqPermission> reqPermissions = new ArrayList<>();
1967         if (!moduleJson.containsKey(REQUEST_PERMISSIONS)) {
1968             return reqPermissions;
1969         }
1970         JSONArray requestPermissionObjs = moduleJson.getJSONArray(REQUEST_PERMISSIONS);
1971         for (int i = 0; i < requestPermissionObjs.size(); ++i) {
1972             ReqPermission reqPermission = new ReqPermission();
1973             JSONObject requestPermission = requestPermissionObjs.getJSONObject(i);
1974             reqPermission.name = getJsonString(requestPermission, NAME);
1975             reqPermission.reason = parseResourceByKey(requestPermission, data, REASON, REASON_ID);
1976             if (requestPermission.containsKey(REASON_ID)) {
1977                 reqPermission.setReasons(parseResourceMapByKey(requestPermission, data, REASON_ID));
1978             }
1979             if (requestPermission.containsKey(USED_SCENE)) {
1980                 reqPermission.usedScene = parseModuleUsedScene(requestPermission.getJSONObject(USED_SCENE));
1981             }
1982             reqPermissions.add(reqPermission);
1983         }
1984         return reqPermissions;
1985     }
1986 
parseModuleUsedScene(JSONObject usedSceneObj)1987     private static UsedScene parseModuleUsedScene(JSONObject usedSceneObj) {
1988         UsedScene usedScene = new UsedScene();
1989         if (usedSceneObj.containsKey(ABILITIES)) {
1990             usedScene.ability = JSON.parseArray(getJsonString(usedSceneObj, ABILITIES), String.class);
1991         }
1992         if (usedSceneObj.containsKey(WHEN)) {
1993             usedScene.when = getJsonString(usedSceneObj, WHEN);
1994         }
1995         return usedScene;
1996     }
1997 
1998     /**
1999      * get the String from JSONObject by the key.
2000      *
2001      * @param jsonObject uncompress json object
2002      * @param key value key
2003      * @return the result
2004      */
getJsonString(JSONObject jsonObject, String key)2005     private static String getJsonString(JSONObject jsonObject, String key) {
2006         String value = "";
2007         if (jsonObject != null && jsonObject.containsKey(key) && jsonObject.get(key) != null) {
2008             value = jsonObject.get(key).toString();
2009         }
2010         return value;
2011     }
2012 
2013     /**
2014      * get the String from JSONObject by the key.
2015      *
2016      * @param jsonObject uncompress json object
2017      * @param key value key
2018      * @param defaultValue the default value
2019      * @return the result
2020      */
getJsonString(JSONObject jsonObject, String key, String defaultValue)2021     private static String getJsonString(JSONObject jsonObject, String key, String defaultValue) {
2022         String value = defaultValue;
2023         if (jsonObject != null && jsonObject.containsKey(key) && jsonObject.get(key) != null) {
2024             value = jsonObject.get(key).toString();
2025         }
2026         return value;
2027     }
2028 
getJsonIntValue(JSONObject jsonObject, String key, int defaultValue)2029     private static int getJsonIntValue(JSONObject jsonObject, String key, int defaultValue) {
2030         int value = defaultValue;
2031         if (jsonObject != null && jsonObject.containsKey(key)) {
2032             value = jsonObject.getIntValue(key);
2033         }
2034         return value;
2035     }
2036 
getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue)2037     private static boolean getJsonBooleanValue(JSONObject jsonObject, String key, boolean defaultValue) {
2038         boolean value = defaultValue;
2039         if (jsonObject != null && jsonObject.containsKey(key)) {
2040             value = jsonObject.getBooleanValue(key);
2041         }
2042         return value;
2043     }
2044 
setFAProviderAbility(JSONObject moduleJson, HapInfo hapInfo, List<AbilityInfo> abilityInfos)2045     private static void setFAProviderAbility(JSONObject moduleJson, HapInfo hapInfo,
2046                                              List<AbilityInfo> abilityInfos) throws BundleException {
2047         if (abilityInfos.isEmpty()) {
2048             throw new BundleException("JsonUtil::setProviderAbility abilityInfo is empty.");
2049         }
2050         String serviceProviderAbility = parseFAServiceProviderAbility(moduleJson, abilityInfos);
2051         for (AbilityInfo abilityInfo : abilityInfos) {
2052             if (!abilityInfo.formInfos.isEmpty()) {
2053                 if (SERVICE.equals(abilityInfo.type)) {
2054                     setProviderAbilityForForm(abilityInfo.formInfos, serviceProviderAbility);
2055                 }
2056                 if (PAGE.equals(abilityInfo.type)) {
2057                     setProviderAbilityForForm(abilityInfo.formInfos, abilityInfo.name);
2058                 }
2059                 hapInfo.formInfos.addAll(abilityInfo.formInfos);
2060             }
2061         }
2062     }
2063 
setProviderAbilityForForm(List<AbilityFormInfo> abilityFormInfos, String providerAbility)2064     private static void setProviderAbilityForForm(List<AbilityFormInfo> abilityFormInfos, String providerAbility) {
2065         for (AbilityFormInfo abilityFormInfo : abilityFormInfos) {
2066             abilityFormInfo.providerAbility = providerAbility;
2067         }
2068     }
2069 
parseStageServiceProvider(JSONObject moduleJson, List<ModuleAbilityInfo> moduleAbilityInfos)2070     private static String parseStageServiceProvider(JSONObject moduleJson,
2071                                                     List<ModuleAbilityInfo> moduleAbilityInfos) throws BundleException {
2072         if (moduleJson.containsKey(MAIN_ELEMENT)) {
2073             return getJsonString(moduleJson, MAIN_ELEMENT);
2074         }
2075         if (!moduleAbilityInfos.isEmpty()) {
2076             for (ModuleAbilityInfo moduleAbilityInfo : moduleAbilityInfos) {
2077                 if (isSystemHomeAbility(moduleAbilityInfo.skills)) {
2078                     return moduleAbilityInfo.name;
2079                 }
2080             }
2081             return moduleAbilityInfos.get(0).name;
2082         }
2083         return "";
2084     }
2085 
parseFAServiceProviderAbility(JSONObject moduleJson, List<AbilityInfo> abilityInfos)2086     private static String parseFAServiceProviderAbility(JSONObject moduleJson,
2087                                                         List<AbilityInfo> abilityInfos) throws BundleException {
2088         if (abilityInfos.isEmpty()) {
2089             throw new BundleException("JsonUtil::parseServiceProviderAbility abilityInfos is empty.");
2090         }
2091 
2092         if (moduleJson.containsKey(MAIN_ABILITY)) {
2093             return getJsonString(moduleJson, MAIN_ABILITY);
2094         }
2095         for (AbilityInfo abilityInfo : abilityInfos) {
2096             if (isSystemHomeAbility(abilityInfo.skills)) {
2097                 return abilityInfo.name;
2098             }
2099         }
2100         for (AbilityInfo abilityInfo : abilityInfos) {
2101             if (abilityInfo.type.equals(PAGE)) {
2102                 return abilityInfo.name;
2103             }
2104         }
2105         return "";
2106     }
2107 
isSystemHomeAbility(List<SkillInfo> skills)2108     private static boolean isSystemHomeAbility(List<SkillInfo> skills) {
2109         for (SkillInfo skillInfo : skills) {
2110             if (skillInfo.entities.contains(ENTITY_SYSTEM_HOME) && skillInfo.actions.contains(ACTION_SYSTEM_HOME)) {
2111                 return true;
2112             }
2113         }
2114         return false;
2115     }
2116 
2117     /**
2118      * parse patch.json form json string.
2119      *
2120      * @param jsonString is the file path of hqf file
2121      * @return HQFVerifyInfo
2122      */
parsePatch(String jsonString)2123     static HQFInfo parsePatch(String jsonString) throws BundleException {
2124         HQFInfo hqfVerifyInfo = new HQFInfo();
2125         JSONObject jsonObject = JSON.parseObject(jsonString);
2126         JSONObject appObj = jsonObject.getJSONObject(APP);
2127         if (appObj == null) {
2128             LOG.error("parsePatch failed, input patch.json is invalid, patch.json has no app.");
2129             throw new BundleException("parsePatch failed, input patch.json is invalid.");
2130         }
2131 
2132         if (appObj.containsKey(BUNDLENAME)) {
2133             hqfVerifyInfo.setBundleName(appObj.getString(BUNDLENAME));
2134         }
2135         if (appObj.containsKey(VERSIONCODE)) {
2136             hqfVerifyInfo.setVersionCode(appObj.getIntValue(VERSIONCODE));
2137         }
2138         if (appObj.containsKey(VERSIONNAME)) {
2139             hqfVerifyInfo.setVersionName(appObj.getString(VERSIONNAME));
2140         }
2141         if (appObj.containsKey(PATCH_VERSION_CODE)) {
2142             hqfVerifyInfo.setPatchVersionCode(appObj.getIntValue(PATCH_VERSION_CODE));
2143         }
2144         if (appObj.containsKey(PATCH_VERSION_NAME)) {
2145             hqfVerifyInfo.setPatchVersionName(appObj.getString(PATCH_VERSION_NAME));
2146         }
2147         JSONObject moduleObj = jsonObject.getJSONObject(MODULE);
2148         if (moduleObj == null) {
2149             LOG.error("parse failed, input patch.json is invalid, patch.json has no module.");
2150             throw new BundleException("parse failed, input patch.json is invalid, patch.json has no module.");
2151         }
2152         if (moduleObj.containsKey(NAME)) {
2153             hqfVerifyInfo.setModuleName(moduleObj.getString(NAME));
2154         }
2155         if (moduleObj.containsKey(TYPE)) {
2156             hqfVerifyInfo.setType(moduleObj.getString(TYPE));
2157         }
2158         if (moduleObj.containsKey(DEVICE_TYPES)) {
2159             hqfVerifyInfo.setDeviceTypes(JSONObject.parseArray(getJsonString(moduleObj, DEVICE_TYPES), String.class));
2160         }
2161         if (moduleObj.containsKey(ORIGINAL_MODULE_HASH)) {
2162             hqfVerifyInfo.setOriginalModuleHash(moduleObj.getString(ORIGINAL_MODULE_HASH));
2163         }
2164         return hqfVerifyInfo;
2165     }
2166 }
2167