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