1 /*
2 * Copyright (c) 2022-2024 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 #include "module_profile.h"
17
18 #include <sstream>
19
20 #include "parameter.h"
21 #include "parameters.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26 const std::string COMPRESS_NATIVE_LIBS = "persist.bms.supportCompressNativeLibs";
27 const int32_t THRESHOLD_VAL_LEN = 40;
28 constexpr uint8_t MAX_MODULE_NAME = 128;
IsSupportCompressNativeLibs()29 bool IsSupportCompressNativeLibs()
30 {
31 char compressNativeLibs[THRESHOLD_VAL_LEN] = {0};
32 int32_t ret = GetParameter(COMPRESS_NATIVE_LIBS.c_str(), "", compressNativeLibs, THRESHOLD_VAL_LEN);
33 if (ret <= 0) {
34 APP_LOGD("GetParameter %{public}s failed", COMPRESS_NATIVE_LIBS.c_str());
35 return false;
36 }
37 return std::strcmp(compressNativeLibs, "true") == 0;
38 }
39 }
40
41 namespace Profile {
42 int32_t g_parseResult = ERR_OK;
43 std::mutex g_mutex;
44
45 const std::set<std::string> MODULE_TYPE_SET = {
46 "entry",
47 "feature",
48 "shared"
49 };
50
51 const std::set<std::string> VIRTUAL_MACHINE_SET = {
52 "ark",
53 "default"
54 };
55
56 const std::map<std::string, uint32_t> BACKGROUND_MODES_MAP = {
57 {ProfileReader::KEY_DATA_TRANSFER, ProfileReader::VALUE_DATA_TRANSFER},
58 {ProfileReader::KEY_AUDIO_PLAYBACK, ProfileReader::VALUE_AUDIO_PLAYBACK},
59 {ProfileReader::KEY_AUDIO_RECORDING, ProfileReader::VALUE_AUDIO_RECORDING},
60 {ProfileReader::KEY_LOCATION, ProfileReader::VALUE_LOCATION},
61 {ProfileReader::KEY_BLUETOOTH_INTERACTION, ProfileReader::VALUE_BLUETOOTH_INTERACTION},
62 {ProfileReader::KEY_MULTI_DEVICE_CONNECTION, ProfileReader::VALUE_MULTI_DEVICE_CONNECTION},
63 {ProfileReader::KEY_WIFI_INTERACTION, ProfileReader::VALUE_WIFI_INTERACTION},
64 {ProfileReader::KEY_VOIP, ProfileReader::VALUE_VOIP},
65 {ProfileReader::KEY_TASK_KEEPING, ProfileReader::VALUE_TASK_KEEPING},
66 {ProfileReader::KEY_PICTURE_IN_PICTURE, ProfileReader::VALUE_PICTURE_IN_PICTURE},
67 {ProfileReader::KEY_SCREEN_FETCH, ProfileReader::VALUE_SCREEN_FETCH}
68 };
69
70 const std::set<std::string> GRANT_MODE_SET = {
71 "system_grant",
72 "user_grant"
73 };
74
75 const std::set<std::string> AVAILABLE_LEVEL_SET = {
76 "system_core",
77 "system_basic",
78 "normal"
79 };
80
81 const std::map<std::string, LaunchMode> LAUNCH_MODE_MAP = {
82 {"singleton", LaunchMode::SINGLETON},
83 {"standard", LaunchMode::STANDARD},
84 {"multiton", LaunchMode::STANDARD},
85 {"specified", LaunchMode::SPECIFIED}
86 };
87 const std::unordered_map<std::string, DisplayOrientation> DISPLAY_ORIENTATION_MAP = {
88 {"unspecified", DisplayOrientation::UNSPECIFIED},
89 {"landscape", DisplayOrientation::LANDSCAPE},
90 {"portrait", DisplayOrientation::PORTRAIT},
91 {"follow_recent", DisplayOrientation::FOLLOWRECENT},
92 {"landscape_inverted", DisplayOrientation::LANDSCAPE_INVERTED},
93 {"portrait_inverted", DisplayOrientation::PORTRAIT_INVERTED},
94 {"auto_rotation", DisplayOrientation::AUTO_ROTATION},
95 {"auto_rotation_landscape", DisplayOrientation::AUTO_ROTATION_LANDSCAPE},
96 {"auto_rotation_portrait", DisplayOrientation::AUTO_ROTATION_PORTRAIT},
97 {"auto_rotation_restricted", DisplayOrientation::AUTO_ROTATION_RESTRICTED},
98 {"auto_rotation_landscape_restricted", DisplayOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED},
99 {"auto_rotation_portrait_restricted", DisplayOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED},
100 {"locked", DisplayOrientation::LOCKED},
101 {"auto_rotation_unspecified", DisplayOrientation::AUTO_ROTATION_UNSPECIFIED},
102 {"follow_desktop", DisplayOrientation::FOLLOW_DESKTOP},
103 };
104 const std::unordered_map<std::string, SupportWindowMode> WINDOW_MODE_MAP = {
105 {"fullscreen", SupportWindowMode::FULLSCREEN},
106 {"split", SupportWindowMode::SPLIT},
107 {"floating", SupportWindowMode::FLOATING}
108 };
109 const std::unordered_map<std::string, BundleType> BUNDLE_TYPE_MAP = {
110 {"app", BundleType::APP},
111 {"atomicService", BundleType::ATOMIC_SERVICE},
112 {"shared", BundleType::SHARED},
113 {"appService", BundleType::APP_SERVICE_FWK}
114 };
115 const size_t MAX_QUERYSCHEMES_LENGTH = 50;
116
117 const std::map<std::string, MultiAppModeType> MULTI_APP_MODE_MAP = {
118 {"multiInstance", MultiAppModeType::MULTI_INSTANCE},
119 {"appClone", MultiAppModeType::APP_CLONE}
120 };
121
122 struct DeviceConfig {
123 // pair first : if exist in module.json then true, otherwise false
124 // pair second : actual value
125 std::pair<bool, int32_t> minAPIVersion = std::make_pair<>(false, 0);
126 std::pair<bool, bool> keepAlive = std::make_pair<>(false, false);
127 std::pair<bool, bool> removable = std::make_pair<>(false, true);
128 std::pair<bool, bool> singleton = std::make_pair<>(false, false);
129 std::pair<bool, bool> userDataClearable = std::make_pair<>(false, true);
130 std::pair<bool, bool> accessible = std::make_pair<>(false, true);
131 };
132
133 struct Metadata {
134 std::string name;
135 std::string value;
136 std::string resource;
137 };
138
139 struct HnpPackage {
140 std::string package;
141 std::string type;
142 };
143
144 struct Ability {
145 std::string name;
146 std::string srcEntrance;
147 std::string launchType = ABILITY_LAUNCH_TYPE_DEFAULT_VALUE;
148 std::string description;
149 uint32_t descriptionId = 0;
150 std::string icon;
151 uint32_t iconId = 0;
152 std::string label;
153 uint32_t labelId = 0;
154 int32_t priority = 0;
155 std::vector<std::string> permissions;
156 std::vector<Metadata> metadata;
157 bool visible = false;
158 bool continuable = false;
159 std::vector<Skill> skills;
160 std::vector<std::string> backgroundModes;
161 std::string startWindowIcon;
162 uint32_t startWindowIconId = 0;
163 std::string startWindowBackground;
164 uint32_t startWindowBackgroundId = 0;
165 bool removeMissionAfterTerminate = false;
166 std::string orientation = "unspecified";
167 std::vector<std::string> windowModes;
168 double maxWindowRatio = 0;
169 double minWindowRatio = 0;
170 uint32_t maxWindowWidth = 0;
171 uint32_t minWindowWidth = 0;
172 uint32_t maxWindowHeight = 0;
173 uint32_t minWindowHeight = 0;
174 bool excludeFromMissions = false;
175 bool recoverable = false;
176 bool unclearableMission = false;
177 bool excludeFromDock = false;
178 std::string preferMultiWindowOrientation = "default";
179 bool isolationProcess = false;
180 std::vector<std::string> continueType;
181 uint32_t orientationId = 0;
182 std::vector<std::string> continueBundleNames;
183 std::string process;
184 };
185
186 struct Extension {
187 std::string name;
188 std::string srcEntrance;
189 std::string icon;
190 uint32_t iconId = 0;
191 std::string label;
192 uint32_t labelId = 0;
193 std::string description;
194 uint32_t descriptionId = 0;
195 int32_t priority = 0;
196 std::string type;
197 std::string readPermission;
198 std::string writePermission;
199 std::string uri;
200 std::vector<std::string> permissions;
201 bool visible = false;
202 std::vector<Skill> skills;
203 std::vector<Metadata> metadata;
204 std::string extensionProcessMode;
205 std::vector<std::string> dataGroupIds;
206 std::string customProcess;
207 };
208
209 struct MultiAppMode {
210 std::string multiAppModeType;
211 int32_t maxCount = 0;
212 };
213
214 struct App {
215 std::string bundleName;
216 bool debug = false;
217 std::string icon;
218 uint32_t iconId = 0;
219 std::string label;
220 uint32_t labelId = 0;
221 std::string description;
222 uint32_t descriptionId = 0;
223 std::string vendor;
224 int32_t versionCode = 0;
225 std::string versionName;
226 int32_t minCompatibleVersionCode = -1;
227 uint32_t minAPIVersion = 0;
228 int32_t targetAPIVersion = 0;
229 std::string apiReleaseType = APP_API_RELEASETYPE_DEFAULT_VALUE;
230 bool keepAlive = false;
231 std::pair<bool, bool> removable = std::make_pair<>(false, true);
232 bool singleton = false;
233 bool userDataClearable = true;
234 bool accessible = false;
235 std::vector<std::string> targetBundleList;
236 std::map<std::string, DeviceConfig> deviceConfigs;
237 bool multiProjects = false;
238 std::string targetBundle;
239 int32_t targetPriority = 0;
240 bool asanEnabled = false;
241 std::string bundleType = Profile::BUNDLE_TYPE_APP;
242 std::string compileSdkVersion;
243 std::string compileSdkType = Profile::COMPILE_SDK_TYPE_OPEN_HARMONY;
244 bool gwpAsanEnabled = false;
245 bool hwasanEnabled = false;
246 bool tsanEnabled = false;
247 std::vector<ApplicationEnvironment> appEnvironments;
248 MultiAppMode multiAppMode;
249 int32_t maxChildProcess = OHOS::system::GetIntParameter(MAX_CHILD_PROCESS, 1);
250 std::string configuration;
251 bool cloudFileSyncEnabled = false;
252 };
253
254 struct Module {
255 std::string name;
256 std::string type;
257 std::string srcEntrance;
258 std::string description;
259 uint32_t descriptionId = 0;
260 std::string process;
261 std::string mainElement;
262 std::vector<std::string> deviceTypes;
263 bool deliveryWithInstall = false;
264 bool installationFree = false;
265 std::string virtualMachine = MODULE_VIRTUAL_MACHINE_DEFAULT_VALUE;
266 std::string pages;
267 std::vector<Metadata> metadata;
268 std::vector<HnpPackage> hnpPackages;
269 std::vector<Ability> abilities;
270 std::vector<Extension> extensionAbilities;
271 std::vector<RequestPermission> requestPermissions;
272 std::vector<DefinePermission> definePermissions;
273 std::vector<Dependency> dependencies;
274 std::string compileMode;
275 bool isLibIsolated = false;
276 std::string targetModule;
277 int32_t targetPriority = 0;
278 std::vector<ProxyData> proxyDatas;
279 std::vector<ProxyData> proxyData;
280 std::string buildHash;
281 std::string isolationMode;
282 bool compressNativeLibs = true;
283 std::string fileContextMenu;
284 std::vector<std::string> querySchemes;
285 std::string routerMap;
286 std::vector<AppEnvironment> appEnvironments;
287 std::string packageName;
288 std::string appStartup;
289 };
290
291 struct ModuleJson {
292 App app;
293 Module module;
294 };
295
from_json(const nlohmann::json & jsonObject,Metadata & metadata)296 void from_json(const nlohmann::json &jsonObject, Metadata &metadata)
297 {
298 APP_LOGD("read metadata tag from module.json");
299 const auto &jsonObjectEnd = jsonObject.end();
300 GetValueIfFindKey<std::string>(jsonObject,
301 jsonObjectEnd,
302 META_DATA_NAME,
303 metadata.name,
304 JsonType::STRING,
305 false,
306 g_parseResult,
307 ArrayType::NOT_ARRAY);
308 GetValueIfFindKey<std::string>(jsonObject,
309 jsonObjectEnd,
310 META_DATA_VALUE,
311 metadata.value,
312 JsonType::STRING,
313 false,
314 g_parseResult,
315 ArrayType::NOT_ARRAY);
316 GetValueIfFindKey<std::string>(jsonObject,
317 jsonObjectEnd,
318 META_DATA_RESOURCE,
319 metadata.resource,
320 JsonType::STRING,
321 false,
322 g_parseResult,
323 ArrayType::NOT_ARRAY);
324 }
325
from_json(const nlohmann::json & jsonObject,HnpPackage & hnpPackage)326 void from_json(const nlohmann::json &jsonObject, HnpPackage &hnpPackage)
327 {
328 APP_LOGD("read hnppackage tag from module.json");
329 const auto &jsonObjectEnd = jsonObject.end();
330 GetValueIfFindKey<std::string>(jsonObject,
331 jsonObjectEnd,
332 HNP_PACKAGE,
333 hnpPackage.package,
334 JsonType::STRING,
335 false,
336 g_parseResult,
337 ArrayType::NOT_ARRAY);
338 GetValueIfFindKey<std::string>(jsonObject,
339 jsonObjectEnd,
340 HNP_TYPE,
341 hnpPackage.type,
342 JsonType::STRING,
343 false,
344 g_parseResult,
345 ArrayType::NOT_ARRAY);
346 }
347
from_json(const nlohmann::json & jsonObject,Ability & ability)348 void from_json(const nlohmann::json &jsonObject, Ability &ability)
349 {
350 APP_LOGD("read ability tag from module.json");
351 const auto &jsonObjectEnd = jsonObject.end();
352 GetValueIfFindKey<std::string>(jsonObject,
353 jsonObjectEnd,
354 ABILITY_NAME,
355 ability.name,
356 JsonType::STRING,
357 true,
358 g_parseResult,
359 ArrayType::NOT_ARRAY);
360 // both srcEntry and srcEntrance can be configured, but srcEntry has higher priority
361 if (jsonObject.find(SRC_ENTRY) != jsonObject.end()) {
362 GetValueIfFindKey<std::string>(jsonObject,
363 jsonObjectEnd,
364 SRC_ENTRY,
365 ability.srcEntrance,
366 JsonType::STRING,
367 true,
368 g_parseResult,
369 ArrayType::NOT_ARRAY);
370 } else {
371 GetValueIfFindKey<std::string>(jsonObject,
372 jsonObjectEnd,
373 SRC_ENTRANCE,
374 ability.srcEntrance,
375 JsonType::STRING,
376 true,
377 g_parseResult,
378 ArrayType::NOT_ARRAY);
379 }
380 GetValueIfFindKey<std::string>(jsonObject,
381 jsonObjectEnd,
382 ABILITY_LAUNCH_TYPE,
383 ability.launchType,
384 JsonType::STRING,
385 false,
386 g_parseResult,
387 ArrayType::NOT_ARRAY);
388 GetValueIfFindKey<std::string>(jsonObject,
389 jsonObjectEnd,
390 DESCRIPTION,
391 ability.description,
392 JsonType::STRING,
393 false,
394 g_parseResult,
395 ArrayType::NOT_ARRAY);
396 GetValueIfFindKey<uint32_t>(jsonObject,
397 jsonObjectEnd,
398 DESCRIPTION_ID,
399 ability.descriptionId,
400 JsonType::NUMBER,
401 false,
402 g_parseResult,
403 ArrayType::NOT_ARRAY);
404 GetValueIfFindKey<std::string>(jsonObject,
405 jsonObjectEnd,
406 ICON,
407 ability.icon,
408 JsonType::STRING,
409 false,
410 g_parseResult,
411 ArrayType::NOT_ARRAY);
412 GetValueIfFindKey<uint32_t>(jsonObject,
413 jsonObjectEnd,
414 ICON_ID,
415 ability.iconId,
416 JsonType::NUMBER,
417 false,
418 g_parseResult,
419 ArrayType::NOT_ARRAY);
420 GetValueIfFindKey<std::string>(jsonObject,
421 jsonObjectEnd,
422 LABEL,
423 ability.label,
424 JsonType::STRING,
425 false,
426 g_parseResult,
427 ArrayType::NOT_ARRAY);
428 GetValueIfFindKey<uint32_t>(jsonObject,
429 jsonObjectEnd,
430 LABEL_ID,
431 ability.labelId,
432 JsonType::NUMBER,
433 false,
434 g_parseResult,
435 ArrayType::NOT_ARRAY);
436 GetValueIfFindKey<int32_t>(jsonObject,
437 jsonObjectEnd,
438 PRIORITY,
439 ability.priority,
440 JsonType::NUMBER,
441 false,
442 g_parseResult,
443 ArrayType::NOT_ARRAY);
444 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
445 jsonObjectEnd,
446 PERMISSIONS,
447 ability.permissions,
448 JsonType::ARRAY,
449 false,
450 g_parseResult,
451 ArrayType::STRING);
452 GetValueIfFindKey<std::vector<Metadata>>(jsonObject,
453 jsonObjectEnd,
454 META_DATA,
455 ability.metadata,
456 JsonType::ARRAY,
457 false,
458 g_parseResult,
459 ArrayType::OBJECT);
460 // both exported and visible can be configured, but exported has higher priority
461 GetValueIfFindKey<bool>(jsonObject,
462 jsonObjectEnd,
463 VISIBLE,
464 ability.visible,
465 JsonType::BOOLEAN,
466 false,
467 g_parseResult,
468 ArrayType::NOT_ARRAY);
469 GetValueIfFindKey<bool>(jsonObject,
470 jsonObjectEnd,
471 EXPORTED,
472 ability.visible,
473 JsonType::BOOLEAN,
474 false,
475 g_parseResult,
476 ArrayType::NOT_ARRAY);
477 GetValueIfFindKey<bool>(jsonObject,
478 jsonObjectEnd,
479 ABILITY_CONTINUABLE,
480 ability.continuable,
481 JsonType::BOOLEAN,
482 false,
483 g_parseResult,
484 ArrayType::NOT_ARRAY);
485 GetValueIfFindKey<std::vector<Skill>>(jsonObject,
486 jsonObjectEnd,
487 SKILLS,
488 ability.skills,
489 JsonType::ARRAY,
490 false,
491 g_parseResult,
492 ArrayType::OBJECT);
493 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
494 jsonObjectEnd,
495 ABILITY_BACKGROUNDMODES,
496 ability.backgroundModes,
497 JsonType::ARRAY,
498 false,
499 g_parseResult,
500 ArrayType::STRING);
501 GetValueIfFindKey<std::string>(jsonObject,
502 jsonObjectEnd,
503 ABILITY_START_WINDOW_ICON,
504 ability.startWindowIcon,
505 JsonType::STRING,
506 false,
507 g_parseResult,
508 ArrayType::NOT_ARRAY);
509 GetValueIfFindKey<uint32_t>(jsonObject,
510 jsonObjectEnd,
511 ABILITY_START_WINDOW_ICON_ID,
512 ability.startWindowIconId,
513 JsonType::NUMBER,
514 false,
515 g_parseResult,
516 ArrayType::NOT_ARRAY);
517 GetValueIfFindKey<std::string>(jsonObject,
518 jsonObjectEnd,
519 ABILITY_START_WINDOW_BACKGROUND,
520 ability.startWindowBackground,
521 JsonType::STRING,
522 false,
523 g_parseResult,
524 ArrayType::NOT_ARRAY);
525 GetValueIfFindKey<uint32_t>(jsonObject,
526 jsonObjectEnd,
527 ABILITY_START_WINDOW_BACKGROUND_ID,
528 ability.startWindowBackgroundId,
529 JsonType::NUMBER,
530 false,
531 g_parseResult,
532 ArrayType::NOT_ARRAY);
533 GetValueIfFindKey<bool>(jsonObject,
534 jsonObjectEnd,
535 ABILITY_REMOVE_MISSION_AFTER_TERMINATE,
536 ability.removeMissionAfterTerminate,
537 JsonType::BOOLEAN,
538 false,
539 g_parseResult,
540 ArrayType::NOT_ARRAY);
541 GetValueIfFindKey<std::string>(jsonObject,
542 jsonObjectEnd,
543 ABILITY_ORIENTATION,
544 ability.orientation,
545 JsonType::STRING,
546 false,
547 g_parseResult,
548 ArrayType::NOT_ARRAY);
549 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
550 jsonObjectEnd,
551 ABILITY_SUPPORT_WINDOW_MODE,
552 ability.windowModes,
553 JsonType::ARRAY,
554 false,
555 g_parseResult,
556 ArrayType::STRING);
557 GetValueIfFindKey<double>(jsonObject,
558 jsonObjectEnd,
559 ABILITY_MAX_WINDOW_RATIO,
560 ability.maxWindowRatio,
561 JsonType::NUMBER,
562 false,
563 g_parseResult,
564 ArrayType::NOT_ARRAY);
565 GetValueIfFindKey<double>(jsonObject,
566 jsonObjectEnd,
567 ABILITY_MIN_WINDOW_RATIO,
568 ability.minWindowRatio,
569 JsonType::NUMBER,
570 false,
571 g_parseResult,
572 ArrayType::NOT_ARRAY);
573 GetValueIfFindKey<uint32_t>(jsonObject,
574 jsonObjectEnd,
575 ABILITY_MAX_WINDOW_WIDTH,
576 ability.maxWindowWidth,
577 JsonType::NUMBER,
578 false,
579 g_parseResult,
580 ArrayType::NOT_ARRAY);
581 GetValueIfFindKey<uint32_t>(jsonObject,
582 jsonObjectEnd,
583 ABILITY_MIN_WINDOW_WIDTH,
584 ability.minWindowWidth,
585 JsonType::NUMBER,
586 false,
587 g_parseResult,
588 ArrayType::NOT_ARRAY);
589 GetValueIfFindKey<uint32_t>(jsonObject,
590 jsonObjectEnd,
591 ABILITY_MAX_WINDOW_HEIGHT,
592 ability.maxWindowHeight,
593 JsonType::NUMBER,
594 false,
595 g_parseResult,
596 ArrayType::NOT_ARRAY);
597 GetValueIfFindKey<uint32_t>(jsonObject,
598 jsonObjectEnd,
599 ABILITY_MIN_WINDOW_HEIGHT,
600 ability.minWindowHeight,
601 JsonType::NUMBER,
602 false,
603 g_parseResult,
604 ArrayType::NOT_ARRAY);
605 GetValueIfFindKey<bool>(jsonObject,
606 jsonObjectEnd,
607 ABILITY_EXCLUDE_FROM_MISSIONS,
608 ability.excludeFromMissions,
609 JsonType::BOOLEAN,
610 false,
611 g_parseResult,
612 ArrayType::NOT_ARRAY);
613 GetValueIfFindKey<bool>(jsonObject,
614 jsonObjectEnd,
615 ABILITY_RECOVERABLE,
616 ability.recoverable,
617 JsonType::BOOLEAN,
618 false,
619 g_parseResult,
620 ArrayType::NOT_ARRAY);
621 GetValueIfFindKey<bool>(jsonObject,
622 jsonObjectEnd,
623 ABILITY_UNCLEARABLE_MISSION,
624 ability.unclearableMission,
625 JsonType::BOOLEAN,
626 false,
627 g_parseResult,
628 ArrayType::NOT_ARRAY);
629 GetValueIfFindKey<bool>(jsonObject,
630 jsonObjectEnd,
631 ABILITY_EXCLUDEFROMDOCK_MISSION,
632 ability.excludeFromDock,
633 JsonType::BOOLEAN,
634 false,
635 g_parseResult,
636 ArrayType::NOT_ARRAY);
637 GetValueIfFindKey<std::string>(jsonObject,
638 jsonObjectEnd,
639 ABILITY_PREFER_MULTI_WINDOW_ORIENTATION_MISSION,
640 ability.preferMultiWindowOrientation,
641 JsonType::STRING,
642 false,
643 g_parseResult,
644 ArrayType::NOT_ARRAY);
645 GetValueIfFindKey<bool>(jsonObject,
646 jsonObjectEnd,
647 ABILITY_ISOLATION_PROCESS,
648 ability.isolationProcess,
649 JsonType::BOOLEAN,
650 false,
651 g_parseResult,
652 ArrayType::NOT_ARRAY);
653 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
654 jsonObjectEnd,
655 ABILITY_CONTINUE_TYPE,
656 ability.continueType,
657 JsonType::ARRAY,
658 false,
659 g_parseResult,
660 ArrayType::STRING);
661 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
662 jsonObjectEnd,
663 ABILITY_CONTINUE_BUNDLE_NAME,
664 ability.continueBundleNames,
665 JsonType::ARRAY,
666 false,
667 g_parseResult,
668 ArrayType::STRING);
669 GetValueIfFindKey<uint32_t>(jsonObject,
670 jsonObjectEnd,
671 ABILITY_ORIENTATION_ID,
672 ability.orientationId,
673 JsonType::NUMBER,
674 false,
675 g_parseResult,
676 ArrayType::NOT_ARRAY);
677 GetValueIfFindKey<std::string>(jsonObject,
678 jsonObjectEnd,
679 MODULE_PROCESS,
680 ability.process,
681 JsonType::STRING,
682 false,
683 g_parseResult,
684 ArrayType::NOT_ARRAY);
685 }
686
from_json(const nlohmann::json & jsonObject,Extension & extension)687 void from_json(const nlohmann::json &jsonObject, Extension &extension)
688 {
689 APP_LOGD("read extension tag from module.json");
690 const auto &jsonObjectEnd = jsonObject.end();
691 GetValueIfFindKey<std::string>(jsonObject,
692 jsonObjectEnd,
693 EXTENSION_ABILITY_NAME,
694 extension.name,
695 JsonType::STRING,
696 true,
697 g_parseResult,
698 ArrayType::NOT_ARRAY);
699 // both srcEntry and srcEntrance can be configured, but srcEntry has higher priority
700 if (jsonObject.find(SRC_ENTRY) != jsonObject.end()) {
701 GetValueIfFindKey<std::string>(jsonObject,
702 jsonObjectEnd,
703 SRC_ENTRY,
704 extension.srcEntrance,
705 JsonType::STRING,
706 true,
707 g_parseResult,
708 ArrayType::NOT_ARRAY);
709 } else {
710 GetValueIfFindKey<std::string>(jsonObject,
711 jsonObjectEnd,
712 SRC_ENTRANCE,
713 extension.srcEntrance,
714 JsonType::STRING,
715 true,
716 g_parseResult,
717 ArrayType::NOT_ARRAY);
718 }
719 GetValueIfFindKey<std::string>(jsonObject,
720 jsonObjectEnd,
721 ICON,
722 extension.icon,
723 JsonType::STRING,
724 false,
725 g_parseResult,
726 ArrayType::NOT_ARRAY);
727 GetValueIfFindKey<uint32_t>(jsonObject,
728 jsonObjectEnd,
729 ICON_ID,
730 extension.iconId,
731 JsonType::NUMBER,
732 false,
733 g_parseResult,
734 ArrayType::NOT_ARRAY);
735 GetValueIfFindKey<std::string>(jsonObject,
736 jsonObjectEnd,
737 LABEL,
738 extension.label,
739 JsonType::STRING,
740 false,
741 g_parseResult,
742 ArrayType::NOT_ARRAY);
743 GetValueIfFindKey<uint32_t>(jsonObject,
744 jsonObjectEnd,
745 LABEL_ID,
746 extension.labelId,
747 JsonType::NUMBER,
748 false,
749 g_parseResult,
750 ArrayType::NOT_ARRAY);
751 GetValueIfFindKey<std::string>(jsonObject,
752 jsonObjectEnd,
753 DESCRIPTION,
754 extension.description,
755 JsonType::STRING,
756 false,
757 g_parseResult,
758 ArrayType::NOT_ARRAY);
759 GetValueIfFindKey<uint32_t>(jsonObject,
760 jsonObjectEnd,
761 DESCRIPTION_ID,
762 extension.descriptionId,
763 JsonType::NUMBER,
764 false,
765 g_parseResult,
766 ArrayType::NOT_ARRAY);
767 GetValueIfFindKey<int32_t>(jsonObject,
768 jsonObjectEnd,
769 PRIORITY,
770 extension.priority,
771 JsonType::NUMBER,
772 false,
773 g_parseResult,
774 ArrayType::NOT_ARRAY);
775 GetValueIfFindKey<std::string>(jsonObject,
776 jsonObjectEnd,
777 EXTENSION_ABILITY_TYPE,
778 extension.type,
779 JsonType::STRING,
780 true,
781 g_parseResult,
782 ArrayType::NOT_ARRAY);
783 GetValueIfFindKey<std::string>(jsonObject,
784 jsonObjectEnd,
785 EXTENSION_ABILITY_READ_PERMISSION,
786 extension.readPermission,
787 JsonType::STRING,
788 false,
789 g_parseResult,
790 ArrayType::NOT_ARRAY);
791 GetValueIfFindKey<std::string>(jsonObject,
792 jsonObjectEnd,
793 EXTENSION_ABILITY_WRITE_PERMISSION,
794 extension.writePermission,
795 JsonType::STRING,
796 false,
797 g_parseResult,
798 ArrayType::NOT_ARRAY);
799 GetValueIfFindKey<std::string>(jsonObject,
800 jsonObjectEnd,
801 EXTENSION_URI,
802 extension.uri,
803 JsonType::STRING,
804 false,
805 g_parseResult,
806 ArrayType::NOT_ARRAY);
807 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
808 jsonObjectEnd,
809 PERMISSIONS,
810 extension.permissions,
811 JsonType::ARRAY,
812 false,
813 g_parseResult,
814 ArrayType::STRING);
815 // both exported and visible can be configured, but exported has higher priority
816 GetValueIfFindKey<bool>(jsonObject,
817 jsonObjectEnd,
818 VISIBLE,
819 extension.visible,
820 JsonType::BOOLEAN,
821 false,
822 g_parseResult,
823 ArrayType::NOT_ARRAY);
824 GetValueIfFindKey<bool>(jsonObject,
825 jsonObjectEnd,
826 EXPORTED,
827 extension.visible,
828 JsonType::BOOLEAN,
829 false,
830 g_parseResult,
831 ArrayType::NOT_ARRAY);
832 GetValueIfFindKey<std::vector<Skill>>(jsonObject,
833 jsonObjectEnd,
834 SKILLS,
835 extension.skills,
836 JsonType::ARRAY,
837 false,
838 g_parseResult,
839 ArrayType::OBJECT);
840 GetValueIfFindKey<std::vector<Metadata>>(jsonObject,
841 jsonObjectEnd,
842 META_DATA,
843 extension.metadata,
844 JsonType::ARRAY,
845 false,
846 g_parseResult,
847 ArrayType::OBJECT);
848 GetValueIfFindKey<std::string>(jsonObject,
849 jsonObjectEnd,
850 EXTENSION_PROCESS_MODE,
851 extension.extensionProcessMode,
852 JsonType::STRING,
853 false,
854 g_parseResult,
855 ArrayType::NOT_ARRAY);
856 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
857 jsonObjectEnd,
858 DATA_GROUP_IDS,
859 extension.dataGroupIds,
860 JsonType::ARRAY,
861 false,
862 g_parseResult,
863 ArrayType::STRING);
864 GetValueIfFindKey<std::string>(jsonObject,
865 jsonObjectEnd,
866 MODULE_PROCESS,
867 extension.customProcess,
868 JsonType::STRING,
869 false,
870 g_parseResult,
871 ArrayType::NOT_ARRAY);
872 }
873
from_json(const nlohmann::json & jsonObject,DeviceConfig & deviceConfig)874 void from_json(const nlohmann::json &jsonObject, DeviceConfig &deviceConfig)
875 {
876 const auto &jsonObjectEnd = jsonObject.end();
877 if (jsonObject.find(MIN_API_VERSION) != jsonObjectEnd) {
878 deviceConfig.minAPIVersion.first = true;
879 GetValueIfFindKey<int32_t>(jsonObject,
880 jsonObjectEnd,
881 MIN_API_VERSION,
882 deviceConfig.minAPIVersion.second,
883 JsonType::NUMBER,
884 false,
885 g_parseResult,
886 ArrayType::NOT_ARRAY);
887 }
888 if (jsonObject.find(DEVICE_CONFIG_KEEP_ALIVE) != jsonObjectEnd) {
889 deviceConfig.keepAlive.first = true;
890 GetValueIfFindKey<bool>(jsonObject,
891 jsonObjectEnd,
892 DEVICE_CONFIG_KEEP_ALIVE,
893 deviceConfig.keepAlive.second,
894 JsonType::BOOLEAN,
895 false,
896 g_parseResult,
897 ArrayType::NOT_ARRAY);
898 }
899 if (jsonObject.find(DEVICE_CONFIG_REMOVABLE) != jsonObjectEnd) {
900 deviceConfig.removable.first = true;
901 GetValueIfFindKey<bool>(jsonObject,
902 jsonObjectEnd,
903 DEVICE_CONFIG_REMOVABLE,
904 deviceConfig.removable.second,
905 JsonType::BOOLEAN,
906 false,
907 g_parseResult,
908 ArrayType::NOT_ARRAY);
909 }
910 if (jsonObject.find(DEVICE_CONFIG_SINGLETON) != jsonObjectEnd) {
911 deviceConfig.singleton.first = true;
912 GetValueIfFindKey<bool>(jsonObject,
913 jsonObjectEnd,
914 DEVICE_CONFIG_SINGLETON,
915 deviceConfig.singleton.second,
916 JsonType::BOOLEAN,
917 false,
918 g_parseResult,
919 ArrayType::NOT_ARRAY);
920 }
921 if (jsonObject.find(DEVICE_CONFIG_USER_DATA_CLEARABLE) != jsonObjectEnd) {
922 deviceConfig.userDataClearable.first = true;
923 GetValueIfFindKey<bool>(jsonObject,
924 jsonObjectEnd,
925 DEVICE_CONFIG_USER_DATA_CLEARABLE,
926 deviceConfig.userDataClearable.second,
927 JsonType::BOOLEAN,
928 false,
929 g_parseResult,
930 ArrayType::NOT_ARRAY);
931 }
932 if (jsonObject.find(DEVICE_CONFIG_ACCESSIBLE) != jsonObjectEnd) {
933 deviceConfig.accessible.first = true;
934 GetValueIfFindKey<bool>(jsonObject,
935 jsonObjectEnd,
936 DEVICE_CONFIG_ACCESSIBLE,
937 deviceConfig.accessible.second,
938 JsonType::BOOLEAN,
939 false,
940 g_parseResult,
941 ArrayType::NOT_ARRAY);
942 }
943 }
944
from_json(const nlohmann::json & jsonObject,MultiAppMode & multiAppMode)945 void from_json(const nlohmann::json &jsonObject, MultiAppMode &multiAppMode)
946 {
947 // these are required fields.
948 const auto &jsonObjectEnd = jsonObject.end();
949 GetValueIfFindKey<std::string>(jsonObject,
950 jsonObjectEnd,
951 MULTI_APP_MODE_TYPE,
952 multiAppMode.multiAppModeType,
953 JsonType::STRING,
954 false,
955 g_parseResult,
956 ArrayType::NOT_ARRAY);
957 GetValueIfFindKey<int32_t>(jsonObject,
958 jsonObjectEnd,
959 MULTI_APP_MODE_MAX_ADDITIONAL_NUMBER,
960 multiAppMode.maxCount,
961 JsonType::NUMBER,
962 false,
963 g_parseResult,
964 ArrayType::NOT_ARRAY);
965 }
966
from_json(const nlohmann::json & jsonObject,App & app)967 void from_json(const nlohmann::json &jsonObject, App &app)
968 {
969 APP_LOGD("read app tag from module.json");
970 const auto &jsonObjectEnd = jsonObject.end();
971 GetValueIfFindKey<std::string>(jsonObject,
972 jsonObjectEnd,
973 APP_BUNDLE_NAME,
974 app.bundleName,
975 JsonType::STRING,
976 true,
977 g_parseResult,
978 ArrayType::NOT_ARRAY);
979 GetValueIfFindKey<std::string>(jsonObject,
980 jsonObjectEnd,
981 ICON,
982 app.icon,
983 JsonType::STRING,
984 true,
985 g_parseResult,
986 ArrayType::NOT_ARRAY);
987 GetValueIfFindKey<std::string>(jsonObject,
988 jsonObjectEnd,
989 LABEL,
990 app.label,
991 JsonType::STRING,
992 true,
993 g_parseResult,
994 ArrayType::NOT_ARRAY);
995 GetValueIfFindKey<int32_t>(jsonObject,
996 jsonObjectEnd,
997 APP_VERSION_CODE,
998 app.versionCode,
999 JsonType::NUMBER,
1000 true,
1001 g_parseResult,
1002 ArrayType::NOT_ARRAY);
1003 GetValueIfFindKey<std::string>(jsonObject,
1004 jsonObjectEnd,
1005 APP_VERSION_NAME,
1006 app.versionName,
1007 JsonType::STRING,
1008 true,
1009 g_parseResult,
1010 ArrayType::NOT_ARRAY);
1011 GetValueIfFindKey<uint32_t>(jsonObject,
1012 jsonObjectEnd,
1013 APP_MIN_API_VERSION,
1014 app.minAPIVersion,
1015 JsonType::NUMBER,
1016 true,
1017 g_parseResult,
1018 ArrayType::NOT_ARRAY);
1019 GetValueIfFindKey<int32_t>(jsonObject,
1020 jsonObjectEnd,
1021 APP_TARGET_API_VERSION,
1022 app.targetAPIVersion,
1023 JsonType::NUMBER,
1024 true,
1025 g_parseResult,
1026 ArrayType::NOT_ARRAY);
1027 GetValueIfFindKey<bool>(jsonObject,
1028 jsonObjectEnd,
1029 APP_DEBUG,
1030 app.debug,
1031 JsonType::BOOLEAN,
1032 false,
1033 g_parseResult,
1034 ArrayType::NOT_ARRAY);
1035 GetValueIfFindKey<uint32_t>(jsonObject,
1036 jsonObjectEnd,
1037 ICON_ID,
1038 app.iconId,
1039 JsonType::NUMBER,
1040 false,
1041 g_parseResult,
1042 ArrayType::NOT_ARRAY);
1043 GetValueIfFindKey<uint32_t>(jsonObject,
1044 jsonObjectEnd,
1045 LABEL_ID,
1046 app.labelId,
1047 JsonType::NUMBER,
1048 false,
1049 g_parseResult,
1050 ArrayType::NOT_ARRAY);
1051 GetValueIfFindKey<std::string>(jsonObject,
1052 jsonObjectEnd,
1053 DESCRIPTION,
1054 app.description,
1055 JsonType::STRING,
1056 false,
1057 g_parseResult,
1058 ArrayType::NOT_ARRAY);
1059 GetValueIfFindKey<uint32_t>(jsonObject,
1060 jsonObjectEnd,
1061 DESCRIPTION_ID,
1062 app.descriptionId,
1063 JsonType::NUMBER,
1064 false,
1065 g_parseResult,
1066 ArrayType::NOT_ARRAY);
1067 GetValueIfFindKey<std::string>(jsonObject,
1068 jsonObjectEnd,
1069 APP_VENDOR,
1070 app.vendor,
1071 JsonType::STRING,
1072 false,
1073 g_parseResult,
1074 ArrayType::NOT_ARRAY);
1075 GetValueIfFindKey<int32_t>(jsonObject,
1076 jsonObjectEnd,
1077 APP_MIN_COMPATIBLE_VERSION_CODE,
1078 app.minCompatibleVersionCode,
1079 JsonType::NUMBER,
1080 false,
1081 g_parseResult,
1082 ArrayType::NOT_ARRAY);
1083 GetValueIfFindKey<std::string>(jsonObject,
1084 jsonObjectEnd,
1085 APP_API_RELEASETYPE,
1086 app.apiReleaseType,
1087 JsonType::STRING,
1088 false,
1089 g_parseResult,
1090 ArrayType::NOT_ARRAY);
1091 GetValueIfFindKey<bool>(jsonObject,
1092 jsonObjectEnd,
1093 APP_KEEP_ALIVE,
1094 app.keepAlive,
1095 JsonType::BOOLEAN,
1096 false,
1097 g_parseResult,
1098 ArrayType::NOT_ARRAY);
1099 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
1100 jsonObjectEnd,
1101 APP_TARGETBUNDLELIST,
1102 app.targetBundleList,
1103 JsonType::ARRAY,
1104 false,
1105 g_parseResult,
1106 ArrayType::STRING);
1107 if (jsonObject.find(APP_REMOVABLE) != jsonObject.end()) {
1108 app.removable.first = true;
1109 GetValueIfFindKey<bool>(jsonObject,
1110 jsonObjectEnd,
1111 APP_REMOVABLE,
1112 app.removable.second,
1113 JsonType::BOOLEAN,
1114 false,
1115 g_parseResult,
1116 ArrayType::NOT_ARRAY);
1117 }
1118 GetValueIfFindKey<bool>(jsonObject,
1119 jsonObjectEnd,
1120 APP_SINGLETON,
1121 app.singleton,
1122 JsonType::BOOLEAN,
1123 false,
1124 g_parseResult,
1125 ArrayType::NOT_ARRAY);
1126 GetValueIfFindKey<bool>(jsonObject,
1127 jsonObjectEnd,
1128 APP_USER_DATA_CLEARABLE,
1129 app.userDataClearable,
1130 JsonType::BOOLEAN,
1131 false,
1132 g_parseResult,
1133 ArrayType::NOT_ARRAY);
1134 GetValueIfFindKey<bool>(jsonObject,
1135 jsonObjectEnd,
1136 APP_ACCESSIBLE,
1137 app.accessible,
1138 JsonType::BOOLEAN,
1139 false,
1140 g_parseResult,
1141 ArrayType::NOT_ARRAY);
1142 GetValueIfFindKey<bool>(jsonObject,
1143 jsonObjectEnd,
1144 APP_ASAN_ENABLED,
1145 app.asanEnabled,
1146 JsonType::BOOLEAN,
1147 false,
1148 g_parseResult,
1149 ArrayType::NOT_ARRAY);
1150 GetValueIfFindKey<std::string>(jsonObject,
1151 jsonObjectEnd,
1152 BUNDLE_TYPE,
1153 app.bundleType,
1154 JsonType::STRING,
1155 false,
1156 g_parseResult,
1157 ArrayType::NOT_ARRAY);
1158 if (jsonObject.find(APP_PHONE) != jsonObjectEnd) {
1159 DeviceConfig deviceConfig;
1160 GetValueIfFindKey<DeviceConfig>(jsonObject,
1161 jsonObjectEnd,
1162 APP_PHONE,
1163 deviceConfig,
1164 JsonType::OBJECT,
1165 false,
1166 g_parseResult,
1167 ArrayType::NOT_ARRAY);
1168 app.deviceConfigs[APP_PHONE] = deviceConfig;
1169 }
1170 if (jsonObject.find(APP_TABLET) != jsonObjectEnd) {
1171 DeviceConfig deviceConfig;
1172 GetValueIfFindKey<DeviceConfig>(jsonObject,
1173 jsonObjectEnd,
1174 APP_TABLET,
1175 deviceConfig,
1176 JsonType::OBJECT,
1177 false,
1178 g_parseResult,
1179 ArrayType::NOT_ARRAY);
1180 app.deviceConfigs[APP_TABLET] = deviceConfig;
1181 }
1182 if (jsonObject.find(APP_TV) != jsonObjectEnd) {
1183 DeviceConfig deviceConfig;
1184 GetValueIfFindKey<DeviceConfig>(jsonObject,
1185 jsonObjectEnd,
1186 APP_TV,
1187 deviceConfig,
1188 JsonType::OBJECT,
1189 false,
1190 g_parseResult,
1191 ArrayType::NOT_ARRAY);
1192 app.deviceConfigs[APP_TV] = deviceConfig;
1193 }
1194 if (jsonObject.find(APP_WEARABLE) != jsonObjectEnd) {
1195 DeviceConfig deviceConfig;
1196 GetValueIfFindKey<DeviceConfig>(jsonObject,
1197 jsonObjectEnd,
1198 APP_WEARABLE,
1199 deviceConfig,
1200 JsonType::OBJECT,
1201 false,
1202 g_parseResult,
1203 ArrayType::NOT_ARRAY);
1204 app.deviceConfigs[APP_WEARABLE] = deviceConfig;
1205 }
1206 if (jsonObject.find(APP_LITE_WEARABLE) != jsonObjectEnd) {
1207 DeviceConfig deviceConfig;
1208 GetValueIfFindKey<DeviceConfig>(jsonObject,
1209 jsonObjectEnd,
1210 APP_LITE_WEARABLE,
1211 deviceConfig,
1212 JsonType::OBJECT,
1213 false,
1214 g_parseResult,
1215 ArrayType::NOT_ARRAY);
1216 app.deviceConfigs[APP_LITE_WEARABLE] = deviceConfig;
1217 }
1218 if (jsonObject.find(APP_CAR) != jsonObjectEnd) {
1219 DeviceConfig deviceConfig;
1220 GetValueIfFindKey<DeviceConfig>(jsonObject,
1221 jsonObjectEnd,
1222 APP_CAR,
1223 deviceConfig,
1224 JsonType::OBJECT,
1225 false,
1226 g_parseResult,
1227 ArrayType::NOT_ARRAY);
1228 app.deviceConfigs[APP_CAR] = deviceConfig;
1229 }
1230 if (jsonObject.find(APP_SMART_VISION) != jsonObjectEnd) {
1231 DeviceConfig deviceConfig;
1232 GetValueIfFindKey<DeviceConfig>(jsonObject,
1233 jsonObjectEnd,
1234 APP_SMART_VISION,
1235 deviceConfig,
1236 JsonType::OBJECT,
1237 false,
1238 g_parseResult,
1239 ArrayType::NOT_ARRAY);
1240 app.deviceConfigs[APP_SMART_VISION] = deviceConfig;
1241 }
1242 if (jsonObject.find(APP_ROUTER) != jsonObjectEnd) {
1243 DeviceConfig deviceConfig;
1244 GetValueIfFindKey<DeviceConfig>(jsonObject,
1245 jsonObjectEnd,
1246 APP_ROUTER,
1247 deviceConfig,
1248 JsonType::OBJECT,
1249 false,
1250 g_parseResult,
1251 ArrayType::NOT_ARRAY);
1252 app.deviceConfigs[APP_ROUTER] = deviceConfig;
1253 }
1254 if (jsonObject.find(APP_TWO_IN_ONE) != jsonObjectEnd) {
1255 DeviceConfig deviceConfig;
1256 GetValueIfFindKey<DeviceConfig>(jsonObject,
1257 jsonObjectEnd,
1258 APP_TWO_IN_ONE,
1259 deviceConfig,
1260 JsonType::OBJECT,
1261 false,
1262 g_parseResult,
1263 ArrayType::NOT_ARRAY);
1264 app.deviceConfigs[APP_TWO_IN_ONE] = deviceConfig;
1265 }
1266 GetValueIfFindKey<bool>(jsonObject,
1267 jsonObjectEnd,
1268 APP_MULTI_PROJECTS,
1269 app.multiProjects,
1270 JsonType::BOOLEAN,
1271 false,
1272 g_parseResult,
1273 ArrayType::NOT_ARRAY);
1274 GetValueIfFindKey<std::string>(jsonObject,
1275 jsonObjectEnd,
1276 APP_TARGET_BUNDLE_NAME,
1277 app.targetBundle,
1278 JsonType::STRING,
1279 false,
1280 g_parseResult,
1281 ArrayType::NOT_ARRAY);
1282 GetValueIfFindKey<int32_t>(jsonObject,
1283 jsonObjectEnd,
1284 APP_TARGET_PRIORITY,
1285 app.targetPriority,
1286 JsonType::NUMBER,
1287 false,
1288 g_parseResult,
1289 ArrayType::NOT_ARRAY);
1290 GetValueIfFindKey<std::string>(jsonObject,
1291 jsonObjectEnd,
1292 COMPILE_SDK_VERSION,
1293 app.compileSdkVersion,
1294 JsonType::STRING,
1295 false,
1296 g_parseResult,
1297 ArrayType::NOT_ARRAY);
1298 GetValueIfFindKey<std::string>(jsonObject,
1299 jsonObjectEnd,
1300 COMPILE_SDK_TYPE,
1301 app.compileSdkType,
1302 JsonType::STRING,
1303 false,
1304 g_parseResult,
1305 ArrayType::NOT_ARRAY);
1306 GetValueIfFindKey<bool>(jsonObject,
1307 jsonObjectEnd,
1308 APP_GWP_ASAN_ENABLED,
1309 app.gwpAsanEnabled,
1310 JsonType::BOOLEAN,
1311 false,
1312 g_parseResult,
1313 ArrayType::NOT_ARRAY);
1314 GetValueIfFindKey<bool>(jsonObject,
1315 jsonObjectEnd,
1316 APP_TSAN_ENABLED,
1317 app.tsanEnabled,
1318 JsonType::BOOLEAN,
1319 false,
1320 g_parseResult,
1321 ArrayType::NOT_ARRAY);
1322 GetValueIfFindKey<std::vector<ApplicationEnvironment>>(jsonObject,
1323 jsonObjectEnd,
1324 MODULE_APP_ENVIRONMENTS,
1325 app.appEnvironments,
1326 JsonType::ARRAY,
1327 false,
1328 g_parseResult,
1329 ArrayType::OBJECT);
1330 GetValueIfFindKey<MultiAppMode>(jsonObject,
1331 jsonObjectEnd,
1332 APP_MULTI_APP_MODE,
1333 app.multiAppMode,
1334 JsonType::OBJECT,
1335 false,
1336 g_parseResult,
1337 ArrayType::NOT_ARRAY);
1338 GetValueIfFindKey<int32_t>(jsonObject,
1339 jsonObjectEnd,
1340 APP_MAX_CHILD_PROCESS,
1341 app.maxChildProcess,
1342 JsonType::NUMBER,
1343 false,
1344 g_parseResult,
1345 ArrayType::NOT_ARRAY);
1346 GetValueIfFindKey<bool>(jsonObject,
1347 jsonObjectEnd,
1348 APP_HWASAN_ENABLED,
1349 app.hwasanEnabled,
1350 JsonType::BOOLEAN,
1351 false,
1352 g_parseResult,
1353 ArrayType::NOT_ARRAY);
1354 GetValueIfFindKey<std::string>(jsonObject,
1355 jsonObjectEnd,
1356 APP_CONFIGURATION,
1357 app.configuration,
1358 JsonType::STRING,
1359 false,
1360 g_parseResult,
1361 ArrayType::NOT_ARRAY);
1362 GetValueIfFindKey<bool>(jsonObject,
1363 jsonObjectEnd,
1364 APP_CLOUD_FILE_SYNC_ENABLED,
1365 app.cloudFileSyncEnabled,
1366 JsonType::BOOLEAN,
1367 false,
1368 g_parseResult,
1369 ArrayType::NOT_ARRAY);
1370 }
1371
from_json(const nlohmann::json & jsonObject,Module & module)1372 void from_json(const nlohmann::json &jsonObject, Module &module)
1373 {
1374 APP_LOGD("read module tag from module.json");
1375 const auto &jsonObjectEnd = jsonObject.end();
1376 GetValueIfFindKey<std::string>(jsonObject,
1377 jsonObjectEnd,
1378 MODULE_NAME,
1379 module.name,
1380 JsonType::STRING,
1381 true,
1382 g_parseResult,
1383 ArrayType::NOT_ARRAY);
1384 GetValueIfFindKey<std::string>(jsonObject,
1385 jsonObjectEnd,
1386 MODULE_TYPE,
1387 module.type,
1388 JsonType::STRING,
1389 true,
1390 g_parseResult,
1391 ArrayType::NOT_ARRAY);
1392 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
1393 jsonObjectEnd,
1394 MODULE_DEVICE_TYPES,
1395 module.deviceTypes,
1396 JsonType::ARRAY,
1397 true,
1398 g_parseResult,
1399 ArrayType::STRING);
1400 GetValueIfFindKey<bool>(jsonObject,
1401 jsonObjectEnd,
1402 MODULE_DELIVERY_WITH_INSTALL,
1403 module.deliveryWithInstall,
1404 JsonType::BOOLEAN,
1405 true,
1406 g_parseResult,
1407 ArrayType::NOT_ARRAY);
1408 GetValueIfFindKey<std::string>(jsonObject,
1409 jsonObjectEnd,
1410 MODULE_PAGES,
1411 module.pages,
1412 JsonType::STRING,
1413 false,
1414 g_parseResult,
1415 ArrayType::NOT_ARRAY);
1416 // both srcEntry and srcEntrance can be configured, but srcEntry has higher priority
1417 if (jsonObject.find(SRC_ENTRY) != jsonObject.end()) {
1418 GetValueIfFindKey<std::string>(jsonObject,
1419 jsonObjectEnd,
1420 SRC_ENTRY,
1421 module.srcEntrance,
1422 JsonType::STRING,
1423 false,
1424 g_parseResult,
1425 ArrayType::NOT_ARRAY);
1426 } else {
1427 GetValueIfFindKey<std::string>(jsonObject,
1428 jsonObjectEnd,
1429 SRC_ENTRANCE,
1430 module.srcEntrance,
1431 JsonType::STRING,
1432 false,
1433 g_parseResult,
1434 ArrayType::NOT_ARRAY);
1435 }
1436 GetValueIfFindKey<std::string>(jsonObject,
1437 jsonObjectEnd,
1438 DESCRIPTION,
1439 module.description,
1440 JsonType::STRING,
1441 false,
1442 g_parseResult,
1443 ArrayType::NOT_ARRAY);
1444 GetValueIfFindKey<uint32_t>(jsonObject,
1445 jsonObjectEnd,
1446 DESCRIPTION_ID,
1447 module.descriptionId,
1448 JsonType::NUMBER,
1449 false,
1450 g_parseResult,
1451 ArrayType::NOT_ARRAY);
1452 GetValueIfFindKey<std::string>(jsonObject,
1453 jsonObjectEnd,
1454 MODULE_PROCESS,
1455 module.process,
1456 JsonType::STRING,
1457 false,
1458 g_parseResult,
1459 ArrayType::NOT_ARRAY);
1460 GetValueIfFindKey<std::string>(jsonObject,
1461 jsonObjectEnd,
1462 MODULE_MAIN_ELEMENT,
1463 module.mainElement,
1464 JsonType::STRING,
1465 false,
1466 g_parseResult,
1467 ArrayType::NOT_ARRAY);
1468 GetValueIfFindKey<bool>(jsonObject,
1469 jsonObjectEnd,
1470 MODULE_INSTALLATION_FREE,
1471 module.installationFree,
1472 JsonType::BOOLEAN,
1473 false,
1474 g_parseResult,
1475 ArrayType::NOT_ARRAY);
1476 GetValueIfFindKey<std::string>(jsonObject,
1477 jsonObjectEnd,
1478 MODULE_VIRTUAL_MACHINE,
1479 module.virtualMachine,
1480 JsonType::STRING,
1481 false,
1482 g_parseResult,
1483 ArrayType::NOT_ARRAY);
1484 GetValueIfFindKey<std::vector<Metadata>>(jsonObject,
1485 jsonObjectEnd,
1486 META_DATA,
1487 module.metadata,
1488 JsonType::ARRAY,
1489 false,
1490 g_parseResult,
1491 ArrayType::OBJECT);
1492 GetValueIfFindKey<std::vector<HnpPackage>>(jsonObject,
1493 jsonObjectEnd,
1494 MODULE_HNP_PACKAGE,
1495 module.hnpPackages,
1496 JsonType::ARRAY,
1497 false,
1498 g_parseResult,
1499 ArrayType::OBJECT);
1500 GetValueIfFindKey<std::vector<Ability>>(jsonObject,
1501 jsonObjectEnd,
1502 MODULE_ABILITIES,
1503 module.abilities,
1504 JsonType::ARRAY,
1505 false,
1506 g_parseResult,
1507 ArrayType::OBJECT);
1508 GetValueIfFindKey<std::vector<Extension>>(jsonObject,
1509 jsonObjectEnd,
1510 MODULE_EXTENSION_ABILITIES,
1511 module.extensionAbilities,
1512 JsonType::ARRAY,
1513 false,
1514 g_parseResult,
1515 ArrayType::OBJECT);
1516 GetValueIfFindKey<std::vector<RequestPermission>>(jsonObject,
1517 jsonObjectEnd,
1518 MODULE_REQUEST_PERMISSIONS,
1519 module.requestPermissions,
1520 JsonType::ARRAY,
1521 false,
1522 g_parseResult,
1523 ArrayType::OBJECT);
1524 GetValueIfFindKey<std::vector<DefinePermission>>(jsonObject,
1525 jsonObjectEnd,
1526 MODULE_DEFINE_PERMISSIONS,
1527 module.definePermissions,
1528 JsonType::ARRAY,
1529 false,
1530 g_parseResult,
1531 ArrayType::OBJECT);
1532 GetValueIfFindKey<std::vector<Dependency>>(jsonObject,
1533 jsonObjectEnd,
1534 MODULE_DEPENDENCIES,
1535 module.dependencies,
1536 JsonType::ARRAY,
1537 false,
1538 g_parseResult,
1539 ArrayType::OBJECT);
1540 GetValueIfFindKey<std::string>(jsonObject,
1541 jsonObjectEnd,
1542 MODULE_COMPILE_MODE,
1543 module.compileMode,
1544 JsonType::STRING,
1545 false,
1546 g_parseResult,
1547 ArrayType::NOT_ARRAY);
1548 GetValueIfFindKey<bool>(jsonObject,
1549 jsonObjectEnd,
1550 MODULE_IS_LIB_ISOLATED,
1551 module.isLibIsolated,
1552 JsonType::BOOLEAN,
1553 false,
1554 g_parseResult,
1555 ArrayType::NOT_ARRAY);
1556 GetValueIfFindKey<std::string>(jsonObject,
1557 jsonObjectEnd,
1558 MODULE_TARGET_MODULE_NAME,
1559 module.targetModule,
1560 JsonType::STRING,
1561 false,
1562 g_parseResult,
1563 ArrayType::NOT_ARRAY);
1564 GetValueIfFindKey<int32_t>(jsonObject,
1565 jsonObjectEnd,
1566 MODULE_TARGET_PRIORITY,
1567 module.targetPriority,
1568 JsonType::NUMBER,
1569 false,
1570 g_parseResult,
1571 ArrayType::NOT_ARRAY);
1572 GetValueIfFindKey<std::vector<ProxyData>>(jsonObject,
1573 jsonObjectEnd,
1574 MODULE_PROXY_DATAS,
1575 module.proxyDatas,
1576 JsonType::ARRAY,
1577 false,
1578 g_parseResult,
1579 ArrayType::OBJECT);
1580 GetValueIfFindKey<std::vector<ProxyData>>(jsonObject,
1581 jsonObjectEnd,
1582 MODULE_PROXY_DATA,
1583 module.proxyData,
1584 JsonType::ARRAY,
1585 false,
1586 g_parseResult,
1587 ArrayType::OBJECT);
1588 GetValueIfFindKey<std::string>(jsonObject,
1589 jsonObjectEnd,
1590 MODULE_BUILD_HASH,
1591 module.buildHash,
1592 JsonType::STRING,
1593 false,
1594 g_parseResult,
1595 ArrayType::NOT_ARRAY);
1596 GetValueIfFindKey<std::string>(jsonObject,
1597 jsonObjectEnd,
1598 MODULE_ISOLATION_MODE,
1599 module.isolationMode,
1600 JsonType::STRING,
1601 false,
1602 g_parseResult,
1603 ArrayType::NOT_ARRAY);
1604 if (IsSupportCompressNativeLibs()) {
1605 GetValueIfFindKey<bool>(jsonObject,
1606 jsonObjectEnd,
1607 MODULE_COMPRESS_NATIVE_LIBS,
1608 module.compressNativeLibs,
1609 JsonType::BOOLEAN,
1610 false,
1611 g_parseResult,
1612 ArrayType::NOT_ARRAY);
1613 }
1614 GetValueIfFindKey<std::string>(jsonObject,
1615 jsonObjectEnd,
1616 MODULE_FILE_CONTEXT_MENU,
1617 module.fileContextMenu,
1618 JsonType::STRING,
1619 false,
1620 g_parseResult,
1621 ArrayType::NOT_ARRAY);
1622 GetValueIfFindKey<std::vector<std::string>>(jsonObject,
1623 jsonObjectEnd,
1624 MODULE_QUERY_SCHEMES,
1625 module.querySchemes,
1626 JsonType::ARRAY,
1627 false,
1628 g_parseResult,
1629 ArrayType::STRING);
1630 GetValueIfFindKey<std::string>(jsonObject,
1631 jsonObjectEnd,
1632 MODULE_ROUTER_MAP,
1633 module.routerMap,
1634 JsonType::STRING,
1635 false,
1636 g_parseResult,
1637 ArrayType::NOT_ARRAY);
1638 GetValueIfFindKey<std::vector<AppEnvironment>>(jsonObject,
1639 jsonObjectEnd,
1640 MODULE_APP_ENVIRONMENTS,
1641 module.appEnvironments,
1642 JsonType::ARRAY,
1643 false,
1644 g_parseResult,
1645 ArrayType::OBJECT);
1646 GetValueIfFindKey<std::string>(jsonObject,
1647 jsonObjectEnd,
1648 MODULE_PACKAGE_NAME,
1649 module.packageName,
1650 JsonType::STRING,
1651 false,
1652 g_parseResult,
1653 ArrayType::NOT_ARRAY);
1654 GetValueIfFindKey<std::string>(jsonObject,
1655 jsonObjectEnd,
1656 MODULE_APP_STARTUP,
1657 module.appStartup,
1658 JsonType::STRING,
1659 false,
1660 g_parseResult,
1661 ArrayType::NOT_ARRAY);
1662 }
1663
from_json(const nlohmann::json & jsonObject,ModuleJson & moduleJson)1664 void from_json(const nlohmann::json &jsonObject, ModuleJson &moduleJson)
1665 {
1666 const auto &jsonObjectEnd = jsonObject.end();
1667 GetValueIfFindKey<App>(jsonObject,
1668 jsonObjectEnd,
1669 APP,
1670 moduleJson.app,
1671 JsonType::OBJECT,
1672 true,
1673 g_parseResult,
1674 ArrayType::NOT_ARRAY);
1675 GetValueIfFindKey<Module>(jsonObject,
1676 jsonObjectEnd,
1677 MODULE,
1678 moduleJson.module,
1679 JsonType::OBJECT,
1680 true,
1681 g_parseResult,
1682 ArrayType::NOT_ARRAY);
1683 }
1684 } // namespace Profile
1685
1686 namespace {
1687 struct TransformParam {
1688 bool isSystemApp = false;
1689 bool isPreInstallApp = false;
1690 };
1691
GetMetadata(std::vector<Metadata> & metadata,const std::vector<Profile::Metadata> & profileMetadata)1692 void GetMetadata(std::vector<Metadata> &metadata, const std::vector<Profile::Metadata> &profileMetadata)
1693 {
1694 for (const Profile::Metadata &item : profileMetadata) {
1695 Metadata tmpMetadata;
1696 tmpMetadata.name = item.name;
1697 tmpMetadata.value = item.value;
1698 tmpMetadata.resource = item.resource;
1699 metadata.emplace_back(tmpMetadata);
1700 }
1701 }
1702
GetHnpPackage(std::vector<HnpPackage> & hnpPackage,const std::vector<Profile::HnpPackage> & profileHnpPackage)1703 void GetHnpPackage(std::vector<HnpPackage> &hnpPackage, const std::vector<Profile::HnpPackage> &profileHnpPackage)
1704 {
1705 for (const Profile::HnpPackage &item : profileHnpPackage) {
1706 HnpPackage tmpHnpPackage;
1707 tmpHnpPackage.package = item.package;
1708 tmpHnpPackage.type = item.type;
1709 hnpPackage.emplace_back(tmpHnpPackage);
1710 }
1711 }
1712
CheckBundleNameIsValid(const std::string & bundleName)1713 bool CheckBundleNameIsValid(const std::string &bundleName)
1714 {
1715 if (bundleName.empty()) {
1716 APP_LOGE("bundleName is empty");
1717 return false;
1718 }
1719 if (bundleName.size() < Constants::MIN_BUNDLE_NAME || bundleName.size() > Constants::MAX_BUNDLE_NAME) {
1720 APP_LOGE("bundleName size too long or too short");
1721 return false;
1722 }
1723 char head = bundleName.at(0);
1724 if (!isalpha(head)) {
1725 return false;
1726 }
1727 for (const auto &c : bundleName) {
1728 if (!isalnum(c) && (c != '.') && (c != '_')) {
1729 return false;
1730 }
1731 }
1732 return true;
1733 }
1734
CheckModuleNameIsValid(const std::string & moduleName)1735 bool CheckModuleNameIsValid(const std::string &moduleName)
1736 {
1737 if (moduleName.empty()) {
1738 APP_LOGE("module name is empty");
1739 return false;
1740 }
1741 if (moduleName.size() > MAX_MODULE_NAME) {
1742 APP_LOGE("module name size too long");
1743 return false;
1744 }
1745 if (moduleName.find(ServiceConstants::RELATIVE_PATH) != std::string::npos) {
1746 return false;
1747 }
1748 if (moduleName.find(ServiceConstants::MODULE_NAME_SEPARATOR) != std::string::npos) {
1749 APP_LOGE("module name should not contain ,");
1750 return false;
1751 }
1752 return true;
1753 }
1754
UpdateNativeSoAttrs(const std::string & cpuAbi,const std::string & soRelativePath,bool isLibIsolated,InnerBundleInfo & innerBundleInfo)1755 void UpdateNativeSoAttrs(
1756 const std::string &cpuAbi,
1757 const std::string &soRelativePath,
1758 bool isLibIsolated,
1759 InnerBundleInfo &innerBundleInfo)
1760 {
1761 APP_LOGD("cpuAbi %{public}s, soRelativePath : %{public}s, isLibIsolated : %{public}d",
1762 cpuAbi.c_str(), soRelativePath.c_str(), isLibIsolated);
1763 innerBundleInfo.SetCpuAbi(cpuAbi);
1764 if (!innerBundleInfo.IsCompressNativeLibs(innerBundleInfo.GetCurModuleName())) {
1765 APP_LOGD("UpdateNativeSoAttrs compressNativeLibs is false, no need to decompress so");
1766 if (!isLibIsolated) {
1767 innerBundleInfo.SetNativeLibraryPath(soRelativePath);
1768 }
1769 if (!soRelativePath.empty()) {
1770 innerBundleInfo.SetModuleNativeLibraryPath(ServiceConstants::LIBS + cpuAbi);
1771 innerBundleInfo.SetSharedModuleNativeLibraryPath(ServiceConstants::LIBS + cpuAbi);
1772 }
1773 innerBundleInfo.SetModuleCpuAbi(cpuAbi);
1774 return;
1775 }
1776 if (!isLibIsolated) {
1777 innerBundleInfo.SetNativeLibraryPath(soRelativePath);
1778 return;
1779 }
1780
1781 innerBundleInfo.SetModuleNativeLibraryPath(
1782 innerBundleInfo.GetCurModuleName() + ServiceConstants::PATH_SEPARATOR + soRelativePath);
1783 innerBundleInfo.SetSharedModuleNativeLibraryPath(
1784 innerBundleInfo.GetCurModuleName() + ServiceConstants::PATH_SEPARATOR + soRelativePath);
1785 innerBundleInfo.SetModuleCpuAbi(cpuAbi);
1786 }
1787
ParserNativeSo(const Profile::ModuleJson & moduleJson,const BundleExtractor & bundleExtractor,InnerBundleInfo & innerBundleInfo)1788 bool ParserNativeSo(
1789 const Profile::ModuleJson &moduleJson,
1790 const BundleExtractor &bundleExtractor,
1791 InnerBundleInfo &innerBundleInfo)
1792 {
1793 std::string abis = GetAbiList();
1794 std::vector<std::string> abiList;
1795 SplitStr(abis, ServiceConstants::ABI_SEPARATOR, abiList, false, false);
1796 if (abiList.empty()) {
1797 APP_LOGD("Abi is empty");
1798 return false;
1799 }
1800
1801 bool isDefault =
1802 std::find(abiList.begin(), abiList.end(), ServiceConstants::ABI_DEFAULT) != abiList.end();
1803 bool isSystemLib64Exist = BundleUtil::IsExistDir(ServiceConstants::SYSTEM_LIB64);
1804 APP_LOGD("abi list : %{public}s, isDefault : %{public}d", abis.c_str(), isDefault);
1805 std::string cpuAbi;
1806 std::string soRelativePath;
1807 bool soExist = bundleExtractor.IsDirExist(ServiceConstants::LIBS);
1808 if (!soExist) {
1809 APP_LOGD("so not exist");
1810 if (isDefault) {
1811 cpuAbi = isSystemLib64Exist ? ServiceConstants::ARM64_V8A : ServiceConstants::ARM_EABI_V7A;
1812 UpdateNativeSoAttrs(cpuAbi, soRelativePath, false, innerBundleInfo);
1813 return true;
1814 }
1815
1816 for (const auto &abi : abiList) {
1817 if (ServiceConstants::ABI_MAP.find(abi) != ServiceConstants::ABI_MAP.end()) {
1818 cpuAbi = abi;
1819 UpdateNativeSoAttrs(cpuAbi, soRelativePath, false, innerBundleInfo);
1820 return true;
1821 }
1822 }
1823
1824 return false;
1825 }
1826
1827 APP_LOGD("so exist");
1828 bool isLibIsolated = moduleJson.module.isLibIsolated;
1829 if (isDefault) {
1830 if (isSystemLib64Exist) {
1831 if (bundleExtractor.IsDirExist(ServiceConstants::LIBS + ServiceConstants::ARM64_V8A)) {
1832 cpuAbi = ServiceConstants::ARM64_V8A;
1833 soRelativePath = ServiceConstants::LIBS + ServiceConstants::ABI_MAP.at(ServiceConstants::ARM64_V8A);
1834 UpdateNativeSoAttrs(cpuAbi, soRelativePath, isLibIsolated, innerBundleInfo);
1835 return true;
1836 }
1837
1838 return false;
1839 }
1840
1841 if (bundleExtractor.IsDirExist(ServiceConstants::LIBS + ServiceConstants::ARM_EABI_V7A)) {
1842 cpuAbi = ServiceConstants::ARM_EABI_V7A;
1843 soRelativePath = ServiceConstants::LIBS + ServiceConstants::ABI_MAP.at(ServiceConstants::ARM_EABI_V7A);
1844 UpdateNativeSoAttrs(cpuAbi, soRelativePath, isLibIsolated, innerBundleInfo);
1845 return true;
1846 }
1847
1848 if (bundleExtractor.IsDirExist(ServiceConstants::LIBS + ServiceConstants::ARM_EABI)) {
1849 cpuAbi = ServiceConstants::ARM_EABI;
1850 soRelativePath = ServiceConstants::LIBS + ServiceConstants::ABI_MAP.at(ServiceConstants::ARM_EABI);
1851 UpdateNativeSoAttrs(cpuAbi, soRelativePath, isLibIsolated, innerBundleInfo);
1852 return true;
1853 }
1854
1855 return false;
1856 }
1857
1858 for (const auto &abi : abiList) {
1859 std::string libsPath;
1860 libsPath.append(ServiceConstants::LIBS).append(abi).append(ServiceConstants::PATH_SEPARATOR);
1861 if (ServiceConstants::ABI_MAP.find(abi) != ServiceConstants::ABI_MAP.end() &&
1862 bundleExtractor.IsDirExist(libsPath)) {
1863 cpuAbi = abi;
1864 soRelativePath = ServiceConstants::LIBS + ServiceConstants::ABI_MAP.at(abi);
1865 UpdateNativeSoAttrs(cpuAbi, soRelativePath, isLibIsolated, innerBundleInfo);
1866 return true;
1867 }
1868 }
1869
1870 return false;
1871 }
1872
ParserAtomicModuleConfig(const nlohmann::json & jsonObject,InnerBundleInfo & innerBundleInfo)1873 bool ParserAtomicModuleConfig(const nlohmann::json &jsonObject, InnerBundleInfo &innerBundleInfo)
1874 {
1875 nlohmann::json moduleJson = jsonObject.at(Profile::MODULE);
1876 std::vector<std::string> preloads;
1877 std::string moduleName = moduleJson.at(Profile::MODULE_NAME);
1878 if (moduleJson.contains(Profile::MODULE_ATOMIC_SERVICE)) {
1879 nlohmann::json moduleAtomicObj = moduleJson.at(Profile::MODULE_ATOMIC_SERVICE);
1880 if (moduleAtomicObj.contains(Profile::MODULE_ATOMIC_SERVICE_PRELOADS)) {
1881 nlohmann::json preloadObj = moduleAtomicObj.at(Profile::MODULE_ATOMIC_SERVICE_PRELOADS);
1882 if (preloadObj.empty()) {
1883 APP_LOGD("preloadObj is empty");
1884 return true;
1885 }
1886 if (preloadObj.size() > Constants::MAX_JSON_ARRAY_LENGTH) {
1887 APP_LOGE("preloads config in module.json is oversize");
1888 return false;
1889 }
1890 for (const auto &preload : preloadObj) {
1891 if (preload.contains(Profile::PRELOADS_MODULE_NAME)) {
1892 std::string preloadName = preload.at(Profile::PRELOADS_MODULE_NAME);
1893 preloads.emplace_back(preloadName);
1894 } else {
1895 APP_LOGE("preloads must have moduleName");
1896 return false;
1897 }
1898 }
1899 }
1900 }
1901 innerBundleInfo.SetInnerModuleAtomicPreload(moduleName, preloads);
1902 return true;
1903 }
1904
ParserAtomicConfig(const nlohmann::json & jsonObject,InnerBundleInfo & innerBundleInfo)1905 bool ParserAtomicConfig(const nlohmann::json &jsonObject, InnerBundleInfo &innerBundleInfo)
1906 {
1907 if (!jsonObject.contains(Profile::MODULE) || !jsonObject.contains(Profile::APP)) {
1908 APP_LOGE("ParserAtomicConfig failed due to bad module.json");
1909 return false;
1910 }
1911 nlohmann::json appJson = jsonObject.at(Profile::APP);
1912 nlohmann::json moduleJson = jsonObject.at(Profile::MODULE);
1913 if (!moduleJson.is_object() || !appJson.is_object()) {
1914 APP_LOGE("module.json file lacks of invalid module or app properties");
1915 return false;
1916 }
1917 BundleType bundleType = BundleType::APP;
1918 if (appJson.contains(Profile::BUNDLE_TYPE)) {
1919 if (appJson.at(Profile::BUNDLE_TYPE) == Profile::BUNDLE_TYPE_ATOMIC_SERVICE) {
1920 bundleType = BundleType::ATOMIC_SERVICE;
1921 } else if (appJson.at(Profile::BUNDLE_TYPE) == Profile::BUNDLE_TYPE_SHARED) {
1922 bundleType = BundleType::SHARED;
1923 } else if (appJson.at(Profile::BUNDLE_TYPE) == Profile::BUNDLE_TYPE_APP_SERVICE_FWK) {
1924 bundleType = BundleType::APP_SERVICE_FWK;
1925 }
1926 }
1927
1928 innerBundleInfo.SetApplicationBundleType(bundleType);
1929 if (!ParserAtomicModuleConfig(jsonObject, innerBundleInfo)) {
1930 APP_LOGE("parse module atomicService failed");
1931 return false;
1932 }
1933 return true;
1934 }
1935
ParserArkNativeFilePath(const Profile::ModuleJson & moduleJson,const BundleExtractor & bundleExtractor,InnerBundleInfo & innerBundleInfo)1936 bool ParserArkNativeFilePath(
1937 const Profile::ModuleJson &moduleJson,
1938 const BundleExtractor &bundleExtractor,
1939 InnerBundleInfo &innerBundleInfo)
1940 {
1941 std::string abis = GetAbiList();
1942 std::vector<std::string> abiList;
1943 SplitStr(abis, ServiceConstants::ABI_SEPARATOR, abiList, false, false);
1944 if (abiList.empty()) {
1945 APP_LOGD("Abi is empty");
1946 return false;
1947 }
1948
1949 bool isDefault =
1950 std::find(abiList.begin(), abiList.end(), ServiceConstants::ABI_DEFAULT) != abiList.end();
1951 bool isSystemLib64Exist = BundleUtil::IsExistDir(ServiceConstants::SYSTEM_LIB64);
1952 APP_LOGD("abi list : %{public}s, isDefault : %{public}d", abis.c_str(), isDefault);
1953 bool anExist = bundleExtractor.IsDirExist(ServiceConstants::AN);
1954 if (!anExist) {
1955 APP_LOGD("an not exist");
1956 return true;
1957 }
1958
1959 APP_LOGD("an exist");
1960 if (isDefault) {
1961 if (isSystemLib64Exist) {
1962 if (bundleExtractor.IsDirExist(ServiceConstants::AN + ServiceConstants::ARM64_V8A)) {
1963 innerBundleInfo.SetArkNativeFileAbi(ServiceConstants::ARM64_V8A);
1964 return true;
1965 }
1966
1967 return false;
1968 }
1969
1970 if (bundleExtractor.IsDirExist(ServiceConstants::AN + ServiceConstants::ARM_EABI_V7A)) {
1971 innerBundleInfo.SetArkNativeFileAbi(ServiceConstants::ARM_EABI_V7A);
1972 return true;
1973 }
1974
1975 if (bundleExtractor.IsDirExist(ServiceConstants::AN + ServiceConstants::ARM_EABI)) {
1976 innerBundleInfo.SetArkNativeFileAbi(ServiceConstants::ARM_EABI);
1977 return true;
1978 }
1979
1980 return false;
1981 }
1982
1983 for (const auto &abi : abiList) {
1984 std::string libsPath;
1985 libsPath.append(ServiceConstants::AN).append(abi).append(ServiceConstants::PATH_SEPARATOR);
1986 if (ServiceConstants::ABI_MAP.find(abi) != ServiceConstants::ABI_MAP.end() &&
1987 bundleExtractor.IsDirExist(libsPath)) {
1988 innerBundleInfo.SetArkNativeFileAbi(abi);
1989 return true;
1990 }
1991 }
1992
1993 return false;
1994 }
1995
ToMultiAppModeType(const std::string & type)1996 MultiAppModeType ToMultiAppModeType(const std::string &type)
1997 {
1998 auto iter = Profile::MULTI_APP_MODE_MAP.find(type);
1999 if (iter != Profile::MULTI_APP_MODE_MAP.end()) {
2000 return iter->second;
2001 }
2002 return MultiAppModeType::UNSPECIFIED;
2003 }
2004
ToInnerProfileConfiguration(const BundleExtractor & bundleExtractor,const std::string & configuration,std::string & result)2005 bool ToInnerProfileConfiguration(
2006 const BundleExtractor &bundleExtractor,
2007 const std::string &configuration,
2008 std::string &result)
2009 {
2010 constexpr const char* PROFILE_PATH = "resources/base/profile/";
2011 constexpr const char* PROFILE_PREFIX = "$profile:";
2012 constexpr const char* JSON_SUFFIX = ".json";
2013 auto pos = configuration.find(PROFILE_PREFIX);
2014 if (pos == std::string::npos) {
2015 APP_LOGD("invalid profile configuration");
2016 return false;
2017 }
2018 std::string profileConfiguration = configuration.substr(pos + strlen(PROFILE_PREFIX));
2019 std::string profilePath = PROFILE_PATH + profileConfiguration + JSON_SUFFIX;
2020
2021 if (!bundleExtractor.HasEntry(profilePath)) {
2022 APP_LOGE("profile not exist");
2023 return false;
2024 }
2025 std::stringstream profileStream;
2026 if (!bundleExtractor.ExtractByName(profilePath, profileStream)) {
2027 APP_LOGE("extract profile failed");
2028 return false;
2029 }
2030 result = profileStream.str();
2031 return true;
2032 }
2033
ToApplicationInfo(const Profile::ModuleJson & moduleJson,const BundleExtractor & bundleExtractor,const TransformParam & transformParam,ApplicationInfo & applicationInfo)2034 bool ToApplicationInfo(
2035 const Profile::ModuleJson &moduleJson,
2036 const BundleExtractor &bundleExtractor,
2037 const TransformParam &transformParam,
2038 ApplicationInfo &applicationInfo)
2039 {
2040 APP_LOGD("transform ModuleJson to ApplicationInfo");
2041 auto app = moduleJson.app;
2042 applicationInfo.name = app.bundleName;
2043 applicationInfo.bundleName = app.bundleName;
2044
2045 applicationInfo.versionCode = static_cast<uint32_t>(app.versionCode);
2046 applicationInfo.versionName = app.versionName;
2047 if (app.minCompatibleVersionCode != -1) {
2048 applicationInfo.minCompatibleVersionCode = app.minCompatibleVersionCode;
2049 } else {
2050 applicationInfo.minCompatibleVersionCode = static_cast<int32_t>(applicationInfo.versionCode);
2051 }
2052
2053 applicationInfo.apiCompatibleVersion = app.minAPIVersion;
2054 applicationInfo.apiTargetVersion = app.targetAPIVersion;
2055
2056 applicationInfo.iconPath = app.icon;
2057 applicationInfo.iconId = app.iconId;
2058 applicationInfo.label = app.label;
2059 applicationInfo.labelId = app.labelId;
2060 applicationInfo.description = app.description;
2061 applicationInfo.descriptionId = app.descriptionId;
2062 applicationInfo.iconResource =
2063 BundleUtil::GetResource(app.bundleName, moduleJson.module.name, app.iconId);
2064 applicationInfo.labelResource =
2065 BundleUtil::GetResource(app.bundleName, moduleJson.module.name, app.labelId);
2066 applicationInfo.descriptionResource =
2067 BundleUtil::GetResource(app.bundleName, moduleJson.module.name, app.descriptionId);
2068 applicationInfo.targetBundleList = app.targetBundleList;
2069
2070 if (transformParam.isSystemApp && transformParam.isPreInstallApp) {
2071 applicationInfo.keepAlive = app.keepAlive;
2072 applicationInfo.singleton = app.singleton;
2073 applicationInfo.userDataClearable = app.userDataClearable;
2074 if (app.removable.first) {
2075 applicationInfo.removable = app.removable.second;
2076 } else {
2077 applicationInfo.removable = false;
2078 }
2079 applicationInfo.accessible = app.accessible;
2080 }
2081
2082 applicationInfo.apiReleaseType = app.apiReleaseType;
2083 applicationInfo.debug = app.debug;
2084 applicationInfo.deviceId = ServiceConstants::CURRENT_DEVICE_ID;
2085 applicationInfo.distributedNotificationEnabled = true;
2086 applicationInfo.entityType = Profile::APP_ENTITY_TYPE_DEFAULT_VALUE;
2087 applicationInfo.vendor = app.vendor;
2088 applicationInfo.asanEnabled = app.asanEnabled;
2089 if (app.bundleType == Profile::BUNDLE_TYPE_ATOMIC_SERVICE) {
2090 applicationInfo.bundleType = BundleType::ATOMIC_SERVICE;
2091 }
2092
2093 // device adapt
2094 std::string deviceType = GetDeviceType();
2095 APP_LOGD("deviceType : %{public}s", deviceType.c_str());
2096 if (app.deviceConfigs.find(deviceType) != app.deviceConfigs.end()) {
2097 Profile::DeviceConfig deviceConfig = app.deviceConfigs.at(deviceType);
2098 if (deviceConfig.minAPIVersion.first) {
2099 applicationInfo.apiCompatibleVersion = static_cast<uint32_t>(deviceConfig.minAPIVersion.second);
2100 }
2101 if (applicationInfo.isSystemApp && transformParam.isPreInstallApp) {
2102 if (deviceConfig.keepAlive.first) {
2103 applicationInfo.keepAlive = deviceConfig.keepAlive.second;
2104 }
2105 if (deviceConfig.singleton.first) {
2106 applicationInfo.singleton = deviceConfig.singleton.second;
2107 }
2108 if (deviceConfig.userDataClearable.first) {
2109 applicationInfo.userDataClearable = deviceConfig.userDataClearable.second;
2110 }
2111 if (deviceConfig.removable.first) {
2112 applicationInfo.removable = deviceConfig.removable.second;
2113 }
2114 if (deviceConfig.accessible.first) {
2115 applicationInfo.accessible = deviceConfig.accessible.second;
2116 }
2117 }
2118 }
2119
2120 applicationInfo.enabled = true;
2121 applicationInfo.multiProjects = app.multiProjects;
2122 applicationInfo.process = app.bundleName;
2123 applicationInfo.targetBundleName = app.targetBundle;
2124 applicationInfo.targetPriority = app.targetPriority;
2125
2126 auto iterBundleType = std::find_if(std::begin(Profile::BUNDLE_TYPE_MAP),
2127 std::end(Profile::BUNDLE_TYPE_MAP),
2128 [&app](const auto &item) { return item.first == app.bundleType; });
2129 if (iterBundleType != Profile::BUNDLE_TYPE_MAP.end()) {
2130 applicationInfo.bundleType = iterBundleType->second;
2131 }
2132 applicationInfo.compileSdkVersion = app.compileSdkVersion;
2133 applicationInfo.compileSdkType = app.compileSdkType;
2134 applicationInfo.gwpAsanEnabled = app.gwpAsanEnabled;
2135 applicationInfo.tsanEnabled = app.tsanEnabled;
2136 applicationInfo.hwasanEnabled = app.hwasanEnabled;
2137 applicationInfo.appEnvironments = app.appEnvironments;
2138 // bundleType is app && moduleType is entry or feature
2139 if (applicationInfo.bundleType == BundleType::APP &&
2140 (moduleJson.module.type == Profile::MODULE_TYPE_ENTRY ||
2141 moduleJson.module.type == Profile::MODULE_TYPE_FEATURE)) {
2142 applicationInfo.multiAppMode.multiAppModeType = ToMultiAppModeType(app.multiAppMode.multiAppModeType);
2143 applicationInfo.multiAppMode.maxCount = app.multiAppMode.maxCount;
2144 if (applicationInfo.multiAppMode.multiAppModeType == MultiAppModeType::APP_CLONE) {
2145 int32_t maxNumber = applicationInfo.multiAppMode.maxCount;
2146 if (maxNumber <= Constants::INITIAL_APP_INDEX || maxNumber > ServiceConstants::CLONE_APP_INDEX_MAX) {
2147 return false;
2148 }
2149 }
2150 }
2151 applicationInfo.maxChildProcess = app.maxChildProcess;
2152 if (app.configuration != "") {
2153 if (!ToInnerProfileConfiguration(bundleExtractor, app.configuration, applicationInfo.configuration)) {
2154 APP_LOGE("parse profile configuration fail %{public}s", app.configuration.c_str());
2155 return false;
2156 }
2157 }
2158 applicationInfo.cloudFileSyncEnabled = app.cloudFileSyncEnabled;
2159 return true;
2160 }
2161
ToBundleInfo(const ApplicationInfo & applicationInfo,const InnerModuleInfo & innerModuleInfo,const TransformParam & transformParam,BundleInfo & bundleInfo)2162 bool ToBundleInfo(
2163 const ApplicationInfo &applicationInfo,
2164 const InnerModuleInfo &innerModuleInfo,
2165 const TransformParam &transformParam,
2166 BundleInfo &bundleInfo)
2167 {
2168 bundleInfo.name = applicationInfo.bundleName;
2169
2170 bundleInfo.versionCode = static_cast<uint32_t>(applicationInfo.versionCode);
2171 bundleInfo.versionName = applicationInfo.versionName;
2172 bundleInfo.minCompatibleVersionCode = static_cast<uint32_t>(applicationInfo.minCompatibleVersionCode);
2173
2174 bundleInfo.compatibleVersion = static_cast<uint32_t>(applicationInfo.apiCompatibleVersion);
2175 bundleInfo.targetVersion = static_cast<uint32_t>(applicationInfo.apiTargetVersion);
2176
2177 bundleInfo.isKeepAlive = applicationInfo.keepAlive;
2178 bundleInfo.singleton = applicationInfo.singleton;
2179 bundleInfo.isPreInstallApp = transformParam.isPreInstallApp;
2180
2181 bundleInfo.vendor = applicationInfo.vendor;
2182 bundleInfo.releaseType = applicationInfo.apiReleaseType;
2183 bundleInfo.isNativeApp = false;
2184
2185 if (innerModuleInfo.isEntry) {
2186 bundleInfo.mainEntry = innerModuleInfo.moduleName;
2187 bundleInfo.entryModuleName = innerModuleInfo.moduleName;
2188 }
2189
2190 return true;
2191 }
2192
GetBackgroundModes(const std::vector<std::string> & backgroundModes)2193 uint32_t GetBackgroundModes(const std::vector<std::string> &backgroundModes)
2194 {
2195 uint32_t backgroundMode = 0;
2196 for (const std::string &item : backgroundModes) {
2197 if (Profile::BACKGROUND_MODES_MAP.find(item) != Profile::BACKGROUND_MODES_MAP.end()) {
2198 backgroundMode |= Profile::BACKGROUND_MODES_MAP.at(item);
2199 }
2200 }
2201 return backgroundMode;
2202 }
2203
ConvertCompileMode(const std::string & compileMode)2204 inline CompileMode ConvertCompileMode(const std::string& compileMode)
2205 {
2206 if (compileMode == Profile::COMPILE_MODE_ES_MODULE) {
2207 return CompileMode::ES_MODULE;
2208 } else {
2209 return CompileMode::JS_BUNDLE;
2210 }
2211 }
2212
ConvertToAbilityWindowMode(const std::vector<std::string> & windowModes,const std::unordered_map<std::string,SupportWindowMode> & windowMap)2213 std::set<SupportWindowMode> ConvertToAbilityWindowMode(const std::vector<std::string> &windowModes,
2214 const std::unordered_map<std::string, SupportWindowMode> &windowMap)
2215 {
2216 std::set<SupportWindowMode> modes;
2217 for_each(windowModes.begin(), windowModes.end(),
2218 [&windowMap, &modes](const auto &mode)->decltype(auto) {
2219 if (windowMap.find(mode) != windowMap.end()) {
2220 modes.emplace(windowMap.at(mode));
2221 }
2222 });
2223 if (modes.empty()) {
2224 modes.insert(SupportWindowMode::FULLSCREEN);
2225 modes.insert(SupportWindowMode::SPLIT);
2226 modes.insert(SupportWindowMode::FLOATING);
2227 }
2228 return modes;
2229 }
2230
ToAbilityInfo(const Profile::ModuleJson & moduleJson,const Profile::Ability & ability,const TransformParam & transformParam,AbilityInfo & abilityInfo)2231 bool ToAbilityInfo(
2232 const Profile::ModuleJson &moduleJson,
2233 const Profile::Ability &ability,
2234 const TransformParam &transformParam,
2235 AbilityInfo &abilityInfo)
2236 {
2237 APP_LOGD("transform ModuleJson to AbilityInfo");
2238 abilityInfo.name = ability.name;
2239 abilityInfo.srcEntrance = ability.srcEntrance;
2240 abilityInfo.description = ability.description;
2241 abilityInfo.descriptionId = ability.descriptionId;
2242 abilityInfo.iconPath = ability.icon;
2243 abilityInfo.iconId = ability.iconId;
2244 abilityInfo.label = ability.label;
2245 abilityInfo.labelId = ability.labelId;
2246 abilityInfo.priority = ability.priority;
2247 abilityInfo.excludeFromMissions = ability.excludeFromMissions;
2248 abilityInfo.unclearableMission = ability.unclearableMission;
2249 abilityInfo.excludeFromDock = ability.excludeFromDock;
2250 abilityInfo.preferMultiWindowOrientation = ability.preferMultiWindowOrientation;
2251 abilityInfo.recoverable = ability.recoverable;
2252 abilityInfo.permissions = ability.permissions;
2253 abilityInfo.visible = ability.visible;
2254 abilityInfo.continuable = ability.continuable;
2255 abilityInfo.isolationProcess = ability.isolationProcess;
2256 abilityInfo.backgroundModes = GetBackgroundModes(ability.backgroundModes);
2257 GetMetadata(abilityInfo.metadata, ability.metadata);
2258 abilityInfo.package = moduleJson.module.name;
2259 abilityInfo.bundleName = moduleJson.app.bundleName;
2260 abilityInfo.moduleName = moduleJson.module.name;
2261 abilityInfo.applicationName = moduleJson.app.bundleName;
2262 auto iterLaunch = std::find_if(std::begin(Profile::LAUNCH_MODE_MAP),
2263 std::end(Profile::LAUNCH_MODE_MAP),
2264 [&ability](const auto &item) { return item.first == ability.launchType; });
2265 if (iterLaunch != Profile::LAUNCH_MODE_MAP.end()) {
2266 abilityInfo.launchMode = iterLaunch->second;
2267 }
2268 abilityInfo.enabled = true;
2269 abilityInfo.isModuleJson = true;
2270 abilityInfo.isStageBasedModel = true;
2271 abilityInfo.type = AbilityType::PAGE;
2272 for (const std::string &deviceType : moduleJson.module.deviceTypes) {
2273 abilityInfo.deviceTypes.emplace_back(deviceType);
2274 }
2275 abilityInfo.startWindowIcon = ability.startWindowIcon;
2276 abilityInfo.startWindowIconId = ability.startWindowIconId;
2277 abilityInfo.startWindowBackground = ability.startWindowBackground;
2278 abilityInfo.startWindowBackgroundId = ability.startWindowBackgroundId;
2279 abilityInfo.removeMissionAfterTerminate = ability.removeMissionAfterTerminate;
2280 abilityInfo.compileMode = ConvertCompileMode(moduleJson.module.compileMode);
2281 auto iterOrientation = std::find_if(std::begin(Profile::DISPLAY_ORIENTATION_MAP),
2282 std::end(Profile::DISPLAY_ORIENTATION_MAP),
2283 [&ability](const auto &item) { return item.first == ability.orientation; });
2284 if (iterOrientation != Profile::DISPLAY_ORIENTATION_MAP.end()) {
2285 abilityInfo.orientation = iterOrientation->second;
2286 }
2287
2288 auto modesSet = ConvertToAbilityWindowMode(ability.windowModes, Profile::WINDOW_MODE_MAP);
2289 abilityInfo.windowModes.assign(modesSet.begin(), modesSet.end());
2290
2291 if (!ability.continueBundleNames.empty()) {
2292 abilityInfo.continueBundleNames.insert(ability.continueBundleNames.begin(), ability.continueBundleNames.end());
2293 }
2294
2295 abilityInfo.maxWindowRatio = ability.maxWindowRatio;
2296 abilityInfo.minWindowRatio = ability.minWindowRatio;
2297 abilityInfo.maxWindowWidth = ability.maxWindowWidth;
2298 abilityInfo.minWindowWidth = ability.minWindowWidth;
2299 abilityInfo.maxWindowHeight = ability.maxWindowHeight;
2300 abilityInfo.minWindowHeight = ability.minWindowHeight;
2301 if (ability.continueType.empty()) {
2302 abilityInfo.continueType.emplace_back(ability.name);
2303 } else {
2304 abilityInfo.continueType = ability.continueType;
2305 }
2306 abilityInfo.orientationId = ability.orientationId;
2307 abilityInfo.process = ability.process;
2308 return true;
2309 }
2310
ToAbilitySkills(std::vector<Skill> skills,AbilityInfo & abilityInfo)2311 void ToAbilitySkills(std::vector<Skill> skills, AbilityInfo &abilityInfo)
2312 {
2313 for (Skill &skill : skills) {
2314 abilityInfo.skills.push_back(skill);
2315 }
2316 }
2317
ToExtensionAbilitySkills(std::vector<Skill> skills,ExtensionAbilityInfo & extensionInfo)2318 void ToExtensionAbilitySkills(std::vector<Skill> skills, ExtensionAbilityInfo &extensionInfo)
2319 {
2320 for (Skill &skill : skills) {
2321 extensionInfo.skills.push_back(skill);
2322 }
2323 }
2324
ToExtensionInfo(const Profile::ModuleJson & moduleJson,const Profile::Extension & extension,const TransformParam & transformParam,ExtensionAbilityInfo & extensionInfo)2325 void ToExtensionInfo(
2326 const Profile::ModuleJson &moduleJson,
2327 const Profile::Extension &extension,
2328 const TransformParam &transformParam,
2329 ExtensionAbilityInfo &extensionInfo)
2330 {
2331 APP_LOGD("transform ModuleJson to ExtensionAbilityInfo");
2332 extensionInfo.type = ConvertToExtensionAbilityType(extension.type);
2333 extensionInfo.extensionTypeName = extension.type;
2334 extensionInfo.name = extension.name;
2335 extensionInfo.srcEntrance = extension.srcEntrance;
2336 extensionInfo.icon = extension.icon;
2337 extensionInfo.iconId = extension.iconId;
2338 extensionInfo.label = extension.label;
2339 extensionInfo.labelId = extension.labelId;
2340 extensionInfo.description = extension.description;
2341 extensionInfo.descriptionId = extension.descriptionId;
2342 if (transformParam.isSystemApp && transformParam.isPreInstallApp) {
2343 extensionInfo.readPermission = extension.readPermission;
2344 extensionInfo.writePermission = extension.writePermission;
2345 }
2346 extensionInfo.priority = extension.priority;
2347 extensionInfo.uri = extension.uri;
2348 extensionInfo.permissions = extension.permissions;
2349 extensionInfo.visible = extension.visible;
2350 GetMetadata(extensionInfo.metadata, extension.metadata);
2351 extensionInfo.bundleName = moduleJson.app.bundleName;
2352 extensionInfo.moduleName = moduleJson.module.name;
2353
2354 if (extensionInfo.type != ExtensionAbilityType::SERVICE &&
2355 extensionInfo.type != ExtensionAbilityType::DATASHARE) {
2356 extensionInfo.process = extensionInfo.bundleName;
2357 extensionInfo.process.append(":");
2358 extensionInfo.process.append(extensionInfo.extensionTypeName);
2359 }
2360
2361 extensionInfo.compileMode = ConvertCompileMode(moduleJson.module.compileMode);
2362 extensionInfo.extensionProcessMode = ConvertToExtensionProcessMode(extension.extensionProcessMode);
2363 for (const std::string &dataGroup : extension.dataGroupIds) {
2364 extensionInfo.dataGroupIds.emplace_back(dataGroup);
2365 }
2366 extensionInfo.customProcess = extension.customProcess;
2367 }
2368
GetPermissions(const Profile::ModuleJson & moduleJson,const TransformParam & transformParam,InnerModuleInfo & innerModuleInfo)2369 bool GetPermissions(
2370 const Profile::ModuleJson &moduleJson,
2371 const TransformParam &transformParam,
2372 InnerModuleInfo &innerModuleInfo)
2373 {
2374 if (moduleJson.app.bundleName == Profile::SYSTEM_RESOURCES_APP) {
2375 for (const DefinePermission &definePermission : moduleJson.module.definePermissions) {
2376 if (definePermission.name.empty()) {
2377 continue;
2378 }
2379 if (Profile::GRANT_MODE_SET.find(definePermission.grantMode) == Profile::GRANT_MODE_SET.end()) {
2380 continue;
2381 }
2382 if (Profile::AVAILABLE_LEVEL_SET.find(definePermission.availableLevel)
2383 == Profile::AVAILABLE_LEVEL_SET.end()) {
2384 continue;
2385 }
2386 if (!definePermission.availableType.empty() &&
2387 definePermission.availableType != Profile::DEFINEPERMISSION_AVAILABLE_TYPE_MDM) {
2388 APP_LOGE("availableType(%{public}s) invalid", definePermission.availableType.c_str());
2389 return false;
2390 }
2391 innerModuleInfo.definePermissions.emplace_back(definePermission);
2392 }
2393 }
2394 for (const RequestPermission &requestPermission : moduleJson.module.requestPermissions) {
2395 if (requestPermission.name.empty()) {
2396 continue;
2397 }
2398 innerModuleInfo.requestPermissions.emplace_back(requestPermission);
2399 }
2400 return true;
2401 }
2402
ToInnerModuleInfo(const Profile::ModuleJson & moduleJson,const TransformParam & transformParam,const OverlayMsg & overlayMsg,InnerModuleInfo & innerModuleInfo)2403 bool ToInnerModuleInfo(
2404 const Profile::ModuleJson &moduleJson,
2405 const TransformParam &transformParam,
2406 const OverlayMsg &overlayMsg,
2407 InnerModuleInfo &innerModuleInfo)
2408 {
2409 APP_LOGD("transform ModuleJson to InnerModuleInfo");
2410 innerModuleInfo.name = moduleJson.module.name;
2411 innerModuleInfo.modulePackage = moduleJson.module.name;
2412 innerModuleInfo.moduleName = moduleJson.module.name;
2413 innerModuleInfo.description = moduleJson.module.description;
2414 innerModuleInfo.descriptionId = moduleJson.module.descriptionId;
2415 GetMetadata(innerModuleInfo.metadata, moduleJson.module.metadata);
2416 GetHnpPackage(innerModuleInfo.hnpPackages, moduleJson.module.hnpPackages);
2417 innerModuleInfo.distro.deliveryWithInstall = moduleJson.module.deliveryWithInstall;
2418 innerModuleInfo.distro.installationFree = moduleJson.module.installationFree;
2419 innerModuleInfo.distro.moduleName = moduleJson.module.name;
2420 innerModuleInfo.installationFree = moduleJson.module.installationFree;
2421 if (Profile::MODULE_TYPE_SET.find(moduleJson.module.type) != Profile::MODULE_TYPE_SET.end()) {
2422 innerModuleInfo.distro.moduleType = moduleJson.module.type;
2423 if (moduleJson.module.type == Profile::MODULE_TYPE_ENTRY) {
2424 innerModuleInfo.isEntry = true;
2425 }
2426 }
2427
2428 innerModuleInfo.mainAbility = moduleJson.module.mainElement;
2429 innerModuleInfo.srcEntrance = moduleJson.module.srcEntrance;
2430 innerModuleInfo.process = moduleJson.module.process;
2431
2432 for (const std::string &deviceType : moduleJson.module.deviceTypes) {
2433 innerModuleInfo.deviceTypes.emplace_back(deviceType);
2434 }
2435
2436 if (Profile::VIRTUAL_MACHINE_SET.find(moduleJson.module.virtualMachine) != Profile::VIRTUAL_MACHINE_SET.end()) {
2437 innerModuleInfo.virtualMachine = moduleJson.module.virtualMachine;
2438 }
2439
2440 innerModuleInfo.uiSyntax = Profile::MODULE_UI_SYNTAX_DEFAULT_VALUE;
2441 innerModuleInfo.pages = moduleJson.module.pages;
2442 if (!GetPermissions(moduleJson, transformParam, innerModuleInfo)) {
2443 APP_LOGE("GetPermissions failed");
2444 return false;
2445 }
2446 innerModuleInfo.dependencies = moduleJson.module.dependencies;
2447 innerModuleInfo.compileMode = moduleJson.module.compileMode;
2448 innerModuleInfo.isModuleJson = true;
2449 innerModuleInfo.isStageBasedModel = true;
2450 innerModuleInfo.isLibIsolated = moduleJson.module.isLibIsolated;
2451 innerModuleInfo.targetModuleName = moduleJson.module.targetModule;
2452 if (overlayMsg.type != NON_OVERLAY_TYPE && !overlayMsg.isModulePriorityExisted) {
2453 innerModuleInfo.targetPriority = ServiceConstants::OVERLAY_MINIMUM_PRIORITY;
2454 } else {
2455 innerModuleInfo.targetPriority = moduleJson.module.targetPriority;
2456 }
2457 if (moduleJson.module.proxyDatas.empty()) {
2458 innerModuleInfo.proxyDatas = moduleJson.module.proxyData;
2459 } else {
2460 innerModuleInfo.proxyDatas = moduleJson.module.proxyDatas;
2461 }
2462 innerModuleInfo.buildHash = moduleJson.module.buildHash;
2463 innerModuleInfo.isolationMode = moduleJson.module.isolationMode;
2464 innerModuleInfo.compressNativeLibs = moduleJson.module.compressNativeLibs;
2465 innerModuleInfo.fileContextMenu = moduleJson.module.fileContextMenu;
2466
2467 if (moduleJson.module.querySchemes.size() > Profile::MAX_QUERYSCHEMES_LENGTH) {
2468 APP_LOGE("The length of the querySchemes exceeds the limit");
2469 return false;
2470 }
2471 for (const std::string &queryScheme : moduleJson.module.querySchemes) {
2472 innerModuleInfo.querySchemes.emplace_back(queryScheme);
2473 }
2474
2475 innerModuleInfo.routerMap = moduleJson.module.routerMap;
2476 // abilities and fileContextMenu store in InnerBundleInfo
2477 innerModuleInfo.appEnvironments = moduleJson.module.appEnvironments;
2478 innerModuleInfo.packageName = moduleJson.module.packageName;
2479 innerModuleInfo.appStartup = moduleJson.module.appStartup;
2480 return true;
2481 }
2482
SetInstallationFree(InnerModuleInfo & innerModuleInfo,BundleType bundleType)2483 void SetInstallationFree(InnerModuleInfo &innerModuleInfo, BundleType bundleType)
2484 {
2485 if (bundleType == BundleType::ATOMIC_SERVICE) {
2486 innerModuleInfo.distro.installationFree = true;
2487 innerModuleInfo.installationFree = true;
2488 } else {
2489 innerModuleInfo.distro.installationFree = false;
2490 innerModuleInfo.installationFree = false;
2491 }
2492 }
2493
ToInnerBundleInfo(const Profile::ModuleJson & moduleJson,const BundleExtractor & bundleExtractor,const OverlayMsg & overlayMsg,InnerBundleInfo & innerBundleInfo)2494 bool ToInnerBundleInfo(
2495 const Profile::ModuleJson &moduleJson,
2496 const BundleExtractor &bundleExtractor,
2497 const OverlayMsg &overlayMsg,
2498 InnerBundleInfo &innerBundleInfo)
2499 {
2500 APP_LOGD("transform ModuleJson to InnerBundleInfo");
2501 if (!CheckBundleNameIsValid(moduleJson.app.bundleName) || !CheckModuleNameIsValid(moduleJson.module.name)) {
2502 APP_LOGE("bundle name or module name is invalid");
2503 return false;
2504 }
2505
2506 if (overlayMsg.type != NON_OVERLAY_TYPE && !CheckModuleNameIsValid(moduleJson.module.targetModule)) {
2507 APP_LOGE("target moduleName is invalid");
2508 }
2509
2510 if ((overlayMsg.type == OVERLAY_EXTERNAL_BUNDLE) && !CheckBundleNameIsValid(moduleJson.app.targetBundle)) {
2511 APP_LOGE("targetBundleName of the overlay hap is invalid");
2512 return false;
2513 }
2514
2515 TransformParam transformParam;
2516 transformParam.isPreInstallApp = innerBundleInfo.IsPreInstallApp();
2517
2518 ApplicationInfo applicationInfo;
2519 applicationInfo.isSystemApp = innerBundleInfo.GetAppType() == Constants::AppType::SYSTEM_APP;
2520 transformParam.isSystemApp = applicationInfo.isSystemApp;
2521 applicationInfo.isCompressNativeLibs = moduleJson.module.compressNativeLibs;
2522 if (!ToApplicationInfo(moduleJson, bundleExtractor, transformParam, applicationInfo)) {
2523 APP_LOGE("To applicationInfo failed");
2524 return false;
2525 }
2526
2527 InnerModuleInfo innerModuleInfo;
2528 if (!ToInnerModuleInfo(moduleJson, transformParam, overlayMsg, innerModuleInfo)) {
2529 APP_LOGE("To innerModuleInfo failed");
2530 return false;
2531 }
2532 innerModuleInfo.asanEnabled = applicationInfo.asanEnabled;
2533 innerModuleInfo.gwpAsanEnabled = applicationInfo.gwpAsanEnabled;
2534 innerModuleInfo.tsanEnabled = applicationInfo.tsanEnabled;
2535 innerModuleInfo.innerModuleInfoFlag = applicationInfo.hwasanEnabled ? innerModuleInfo.innerModuleInfoFlag |
2536 innerBundleInfo.GetSanitizerFlag(GetInnerModuleInfoFlag::GET_INNER_MODULE_INFO_WITH_HWASANENABLED) :
2537 innerModuleInfo.innerModuleInfoFlag &
2538 (~innerBundleInfo.GetSanitizerFlag(GetInnerModuleInfoFlag::GET_INNER_MODULE_INFO_WITH_HWASANENABLED));
2539 SetInstallationFree(innerModuleInfo, applicationInfo.bundleType);
2540
2541 BundleInfo bundleInfo;
2542 ToBundleInfo(applicationInfo, innerModuleInfo, transformParam, bundleInfo);
2543
2544 // handle abilities
2545 auto entryActionMatcher = [] (const std::string &action) {
2546 return action == Constants::ACTION_HOME || action == Constants::WANT_ACTION_HOME;
2547 };
2548 bool findEntry = false;
2549 for (const Profile::Ability &ability : moduleJson.module.abilities) {
2550 AbilityInfo abilityInfo;
2551 bool isMainElement = false;
2552 ToAbilityInfo(moduleJson, ability, transformParam, abilityInfo);
2553 if (innerModuleInfo.mainAbility == abilityInfo.name) {
2554 innerModuleInfo.icon = abilityInfo.iconPath;
2555 innerModuleInfo.iconId = abilityInfo.iconId;
2556 innerModuleInfo.label = abilityInfo.label;
2557 innerModuleInfo.labelId = abilityInfo.labelId;
2558 isMainElement = true;
2559 }
2560 std::string key;
2561 key.append(moduleJson.app.bundleName).append(".")
2562 .append(moduleJson.module.name).append(".").append(abilityInfo.name);
2563 innerModuleInfo.abilityKeys.emplace_back(key);
2564 innerModuleInfo.skillKeys.emplace_back(key);
2565 innerBundleInfo.InsertSkillInfo(key, ability.skills);
2566 ToAbilitySkills(ability.skills, abilityInfo);
2567 innerBundleInfo.InsertAbilitiesInfo(key, abilityInfo);
2568 if (findEntry && !isMainElement) {
2569 continue;
2570 }
2571 // get entry ability
2572 for (const auto &skill : ability.skills) {
2573 bool isEntryAction = std::find_if(skill.actions.begin(), skill.actions.end(),
2574 entryActionMatcher) != skill.actions.end();
2575 bool isEntryEntity = std::find(skill.entities.begin(), skill.entities.end(),
2576 Constants::ENTITY_HOME) != skill.entities.end();
2577 if (isEntryAction && isEntryEntity) {
2578 innerModuleInfo.entryAbilityKey = key;
2579 innerModuleInfo.label = ability.label;
2580 innerModuleInfo.labelId = ability.labelId;
2581 // get launcher application and ability
2582 bool isLauncherEntity = std::find(skill.entities.begin(), skill.entities.end(),
2583 ServiceConstants::FLAG_HOME_INTENT_FROM_SYSTEM) != skill.entities.end();
2584 if (isLauncherEntity && transformParam.isPreInstallApp) {
2585 applicationInfo.isLauncherApp = true;
2586 abilityInfo.isLauncherAbility = true;
2587 }
2588 findEntry = true;
2589 break;
2590 }
2591 }
2592 }
2593
2594 // handle extensionAbilities
2595 for (const Profile::Extension &extension : moduleJson.module.extensionAbilities) {
2596 ExtensionAbilityInfo extensionInfo;
2597 ToExtensionInfo(moduleJson, extension, transformParam, extensionInfo);
2598
2599 if (innerModuleInfo.mainAbility == extensionInfo.name) {
2600 innerModuleInfo.icon = extensionInfo.icon;
2601 innerModuleInfo.iconId = extensionInfo.iconId;
2602 innerModuleInfo.label = extensionInfo.label;
2603 innerModuleInfo.labelId = extensionInfo.labelId;
2604 }
2605
2606 if (transformParam.isPreInstallApp && !applicationInfo.isLauncherApp) {
2607 for (const auto &skill : extension.skills) {
2608 bool isEntryAction = std::find_if(skill.actions.cbegin(), skill.actions.cend(),
2609 entryActionMatcher) != skill.actions.cend();
2610 bool isEntryEntity = std::find(skill.entities.cbegin(), skill.entities.cend(),
2611 Constants::ENTITY_HOME) != skill.entities.cend();
2612 bool isLauncherEntity = std::find(skill.entities.cbegin(), skill.entities.cend(),
2613 ServiceConstants::FLAG_HOME_INTENT_FROM_SYSTEM) != skill.entities.cend();
2614 if (isEntryAction && isEntryEntity && isLauncherEntity) {
2615 applicationInfo.isLauncherApp = true;
2616 break;
2617 }
2618 }
2619 }
2620
2621 std::string key;
2622 key.append(moduleJson.app.bundleName).append(".")
2623 .append(moduleJson.module.name).append(".").append(extension.name);
2624 innerModuleInfo.extensionKeys.emplace_back(key);
2625 innerModuleInfo.extensionSkillKeys.emplace_back(key);
2626 innerBundleInfo.InsertExtensionSkillInfo(key, extension.skills);
2627 ToExtensionAbilitySkills(extension.skills, extensionInfo);
2628 innerBundleInfo.InsertExtensionInfo(key, extensionInfo);
2629 }
2630 if (!findEntry && !transformParam.isPreInstallApp) {
2631 applicationInfo.needAppDetail = true;
2632 if (BundleUtil::IsExistDir(ServiceConstants::SYSTEM_LIB64)) {
2633 applicationInfo.appDetailAbilityLibraryPath = Profile::APP_DETAIL_ABILITY_LIBRARY_PATH_64;
2634 } else {
2635 applicationInfo.appDetailAbilityLibraryPath = Profile::APP_DETAIL_ABILITY_LIBRARY_PATH;
2636 }
2637 if ((applicationInfo.labelId == 0) && (applicationInfo.label.empty())) {
2638 applicationInfo.label = applicationInfo.bundleName;
2639 }
2640 }
2641 innerBundleInfo.SetCurrentModulePackage(moduleJson.module.name);
2642 innerBundleInfo.SetBaseApplicationInfo(applicationInfo);
2643 innerBundleInfo.SetBaseBundleInfo(bundleInfo);
2644
2645 // Here also need verify module type is shared.
2646 if (applicationInfo.bundleType == BundleType::SHARED) {
2647 innerModuleInfo.bundleType = applicationInfo.bundleType;
2648 innerModuleInfo.versionCode = applicationInfo.versionCode;
2649 innerModuleInfo.versionName = applicationInfo.versionName;
2650 innerBundleInfo.InsertInnerSharedModuleInfo(moduleJson.module.name, innerModuleInfo);
2651 }
2652
2653 innerBundleInfo.InsertInnerModuleInfo(moduleJson.module.name, innerModuleInfo);
2654 innerBundleInfo.SetOverlayType(overlayMsg.type);
2655
2656 if (overlayMsg.type == OVERLAY_EXTERNAL_BUNDLE && !overlayMsg.isAppPriorityExisted) {
2657 innerBundleInfo.SetTargetPriority(ServiceConstants::OVERLAY_MINIMUM_PRIORITY);
2658 } else {
2659 innerBundleInfo.SetTargetPriority(moduleJson.app.targetPriority);
2660 }
2661 int32_t overlayState = overlayMsg.type == OVERLAY_EXTERNAL_BUNDLE ?
2662 ServiceConstants::DEFAULT_OVERLAY_ENABLE_STATUS :
2663 ServiceConstants::DEFAULT_OVERLAY_DISABLE_STATUS;
2664 innerBundleInfo.SetOverlayState(overlayState);
2665 return true;
2666 }
2667 } // namespace
2668
ObtainOverlayType(const nlohmann::json & jsonObject) const2669 OverlayMsg ModuleProfile::ObtainOverlayType(const nlohmann::json &jsonObject) const
2670 {
2671 APP_LOGD("check if overlay installation");
2672 OverlayMsg overlayMsg;
2673 #ifdef BUNDLE_FRAMEWORK_OVERLAY_INSTALLATION
2674 if (!jsonObject.contains(Profile::MODULE) || !jsonObject.contains(Profile::APP)) {
2675 APP_LOGE("ObtainOverlayType failed due to bad module.json");
2676 Profile::g_parseResult = ERR_APPEXECFWK_INSTALL_FAILED_PROFILE_PARSE_FAIL;
2677 return overlayMsg;
2678 }
2679 nlohmann::json moduleJson = jsonObject.at(Profile::MODULE);
2680 nlohmann::json appJson = jsonObject.at(Profile::APP);
2681 if (!moduleJson.is_object() || !appJson.is_object()) {
2682 APP_LOGE("module.json file lacks of invalid module or app properties");
2683 Profile::g_parseResult = ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
2684 return overlayMsg;
2685 }
2686
2687 auto isTargetBundleExisted = appJson.contains(Profile::APP_TARGET_BUNDLE_NAME);
2688 auto isAppPriorityExisted = appJson.contains(Profile::APP_TARGET_PRIORITY);
2689 auto isTargetModuleNameExisted = moduleJson.contains(Profile::MODULE_TARGET_MODULE_NAME);
2690 auto isModulePriorityExisted = moduleJson.contains(Profile::MODULE_TARGET_PRIORITY);
2691 if (!isTargetBundleExisted && !isAppPriorityExisted && !isTargetModuleNameExisted &&
2692 !isModulePriorityExisted) {
2693 return overlayMsg;
2694 }
2695 if (!isTargetModuleNameExisted) {
2696 Profile::g_parseResult = ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED;
2697 APP_LOGE("overlay hap with invalid configuration file");
2698 return overlayMsg;
2699 }
2700 if (!isTargetBundleExisted && isAppPriorityExisted) {
2701 Profile::g_parseResult = ERR_BUNDLEMANAGER_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED;
2702 APP_LOGE("overlay hap with invalid configuration file");
2703 return overlayMsg;
2704 }
2705
2706 APP_LOGI("overlay configuration file is about to parse");
2707 overlayMsg.type = isTargetBundleExisted ? OVERLAY_EXTERNAL_BUNDLE : OVERLAY_INTERNAL_BUNDLE;
2708 overlayMsg.isAppPriorityExisted = isAppPriorityExisted;
2709 overlayMsg.isModulePriorityExisted = isModulePriorityExisted;
2710 return overlayMsg;
2711 #else
2712 return overlayMsg;
2713 #endif
2714 }
2715
TransformTo(const std::ostringstream & source,const BundleExtractor & bundleExtractor,InnerBundleInfo & innerBundleInfo) const2716 ErrCode ModuleProfile::TransformTo(
2717 const std::ostringstream &source,
2718 const BundleExtractor &bundleExtractor,
2719 InnerBundleInfo &innerBundleInfo) const
2720 {
2721 APP_LOGD("transform module.json stream to InnerBundleInfo");
2722 nlohmann::json jsonObject = nlohmann::json::parse(source.str(), nullptr, false);
2723 if (jsonObject.is_discarded()) {
2724 APP_LOGE("bad profile");
2725 return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
2726 }
2727 OverlayMsg overlayMsg;
2728 Profile::ModuleJson moduleJson;
2729 {
2730 std::lock_guard<std::mutex> lock(Profile::g_mutex);
2731 Profile::g_parseResult = ERR_OK;
2732 overlayMsg = ObtainOverlayType(jsonObject);
2733 if ((overlayMsg.type == NON_OVERLAY_TYPE) && (Profile::g_parseResult != ERR_OK)) {
2734 int32_t ret = Profile::g_parseResult;
2735 Profile::g_parseResult = ERR_OK;
2736 APP_LOGE("ObtainOverlayType g_parseResult %{public}d", ret);
2737 return ret;
2738 }
2739 APP_LOGD("overlay type of the hap is %{public}d", overlayMsg.type);
2740 Profile::g_parseResult = ERR_OK;
2741 moduleJson = jsonObject.get<Profile::ModuleJson>();
2742 if (Profile::g_parseResult != ERR_OK) {
2743 APP_LOGE("g_parseResult %{public}d", Profile::g_parseResult);
2744 int32_t ret = Profile::g_parseResult;
2745 // need recover parse result to ERR_OK
2746 Profile::g_parseResult = ERR_OK;
2747 return ret;
2748 }
2749 }
2750 if (!ToInnerBundleInfo(
2751 moduleJson, bundleExtractor, overlayMsg, innerBundleInfo)) {
2752 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
2753 }
2754 if (!ParserAtomicConfig(jsonObject, innerBundleInfo)) {
2755 APP_LOGE("Parser atomicService config failed");
2756 return ERR_APPEXECFWK_PARSE_PROFILE_PROP_CHECK_ERROR;
2757 }
2758 if (!ParserNativeSo(moduleJson, bundleExtractor, innerBundleInfo)) {
2759 #ifdef X86_EMULATOR_MODE
2760 APP_LOGE("Parser native so failed");
2761 return ERR_APPEXECFWK_PARSE_NATIVE_SO_FAILED;
2762 #endif
2763 APP_LOGW("Parser native so failed");
2764 }
2765 if (!ParserArkNativeFilePath(moduleJson, bundleExtractor, innerBundleInfo)) {
2766 #ifdef X86_EMULATOR_MODE
2767 APP_LOGE("Parser ark native file failed");
2768 return ERR_APPEXECFWK_PARSE_AN_FAILED;
2769 #endif
2770 APP_LOGW("Parser ark native file failed");
2771 }
2772 return ERR_OK;
2773 }
2774 } // namespace AppExecFwk
2775 } // namespace OHOS
2776