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