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