1 /*
2 * Copyright (c) 2022-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 "module_running_record.h"
17 #include "app_mgr_service_inner.h"
18 #include "app_running_record.h"
19 #include "hilog_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "ui_extension_utils.h"
22 #include "cache_process_manager.h"
23
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 const std::string ABILITY_OWNER_USERID = "AbilityMS_Owner_UserId";
28 }
ModuleRunningRecord(const std::shared_ptr<ApplicationInfo> & info,const std::shared_ptr<AMSEventHandler> & eventHandler)29 ModuleRunningRecord::ModuleRunningRecord(
30 const std::shared_ptr<ApplicationInfo> &info, const std::shared_ptr<AMSEventHandler> &eventHandler)
31 : appInfo_(info), eventHandler_(eventHandler)
32 {}
33
~ModuleRunningRecord()34 ModuleRunningRecord::~ModuleRunningRecord()
35 {
36 TAG_LOGD(AAFwkTag::APPMGR, "called");
37 }
38
Init(const HapModuleInfo & info)39 void ModuleRunningRecord::Init(const HapModuleInfo &info)
40 {
41 owenInfo_ = info;
42 owenState_ = ModuleRecordState::INITIALIZED_STATE;
43 }
44
GetModuleName() const45 const std::string &ModuleRunningRecord::GetModuleName() const
46 {
47 return owenInfo_.moduleName;
48 }
49
GetAppInfo()50 const std::shared_ptr<ApplicationInfo> ModuleRunningRecord::GetAppInfo()
51 {
52 return appInfo_;
53 }
54
GetAbilityRunningRecordByToken(const sptr<IRemoteObject> & token) const55 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityRunningRecordByToken(
56 const sptr<IRemoteObject> &token) const
57 {
58 if (!token) {
59 TAG_LOGE(AAFwkTag::APPMGR, "token is null");
60 return nullptr;
61 }
62 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
63 const auto &iter = abilities_.find(token);
64 if (iter != abilities_.end()) {
65 return iter->second;
66 }
67 return nullptr;
68 }
69
AddAbility(sptr<IRemoteObject> token,std::shared_ptr<AbilityInfo> abilityInfo,std::shared_ptr<AAFwk::Want> want,int32_t abilityRecordId)70 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::AddAbility(sptr<IRemoteObject> token,
71 std::shared_ptr<AbilityInfo> abilityInfo, std::shared_ptr<AAFwk::Want> want, int32_t abilityRecordId)
72 {
73 TAG_LOGD(AAFwkTag::APPMGR, "Add ability.");
74 if (!token || !abilityInfo) {
75 TAG_LOGE(AAFwkTag::APPMGR, "Param abilityInfo or token is null");
76 return nullptr;
77 }
78 if (GetAbilityRunningRecordByToken(token)) {
79 TAG_LOGE(AAFwkTag::APPMGR, "AbilityRecord already exists and no need to add");
80 return nullptr;
81 }
82 auto abilityRecord = std::make_shared<AbilityRunningRecord>(abilityInfo, token, abilityRecordId);
83 abilityRecord->SetWant(want);
84 if (appInfo_) {
85 abilityRecord->SetIsSingleUser(appInfo_->singleton);
86 }
87 if (want) {
88 abilityRecord->SetOwnerUserId(want->GetIntParam(ABILITY_OWNER_USERID, -1));
89 }
90 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
91 abilities_.emplace(token, abilityRecord);
92 return abilityRecord;
93 }
94
IsLastAbilityRecord(const sptr<IRemoteObject> & token)95 bool ModuleRunningRecord::IsLastAbilityRecord(const sptr<IRemoteObject> &token)
96 {
97 if (!token) {
98 TAG_LOGE(AAFwkTag::APPMGR, "token is nullptr");
99 return false;
100 }
101 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
102 return ((abilities_.size() == 1) && (abilities_.find(token) != abilities_.end()));
103 }
104
GetPageAbilitySize()105 int32_t ModuleRunningRecord::GetPageAbilitySize()
106 {
107 int pageAbilitySize = 0;
108 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
109 for (auto it : abilities_) {
110 std::shared_ptr<AbilityRunningRecord> abilityRunningRecord = it.second;
111 std::shared_ptr<AbilityInfo> abilityInfo = abilityRunningRecord->GetAbilityInfo();
112 if (abilityInfo && abilityInfo->type == AbilityType::PAGE) {
113 pageAbilitySize++;
114 }
115 }
116
117 return pageAbilitySize;
118 }
119
ExtensionAbilityRecordExists()120 bool ModuleRunningRecord::ExtensionAbilityRecordExists()
121 {
122 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
123 for (auto it : abilities_) {
124 std::shared_ptr<AbilityRunningRecord> abilityRunningRecord = it.second;
125 std::shared_ptr<AbilityInfo> abilityInfo = abilityRunningRecord->GetAbilityInfo();
126 if (abilityInfo && abilityInfo->type != AbilityType::PAGE) {
127 return true;
128 }
129 }
130 return false;
131 }
132
GetAbilities() const133 const std::map<const sptr<IRemoteObject>, std::shared_ptr<AbilityRunningRecord>> ModuleRunningRecord::GetAbilities()
134 const
135 {
136 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
137 return abilities_;
138 }
139
GetAbilityByTerminateLists(const sptr<IRemoteObject> & token) const140 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityByTerminateLists(
141 const sptr<IRemoteObject> &token) const
142 {
143 if (!token) {
144 TAG_LOGE(AAFwkTag::APPMGR, "GetAbilityByTerminateLists error, token is null");
145 return nullptr;
146 }
147 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
148 const auto &iter = terminateAbilities_.find(token);
149 if (iter != terminateAbilities_.end()) {
150 return iter->second;
151 }
152 return nullptr;
153 }
154
GetAbilityRunningRecord(const int64_t eventId) const155 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityRunningRecord(const int64_t eventId) const
156 {
157 TAG_LOGD(AAFwkTag::APPMGR, "called");
158 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
159 const auto &iter = std::find_if(abilities_.begin(), abilities_.end(), [eventId](const auto &pair) {
160 return pair.second->GetEventId() == eventId;
161 });
162 if (iter != abilities_.end()) {
163 return iter->second;
164 }
165
166 const auto &finder = std::find_if(terminateAbilities_.begin(),
167 terminateAbilities_.end(),
168 [eventId](const auto &pair) { return pair.second->GetEventId() == eventId; });
169 if (finder != terminateAbilities_.end()) {
170 return finder->second;
171 }
172 return nullptr;
173 }
174
OnAbilityStateChanged(const std::shared_ptr<AbilityRunningRecord> & ability,const AbilityState state)175 void ModuleRunningRecord::OnAbilityStateChanged(
176 const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
177 {
178 if (!ability) {
179 TAG_LOGE(AAFwkTag::APPMGR, "ability is null");
180 return;
181 }
182 AbilityState oldState = ability->GetState();
183 ability->SetState(state);
184 TAG_LOGI(AAFwkTag::APPMGR,
185 "Ability state change from %{public}d to %{public}d. bundle: %{public}s, ability: %{public}s.", oldState, state,
186 ability->GetAbilityInfo()->bundleName.c_str(), ability->GetName().c_str());
187 auto serviceInner = appMgrServiceInner_.lock();
188 if (serviceInner) {
189 serviceInner->OnAbilityStateChanged(ability, state);
190 }
191 }
192
LaunchAbility(const std::shared_ptr<AbilityRunningRecord> & ability)193 void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
194 {
195 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
196 TAG_LOGD(AAFwkTag::APPMGR, "called");
197 if (!ability || !ability->GetToken()) {
198 TAG_LOGE(AAFwkTag::APPMGR, "null abilityRecord or abilityToken");
199 return;
200 }
201 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
202 const auto &iter = abilities_.find(ability->GetToken());
203 if (iter != abilities_.end() && appLifeCycleDeal_->GetApplicationClient()) {
204 TAG_LOGD(AAFwkTag::APPMGR, "Schedule launch ability, name is %{public}s.", ability->GetName().c_str());
205 appLifeCycleDeal_->LaunchAbility(ability);
206 ability->SetState(AbilityState::ABILITY_STATE_READY);
207 } else {
208 TAG_LOGE(AAFwkTag::APPMGR, "Can not find ability or get appThread.");
209 }
210 }
211
LaunchPendingAbilities()212 void ModuleRunningRecord::LaunchPendingAbilities()
213 {
214 TAG_LOGD(AAFwkTag::APPMGR, "Launch pending abilities.");
215 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
216 if (abilities_.empty()) {
217 TAG_LOGE(AAFwkTag::APPMGR, "abilities_ is empty");
218 return;
219 }
220
221 for (const auto &item : abilities_) {
222 const auto &ability = item.second;
223 TAG_LOGD(AAFwkTag::APPMGR, "state : %{public}d", ability->GetState());
224 if (ability->GetState() == AbilityState::ABILITY_STATE_CREATE && ability->GetToken() &&
225 appLifeCycleDeal_->GetApplicationClient()) {
226 TAG_LOGD(AAFwkTag::APPMGR, "name is %{public}s.", ability->GetName().c_str());
227 appLifeCycleDeal_->LaunchAbility(ability);
228 ability->SetState(AbilityState::ABILITY_STATE_READY);
229 }
230 }
231 }
232
TerminateAbility(const std::shared_ptr<AppRunningRecord> & appRecord,const sptr<IRemoteObject> & token,const bool isForce)233 void ModuleRunningRecord::TerminateAbility(const std::shared_ptr<AppRunningRecord> &appRecord,
234 const sptr<IRemoteObject> &token, const bool isForce)
235 {
236 TAG_LOGD(AAFwkTag::APPMGR, "called");
237 auto abilityRecord = GetAbilityRunningRecordByToken(token);
238 if (!abilityRecord) {
239 TAG_LOGE(AAFwkTag::APPMGR, "abilityRecord is nullptr");
240 return;
241 }
242
243 {
244 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
245 terminateAbilities_.emplace(token, abilityRecord);
246 abilities_.erase(token);
247 }
248
249 if (!isForce) {
250 auto curAbilityState = abilityRecord->GetState();
251 auto curAbilityType = abilityRecord->GetAbilityInfo()->type;
252 if (curAbilityState != AbilityState::ABILITY_STATE_BACKGROUND &&
253 curAbilityType == AppExecFwk::AbilityType::PAGE) {
254 TAG_LOGE(AAFwkTag::APPMGR, "current state(%{public}d) error", static_cast<int32_t>(curAbilityState));
255 return;
256 }
257 }
258
259 if (appLifeCycleDeal_) {
260 if (!(appRecord->IsDebugApp() || appRecord->isAttachDebug())) {
261 SendEvent(AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG,
262 AMSEventHandler::TERMINATE_ABILITY_TIMEOUT, abilityRecord);
263 }
264 bool isCachedProcess = DelayedSingleton<CacheProcessManager>::GetInstance()->IsAppShouldCache(appRecord);
265 appLifeCycleDeal_->ScheduleCleanAbility(token, isCachedProcess);
266 } else {
267 TAG_LOGW(AAFwkTag::APPMGR, "appLifeCycleDeal_ is null");
268 auto serviceInner = appMgrServiceInner_.lock();
269 if (serviceInner) {
270 serviceInner->TerminateApplication(appRecord);
271 }
272 }
273
274 TAG_LOGD(AAFwkTag::APPMGR, "end");
275 }
276
SendEvent(uint32_t msg,int64_t timeOut,const std::shared_ptr<AbilityRunningRecord> & abilityRecord)277 void ModuleRunningRecord::SendEvent(
278 uint32_t msg, int64_t timeOut, const std::shared_ptr<AbilityRunningRecord> &abilityRecord)
279 {
280 TAG_LOGD(AAFwkTag::APPMGR, "Send event");
281 if (!eventHandler_) {
282 TAG_LOGE(AAFwkTag::APPMGR, "eventHandler_ is nullptr");
283 return;
284 }
285
286 AppRunningRecord::appEventId_++;
287 abilityRecord->SetEventId(AppRunningRecord::appEventId_);
288 eventHandler_->SendEvent(AAFwk::EventWrap(msg, AppRunningRecord::appEventId_), timeOut);
289 }
290
AbilityTerminated(const sptr<IRemoteObject> & token)291 void ModuleRunningRecord::AbilityTerminated(const sptr<IRemoteObject> &token)
292 {
293 TAG_LOGD(AAFwkTag::APPMGR, "called");
294 if (!token) {
295 TAG_LOGE(AAFwkTag::APPMGR, "token is null");
296 return;
297 }
298
299 if (RemoveTerminateAbilityTimeoutTask(token)) {
300 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
301 terminateAbilities_.erase(token);
302 }
303 }
304
RemoveTerminateAbilityTimeoutTask(const sptr<IRemoteObject> & token) const305 bool ModuleRunningRecord::RemoveTerminateAbilityTimeoutTask(const sptr<IRemoteObject>& token) const
306 {
307 auto abilityRecord = GetAbilityByTerminateLists(token);
308 if (!abilityRecord) {
309 TAG_LOGE(AAFwkTag::APPMGR, "ModuleRunningRecord::AbilityTerminated can not find ability record");
310 return false;
311 }
312 if (!eventHandler_) {
313 TAG_LOGE(AAFwkTag::APPMGR, "eventHandler_ is nullptr");
314 return false;
315 }
316 eventHandler_->RemoveEvent(AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG, abilityRecord->GetEventId());
317 return true;
318 }
319
IsAbilitiesBackgrounded()320 bool ModuleRunningRecord::IsAbilitiesBackgrounded()
321 {
322 TAG_LOGD(AAFwkTag::APPMGR, "called");
323 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
324 for (const auto &iter : abilities_) {
325 const auto &ability = iter.second;
326 if (ability == nullptr) {
327 TAG_LOGE(AAFwkTag::APPMGR, "Ability is nullptr.");
328 continue;
329 }
330 const auto &abilityInfo = ability->GetAbilityInfo();
331 // uiextensionability also has foreground and background states.
332 if (abilityInfo != nullptr && abilityInfo->type != AbilityType::PAGE &&
333 !AAFwk::UIExtensionUtils::IsUIExtension(abilityInfo->extensionAbilityType)) {
334 continue;
335 }
336
337 const auto &state = ability->GetState();
338 if (state != AbilityState::ABILITY_STATE_BACKGROUND &&
339 state != AbilityState::ABILITY_STATE_TERMINATED &&
340 state != AbilityState::ABILITY_STATE_END) {
341 return false;
342 }
343 }
344 return true;
345 }
346
SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> & inner)347 void ModuleRunningRecord::SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> &inner)
348 {
349 appMgrServiceInner_ = inner;
350 }
351
GetModuleRecordState()352 ModuleRecordState ModuleRunningRecord::GetModuleRecordState()
353 {
354 return owenState_;
355 }
356
SetModuleRecordState(const ModuleRecordState & state)357 void ModuleRunningRecord::SetModuleRecordState(const ModuleRecordState &state)
358 {
359 owenState_ = state;
360 }
361
GetHapModuleInfo(HapModuleInfo & info)362 void ModuleRunningRecord::GetHapModuleInfo(HapModuleInfo &info)
363 {
364 info = owenInfo_;
365 }
366
SetApplicationClient(std::shared_ptr<AppLifeCycleDeal> & appLifeCycleDeal)367 void ModuleRunningRecord::SetApplicationClient(std::shared_ptr<AppLifeCycleDeal> &appLifeCycleDeal)
368 {
369 appLifeCycleDeal_ = appLifeCycleDeal;
370 }
371
GetState() const372 ModuleRecordState ModuleRunningRecord::GetState() const
373 {
374 return owenState_;
375 }
376
IsAllAbilityReadyToCleanedByUserRequest()377 bool ModuleRunningRecord::IsAllAbilityReadyToCleanedByUserRequest()
378 {
379 TAG_LOGD(AAFwkTag::APPMGR, "called");
380 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
381 for (const auto &iter : abilities_) {
382 const auto &ability = iter.second;
383 if (ability == nullptr) {
384 TAG_LOGE(AAFwkTag::APPMGR, "ability is nullptr.");
385 continue;
386 }
387 const auto &abilityInfo = ability->GetAbilityInfo();
388 if (abilityInfo != nullptr && abilityInfo->type != AbilityType::PAGE) {
389 continue;
390 }
391
392 if (!ability->IsUserRequestCleaning()) {
393 return false;
394 }
395
396 const auto &state = ability->GetState();
397 if (state != AbilityState::ABILITY_STATE_BACKGROUND &&
398 state != AbilityState::ABILITY_STATE_TERMINATED &&
399 state != AbilityState::ABILITY_STATE_END) {
400 return false;
401 }
402 }
403 return true;
404 }
405 } // namespace AppExecFwk
406 } // namespace OHOS
407