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