• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &currentData, 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> &currentData, 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 &currentJsonData,
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