1 /*
2 * Copyright (c) 2021 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 "app_running_record.h"
17
18 #include "ability_running_record.h"
19 #include "app_log_wrapper.h"
20 #include "app_mgr_service_inner.h"
21
22 namespace OHOS {
23 namespace AppExecFwk {
24 int64_t AppRunningRecord::appEventId_ = 0;
AppRunningRecord(const std::shared_ptr<ApplicationInfo> & info,const int32_t recordId,const std::string & processName)25 AppRunningRecord::AppRunningRecord(
26 const std::shared_ptr<ApplicationInfo> &info, const int32_t recordId, const std::string &processName)
27 : appInfo_(info), appRecordId_(recordId), processName_(processName)
28 {}
29
SetApplicationClient(const sptr<IAppScheduler> & thread)30 void AppRunningRecord::SetApplicationClient(const sptr<IAppScheduler> &thread)
31 {
32 if (!appLifeCycleDeal_) {
33 appLifeCycleDeal_ = std::make_shared<AppLifeCycleDeal>();
34 }
35 appLifeCycleDeal_->SetApplicationClient(thread);
36 }
37
GetBundleName() const38 std::string AppRunningRecord::GetBundleName() const
39 {
40 return appInfo_->bundleName;
41 }
42
IsLauncherApp() const43 bool AppRunningRecord::IsLauncherApp() const
44 {
45 return appInfo_->isLauncherApp;
46 }
47
GetRecordId() const48 int32_t AppRunningRecord::GetRecordId() const
49 {
50 return appRecordId_;
51 }
52
GetName() const53 const std::string &AppRunningRecord::GetName() const
54 {
55 return appInfo_->name;
56 }
57
GetProcessName() const58 const std::string &AppRunningRecord::GetProcessName() const
59 {
60 return processName_;
61 }
62
GetUid() const63 int32_t AppRunningRecord::GetUid() const
64 {
65 return uid_;
66 }
67
SetUid(const int32_t uid)68 void AppRunningRecord::SetUid(const int32_t uid)
69 {
70 uid_ = uid;
71 }
72
GetState() const73 ApplicationState AppRunningRecord::GetState() const
74 {
75 return curState_;
76 }
77
SetState(const ApplicationState state)78 void AppRunningRecord::SetState(const ApplicationState state)
79 {
80 if (state >= ApplicationState::APP_STATE_END) {
81 APP_LOGE("Invalid application state");
82 return;
83 }
84 curState_ = state;
85 }
86
GetAbilities() const87 const std::map<const sptr<IRemoteObject>, std::shared_ptr<AbilityRunningRecord>> &AppRunningRecord::GetAbilities() const
88 {
89 return abilities_;
90 }
91
GetApplicationClient() const92 sptr<IAppScheduler> AppRunningRecord::GetApplicationClient() const
93 {
94 return (appLifeCycleDeal_ ? appLifeCycleDeal_->GetApplicationClient() : nullptr);
95 }
96
AddAbility(const sptr<IRemoteObject> & token,const std::shared_ptr<AbilityInfo> & abilityInfo)97 std::shared_ptr<AbilityRunningRecord> AppRunningRecord::AddAbility(
98 const sptr<IRemoteObject> &token, const std::shared_ptr<AbilityInfo> &abilityInfo)
99 {
100 if (!token || !abilityInfo) {
101 APP_LOGE("Param abilityInfo or token is null");
102 return nullptr;
103 }
104 if (GetAbilityRunningRecordByToken(token)) {
105 APP_LOGE("AbilityRecord already exists and no need to add");
106 return nullptr;
107 }
108 auto abilityRecord = std::make_shared<AbilityRunningRecord>(abilityInfo, token);
109 abilities_.emplace(token, abilityRecord);
110 return abilityRecord;
111 }
112
GetAbilityRunningRecord(const std::string & abilityName) const113 std::shared_ptr<AbilityRunningRecord> AppRunningRecord::GetAbilityRunningRecord(const std::string &abilityName) const
114 {
115 const auto &iter = std::find_if(abilities_.begin(), abilities_.end(), [&abilityName](const auto &pair) {
116 return pair.second->GetName() == abilityName;
117 });
118 return ((iter == abilities_.end()) ? nullptr : iter->second);
119 }
120
GetAbilityRunningRecord(const int64_t eventId) const121 std::shared_ptr<AbilityRunningRecord> AppRunningRecord::GetAbilityRunningRecord(const int64_t eventId) const
122 {
123 APP_LOGI("%{public}s, called", __func__);
124 const auto &iter = std::find_if(abilities_.begin(), abilities_.end(), [eventId](const auto &pair) {
125 return pair.second->GetEventId() == eventId;
126 });
127 if (iter != abilities_.end()) {
128 return iter->second;
129 }
130
131 const auto &finder = std::find_if(terminateAbilitys_.begin(),
132 terminateAbilitys_.end(),
133 [eventId](const auto &pair) { return pair.second->GetEventId() == eventId; });
134 if (finder != terminateAbilitys_.end()) {
135 return finder->second;
136 }
137 return nullptr;
138 }
139
ClearAbility(const std::shared_ptr<AbilityRunningRecord> & record)140 void AppRunningRecord::ClearAbility(const std::shared_ptr<AbilityRunningRecord> &record)
141 {
142 if (!record) {
143 APP_LOGE("Param record is null");
144 return;
145 }
146 if (!GetAbilityRunningRecordByToken(record->GetToken())) {
147 APP_LOGE("Param record is not exist");
148 return;
149 }
150 abilities_.erase(record->GetToken());
151 }
152
ForceKillApp(const std::string & reason) const153 void AppRunningRecord::ForceKillApp([[maybe_unused]] const std::string &reason) const
154 {}
155
ScheduleAppCrash(const std::string & description) const156 void AppRunningRecord::ScheduleAppCrash([[maybe_unused]] const std::string &description) const
157 {}
158
LaunchApplication()159 void AppRunningRecord::LaunchApplication()
160 {
161 if (!appInfo_ || !appLifeCycleDeal_->GetApplicationClient()) {
162 APP_LOGE("appInfo or appThread is null");
163 return;
164 }
165 AppLaunchData launchData;
166 launchData.SetApplicationInfo(*appInfo_);
167 ProcessInfo processInfo(processName_, GetPriorityObject()->GetPid());
168 launchData.SetProcessInfo(processInfo);
169 launchData.SetRecordId(appRecordId_);
170 launchData.SetUId(uid_);
171 APP_LOGI("ScheduleLaunchApplication app:%{public}s", GetName().c_str());
172 appLifeCycleDeal_->LaunchApplication(launchData);
173 }
174
LaunchAbility(const std::shared_ptr<AbilityRunningRecord> & ability)175 void AppRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
176 {
177 if (!ability || !ability->GetToken()) {
178 APP_LOGE("null abilityRecord or abilityToken");
179 return;
180 }
181 const auto &iter = abilities_.find(ability->GetToken());
182 if (iter != abilities_.end() && appLifeCycleDeal_->GetApplicationClient()) {
183 APP_LOGI("ScheduleLaunchAbility ability:%{public}s", ability->GetName().c_str());
184 appLifeCycleDeal_->LaunchAbility(ability);
185 ability->SetState(AbilityState::ABILITY_STATE_READY);
186 OptimizerAbilityStateChanged(ability, AbilityState::ABILITY_STATE_CREATE);
187 }
188 }
189
LaunchPendingAbilities()190 void AppRunningRecord::LaunchPendingAbilities()
191 {
192 for (auto item : abilities_) {
193 if (item.second->GetState() == AbilityState::ABILITY_STATE_CREATE) {
194 LaunchAbility(item.second);
195 }
196 }
197 }
198
ScheduleTerminate()199 void AppRunningRecord::ScheduleTerminate()
200 {
201 SendEvent(AMSEventHandler::TERMINATE_APPLICATION_TIMEOUT_MSG, AMSEventHandler::TERMINATE_APPLICATION_TIMEOUT);
202 appLifeCycleDeal_->ScheduleTerminate();
203 }
204
ScheduleForegroundRunning()205 void AppRunningRecord::ScheduleForegroundRunning()
206 {
207 appLifeCycleDeal_->ScheduleForegroundRunning();
208 }
209
ScheduleBackgroundRunning()210 void AppRunningRecord::ScheduleBackgroundRunning()
211 {
212 appLifeCycleDeal_->ScheduleBackgroundRunning();
213 }
214
ScheduleProcessSecurityExit()215 void AppRunningRecord::ScheduleProcessSecurityExit()
216 {
217 appLifeCycleDeal_->ScheduleProcessSecurityExit();
218 }
219
ScheduleTrimMemory()220 void AppRunningRecord::ScheduleTrimMemory()
221 {
222 appLifeCycleDeal_->ScheduleTrimMemory(priorityObject_->GetTimeLevel());
223 }
224
LowMemoryWarning()225 void AppRunningRecord::LowMemoryWarning()
226 {
227 appLifeCycleDeal_->LowMemoryWarning();
228 }
229
OnAbilityStateChanged(const std::shared_ptr<AbilityRunningRecord> & ability,const AbilityState state)230 void AppRunningRecord::OnAbilityStateChanged(
231 const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
232 {
233 if (!ability) {
234 APP_LOGE("ability is null");
235 return;
236 }
237 AbilityState oldState = ability->GetState();
238 ability->SetState(state);
239 OptimizerAbilityStateChanged(ability, oldState);
240 auto serviceInner = appMgrServiceInner_.lock();
241 if (serviceInner) {
242 serviceInner->OnAbilityStateChanged(ability, state);
243 }
244 }
245
GetAbilityRunningRecordByToken(const sptr<IRemoteObject> & token) const246 std::shared_ptr<AbilityRunningRecord> AppRunningRecord::GetAbilityRunningRecordByToken(
247 const sptr<IRemoteObject> &token) const
248 {
249 if (!token) {
250 APP_LOGE("token is null");
251 return nullptr;
252 }
253 const auto &iter = abilities_.find(token);
254 if (iter != abilities_.end()) {
255 return iter->second;
256 }
257 return nullptr;
258 }
259
GetAbilityByTerminateLists(const sptr<IRemoteObject> & token) const260 std::shared_ptr<AbilityRunningRecord> AppRunningRecord::GetAbilityByTerminateLists(
261 const sptr<IRemoteObject> &token) const
262 {
263 if (!token) {
264 APP_LOGE("token is null");
265 return nullptr;
266 }
267 const auto &iter = terminateAbilitys_.find(token);
268 if (iter != terminateAbilitys_.end()) {
269 return iter->second;
270 }
271 return nullptr;
272 }
273
UpdateAbilityState(const sptr<IRemoteObject> & token,const AbilityState state)274 void AppRunningRecord::UpdateAbilityState(const sptr<IRemoteObject> &token, const AbilityState state)
275 {
276 APP_LOGD("state is :%{public}d", static_cast<int32_t>(state));
277 auto abilityRecord = GetAbilityRunningRecordByToken(token);
278 if (!abilityRecord) {
279 APP_LOGE("can not find ability record");
280 return;
281 }
282 if (state == abilityRecord->GetState()) {
283 APP_LOGE("current state is already, no need update");
284 return;
285 }
286
287 if (state == AbilityState::ABILITY_STATE_FOREGROUND) {
288 AbilityForeground(abilityRecord);
289 } else if (state == AbilityState::ABILITY_STATE_BACKGROUND) {
290 AbilityBackground(abilityRecord);
291 } else {
292 APP_LOGW("wrong state");
293 }
294 }
295
AbilityForeground(const std::shared_ptr<AbilityRunningRecord> & ability)296 void AppRunningRecord::AbilityForeground(const std::shared_ptr<AbilityRunningRecord> &ability)
297 {
298 if (!ability) {
299 APP_LOGE("ability is null");
300 return;
301 }
302 AbilityState curAbilityState = ability->GetState();
303 if (curAbilityState != AbilityState::ABILITY_STATE_READY &&
304 curAbilityState != AbilityState::ABILITY_STATE_BACKGROUND) {
305 APP_LOGE("ability state(%{public}d) error", static_cast<int32_t>(curAbilityState));
306 return;
307 }
308
309 // We need schedule application to foregrounded when current application state is ready or background running.
310 if (curState_ == ApplicationState::APP_STATE_READY || curState_ == ApplicationState::APP_STATE_BACKGROUND) {
311 if (foregroundingAbilityTokens_.empty()) {
312 ScheduleForegroundRunning();
313 }
314 foregroundingAbilityTokens_.push_back(ability->GetToken());
315 return;
316 } else if (curState_ == ApplicationState::APP_STATE_FOREGROUND) {
317 // Just change ability to foreground if current application state is foreground.
318 OnAbilityStateChanged(ability, AbilityState::ABILITY_STATE_FOREGROUND);
319 auto serviceInner = appMgrServiceInner_.lock();
320 if (serviceInner) {
321 serviceInner->OnAppStateChanged(shared_from_this(), curState_);
322 }
323 } else {
324 APP_LOGW("wrong application state");
325 }
326 }
327
AbilityBackground(const std::shared_ptr<AbilityRunningRecord> & ability)328 void AppRunningRecord::AbilityBackground(const std::shared_ptr<AbilityRunningRecord> &ability)
329 {
330 if (!ability) {
331 APP_LOGE("ability is null");
332 return;
333 }
334 if (ability->GetState() != AbilityState::ABILITY_STATE_FOREGROUND) {
335 APP_LOGE("ability state is not foreground");
336 return;
337 }
338
339 // First change ability to backgrounded.
340 OnAbilityStateChanged(ability, AbilityState::ABILITY_STATE_BACKGROUND);
341 if (curState_ == ApplicationState::APP_STATE_FOREGROUND) {
342 int32_t foregroundSize = 0;
343 for (const auto &item : abilities_) {
344 const auto &abilityRecord = item.second;
345 if (abilityRecord && abilityRecord->GetState() == AbilityState::ABILITY_STATE_FOREGROUND) {
346 foregroundSize++;
347 break;
348 }
349 }
350
351 // Then schedule application background when all ability is not foreground.
352 if (foregroundSize == 0) {
353 ScheduleBackgroundRunning();
354 }
355 } else {
356 APP_LOGW("wrong application state");
357 }
358 }
359
OptimizerAbilityStateChanged(const std::shared_ptr<AbilityRunningRecord> & ability,const AbilityState state)360 void AppRunningRecord::OptimizerAbilityStateChanged(
361 const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
362 {
363 auto serviceInner = appMgrServiceInner_.lock();
364 if (serviceInner) {
365 serviceInner->OptimizerAbilityStateChanged(ability, state);
366 }
367 }
368
PopForegroundingAbilityTokens()369 void AppRunningRecord::PopForegroundingAbilityTokens()
370 {
371 APP_LOGD("size:%{public}d", static_cast<int32_t>(foregroundingAbilityTokens_.size()));
372 while (!foregroundingAbilityTokens_.empty()) {
373 const auto &token = foregroundingAbilityTokens_.front();
374 auto ability = GetAbilityRunningRecordByToken(token);
375 OnAbilityStateChanged(ability, AbilityState::ABILITY_STATE_FOREGROUND);
376 foregroundingAbilityTokens_.pop_front();
377 }
378 }
379
TerminateAbility(const sptr<IRemoteObject> & token,const bool isForce)380 void AppRunningRecord::TerminateAbility(const sptr<IRemoteObject> &token, const bool isForce)
381 {
382 APP_LOGD("AppRunningRecord::TerminateAbility begin");
383 auto abilityRecord = GetAbilityRunningRecordByToken(token);
384 if (!abilityRecord) {
385 APP_LOGE("AppRunningRecord::TerminateAbility can not find ability record");
386 return;
387 }
388
389 terminateAbilitys_.emplace(token, abilityRecord);
390 abilities_.erase(token);
391
392 SendEvent(
393 AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG, AMSEventHandler::TERMINATE_ABILITY_TIMEOUT, abilityRecord);
394
395 if (!isForce) {
396 auto curAbilityState = abilityRecord->GetState();
397 if (curAbilityState != AbilityState::ABILITY_STATE_BACKGROUND) {
398 APP_LOGE("AppRunningRecord::TerminateAbility current state(%{public}d) error",
399 static_cast<int32_t>(curAbilityState));
400 return;
401 }
402 }
403
404 OptimizerAbilityStateChanged(abilityRecord, AbilityState::ABILITY_STATE_TERMINATED);
405 appLifeCycleDeal_->ScheduleCleanAbility(token);
406
407 APP_LOGD("AppRunningRecord::TerminateAbility end");
408 }
409
AbilityTerminated(const sptr<IRemoteObject> & token)410 void AppRunningRecord::AbilityTerminated(const sptr<IRemoteObject> &token)
411 {
412 APP_LOGI("%{public}s, called", __func__);
413 if (!token) {
414 APP_LOGE("token is null");
415 return;
416 }
417
418 if (!eventHandler_) {
419 APP_LOGE("eventHandler_ is nullptr");
420 return;
421 }
422
423 auto abilityRecord = GetAbilityByTerminateLists(token);
424 if (!abilityRecord) {
425 APP_LOGE("AppRunningRecord::AbilityTerminated can not find ability record");
426 return;
427 }
428
429 eventHandler_->RemoveEvent(AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG, abilityRecord->GetEventId());
430 terminateAbilitys_.erase(token);
431 if (abilities_.empty()) {
432 ScheduleTerminate();
433 }
434 }
435
RegisterAppDeathRecipient() const436 void AppRunningRecord::RegisterAppDeathRecipient() const
437 {
438 if (!appLifeCycleDeal_->GetApplicationClient()) {
439 APP_LOGE("appThread is null");
440 return;
441 }
442 auto object = appLifeCycleDeal_->GetApplicationClient()->AsObject();
443 if (object) {
444 object->AddDeathRecipient(appDeathRecipient_);
445 }
446 }
447
RemoveAppDeathRecipient() const448 void AppRunningRecord::RemoveAppDeathRecipient() const
449 {
450 if (!appLifeCycleDeal_->GetApplicationClient()) {
451 APP_LOGE("appThread is null");
452 return;
453 }
454 auto object = appLifeCycleDeal_->GetApplicationClient()->AsObject();
455 if (object) {
456 object->RemoveDeathRecipient(appDeathRecipient_);
457 }
458 }
459
SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> & inner)460 void AppRunningRecord::SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> &inner)
461 {
462 appMgrServiceInner_ = inner;
463 }
464
SetAppDeathRecipient(const sptr<AppDeathRecipient> & appDeathRecipient)465 void AppRunningRecord::SetAppDeathRecipient(const sptr<AppDeathRecipient> &appDeathRecipient)
466 {
467 appDeathRecipient_ = appDeathRecipient;
468 }
469
GetPriorityObject()470 std::shared_ptr<PriorityObject> AppRunningRecord::GetPriorityObject()
471 {
472 if (!priorityObject_) {
473 priorityObject_ = std::make_shared<PriorityObject>();
474 }
475
476 return priorityObject_;
477 }
478
SendEvent(uint32_t msg,int64_t timeOut,const std::shared_ptr<AbilityRunningRecord> & abilityRecord)479 void AppRunningRecord::SendEvent(
480 uint32_t msg, int64_t timeOut, const std::shared_ptr<AbilityRunningRecord> &abilityRecord)
481 {
482 if (!eventHandler_) {
483 APP_LOGE("eventHandler_ is nullptr");
484 return;
485 }
486
487 appEventId_++;
488 abilityRecord->SetEventId(appEventId_);
489 eventHandler_->SendEvent(msg, appEventId_, timeOut);
490 }
491
SendEvent(uint32_t msg,int64_t timeOut)492 void AppRunningRecord::SendEvent(uint32_t msg, int64_t timeOut)
493 {
494 if (!eventHandler_) {
495 APP_LOGE("eventHandler_ is nullptr");
496 return;
497 }
498 appEventId_++;
499 eventId_ = appEventId_;
500 eventHandler_->SendEvent(msg, appEventId_, timeOut);
501 }
502
GetEventId() const503 int64_t AppRunningRecord::GetEventId() const
504 {
505 return eventId_;
506 }
507
SetEventHandler(const std::shared_ptr<AMSEventHandler> & handler)508 void AppRunningRecord::SetEventHandler(const std::shared_ptr<AMSEventHandler> &handler)
509 {
510 eventHandler_ = handler;
511 }
512
IsLastAbilityRecord(const sptr<IRemoteObject> & token)513 bool AppRunningRecord::IsLastAbilityRecord(const sptr<IRemoteObject> &token)
514 {
515 if (!token) {
516 APP_LOGE("%{public}s, token is nullptr", __func__);
517 return false;
518 }
519
520 return ((abilities_.size() == 1) && (abilities_.find(token) != abilities_.end()));
521 }
522
SetTerminating()523 void AppRunningRecord::SetTerminating()
524 {
525 isTerminating = true;
526 }
527
IsTerminating()528 bool AppRunningRecord::IsTerminating()
529 {
530 return isTerminating;
531 }
532 } // namespace AppExecFwk
533 } // namespace OHOS
534