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 "ability_keep_alive_service.h"
17
18 #include "ability_keep_alive_data_manager.h"
19 #include "ability_manager_service.h"
20 #include "hilog_tag_wrapper.h"
21
22 namespace OHOS {
23 namespace AbilityRuntime {
24 using namespace OHOS::AAFwk;
25
GetInstance()26 AbilityKeepAliveService &AbilityKeepAliveService::GetInstance()
27 {
28 static AbilityKeepAliveService instance;
29 return instance;
30 }
31
AbilityKeepAliveService()32 AbilityKeepAliveService::AbilityKeepAliveService() {}
33
~AbilityKeepAliveService()34 AbilityKeepAliveService::~AbilityKeepAliveService() {}
35
SetApplicationKeepAlive(KeepAliveInfo & info,bool flag)36 int32_t AbilityKeepAliveService::SetApplicationKeepAlive(KeepAliveInfo &info, bool flag)
37 {
38 TAG_LOGD(AAFwkTag::KEEP_ALIVE, "SetApplicationKeepAlive is called,"
39 " bundleName: %{public}s, userId: %{public}d, flag: %{public}d",
40 info.bundleName.c_str(), info.userId, static_cast<int>(flag));
41
42 GetValidUserId(info.userId);
43
44 if (flag) {
45 return SetKeepAliveTrue(info);
46 }
47 return CancelKeepAlive(info);
48 }
49
SetKeepAliveTrue(const KeepAliveInfo & info)50 int32_t AbilityKeepAliveService::SetKeepAliveTrue(const KeepAliveInfo &info)
51 {
52 KeepAliveStatus status = AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveData(info);
53 if (status.code != ERR_OK && status.code != ERR_NAME_NOT_FOUND) {
54 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "QueryKeepAliveData fail");
55 return status.code;
56 }
57
58 if (status.code == ERR_NAME_NOT_FOUND) {
59 return AbilityKeepAliveDataManager::GetInstance().InsertKeepAliveData(info);
60 }
61
62 if (static_cast<int32_t>(status.setter) <= static_cast<int32_t>(info.setter)) {
63 TAG_LOGI(AAFwkTag::KEEP_ALIVE, "app is already set");
64 return ERR_OK;
65 }
66
67 (void)AbilityKeepAliveDataManager::GetInstance().DeleteKeepAliveData(info);
68 return AbilityKeepAliveDataManager::GetInstance().InsertKeepAliveData(info);
69 }
70
CancelKeepAlive(const KeepAliveInfo & info)71 int32_t AbilityKeepAliveService::CancelKeepAlive(const KeepAliveInfo &info)
72 {
73 KeepAliveStatus status = AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveData(info);
74 if (status.code != ERR_OK && status.code != ERR_NAME_NOT_FOUND) {
75 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "QueryKeepAliveData fail");
76 return status.code;
77 }
78
79 if (status.code == ERR_NAME_NOT_FOUND) {
80 return ERR_TARGET_BUNDLE_NOT_EXIST;
81 }
82
83 if (static_cast<int32_t>(status.setter) < static_cast<int32_t>(info.setter)) {
84 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "app is set keep-alive by system, cannot unset by user");
85 return CHECK_PERMISSION_FAILED;
86 }
87
88 return AbilityKeepAliveDataManager::GetInstance().DeleteKeepAliveData(info);
89 }
90
QueryKeepAliveApplications(int32_t userId,int32_t appType,std::vector<KeepAliveInfo> & infoList)91 int32_t AbilityKeepAliveService::QueryKeepAliveApplications(int32_t userId,
92 int32_t appType, std::vector<KeepAliveInfo> &infoList)
93 {
94 GetValidUserId(userId);
95 KeepAliveInfo queryParam;
96 queryParam.userId = userId;
97 queryParam.appType = KeepAliveAppType(appType);
98 return AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveApplications(
99 queryParam, infoList);
100 }
101
GetValidUserId(int32_t & userId)102 void AbilityKeepAliveService::GetValidUserId(int32_t &userId)
103 {
104 if (userId >= 0) {
105 return;
106 }
107 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
108 if (abilityMgr == nullptr) {
109 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "null abilityMgr");
110 return;
111 }
112
113 if (userId < 0) {
114 userId = abilityMgr->GetUserId();
115 }
116 }
117
IsKeepAliveApp(const std::string & bundleName,int32_t userId)118 bool AbilityKeepAliveService::IsKeepAliveApp(const std::string &bundleName, int32_t userId)
119 {
120 if (bundleName.empty()) {
121 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "bundle name empty");
122 return false;
123 }
124
125 GetValidUserId(userId);
126 KeepAliveInfo info;
127 info.bundleName = bundleName;
128 info.userId = userId;
129 KeepAliveStatus status = AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveData(info);
130 return (status.code == ERR_OK);
131 }
132
GetKeepAliveApplications(int32_t userId,std::vector<KeepAliveInfo> & infoList)133 int32_t AbilityKeepAliveService::GetKeepAliveApplications(int32_t userId, std::vector<KeepAliveInfo> &infoList)
134 {
135 KeepAliveInfo queryParam;
136 queryParam.userId = userId;
137 return AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveApplications(
138 queryParam, infoList);
139 }
140
SetAppServiceExtensionKeepAlive(KeepAliveInfo & info,bool flag)141 int32_t AbilityKeepAliveService::SetAppServiceExtensionKeepAlive(KeepAliveInfo &info, bool flag)
142 {
143 TAG_LOGD(AAFwkTag::KEEP_ALIVE, "SetAppServiceExtensionKeepAlive is called,"
144 " bundleName: %{public}s, userId: %{public}d, flag: %{public}d",
145 info.bundleName.c_str(), info.userId, static_cast<int>(flag));
146
147 KeepAliveStatus status = AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveData(info);
148 if (status.code != ERR_OK && status.code != ERR_NAME_NOT_FOUND) {
149 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "QueryKeepAliveData fail");
150 return status.code;
151 }
152
153 if (status.code == ERR_NAME_NOT_FOUND) {
154 return flag ? AbilityKeepAliveDataManager::GetInstance().InsertKeepAliveData(info) :
155 ERR_GET_TARGET_BUNDLE_INFO_FAILED;
156 }
157
158 if (!flag) {
159 if (info.setterId != status.setterId && info.setter == status.setter) {
160 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "setter id is different, cannot unset");
161 return ERR_CHANGE_KEEP_ALIVE;
162 } else if (info.setter == KeepAliveSetter::USER && status.policy == KeepAlivePolicy::NOT_ALLOW_CANCEL) {
163 TAG_LOGE(AAFwkTag::KEEP_ALIVE, "app service extension is set keep-alive by system, cannot unset by user");
164 return ERR_CHANGE_KEEP_ALIVE;
165 }
166 return AbilityKeepAliveDataManager::GetInstance().DeleteKeepAliveData(info);
167 }
168
169 if (info.setter == KeepAliveSetter::USER ||
170 (info.setter == KeepAliveSetter::SYSTEM && info.policy == status.policy)) {
171 TAG_LOGI(AAFwkTag::KEEP_ALIVE, "app service extension is already set");
172 return ERR_OK;
173 }
174
175 (void)AbilityKeepAliveDataManager::GetInstance().DeleteKeepAliveData(info);
176 return AbilityKeepAliveDataManager::GetInstance().InsertKeepAliveData(info);
177 }
178
QueryKeepAliveAppServiceExtensions(std::vector<KeepAliveInfo> & infoList)179 int32_t AbilityKeepAliveService::QueryKeepAliveAppServiceExtensions(std::vector<KeepAliveInfo> &infoList)
180 {
181 KeepAliveInfo queryParam;
182 queryParam.userId = U1_USER_ID;
183 return AbilityKeepAliveDataManager::GetInstance().QueryKeepAliveApplications(
184 queryParam, infoList);
185 }
186
ClearKeepAliveAppServiceExtension(const KeepAliveInfo & info)187 int32_t AbilityKeepAliveService::ClearKeepAliveAppServiceExtension(const KeepAliveInfo &info)
188 {
189 TAG_LOGD(AAFwkTag::KEEP_ALIVE, "ClearKeepAliveAppServiceExtension is called,"
190 "setterId: %{public}d", info.setterId);
191 return AbilityKeepAliveDataManager::GetInstance().DeleteKeepAliveDataWithSetterId(info);
192 }
193 } // namespace AbilityRuntime
194 } // namespace OHOS
195