1 /*
2 * Copyright (c) 2024-2025 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 "main_element_utils.h"
17
18 #include "ability_manager_service.h"
19 #include "ability_util.h"
20 #include "keep_alive_process_manager.h"
21
22 namespace OHOS {
23 namespace AAFwk {
24 namespace {
25 /**
26 * IsMainElementTypeOk, check if it is a valid main element type.
27 *
28 * @param hapModuleInfo The hap module info.
29 * @param mainElement The returned main element.
30 * @param userId User id.
31 * @return Whether it is a valid main element type.
32 */
IsMainElementTypeOk(const AppExecFwk::HapModuleInfo & hapModuleInfo,const std::string & mainElement,int32_t userId)33 bool IsMainElementTypeOk(const AppExecFwk::HapModuleInfo &hapModuleInfo, const std::string &mainElement,
34 int32_t userId)
35 {
36 if (userId == 0) {
37 for (const auto &abilityInfo: hapModuleInfo.abilityInfos) {
38 TAG_LOGD(AAFwkTag::ABILITYMGR, "compare ability: %{public}s", abilityInfo.name.c_str());
39 if (abilityInfo.name == mainElement) {
40 return abilityInfo.type != AppExecFwk::AbilityType::PAGE;
41 }
42 }
43 return true;
44 }
45 for (const auto &extensionInfo: hapModuleInfo.extensionInfos) {
46 TAG_LOGD(AAFwkTag::ABILITYMGR, "compare extension: %{public}s", extensionInfo.name.c_str());
47 if (extensionInfo.name == mainElement) {
48 return extensionInfo.type == AppExecFwk::ExtensionAbilityType::SERVICE;
49 }
50 }
51 return false;
52 }
53 } // namespace
54
UpdateMainElement(const std::string & bundleName,const std::string & moduleName,const std::string & mainElement,bool updateEnable,int32_t userId)55 void MainElementUtils::UpdateMainElement(const std::string &bundleName, const std::string &moduleName,
56 const std::string &mainElement, bool updateEnable, int32_t userId)
57 {
58 auto abilityMs = DelayedSingleton<AbilityManagerService>::GetInstance();
59 CHECK_POINTER(abilityMs);
60 auto ret = abilityMs->UpdateKeepAliveEnableState(bundleName, moduleName, mainElement, updateEnable, userId);
61 if (ret != ERR_OK) {
62 TAG_LOGE(AAFwkTag::ABILITYMGR,
63 "update keepAlive fail,bundle:%{public}s,mainElement:%{public}s,enable:%{public}d,userId:%{public}d",
64 bundleName.c_str(), mainElement.c_str(), updateEnable, userId);
65 }
66 }
67
IsMainUIAbility(const std::string & bundleName,const std::string & abilityName,int32_t userId)68 bool MainElementUtils::IsMainUIAbility(const std::string &bundleName,
69 const std::string &abilityName, int32_t userId)
70 {
71 auto bms = AbilityUtil::GetBundleManagerHelper();
72 CHECK_POINTER_AND_RETURN_LOG(bms, false, "bms nullptr");
73 AppExecFwk::BundleInfo bundleInfo;
74 if (IN_PROCESS_CALL(bms->GetBundleInfoV9(bundleName,
75 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
76 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE),
77 bundleInfo, userId)) != ERR_OK) {
78 TAG_LOGE(AAFwkTag::ABILITYMGR, "IsMainUIAbility get bundleInfo failed");
79 return false;
80 }
81 std::string mainElementName;
82 if (CheckMainUIAbility(bundleInfo, mainElementName)) {
83 TAG_LOGD(AAFwkTag::ABILITYMGR, "IsMainUIAbility %{public}s::%{public}s",
84 abilityName.c_str(), mainElementName.c_str());
85 return abilityName == mainElementName;
86 }
87 return false;
88 }
89
SetMainUIAbilityKeepAliveFlag(bool isMainUIAbility,const std::string & bundleName,AbilityRuntime::LoadParam & loadParam)90 void MainElementUtils::SetMainUIAbilityKeepAliveFlag(bool isMainUIAbility,
91 const std::string &bundleName, AbilityRuntime::LoadParam &loadParam)
92 {
93 if (bundleName.empty()) {
94 TAG_LOGE(AAFwkTag::ABILITYMGR, "bundleName is empty");
95 return;
96 }
97 if (!isMainUIAbility) {
98 return;
99 }
100 loadParam.isMainElementRunning = true;
101 if (KeepAliveProcessManager::GetInstance().IsKeepAliveBundle(bundleName, DEFAULT_INVAL_VALUE)) {
102 TAG_LOGD(AAFwkTag::ABILITYMGR, "Set KeepAlive for main UIAbility");
103 loadParam.isKeepAlive = true;
104 }
105 }
106
CheckMainElement(const AppExecFwk::HapModuleInfo & hapModuleInfo,const std::string & processName,std::string & mainElement,bool & isDataAbility,std::string & uriStr,int32_t userId)107 bool MainElementUtils::CheckMainElement(const AppExecFwk::HapModuleInfo &hapModuleInfo,
108 const std::string &processName, std::string &mainElement, bool &isDataAbility,
109 std::string &uriStr, int32_t userId)
110 {
111 if (!hapModuleInfo.isModuleJson) {
112 // old application model
113 mainElement = hapModuleInfo.mainAbility;
114 if (mainElement.empty()) {
115 return false;
116 }
117
118 // old application model, use ability 'process'
119 bool isAbilityKeepAlive = false;
120 for (auto abilityInfo : hapModuleInfo.abilityInfos) {
121 if (abilityInfo.process != processName || abilityInfo.name != mainElement) {
122 continue;
123 }
124 isAbilityKeepAlive = true;
125 }
126 if (!isAbilityKeepAlive) {
127 return false;
128 }
129
130 isDataAbility = DelayedSingleton<AbilityManagerService>::GetInstance()->GetDataAbilityUri(
131 hapModuleInfo.abilityInfos, mainElement, uriStr);
132 if (isDataAbility) {
133 return false;
134 }
135 } else {
136 TAG_LOGI(AAFwkTag::ABILITYMGR, "new mode: %{public}s", hapModuleInfo.bundleName.c_str());
137 // new application model
138 mainElement = hapModuleInfo.mainElementName;
139 if (mainElement.empty()) {
140 TAG_LOGI(AAFwkTag::ABILITYMGR, "mainElement empty");
141 return false;
142 }
143
144 // new application model, user model 'process'
145 if (hapModuleInfo.process != processName) {
146 TAG_LOGI(AAFwkTag::ABILITYMGR, "processName err: %{public}s", processName.c_str());
147 return false;
148 }
149 }
150 return IsMainElementTypeOk(hapModuleInfo, mainElement, userId);
151 }
152
CheckMainUIAbility(const AppExecFwk::BundleInfo & bundleInfo,std::string & mainElementName)153 bool MainElementUtils::CheckMainUIAbility(const AppExecFwk::BundleInfo &bundleInfo, std::string& mainElementName)
154 {
155 for (const auto& hapModuleInfo : bundleInfo.hapModuleInfos) {
156 if (hapModuleInfo.moduleType != AppExecFwk::ModuleType::ENTRY) {
157 continue;
158 }
159
160 mainElementName = hapModuleInfo.mainElementName;
161 if (mainElementName.empty()) {
162 return false;
163 }
164 for (const auto &abilityInfo: hapModuleInfo.abilityInfos) {
165 if (abilityInfo.type != AppExecFwk::AbilityType::PAGE) {
166 continue;
167 }
168 if (abilityInfo.name == mainElementName) {
169 return true;
170 }
171 }
172 break;
173 }
174 return false;
175 }
176
CheckStatusBarAbility(const AppExecFwk::BundleInfo & bundleInfo)177 bool MainElementUtils::CheckStatusBarAbility(const AppExecFwk::BundleInfo &bundleInfo)
178 {
179 for (const auto& hapModuleInfo : bundleInfo.hapModuleInfos) {
180 for (const auto &extensionInfo: hapModuleInfo.extensionInfos) {
181 if (extensionInfo.type == AppExecFwk::ExtensionAbilityType::STATUS_BAR_VIEW) {
182 return true;
183 }
184 }
185 }
186 return false;
187 }
188
CheckAppServiceExtension(const AppExecFwk::BundleInfo & bundleInfo,std::string & mainElementName)189 bool MainElementUtils::CheckAppServiceExtension(const AppExecFwk::BundleInfo &bundleInfo, std::string& mainElementName)
190 {
191 for (const auto& hapModuleInfo : bundleInfo.hapModuleInfos) {
192 if (hapModuleInfo.moduleType != AppExecFwk::ModuleType::ENTRY) {
193 continue;
194 }
195
196 mainElementName = hapModuleInfo.mainElementName;
197 if (mainElementName.empty()) {
198 return false;
199 }
200
201 for (const auto &extensionInfo: hapModuleInfo.extensionInfos) {
202 if (extensionInfo.type != AppExecFwk::ExtensionAbilityType::APP_SERVICE) {
203 continue;
204 }
205
206 if (extensionInfo.name == mainElementName) {
207 return true;
208 }
209 }
210 }
211 return false;
212 }
213 } // namespace AAFwk
214 } // namespace OHOS
215