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