1 /*
2 * Copyright (c) 2022-2023 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_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "ui_extension_utils.h"
22
23 namespace OHOS {
24 namespace AppExecFwk {
25 namespace {
26 const std::string ABILITY_OWNER_USERID = "AbilityMS_Owner_UserId";
27 }
ModuleRunningRecord(const std::shared_ptr<ApplicationInfo> & info,const std::shared_ptr<AMSEventHandler> & eventHandler)28 ModuleRunningRecord::ModuleRunningRecord(
29 const std::shared_ptr<ApplicationInfo> &info, const std::shared_ptr<AMSEventHandler> &eventHandler)
30 : appInfo_(info), eventHandler_(eventHandler)
31 {}
32
~ModuleRunningRecord()33 ModuleRunningRecord::~ModuleRunningRecord()
34 {
35 HILOG_DEBUG("called");
36 }
37
Init(const HapModuleInfo & info)38 void ModuleRunningRecord::Init(const HapModuleInfo &info)
39 {
40 owenInfo_ = info;
41 owenState_ = ModuleRecordState::INITIALIZED_STATE;
42 }
43
GetModuleName() const44 const std::string &ModuleRunningRecord::GetModuleName() const
45 {
46 return owenInfo_.moduleName;
47 }
48
GetAppInfo()49 const std::shared_ptr<ApplicationInfo> ModuleRunningRecord::GetAppInfo()
50 {
51 return appInfo_;
52 }
53
GetAbilityRunningRecordByToken(const sptr<IRemoteObject> & token) const54 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityRunningRecordByToken(
55 const sptr<IRemoteObject> &token) const
56 {
57 if (!token) {
58 HILOG_ERROR("token is null");
59 return nullptr;
60 }
61 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
62 const auto &iter = abilities_.find(token);
63 if (iter != abilities_.end()) {
64 return iter->second;
65 }
66 return nullptr;
67 }
68
AddAbility(const sptr<IRemoteObject> & token,const std::shared_ptr<AbilityInfo> & abilityInfo,const std::shared_ptr<AAFwk::Want> & want)69 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::AddAbility(const sptr<IRemoteObject> &token,
70 const std::shared_ptr<AbilityInfo> &abilityInfo, const std::shared_ptr<AAFwk::Want> &want)
71 {
72 HILOG_DEBUG("Add ability.");
73 if (!token || !abilityInfo) {
74 HILOG_ERROR("Param abilityInfo or token is null");
75 return nullptr;
76 }
77 if (GetAbilityRunningRecordByToken(token)) {
78 HILOG_ERROR("AbilityRecord already exists and no need to add");
79 return nullptr;
80 }
81 auto abilityRecord = std::make_shared<AbilityRunningRecord>(abilityInfo, token);
82 abilityRecord->SetWant(want);
83 if (appInfo_) {
84 abilityRecord->SetIsSingleUser(appInfo_->singleton);
85 }
86 if (want) {
87 abilityRecord->SetOwnerUserId(want->GetIntParam(ABILITY_OWNER_USERID, -1));
88 }
89 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
90 abilities_.emplace(token, abilityRecord);
91 return abilityRecord;
92 }
93
IsLastAbilityRecord(const sptr<IRemoteObject> & token)94 bool ModuleRunningRecord::IsLastAbilityRecord(const sptr<IRemoteObject> &token)
95 {
96 if (!token) {
97 HILOG_ERROR("token is nullptr");
98 return false;
99 }
100 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
101 return ((abilities_.size() == 1) && (abilities_.find(token) != abilities_.end()));
102 }
103
GetPageAbilitySize()104 int32_t ModuleRunningRecord::GetPageAbilitySize()
105 {
106 int pageAbilitySize = 0;
107 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
108 for (auto it : abilities_) {
109 std::shared_ptr<AbilityRunningRecord> abilityRunningRecord = it.second;
110 std::shared_ptr<AbilityInfo> abilityInfo = abilityRunningRecord->GetAbilityInfo();
111 if (abilityInfo->type == AbilityType::PAGE) {
112 pageAbilitySize++;
113 }
114 }
115
116 return pageAbilitySize;
117 }
118
GetAbilities() const119 const std::map<const sptr<IRemoteObject>, std::shared_ptr<AbilityRunningRecord>> ModuleRunningRecord::GetAbilities()
120 const
121 {
122 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
123 return abilities_;
124 }
125
GetAbilityByTerminateLists(const sptr<IRemoteObject> & token) const126 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityByTerminateLists(
127 const sptr<IRemoteObject> &token) const
128 {
129 if (!token) {
130 HILOG_ERROR("GetAbilityByTerminateLists error, token is null");
131 return nullptr;
132 }
133 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
134 const auto &iter = terminateAbilities_.find(token);
135 if (iter != terminateAbilities_.end()) {
136 return iter->second;
137 }
138 return nullptr;
139 }
140
GetAbilityRunningRecord(const int64_t eventId) const141 std::shared_ptr<AbilityRunningRecord> ModuleRunningRecord::GetAbilityRunningRecord(const int64_t eventId) const
142 {
143 HILOG_DEBUG("called");
144 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
145 const auto &iter = std::find_if(abilities_.begin(), abilities_.end(), [eventId](const auto &pair) {
146 return pair.second->GetEventId() == eventId;
147 });
148 if (iter != abilities_.end()) {
149 return iter->second;
150 }
151
152 const auto &finder = std::find_if(terminateAbilities_.begin(),
153 terminateAbilities_.end(),
154 [eventId](const auto &pair) { return pair.second->GetEventId() == eventId; });
155 if (finder != terminateAbilities_.end()) {
156 return finder->second;
157 }
158 return nullptr;
159 }
160
OnAbilityStateChanged(const std::shared_ptr<AbilityRunningRecord> & ability,const AbilityState state)161 void ModuleRunningRecord::OnAbilityStateChanged(
162 const std::shared_ptr<AbilityRunningRecord> &ability, const AbilityState state)
163 {
164 if (!ability) {
165 HILOG_ERROR("ability is null");
166 return;
167 }
168 AbilityState oldState = ability->GetState();
169 ability->SetState(state);
170 HILOG_INFO("Ability state change from %{public}d to %{public}d. bundle: %{public}s, ability: %{public}s.",
171 oldState, state, ability->GetAbilityInfo()->bundleName.c_str(), ability->GetName().c_str());
172 auto serviceInner = appMgrServiceInner_.lock();
173 if (serviceInner) {
174 serviceInner->OnAbilityStateChanged(ability, state);
175 }
176 }
177
LaunchAbility(const std::shared_ptr<AbilityRunningRecord> & ability)178 void ModuleRunningRecord::LaunchAbility(const std::shared_ptr<AbilityRunningRecord> &ability)
179 {
180 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
181 HILOG_DEBUG("called");
182 if (!ability || !ability->GetToken()) {
183 HILOG_ERROR("null abilityRecord or abilityToken");
184 return;
185 }
186 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
187 const auto &iter = abilities_.find(ability->GetToken());
188 if (iter != abilities_.end() && appLifeCycleDeal_->GetApplicationClient()) {
189 HILOG_DEBUG("Schedule launch ability, name is %{public}s.", ability->GetName().c_str());
190 appLifeCycleDeal_->LaunchAbility(ability);
191 ability->SetState(AbilityState::ABILITY_STATE_READY);
192 } else {
193 HILOG_ERROR("Can not find ability or get appThread.");
194 }
195 }
196
LaunchPendingAbilities()197 void ModuleRunningRecord::LaunchPendingAbilities()
198 {
199 HILOG_DEBUG("Launch pending abilities.");
200 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
201 if (abilities_.empty()) {
202 HILOG_ERROR("abilities_ is empty");
203 return;
204 }
205
206 for (const auto &item : abilities_) {
207 const auto &ability = item.second;
208 HILOG_DEBUG("state : %{public}d", ability->GetState());
209 if (ability->GetState() == AbilityState::ABILITY_STATE_CREATE && ability->GetToken() &&
210 appLifeCycleDeal_->GetApplicationClient()) {
211 HILOG_DEBUG("name is %{public}s.", ability->GetName().c_str());
212 appLifeCycleDeal_->LaunchAbility(ability);
213 ability->SetState(AbilityState::ABILITY_STATE_READY);
214 }
215 }
216 }
217
TerminateAbility(const std::shared_ptr<AppRunningRecord> & appRecord,const sptr<IRemoteObject> & token,const bool isForce)218 void ModuleRunningRecord::TerminateAbility(const std::shared_ptr<AppRunningRecord> &appRecord,
219 const sptr<IRemoteObject> &token, const bool isForce)
220 {
221 HILOG_DEBUG("called");
222 auto abilityRecord = GetAbilityRunningRecordByToken(token);
223 if (!abilityRecord) {
224 HILOG_ERROR("abilityRecord is nullptr");
225 return;
226 }
227
228 {
229 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
230 terminateAbilities_.emplace(token, abilityRecord);
231 abilities_.erase(token);
232 }
233
234 if (!isForce) {
235 auto curAbilityState = abilityRecord->GetState();
236 auto curAbilityType = abilityRecord->GetAbilityInfo()->type;
237 if (curAbilityState != AbilityState::ABILITY_STATE_BACKGROUND &&
238 curAbilityType == AppExecFwk::AbilityType::PAGE) {
239 HILOG_ERROR("current state(%{public}d) error", static_cast<int32_t>(curAbilityState));
240 return;
241 }
242 }
243
244 if (appLifeCycleDeal_) {
245 if (!(appRecord->IsDebugApp() || appRecord->isAttachDebug())) {
246 SendEvent(AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG,
247 AMSEventHandler::TERMINATE_ABILITY_TIMEOUT, abilityRecord);
248 }
249 appLifeCycleDeal_->ScheduleCleanAbility(token);
250 } else {
251 HILOG_WARN("appLifeCycleDeal_ is null");
252 auto serviceInner = appMgrServiceInner_.lock();
253 if (serviceInner) {
254 serviceInner->TerminateApplication(appRecord);
255 }
256 }
257
258 HILOG_DEBUG("end");
259 }
260
SendEvent(uint32_t msg,int64_t timeOut,const std::shared_ptr<AbilityRunningRecord> & abilityRecord)261 void ModuleRunningRecord::SendEvent(
262 uint32_t msg, int64_t timeOut, const std::shared_ptr<AbilityRunningRecord> &abilityRecord)
263 {
264 HILOG_DEBUG("Send event");
265 if (!eventHandler_) {
266 HILOG_ERROR("eventHandler_ is nullptr");
267 return;
268 }
269
270 AppRunningRecord::appEventId_++;
271 abilityRecord->SetEventId(AppRunningRecord::appEventId_);
272 eventHandler_->SendEvent(AAFwk::EventWrap(msg, AppRunningRecord::appEventId_), timeOut);
273 }
274
AbilityTerminated(const sptr<IRemoteObject> & token)275 void ModuleRunningRecord::AbilityTerminated(const sptr<IRemoteObject> &token)
276 {
277 HILOG_DEBUG("called");
278 if (!token) {
279 HILOG_ERROR("token is null");
280 return;
281 }
282
283 if (RemoveTerminateAbilityTimeoutTask(token)) {
284 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
285 terminateAbilities_.erase(token);
286 }
287 }
288
RemoveTerminateAbilityTimeoutTask(const sptr<IRemoteObject> & token) const289 bool ModuleRunningRecord::RemoveTerminateAbilityTimeoutTask(const sptr<IRemoteObject>& token) const
290 {
291 auto abilityRecord = GetAbilityByTerminateLists(token);
292 if (!abilityRecord) {
293 HILOG_ERROR("ModuleRunningRecord::AbilityTerminated can not find ability record");
294 return false;
295 }
296 if (!eventHandler_) {
297 HILOG_ERROR("eventHandler_ is nullptr");
298 return false;
299 }
300 eventHandler_->RemoveEvent(AMSEventHandler::TERMINATE_ABILITY_TIMEOUT_MSG, abilityRecord->GetEventId());
301 return true;
302 }
303
IsAbilitiesBackgrounded()304 bool ModuleRunningRecord::IsAbilitiesBackgrounded()
305 {
306 HILOG_DEBUG("Called.");
307 std::lock_guard<ffrt::mutex> lock(abilitiesMutex_);
308 for (const auto &iter : abilities_) {
309 const auto &ability = iter.second;
310 if (ability == nullptr) {
311 HILOG_ERROR("Ability is nullptr.");
312 continue;
313 }
314 const auto &abilityInfo = ability->GetAbilityInfo();
315 // uiextensionability also has foreground and background states.
316 if (abilityInfo != nullptr && abilityInfo->type != AbilityType::PAGE &&
317 !AAFwk::UIExtensionUtils::IsUIExtension(abilityInfo->extensionAbilityType)) {
318 continue;
319 }
320
321 const auto &state = ability->GetState();
322 if (state != AbilityState::ABILITY_STATE_BACKGROUND &&
323 state != AbilityState::ABILITY_STATE_TERMINATED &&
324 state != AbilityState::ABILITY_STATE_END) {
325 return false;
326 }
327 }
328 return true;
329 }
330
SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> & inner)331 void ModuleRunningRecord::SetAppMgrServiceInner(const std::weak_ptr<AppMgrServiceInner> &inner)
332 {
333 appMgrServiceInner_ = inner;
334 }
335
GetModuleRecordState()336 ModuleRecordState ModuleRunningRecord::GetModuleRecordState()
337 {
338 return owenState_;
339 }
340
SetModuleRecordState(const ModuleRecordState & state)341 void ModuleRunningRecord::SetModuleRecordState(const ModuleRecordState &state)
342 {
343 owenState_ = state;
344 }
345
GetHapModuleInfo(HapModuleInfo & info)346 void ModuleRunningRecord::GetHapModuleInfo(HapModuleInfo &info)
347 {
348 info = owenInfo_;
349 }
350
SetApplicationClient(std::shared_ptr<AppLifeCycleDeal> & appLifeCycleDeal)351 void ModuleRunningRecord::SetApplicationClient(std::shared_ptr<AppLifeCycleDeal> &appLifeCycleDeal)
352 {
353 appLifeCycleDeal_ = appLifeCycleDeal;
354 }
355
GetState() const356 ModuleRecordState ModuleRunningRecord::GetState() const
357 {
358 return owenState_;
359 }
360 } // namespace AppExecFwk
361 } // namespace OHOS
362