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