1 /*
2 * Copyright (c) 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 "manage_keep_alive_apps_plugin.h"
17
18 #include <algorithm>
19
20 #include "app_control/app_control_proxy.h"
21 #include "manage_keep_alive_apps_serializer.h"
22 #include "bundle_info.h"
23 #include "edm_constants.h"
24 #include "edm_ipc_interface_code.h"
25 #include "edm_sys_manager.h"
26 #include "element_name.h"
27 #include "func_code_utils.h"
28 #include "iplugin_manager.h"
29 #include "ipolicy_manager.h"
30 #include "system_ability_definition.h"
31
32 namespace OHOS {
33 namespace EDM {
34 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(std::make_shared<ManageKeepAliveAppsPlugin>());
35 const ErrCode ERR_TARGET_BUNDLE_NOT_EXIST = 2097241;
36 const ErrCode ERR_NO_MAIN_ABILITY = 29360135;
37 const ErrCode ERR_NO_STATUS_BAR_ABILITY = 29360136;
38 const ErrCode ERR_NOT_ATTACHED_TO_STATUS_BAR = 29360137;
39 const ErrCode ERR_CAPABILITY_NOT_SUPPORT = 2097230;
40
ManageKeepAliveAppsPlugin()41 ManageKeepAliveAppsPlugin::ManageKeepAliveAppsPlugin()
42 {
43 policyCode_ = EdmInterfaceCode::MANAGE_KEEP_ALIVE_APPS;
44 policyName_ = PolicyName::POLICY_MANAGE_KEEP_ALIVE_APPS;
45 permissionConfig_.typePermissions.emplace(IPlugin::PermissionType::SUPER_DEVICE_ADMIN,
46 EdmPermission::PERMISSION_ENTERPRISE_MANAGE_APPLICATION);
47 permissionConfig_.apiType = IPlugin::ApiType::PUBLIC;
48 needSave_ = true;
49 maxListSize_ = EdmConstants::KEEP_ALIVE_APPS_MAX_SIZE;
50 }
51
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)52 ErrCode ManageKeepAliveAppsPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
53 HandlePolicyData &policyData, int32_t userId)
54 {
55 EDMLOGI("ManageKeepAliveAppsPlugin OnHandlePolicy.");
56 uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
57 FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
58 std::vector<std::string> keepAliveApps;
59 data.ReadStringVector(&keepAliveApps);
60 bool disallowModify = true;
61 data.ReadBool(disallowModify);
62 std::vector<ManageKeepAliveAppInfo> currentData;
63 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(policyData.policyData, currentData);
64 std::vector<ManageKeepAliveAppInfo> mergeData;
65 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(policyData.mergePolicyData, mergeData);
66 std::string mergePolicyStr;
67 IPolicyManager::GetInstance()->GetPolicy("", GetPolicyName(), mergePolicyStr, userId);
68 std::vector<ManageKeepAliveAppInfo> totalMergePolicyData;
69 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(mergePolicyStr, totalMergePolicyData);
70 ManageKeepAliveAppsSerializer::GetInstance()->UpdateByMergePolicy(currentData,
71 totalMergePolicyData);
72 ErrCode res = EdmReturnErrCode::PARAM_ERROR;
73 std::string errMessage;
74 if (type == FuncOperateType::SET) {
75 res = OnSetPolicy(keepAliveApps, disallowModify, currentData, mergeData, userId);
76 GetErrorMessage(res, errMessage);
77 } else if (type == FuncOperateType::REMOVE) {
78 res = OnRemovePolicy(keepAliveApps, currentData, mergeData, userId);
79 GetErrorMessage(res, errMessage);
80 }
81 if (res != ERR_OK) {
82 reply.WriteInt32(res);
83 reply.WriteString(errMessage);
84 return res;
85 }
86 reply.WriteInt32(ERR_OK);
87 std::string afterHandle;
88 std::string afterMerge;
89 ManageKeepAliveAppsSerializer::GetInstance()->Serialize(currentData, afterHandle);
90 ManageKeepAliveAppsSerializer::GetInstance()->Serialize(mergeData, afterMerge);
91 policyData.isChanged = (policyData.policyData != afterHandle || mergePolicyStr != afterMerge);
92 policyData.policyData = afterHandle;
93 policyData.mergePolicyData = afterMerge;
94 return ERR_OK;
95 }
96
OnSetPolicy(std::vector<std::string> & data,bool disallowModify,std::vector<ManageKeepAliveAppInfo> & currentData,std::vector<ManageKeepAliveAppInfo> & mergeData,int32_t userId)97 ErrCode ManageKeepAliveAppsPlugin::OnSetPolicy(std::vector<std::string> &data, bool disallowModify,
98 std::vector<ManageKeepAliveAppInfo> ¤tData, std::vector<ManageKeepAliveAppInfo> &mergeData, int32_t userId)
99 {
100 if (data.empty()) {
101 EDMLOGW("ManageKeepAliveAppsPlugin OnSetPolicy data is empty.");
102 return ERR_OK;
103 }
104 if (data.size() > maxListSize_) {
105 EDMLOGE("ManageKeepAliveAppsPlugin OnSetPolicy input data is too large.");
106 return EdmReturnErrCode::PARAM_ERROR;
107 }
108 std::vector<ManageKeepAliveAppInfo> tmpData;
109 for (const auto &item : data) {
110 ManageKeepAliveAppInfo appInfo;
111 appInfo.SetBundleName(item);
112 appInfo.SetDisallowModify(disallowModify);
113 tmpData.push_back(appInfo);
114 }
115 std::vector<ManageKeepAliveAppInfo> addData =
116 ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(currentData, tmpData);
117 std::vector<ManageKeepAliveAppInfo> needAddMergeData =
118 ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(mergeData, addData);
119 std::vector<ManageKeepAliveAppInfo> afterHandle =
120 ManageKeepAliveAppsSerializer::GetInstance()->SetUnionPolicyData(currentData, addData);
121 std::vector<ManageKeepAliveAppInfo> afterMerge =
122 ManageKeepAliveAppsSerializer::GetInstance()->SetUnionPolicyData(mergeData, afterHandle);
123 if (afterMerge.size() > maxListSize_) {
124 EDMLOGE("ManageKeepAliveAppsPlugin OnSetPolicy merge data is too large.");
125 return EdmReturnErrCode::PARAM_ERROR;
126 }
127
128 std::vector<ManageKeepAliveAppInfo> failedData;
129 if (!needAddMergeData.empty()) {
130 std::vector<std::string> needAddBundles;
131 for (const ManageKeepAliveAppInfo &appInfo : needAddMergeData) {
132 needAddBundles.push_back(appInfo.GetBundleName());
133 }
134 ErrCode ret = SetOtherModulePolicy(needAddBundles, userId, failedData, disallowModify);
135 if (FAILED(ret)) {
136 return ret;
137 }
138 }
139 if (failedData.empty()) {
140 currentData = afterHandle;
141 mergeData = afterMerge;
142 } else {
143 currentData = ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(failedData, afterHandle);
144 mergeData = ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(failedData, afterMerge);
145 }
146 return ERR_OK;
147 }
148
OnRemovePolicy(std::vector<std::string> & data,std::vector<ManageKeepAliveAppInfo> & currentData,std::vector<ManageKeepAliveAppInfo> & mergeData,int32_t userId)149 ErrCode ManageKeepAliveAppsPlugin::OnRemovePolicy(std::vector<std::string> &data,
150 std::vector<ManageKeepAliveAppInfo> ¤tData, std::vector<ManageKeepAliveAppInfo> &mergeData, int32_t userId)
151 {
152 if (data.empty()) {
153 EDMLOGW("BasicArrayStringPlugin OnRemovePolicy data is empty.");
154 return ERR_OK;
155 }
156 if (data.size() > maxListSize_) {
157 EDMLOGE("BasicArrayStringPlugin OnRemovePolicy input data is too large.");
158 return EdmReturnErrCode::PARAM_ERROR;
159 }
160 std::vector<ManageKeepAliveAppInfo> needRemovePolicy =
161 ManageKeepAliveAppsSerializer::GetInstance()->SetIntersectionPolicyData(data, currentData);
162 std::vector<ManageKeepAliveAppInfo> needRemoveMergePolicy =
163 ManageKeepAliveAppsSerializer::GetInstance()->SetNeedRemoveMergePolicyData(mergeData, needRemovePolicy);
164
165 std::vector<ManageKeepAliveAppInfo> failedData;
166 if (!needRemoveMergePolicy.empty()) {
167 ErrCode ret = RemoveOtherModulePolicy(needRemoveMergePolicy, userId, failedData);
168 if (FAILED(ret)) {
169 return ret;
170 }
171 }
172 if (failedData.empty()) {
173 currentData = ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(needRemovePolicy,
174 currentData);
175 } else {
176 auto removeData = ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(failedData,
177 needRemovePolicy);
178 currentData = ManageKeepAliveAppsSerializer::GetInstance()->SetDifferencePolicyData(removeData,
179 currentData);
180 }
181 mergeData = ManageKeepAliveAppsSerializer::GetInstance()->SetUnionPolicyData(currentData, mergeData);
182 return ERR_OK;
183 }
184
SetOtherModulePolicy(const std::vector<std::string> & keepAliveApps,int32_t userId,std::vector<ManageKeepAliveAppInfo> & failedData,bool disallowModify)185 ErrCode ManageKeepAliveAppsPlugin::SetOtherModulePolicy(const std::vector<std::string> &keepAliveApps,
186 int32_t userId, std::vector<ManageKeepAliveAppInfo> &failedData, bool disallowModify)
187 {
188 EDMLOGI("ManageKeepAliveAppsPlugin AddKeepAliveApps");
189 auto abilityManager = GetAbilityManager();
190 if (!abilityManager) {
191 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps get abilityManager failed.");
192 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
193 }
194
195 auto appControlProxy = GetAppControlProxy();
196 if (!appControlProxy) {
197 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps appControlProxy failed.");
198 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
199 }
200
201 std::vector<std::string> disallowedRunningBundles;
202 ErrCode ret = appControlProxy->GetAppRunningControlRule(userId, disallowedRunningBundles);
203 if (ret != ERR_OK) {
204 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps GetAppRunningControlRule failed.");
205 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
206 }
207
208 bool flag = false;
209 int32_t res = ERR_OK;
210 for (const auto &bundleName : keepAliveApps) {
211 auto it = std::find(disallowedRunningBundles.begin(), disallowedRunningBundles.end(), bundleName);
212 if (it != disallowedRunningBundles.end()) {
213 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps bundleName: %{public}s is disallowed running.",
214 bundleName.c_str());
215 return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
216 }
217 res = abilityManager->SetApplicationKeepAliveByEDM(bundleName, userId, true, !disallowModify);
218 if (res != ERR_OK) {
219 EDMLOGE("AddKeepAliveApps SetApplicationKeepAliveByEDM err res: %{public}d bundleName: %{public}s ",
220 res, bundleName.c_str());
221 ManageKeepAliveAppInfo appInfo;
222 appInfo.SetBundleName(bundleName);
223 appInfo.SetDisallowModify(disallowModify);
224 failedData.push_back(appInfo);
225 continue;
226 }
227 flag = true;
228 }
229 ParseErrCode(res);
230 return flag ? ERR_OK : res;
231 }
RemoveOtherModulePolicy(const std::vector<ManageKeepAliveAppInfo> & keepAliveApps,int32_t userId,std::vector<ManageKeepAliveAppInfo> & failedData)232 ErrCode ManageKeepAliveAppsPlugin::RemoveOtherModulePolicy(const std::vector<ManageKeepAliveAppInfo> &keepAliveApps,
233 int32_t userId, std::vector<ManageKeepAliveAppInfo> &failedData)
234 {
235 EDMLOGI("ManageKeepAliveAppsPlugin RemoveKeepAliveApps");
236 auto abilityManager = GetAbilityManager();
237 if (!abilityManager) {
238 EDMLOGE("ManageKeepAliveAppsPlugin RemoveKeepAliveApps get abilityManager failed.");
239 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
240 }
241 bool flag = false;
242 int32_t res = ERR_OK;
243 for (const ManageKeepAliveAppInfo &bundleName : keepAliveApps) {
244 res = abilityManager->SetApplicationKeepAliveByEDM(bundleName.GetBundleName(), userId, false);
245 if (res != ERR_OK) {
246 EDMLOGE("RemoveKeepAliveApps SetApplicationKeepAliveByEDM err res: %{public}d bundleName: %{public}s ", res,
247 bundleName.GetBundleName().c_str());
248 failedData.push_back(bundleName);
249 continue;
250 }
251 flag = true;
252 }
253 ParseErrCode(res);
254 return flag ? ERR_OK : res;
255 }
256
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)257 ErrCode ManageKeepAliveAppsPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
258 int32_t userId)
259 {
260 EDMLOGI("ManageKeepAliveAppsPlugin OnGetPolicy.");
261 std::string type = data.ReadString();
262 if (type == EdmConstants::KeepAlive::GET_MANAGE_KEEP_ALIVE_APPS_BUNDLE_NAME) {
263 std::vector<ManageKeepAliveAppInfo> appInfos;
264 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(policyData, appInfos);
265 std::vector<std::string> policies;
266 for (const ManageKeepAliveAppInfo &item : appInfos) {
267 policies.push_back(item.GetBundleName());
268 }
269 reply.WriteInt32(ERR_OK);
270 reply.WriteStringVector(policies);
271 } else if (type == EdmConstants::KeepAlive::GET_MANAGE_KEEP_ALIVE_APP_DISALLOW_MODIFY) {
272 std::string bundleName = data.ReadString();
273 std::string mergePolicyStr;
274 IPolicyManager::GetInstance()->GetPolicy("", GetPolicyName(), mergePolicyStr, userId);
275 std::vector<ManageKeepAliveAppInfo> mergePolicyData;
276 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(mergePolicyStr, mergePolicyData);
277 bool hasSetKeepAlive = false;
278 for (const ManageKeepAliveAppInfo &item : mergePolicyData) {
279 if (item.GetBundleName() == bundleName) {
280 reply.WriteInt32(ERR_OK);
281 reply.WriteBool(item.GetDisallowModify());
282 hasSetKeepAlive = true;
283 break;
284 }
285 }
286 if (!hasSetKeepAlive) {
287 reply.WriteInt32(ERR_OK);
288 reply.WriteBool(false);
289 }
290 } else {
291 EDMLOGE("ManageKeepAliveAppsPlugin::OnGetPolicy type error");
292 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
293 }
294 return ERR_OK;
295 }
296
OnAdminRemove(const std::string & adminName,const std::string & currentJsonData,const std::string & mergeJsonData,int32_t userId)297 ErrCode ManageKeepAliveAppsPlugin::OnAdminRemove(const std::string &adminName, const std::string ¤tJsonData,
298 const std::string &mergeJsonData, int32_t userId)
299 {
300 EDMLOGI("ManageKeepAliveAppsPlugin OnAdminRemoveDone");
301
302 std::vector<ManageKeepAliveAppInfo> currentData;
303 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(currentJsonData, currentData);
304 std::vector<ManageKeepAliveAppInfo> mergeData;
305 ManageKeepAliveAppsSerializer::GetInstance()->Deserialize(mergeJsonData, mergeData);
306 std::vector<ManageKeepAliveAppInfo> needRemoveMergePolicy =
307 ManageKeepAliveAppsSerializer::GetInstance()->SetNeedRemoveMergePolicyData(mergeData, currentData);
308 std::vector<ManageKeepAliveAppInfo> failedData;
309 return RemoveOtherModulePolicy(needRemoveMergePolicy, userId, failedData);
310 }
311
GetOthersMergePolicyData(const std::string & adminName,int32_t userId,std::string & othersMergePolicyData)312 ErrCode ManageKeepAliveAppsPlugin::GetOthersMergePolicyData(const std::string &adminName, int32_t userId,
313 std::string &othersMergePolicyData)
314 {
315 std::unordered_map<std::string, std::string> adminValues;
316 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues, userId);
317 EDMLOGI("IPluginTemplate::GetOthersMergePolicyData %{public}s value size %{public}d.", GetPolicyName().c_str(),
318 (uint32_t)adminValues.size());
319 if (adminValues.empty()) {
320 return ERR_OK;
321 }
322 auto entry = adminValues.find(adminName);
323 if (entry != adminValues.end()) {
324 adminValues.erase(entry);
325 }
326 if (adminValues.empty()) {
327 return ERR_OK;
328 }
329 auto serializer = ManageKeepAliveAppsSerializer::GetInstance();
330 std::vector<std::vector<ManageKeepAliveAppInfo>> data;
331 for (const auto &item : adminValues) {
332 std::vector<ManageKeepAliveAppInfo> dataItem;
333 if (!item.second.empty()) {
334 if (!serializer->Deserialize(item.second, dataItem)) {
335 return ERR_EDM_OPERATE_JSON;
336 }
337 data.push_back(dataItem);
338 }
339 }
340 std::vector<ManageKeepAliveAppInfo> result;
341 if (!serializer->MergePolicy(data, result)) {
342 return ERR_EDM_OPERATE_JSON;
343 }
344
345 std::string mergePolicyStr;
346 IPolicyManager::GetInstance()->GetPolicy("", GetPolicyName(), mergePolicyStr, userId);
347 std::vector<ManageKeepAliveAppInfo> mergePolicyData;
348 if (!serializer->Deserialize(mergePolicyStr, mergePolicyData)) {
349 return ERR_EDM_OPERATE_JSON;
350 }
351
352 if (!serializer->UpdateByMergePolicy(result, mergePolicyData)) {
353 return ERR_EDM_OPERATE_JSON;
354 }
355
356 if (!serializer->Serialize(result, othersMergePolicyData)) {
357 return ERR_EDM_OPERATE_JSON;
358 }
359
360 return ERR_OK;
361 }
362
ParseErrCode(ErrCode & res)363 void ManageKeepAliveAppsPlugin::ParseErrCode(ErrCode &res)
364 {
365 if (res == ERR_CAPABILITY_NOT_SUPPORT) {
366 res = EdmReturnErrCode::INTERFACE_UNSUPPORTED;
367 return;
368 }
369 if (res != ERR_TARGET_BUNDLE_NOT_EXIST && res != ERR_NO_MAIN_ABILITY && res != ERR_NO_STATUS_BAR_ABILITY &&
370 res != ERR_NOT_ATTACHED_TO_STATUS_BAR) {
371 res = EdmReturnErrCode::SYSTEM_ABNORMALLY;
372 }
373 }
374
GetErrorMessage(ErrCode & errCode,std::string & errMessage)375 void ManageKeepAliveAppsPlugin::GetErrorMessage(ErrCode &errCode, std::string &errMessage)
376 {
377 switch (errCode) {
378 case ERR_TARGET_BUNDLE_NOT_EXIST:
379 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
380 errMessage = "Application is not installed.";
381 break;
382 case ERR_NO_MAIN_ABILITY:
383 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
384 errMessage = "Application does not have mainability.";
385 break;
386 case ERR_NO_STATUS_BAR_ABILITY:
387 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
388 errMessage = "Application does not have status bar ability.";
389 break;
390 case ERR_NOT_ATTACHED_TO_STATUS_BAR:
391 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
392 errMessage = "Application does not attach to status bar.";
393 break;
394 default:
395 break;
396 }
397 }
398
GetAbilityManager()399 sptr<AAFwk::IAbilityManager> ManageKeepAliveAppsPlugin::GetAbilityManager()
400 {
401 auto abilityObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::ABILITY_MGR_SERVICE_ID);
402 return iface_cast<AAFwk::IAbilityManager>(abilityObject);
403 }
404
GetAppControlProxy()405 sptr<AppExecFwk::IAppControlMgr> ManageKeepAliveAppsPlugin::GetAppControlProxy()
406 {
407 auto remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
408 sptr<AppExecFwk::IBundleMgr> proxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
409 if (!proxy) {
410 EDMLOGE("ManageKeepAliveAppsPlugin GetAppControlProxy failed.");
411 return nullptr;
412 }
413 return proxy->GetAppControlProxy();
414 }
415 } // namespace EDM
416 } // namespace OHOS