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