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