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 "array_string_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_ = "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 std::vector<std::string> currentData;
61 ArrayStringSerializer::GetInstance()->Deserialize(policyData.policyData, currentData);
62 std::vector<std::string> mergeData;
63 ArrayStringSerializer::GetInstance()->Deserialize(policyData.mergePolicyData, mergeData);
64 ErrCode res = EdmReturnErrCode::PARAM_ERROR;
65 std::string errMessage;
66 if (type == FuncOperateType::SET) {
67 res = OnBasicSetPolicy(keepAliveApps, currentData, mergeData, userId);
68 GetErrorMessage(res, errMessage);
69 } else if (type == FuncOperateType::REMOVE) {
70 res = OnBasicRemovePolicy(keepAliveApps, currentData, mergeData, userId);
71 GetErrorMessage(res, errMessage);
72 }
73 if (res != ERR_OK) {
74 reply.WriteInt32(res);
75 reply.WriteString(errMessage);
76 return res;
77 }
78 reply.WriteInt32(ERR_OK);
79 std::string afterHandle;
80 std::string afterMerge;
81 ArrayStringSerializer::GetInstance()->Serialize(currentData, afterHandle);
82 ArrayStringSerializer::GetInstance()->Serialize(mergeData, afterMerge);
83 policyData.isChanged = (policyData.policyData != afterHandle);
84 policyData.policyData = afterHandle;
85 policyData.mergePolicyData = afterMerge;
86 return ERR_OK;
87 }
88
SetOtherModulePolicy(const std::vector<std::string> & keepAliveApps,int32_t userId,std::vector<std::string> & failedData)89 ErrCode ManageKeepAliveAppsPlugin::SetOtherModulePolicy(const std::vector<std::string> &keepAliveApps,
90 int32_t userId, std::vector<std::string> &failedData)
91 {
92 EDMLOGI("ManageKeepAliveAppsPlugin AddKeepAliveApps");
93 auto abilityManager = GetAbilityManager();
94 if (!abilityManager) {
95 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps get abilityManager failed.");
96 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
97 }
98
99 auto appControlProxy = GetAppControlProxy();
100 if (!appControlProxy) {
101 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps appControlProxy failed.");
102 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
103 }
104
105 std::vector<std::string> disallowedRunningBundles;
106 ErrCode ret = appControlProxy->GetAppRunningControlRule(userId, disallowedRunningBundles);
107 if (ret != ERR_OK) {
108 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps GetAppRunningControlRule failed.");
109 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
110 }
111
112 bool flag = false;
113 int32_t res = ERR_OK;
114 for (const auto &bundleName : keepAliveApps) {
115 auto it = std::find(disallowedRunningBundles.begin(), disallowedRunningBundles.end(), bundleName);
116 if (it != disallowedRunningBundles.end()) {
117 EDMLOGE("ManageKeepAliveAppsPlugin AddKeepAliveApps bundleName: %{public}s is disallowed running.",
118 bundleName.c_str());
119 return EdmReturnErrCode::CONFIGURATION_CONFLICT_FAILED;
120 }
121 res = abilityManager->SetApplicationKeepAliveByEDM(bundleName, userId, true);
122 if (res != ERR_OK) {
123 EDMLOGE("AddKeepAliveApps SetApplicationKeepAliveByEDM err res: %{public}d bundleName: %{public}s ",
124 res, bundleName.c_str());
125 failedData.push_back(bundleName);
126 continue;
127 }
128 flag = true;
129 }
130 ParseErrCode(res);
131 return flag ? ERR_OK : res;
132 }
RemoveOtherModulePolicy(const std::vector<std::string> & keepAliveApps,int32_t userId,std::vector<std::string> & failedData)133 ErrCode ManageKeepAliveAppsPlugin::RemoveOtherModulePolicy(const std::vector<std::string> &keepAliveApps,
134 int32_t userId, std::vector<std::string> &failedData)
135 {
136 EDMLOGI("ManageKeepAliveAppsPlugin RemoveKeepAliveApps");
137 auto abilityManager = GetAbilityManager();
138 if (!abilityManager) {
139 EDMLOGE("ManageKeepAliveAppsPlugin RemoveKeepAliveApps get abilityManager failed.");
140 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
141 }
142 bool flag = false;
143 int32_t res = ERR_OK;
144 for (const auto &bundleName : keepAliveApps) {
145 res = abilityManager->SetApplicationKeepAliveByEDM(bundleName, userId, false);
146 if (res != ERR_OK) {
147 EDMLOGE("RemoveKeepAliveApps SetApplicationKeepAliveByEDM err res: %{public}d bundleName: %{public}s ", res,
148 bundleName.c_str());
149 failedData.push_back(bundleName);
150 continue;
151 }
152 flag = true;
153 }
154 ParseErrCode(res);
155 return flag ? ERR_OK : res;
156 }
157
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)158 ErrCode ManageKeepAliveAppsPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
159 int32_t userId)
160 {
161 EDMLOGI("ManageKeepAliveAppsPlugin OnGetPolicy.");
162 return BasicGetPolicy(policyData, data, reply, userId);
163 }
164
OnAdminRemove(const std::string & adminName,const std::string & currentJsonData,const std::string & mergeJsonData,int32_t userId)165 ErrCode ManageKeepAliveAppsPlugin::OnAdminRemove(const std::string &adminName, const std::string ¤tJsonData,
166 const std::string &mergeJsonData, int32_t userId)
167 {
168 EDMLOGI("ManageKeepAliveAppsPlugin OnAdminRemoveDone");
169
170 std::vector<std::string> currentData;
171 ArrayStringSerializer::GetInstance()->Deserialize(currentJsonData, currentData);
172 std::vector<std::string> mergeData;
173 ArrayStringSerializer::GetInstance()->Deserialize(mergeJsonData, mergeData);
174 return OnBasicAdminRemove(adminName, currentData, mergeData, userId);
175 }
176
GetOthersMergePolicyData(const std::string & adminName,std::string & othersMergePolicyData)177 ErrCode ManageKeepAliveAppsPlugin::GetOthersMergePolicyData(const std::string &adminName,
178 std::string &othersMergePolicyData)
179 {
180 std::unordered_map<std::string, std::string> adminValues;
181 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
182 EDMLOGI("IPluginTemplate::GetOthersMergePolicyData %{public}s value size %{public}d.", GetPolicyName().c_str(),
183 (uint32_t)adminValues.size());
184 if (adminValues.empty()) {
185 return ERR_OK;
186 }
187 auto entry = adminValues.find(adminName);
188 if (entry != adminValues.end()) {
189 adminValues.erase(entry);
190 }
191 if (adminValues.empty()) {
192 return ERR_OK;
193 }
194 auto serializer = ArrayStringSerializer::GetInstance();
195 std::vector<std::vector<std::string>> data;
196 for (const auto &item : adminValues) {
197 std::vector<std::string> dataItem;
198 if (!item.second.empty()) {
199 if (!serializer->Deserialize(item.second, dataItem)) {
200 return ERR_EDM_OPERATE_JSON;
201 }
202 data.push_back(dataItem);
203 }
204 }
205 std::vector<std::string> result;
206 if (!serializer->MergePolicy(data, result)) {
207 return ERR_EDM_OPERATE_JSON;
208 }
209 if (!serializer->Serialize(result, othersMergePolicyData)) {
210 return ERR_EDM_OPERATE_JSON;
211 }
212 return ERR_OK;
213 }
214
ParseErrCode(ErrCode & res)215 void ManageKeepAliveAppsPlugin::ParseErrCode(ErrCode &res)
216 {
217 if (res == ERR_CAPABILITY_NOT_SUPPORT) {
218 res = EdmReturnErrCode::INTERFACE_UNSUPPORTED;
219 return;
220 }
221 if (res != ERR_TARGET_BUNDLE_NOT_EXIST && res != ERR_NO_MAIN_ABILITY && res != ERR_NO_STATUS_BAR_ABILITY &&
222 res != ERR_NOT_ATTACHED_TO_STATUS_BAR) {
223 res = EdmReturnErrCode::SYSTEM_ABNORMALLY;
224 }
225 }
226
GetErrorMessage(ErrCode & errCode,std::string & errMessage)227 void ManageKeepAliveAppsPlugin::GetErrorMessage(ErrCode &errCode, std::string &errMessage)
228 {
229 switch (errCode) {
230 case ERR_TARGET_BUNDLE_NOT_EXIST:
231 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
232 errMessage = "Application is not installed.";
233 break;
234 case ERR_NO_MAIN_ABILITY:
235 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
236 errMessage = "Application does not have mainability.";
237 break;
238 case ERR_NO_STATUS_BAR_ABILITY:
239 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
240 errMessage = "Application does not have status bar ability.";
241 break;
242 case ERR_NOT_ATTACHED_TO_STATUS_BAR:
243 errCode = EdmReturnErrCode::ADD_KEEP_ALIVE_APP_FAILED;
244 errMessage = "Application does not attach to status bar.";
245 break;
246 default:
247 break;
248 }
249 }
250
GetAbilityManager()251 sptr<AAFwk::IAbilityManager> ManageKeepAliveAppsPlugin::GetAbilityManager()
252 {
253 auto abilityObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::ABILITY_MGR_SERVICE_ID);
254 return iface_cast<AAFwk::IAbilityManager>(abilityObject);
255 }
256
GetAppControlProxy()257 sptr<AppExecFwk::IAppControlMgr> ManageKeepAliveAppsPlugin::GetAppControlProxy()
258 {
259 auto remoteObject = EdmSysManager::GetRemoteObjectOfSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
260 sptr<AppExecFwk::IBundleMgr> proxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
261 if (!proxy) {
262 EDMLOGE("ManageKeepAliveAppsPlugin GetAppControlProxy failed.");
263 return nullptr;
264 }
265 return proxy->GetAppControlProxy();
266 }
267 } // namespace EDM
268 } // namespace OHOS