1 /*
2 * Copyright (c) 2021-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 "ability_connect_manager.h"
17
18 #include <algorithm>
19
20 #include "ability_connect_callback_stub.h"
21 #include "ability_manager_errors.h"
22 #include "ability_manager_service.h"
23 #include "ability_util.h"
24 #include "bytrace.h"
25 #include "hilog_wrapper.h"
26 #include "in_process_call_wrapper.h"
27
28 namespace OHOS {
29 namespace AAFwk {
AbilityConnectManager(int userId)30 AbilityConnectManager::AbilityConnectManager(int userId) : userId_(userId)
31 {}
32
~AbilityConnectManager()33 AbilityConnectManager::~AbilityConnectManager()
34 {}
35
StartAbility(const AbilityRequest & abilityRequest)36 int AbilityConnectManager::StartAbility(const AbilityRequest &abilityRequest)
37 {
38 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
39 std::lock_guard<std::recursive_mutex> guard(Lock_);
40 return StartAbilityLocked(abilityRequest);
41 }
42
TerminateAbility(const sptr<IRemoteObject> & token)43 int AbilityConnectManager::TerminateAbility(const sptr<IRemoteObject> &token)
44 {
45 std::lock_guard<std::recursive_mutex> guard(Lock_);
46 return TerminateAbilityLocked(token);
47 }
48
TerminateAbility(const std::shared_ptr<AbilityRecord> & caller,int requestCode)49 int AbilityConnectManager::TerminateAbility(const std::shared_ptr<AbilityRecord> &caller, int requestCode)
50 {
51 HILOG_INFO("Terminate ability.");
52 std::lock_guard<std::recursive_mutex> guard(Lock_);
53
54 std::shared_ptr<AbilityRecord> targetAbility = nullptr;
55 int result = static_cast<int>(ABILITY_VISIBLE_FALSE_DENY_REQUEST);
56 std::for_each(serviceMap_.begin(),
57 serviceMap_.end(),
58 [&targetAbility, &caller, requestCode, &result](ServiceMapType::reference service) {
59 auto callerList = service.second->GetCallerRecordList();
60 for (auto &it : callerList) {
61 if (it->GetCaller() == caller && it->GetRequestCode() == requestCode) {
62 targetAbility = service.second;
63 if (targetAbility) {
64 result = AbilityUtil::JudgeAbilityVisibleControl(targetAbility->GetAbilityInfo());
65 }
66 break;
67 }
68 }
69 });
70
71 if (!targetAbility) {
72 HILOG_ERROR("targetAbility error.");
73 return NO_FOUND_ABILITY_BY_CALLER;
74 }
75 if (result != ERR_OK) {
76 HILOG_ERROR("%{public}s JudgeAbilityVisibleControl error.", __func__);
77 return result;
78 }
79
80 return TerminateAbilityLocked(targetAbility->GetToken());
81 }
82
StopServiceAbility(const AbilityRequest & abilityRequest)83 int AbilityConnectManager::StopServiceAbility(const AbilityRequest &abilityRequest)
84 {
85 HILOG_INFO("Stop Service ability.");
86 std::lock_guard<std::recursive_mutex> guard(Lock_);
87 return StopServiceAbilityLocked(abilityRequest);
88 }
89
TerminateAbilityResult(const sptr<IRemoteObject> & token,int startId)90 int AbilityConnectManager::TerminateAbilityResult(const sptr<IRemoteObject> &token, int startId)
91 {
92 HILOG_INFO("Terminate ability result.");
93 std::lock_guard<std::recursive_mutex> guard(Lock_);
94 return TerminateAbilityResultLocked(token, startId);
95 }
96
StartAbilityLocked(const AbilityRequest & abilityRequest)97 int AbilityConnectManager::StartAbilityLocked(const AbilityRequest &abilityRequest)
98 {
99 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
100 HILOG_INFO("Start ability locked, ability_name: %{public}s", abilityRequest.want.GetElement().GetURI().c_str());
101
102 std::shared_ptr<AbilityRecord> targetService;
103 bool isLoadedAbility = false;
104 GetOrCreateServiceRecord(abilityRequest, false, targetService, isLoadedAbility);
105 CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
106
107 targetService->AddCallerRecord(abilityRequest.callerToken, abilityRequest.requestCode);
108
109 if (!isLoadedAbility) {
110 LoadAbility(targetService);
111 } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) {
112 // It may have been started through connect
113 CommandAbility(targetService);
114 } else {
115 HILOG_ERROR("Target service is already activing.");
116 return START_SERVICE_ABILITY_ACTIVING;
117 }
118
119 sptr<Token> token = targetService->GetToken();
120 sptr<Token> preToken = nullptr;
121 if (targetService->GetPreAbilityRecord()) {
122 preToken = targetService->GetPreAbilityRecord()->GetToken();
123 }
124 DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
125 return ERR_OK;
126 }
127
TerminateAbilityLocked(const sptr<IRemoteObject> & token)128 int AbilityConnectManager::TerminateAbilityLocked(const sptr<IRemoteObject> &token)
129 {
130 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
131 HILOG_INFO("Terminate ability locked.");
132 auto abilityRecord = GetServiceRecordByToken(token);
133 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
134
135 if (abilityRecord->IsTerminating()) {
136 HILOG_INFO("Ability is on terminating.");
137 return ERR_OK;
138 }
139
140 if (!abilityRecord->GetConnectRecordList().empty()) {
141 HILOG_INFO("Target service has been connected. Post disconnect task.");
142 auto connectRecordList = abilityRecord->GetConnectRecordList();
143 HandleTerminateDisconnectTask(connectRecordList);
144 }
145
146 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
147 HILOG_WARN("Disconnect ability terminate timeout.");
148 connectManager->HandleStopTimeoutTask(abilityRecord);
149 };
150 abilityRecord->Terminate(timeoutTask);
151
152 return ERR_OK;
153 }
154
TerminateAbilityResultLocked(const sptr<IRemoteObject> & token,int startId)155 int AbilityConnectManager::TerminateAbilityResultLocked(const sptr<IRemoteObject> &token, int startId)
156 {
157 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
158 HILOG_INFO("Terminate ability result locked, startId: %{public}d", startId);
159 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
160
161 auto abilityRecord = Token::GetAbilityRecordByToken(token);
162 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
163
164 if (abilityRecord->GetStartId() != startId) {
165 HILOG_ERROR("Start id not equal.");
166 return TERMINATE_ABILITY_RESULT_FAILED;
167 }
168
169 return TerminateAbilityLocked(token);
170 }
171
StopServiceAbilityLocked(const AbilityRequest & abilityRequest)172 int AbilityConnectManager::StopServiceAbilityLocked(const AbilityRequest &abilityRequest)
173 {
174 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
175 HILOG_INFO("Stop service ability locked.");
176 AppExecFwk::ElementName element(
177 abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
178 auto abilityRecord = GetServiceRecordByElementName(element.GetURI());
179 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
180
181 if (abilityRecord->IsTerminating()) {
182 HILOG_INFO("Ability is on terminating.");
183 return ERR_OK;
184 }
185
186 if (!abilityRecord->GetConnectRecordList().empty()) {
187 HILOG_INFO("Target service has been connected. Post disconnect task.");
188 auto connectRecordList = abilityRecord->GetConnectRecordList();
189 HandleTerminateDisconnectTask(connectRecordList);
190 }
191
192 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
193 HILOG_WARN("Disconnect ability terminate timeout.");
194 connectManager->HandleStopTimeoutTask(abilityRecord);
195 };
196 abilityRecord->Terminate(timeoutTask);
197
198 return ERR_OK;
199 }
200
GetOrCreateServiceRecord(const AbilityRequest & abilityRequest,const bool isCreatedByConnect,std::shared_ptr<AbilityRecord> & targetService,bool & isLoadedAbility)201 void AbilityConnectManager::GetOrCreateServiceRecord(const AbilityRequest &abilityRequest,
202 const bool isCreatedByConnect, std::shared_ptr<AbilityRecord> &targetService, bool &isLoadedAbility)
203 {
204 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
205 AppExecFwk::ElementName element(
206 abilityRequest.abilityInfo.deviceId, abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name);
207 auto serviceMapIter = serviceMap_.find(element.GetURI());
208 if (serviceMapIter == serviceMap_.end()) {
209 targetService = AbilityRecord::CreateAbilityRecord(abilityRequest);
210 if (isCreatedByConnect && targetService != nullptr) {
211 targetService->SetCreateByConnectMode();
212 }
213 if (targetService && abilityRequest.abilityInfo.name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
214 targetService->SetLauncherRoot();
215 targetService->SetRestarting(abilityRequest.restart, abilityRequest.restartCount);
216 }
217 serviceMap_.emplace(element.GetURI(), targetService);
218 isLoadedAbility = false;
219 } else {
220 targetService = serviceMapIter->second;
221 if (targetService != nullptr) {
222 // want may be changed for the same ability.
223 targetService->SetWant(abilityRequest.want);
224 }
225 isLoadedAbility = true;
226 }
227 }
228
GetConnectRecordListFromMap(const sptr<IAbilityConnection> & connect,std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)229 void AbilityConnectManager::GetConnectRecordListFromMap(
230 const sptr<IAbilityConnection> &connect, std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
231 {
232 auto connectMapIter = connectMap_.find(connect->AsObject());
233 if (connectMapIter != connectMap_.end()) {
234 connectRecordList = connectMapIter->second;
235 }
236 }
237
ConnectAbilityLocked(const AbilityRequest & abilityRequest,const sptr<IAbilityConnection> & connect,const sptr<IRemoteObject> & callerToken)238 int AbilityConnectManager::ConnectAbilityLocked(const AbilityRequest &abilityRequest,
239 const sptr<IAbilityConnection> &connect, const sptr<IRemoteObject> &callerToken)
240 {
241 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
242 HILOG_INFO("%{public}s, ability_name:%{public}s", __func__, abilityRequest.want.GetElement().GetURI().c_str());
243 std::lock_guard<std::recursive_mutex> guard(Lock_);
244
245 // 1. get target service ability record, and check whether it has been loaded.
246 std::shared_ptr<AbilityRecord> targetService;
247 bool isLoadedAbility = false;
248 GetOrCreateServiceRecord(abilityRequest, true, targetService, isLoadedAbility);
249 CHECK_POINTER_AND_RETURN(targetService, ERR_INVALID_VALUE);
250 // 2. get target connectRecordList, and check whether this callback has been connected.
251 ConnectListType connectRecordList;
252 GetConnectRecordListFromMap(connect, connectRecordList);
253 bool isCallbackConnected = !connectRecordList.empty();
254 // 3. If this service ability and callback has been connected, There is no need to connect repeatedly
255 if (isLoadedAbility && (isCallbackConnected) && IsAbilityConnected(targetService, connectRecordList)) {
256 HILOG_ERROR("Service and callback was connected.");
257 return ERR_OK;
258 }
259
260 // 4. Other cases , need to connect the service ability
261 auto connectRecord = ConnectionRecord::CreateConnectionRecord(callerToken, targetService, connect);
262 CHECK_POINTER_AND_RETURN(connectRecord, ERR_INVALID_VALUE);
263 connectRecord->SetConnectState(ConnectionState::CONNECTING);
264 targetService->AddConnectRecordToList(connectRecord);
265 connectRecordList.push_back(connectRecord);
266 if (isCallbackConnected) {
267 RemoveConnectDeathRecipient(connect);
268 connectMap_.erase(connectMap_.find(connect->AsObject()));
269 }
270 AddConnectDeathRecipient(connect);
271 connectMap_.emplace(connect->AsObject(), connectRecordList);
272
273 // 5. load or connect ability
274 if (!isLoadedAbility) {
275 LoadAbility(targetService);
276 } else if (targetService->IsAbilityState(AbilityState::ACTIVE)) {
277 // this service ability has not first connect
278 if (targetService->GetConnectRecordList().size() > 1) {
279 if (eventHandler_ != nullptr) {
280 auto task = [connectRecord]() { connectRecord->CompleteConnect(ERR_OK); };
281 eventHandler_->PostTask(task);
282 }
283 } else {
284 ConnectAbility(targetService);
285 }
286 } else {
287 HILOG_ERROR("Target service is already activing.");
288 }
289
290 auto token = targetService->GetToken();
291 auto preToken = iface_cast<Token>(connectRecord->GetToken());
292 DelayedSingleton<AppScheduler>::GetInstance()->AbilityBehaviorAnalysis(token, preToken, 0, 1, 1);
293 return ERR_OK;
294 }
295
DisconnectAbilityLocked(const sptr<IAbilityConnection> & connect)296 int AbilityConnectManager::DisconnectAbilityLocked(const sptr<IAbilityConnection> &connect)
297 {
298 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
299 HILOG_INFO("Disconnect ability locked.");
300 std::lock_guard<std::recursive_mutex> guard(Lock_);
301
302 // 1. check whether callback was connected.
303 ConnectListType connectRecordList;
304 GetConnectRecordListFromMap(connect, connectRecordList);
305 if (connectRecordList.empty()) {
306 HILOG_ERROR("Can't find the connect list from connect map by callback.");
307 return CONNECTION_NOT_EXIST;
308 }
309
310 // 2. schedule disconnect to target service
311 for (auto &connectRecord : connectRecordList) {
312 if (connectRecord) {
313 auto abilityRecord = connectRecord->GetAbilityRecord();
314 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
315 int result = AbilityUtil::JudgeAbilityVisibleControl(abilityRecord->GetAbilityInfo());
316 if (result != ERR_OK) {
317 HILOG_ERROR("%{public}s JudgeAbilityVisibleControl error.", __func__);
318 return result;
319 }
320 int ret = connectRecord->DisconnectAbility();
321 if (ret != ERR_OK) {
322 HILOG_ERROR("Disconnect ability fail , ret = %{public}d.", ret);
323 return ret;
324 }
325 HILOG_INFO("Disconnect ability ,connect record id %{public}d", connectRecord->GetRecordId());
326 }
327 }
328
329 // 3. target servie has another connection, this record callback disconnected directly.
330 if (eventHandler_ != nullptr) {
331 auto task = [connectRecordList, connectManager = shared_from_this()]() {
332 connectManager->HandleDisconnectTask(connectRecordList);
333 };
334 eventHandler_->PostTask(task);
335 }
336
337 return ERR_OK;
338 }
339
AttachAbilityThreadLocked(const sptr<IAbilityScheduler> & scheduler,const sptr<IRemoteObject> & token)340 int AbilityConnectManager::AttachAbilityThreadLocked(
341 const sptr<IAbilityScheduler> &scheduler, const sptr<IRemoteObject> &token)
342 {
343 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
344 std::lock_guard<std::recursive_mutex> guard(Lock_);
345 auto abilityRecord = GetServiceRecordByToken(token);
346 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
347 if (eventHandler_ != nullptr) {
348 int recordId = abilityRecord->GetRecordId();
349 std::string taskName = std::string("LoadTimeout_") + std::to_string(recordId);
350 eventHandler_->RemoveTask(taskName);
351 eventHandler_->RemoveEvent(AbilityManagerService::LOAD_TIMEOUT_MSG, abilityRecord->GetEventId());
352 }
353 std::string element = abilityRecord->GetWant().GetElement().GetURI();
354 HILOG_INFO("Ability: %{public}s", element.c_str());
355 abilityRecord->SetScheduler(scheduler);
356
357 DelayedSingleton<AppScheduler>::GetInstance()->MoveToForground(token);
358 return ERR_OK;
359 }
360
OnAbilityRequestDone(const sptr<IRemoteObject> & token,const int32_t state)361 void AbilityConnectManager::OnAbilityRequestDone(const sptr<IRemoteObject> &token, const int32_t state)
362 {
363 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
364 std::lock_guard<std::recursive_mutex> guard(Lock_);
365 auto abilitState = DelayedSingleton<AppScheduler>::GetInstance()->ConvertToAppAbilityState(state);
366 auto abilityRecord = GetServiceRecordByToken(token);
367 CHECK_POINTER(abilityRecord);
368 std::string element = abilityRecord->GetWant().GetElement().GetURI();
369 HILOG_INFO("Ability: %{public}s", element.c_str());
370
371 if (abilitState == AppAbilityState::ABILITY_STATE_FOREGROUND) {
372 abilityRecord->Inactivate();
373 } else if (abilitState == AppAbilityState::ABILITY_STATE_BACKGROUND) {
374 DelayedSingleton<AppScheduler>::GetInstance()->TerminateAbility(token);
375 RemoveServiceAbility(abilityRecord);
376 }
377 }
378
OnAppStateChanged(const AppInfo & info)379 void AbilityConnectManager::OnAppStateChanged(const AppInfo &info)
380 {
381 std::lock_guard<std::recursive_mutex> guard(Lock_);
382 std::for_each(serviceMap_.begin(), serviceMap_.end(), [&info](ServiceMapType::reference service) {
383 if (service.second && (info.processName == service.second->GetAbilityInfo().process ||
384 info.processName == service.second->GetApplicationInfo().bundleName)) {
385 auto appName = service.second->GetApplicationInfo().name;
386 auto uid = service.second->GetAbilityInfo().applicationInfo.uid;
387 auto isExist = [&appName, &uid](
388 const AppData &appData) { return appData.appName == appName && appData.uid == uid; };
389 auto iter = std::find_if(info.appData.begin(), info.appData.end(), isExist);
390 if (iter != info.appData.end()) {
391 service.second->SetAppState(info.state);
392 }
393 }
394 });
395 }
396
AbilityTransitionDone(const sptr<IRemoteObject> & token,int state)397 int AbilityConnectManager::AbilityTransitionDone(const sptr<IRemoteObject> &token, int state)
398 {
399 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
400 std::lock_guard<std::recursive_mutex> guard(Lock_);
401 auto abilityRecord = GetServiceRecordByToken(token);
402 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
403
404 std::string element = abilityRecord->GetWant().GetElement().GetURI();
405 int targetState = AbilityRecord::ConvertLifeCycleToAbilityState(static_cast<AbilityLifeCycleState>(state));
406 std::string abilityState = AbilityRecord::ConvertAbilityState(static_cast<AbilityState>(targetState));
407 HILOG_INFO("Ability: %{public}s, state: %{public}s", element.c_str(), abilityState.c_str());
408
409 switch (state) {
410 case AbilityState::INACTIVE: {
411 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
412 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
413 token, AppExecFwk::AbilityState::ABILITY_STATE_CREATE);
414 } else {
415 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
416 token, AppExecFwk::ExtensionState::EXTENSION_STATE_CREATE);
417 }
418 return DispatchInactive(abilityRecord, state);
419 }
420 case AbilityState::INITIAL: {
421 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
422 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
423 token, AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED);
424 } else {
425 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
426 token, AppExecFwk::ExtensionState::EXTENSION_STATE_TERMINATED);
427 }
428 return DispatchTerminate(abilityRecord);
429 }
430 default: {
431 HILOG_WARN("Don't support transiting state: %{public}d", state);
432 return ERR_INVALID_VALUE;
433 }
434 }
435 }
436
ScheduleConnectAbilityDoneLocked(const sptr<IRemoteObject> & token,const sptr<IRemoteObject> & remoteObject)437 int AbilityConnectManager::ScheduleConnectAbilityDoneLocked(
438 const sptr<IRemoteObject> &token, const sptr<IRemoteObject> &remoteObject)
439 {
440 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
441 std::lock_guard<std::recursive_mutex> guard(Lock_);
442 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
443
444 auto abilityRecord = Token::GetAbilityRecordByToken(token);
445 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
446
447 std::string element = abilityRecord->GetWant().GetElement().GetURI();
448 HILOG_DEBUG("Ability: %{public}s", element.c_str());
449
450 if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
451 (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
452 HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
453 return INVALID_CONNECTION_STATE;
454 }
455
456 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
457 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
458 token, AppExecFwk::AbilityState::ABILITY_STATE_CONNECTED);
459 } else {
460 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
461 token, AppExecFwk::ExtensionState::EXTENSION_STATE_CONNECTED);
462 }
463
464 abilityRecord->SetConnRemoteObject(remoteObject);
465 // There may be multiple callers waiting for the connection result
466 auto connectRecordList = abilityRecord->GetConnectRecordList();
467 for (auto &connectRecord : connectRecordList) {
468 connectRecord->ScheduleConnectAbilityDone();
469 }
470
471 return ERR_OK;
472 }
473
ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> & token)474 int AbilityConnectManager::ScheduleDisconnectAbilityDoneLocked(const sptr<IRemoteObject> &token)
475 {
476 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
477 std::lock_guard<std::recursive_mutex> guard(Lock_);
478 auto abilityRecord = GetServiceRecordByToken(token);
479 CHECK_POINTER_AND_RETURN(abilityRecord, CONNECTION_NOT_EXIST);
480
481 auto connect = abilityRecord->GetDisconnectingRecord();
482 CHECK_POINTER_AND_RETURN(connect, CONNECTION_NOT_EXIST);
483
484 if (!abilityRecord->IsAbilityState(AbilityState::ACTIVE)) {
485 HILOG_ERROR("The service ability state is not active ,state: %{public}d", abilityRecord->GetAbilityState());
486 return INVALID_CONNECTION_STATE;
487 }
488
489 if (abilityRecord->GetAbilityInfo().type == AbilityType::SERVICE) {
490 DelayedSingleton<AppScheduler>::GetInstance()->UpdateAbilityState(
491 token, AppExecFwk::AbilityState::ABILITY_STATE_DISCONNECTED);
492 } else {
493 DelayedSingleton<AppScheduler>::GetInstance()->UpdateExtensionState(
494 token, AppExecFwk::ExtensionState::EXTENSION_STATE_DISCONNECTED);
495 }
496
497 std::string element = abilityRecord->GetWant().GetElement().GetURI();
498 HILOG_INFO("disconnect ability done with service %{public}s", element.c_str());
499
500 // complete disconnect and remove record from conn map
501 connect->ScheduleDisconnectAbilityDone();
502 abilityRecord->RemoveConnectRecordFromList(connect);
503 if (abilityRecord->IsConnectListEmpty() && abilityRecord->GetStartId() == 0) {
504 HILOG_INFO("Service ability has no any connection, and not started , need terminate.");
505 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
506 HILOG_WARN("Disconnect ability terminate timeout.");
507 connectManager->HandleStopTimeoutTask(abilityRecord);
508 };
509 abilityRecord->Terminate(timeoutTask);
510 }
511 RemoveConnectionRecordFromMap(connect);
512
513 return ERR_OK;
514 }
515
ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> & token)516 int AbilityConnectManager::ScheduleCommandAbilityDoneLocked(const sptr<IRemoteObject> &token)
517 {
518 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
519 std::lock_guard<std::recursive_mutex> guard(Lock_);
520 CHECK_POINTER_AND_RETURN(token, ERR_INVALID_VALUE);
521 auto abilityRecord = Token::GetAbilityRecordByToken(token);
522 CHECK_POINTER_AND_RETURN(abilityRecord, ERR_INVALID_VALUE);
523 std::string element = abilityRecord->GetWant().GetElement().GetURI();
524 HILOG_DEBUG("Ability: %{public}s", element.c_str());
525
526 if ((!abilityRecord->IsAbilityState(AbilityState::INACTIVE)) &&
527 (!abilityRecord->IsAbilityState(AbilityState::ACTIVE))) {
528 HILOG_ERROR("Ability record state is not inactive ,state: %{public}d", abilityRecord->GetAbilityState());
529 return INVALID_CONNECTION_STATE;
530 }
531 // complete command and pop waiting start ability from queue.
532 CompleteCommandAbility(abilityRecord);
533
534 return ERR_OK;
535 }
536
CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)537 void AbilityConnectManager::CompleteCommandAbility(std::shared_ptr<AbilityRecord> abilityRecord)
538 {
539 CHECK_POINTER(abilityRecord);
540
541 if (eventHandler_) {
542 int recordId = abilityRecord->GetRecordId();
543 std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
544 std::to_string(abilityRecord->GetStartId());
545 eventHandler_->RemoveTask(taskName);
546 }
547
548 abilityRecord->SetAbilityState(AbilityState::ACTIVE);
549 }
550
GetServiceRecordByElementName(const std::string & element)551 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetServiceRecordByElementName(const std::string &element)
552 {
553 std::lock_guard<std::recursive_mutex> guard(Lock_);
554 auto mapIter = serviceMap_.find(element);
555 if (mapIter != serviceMap_.end()) {
556 return mapIter->second;
557 }
558 return nullptr;
559 }
560
GetServiceRecordByToken(const sptr<IRemoteObject> & token)561 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetServiceRecordByToken(const sptr<IRemoteObject> &token)
562 {
563 std::lock_guard<std::recursive_mutex> guard(Lock_);
564 auto IsMatch = [token](auto service) {
565 if (!service.second) {
566 return false;
567 }
568 sptr<IRemoteObject> srcToken = service.second->GetToken();
569 return srcToken == token;
570 };
571 auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
572 if (serviceRecord != serviceMap_.end()) {
573 return serviceRecord->second;
574 }
575 return nullptr;
576 }
577
GetConnectRecordListByCallback(sptr<IAbilityConnection> callback)578 std::list<std::shared_ptr<ConnectionRecord>> AbilityConnectManager::GetConnectRecordListByCallback(
579 sptr<IAbilityConnection> callback)
580 {
581 std::lock_guard<std::recursive_mutex> guard(Lock_);
582 std::list<std::shared_ptr<ConnectionRecord>> connectList;
583 auto connectMapIter = connectMap_.find(callback->AsObject());
584 if (connectMapIter != connectMap_.end()) {
585 connectList = connectMapIter->second;
586 }
587 return connectList;
588 }
589
GetAbilityRecordByEventId(int64_t eventId)590 std::shared_ptr<AbilityRecord> AbilityConnectManager::GetAbilityRecordByEventId(int64_t eventId)
591 {
592 std::lock_guard<std::recursive_mutex> guard(Lock_);
593 auto IsMatch = [eventId](auto service) {
594 if (!service.second) {
595 return false;
596 }
597 return eventId == service.second->GetEventId();
598 };
599 auto serviceRecord = std::find_if(serviceMap_.begin(), serviceMap_.end(), IsMatch);
600 if (serviceRecord != serviceMap_.end()) {
601 return serviceRecord->second;
602 }
603 return nullptr;
604 }
605
RemoveAll()606 void AbilityConnectManager::RemoveAll()
607 {
608 serviceMap_.clear();
609 connectMap_.clear();
610 }
611
LoadAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)612 void AbilityConnectManager::LoadAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
613 {
614 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
615 CHECK_POINTER(abilityRecord);
616 abilityRecord->SetStartTime();
617
618 if (!abilityRecord->CanRestartRootLauncher()) {
619 HILOG_ERROR("Root launcher restart is out of max count.");
620 RemoveServiceAbility(abilityRecord);
621 return;
622 }
623
624 PostTimeOutTask(abilityRecord, AbilityManagerService::LOAD_TIMEOUT_MSG);
625
626 sptr<Token> token = abilityRecord->GetToken();
627 sptr<Token> perToken = nullptr;
628 if (abilityRecord->IsCreateByConnect()) {
629 perToken = iface_cast<Token>(abilityRecord->GetConnectingRecord()->GetToken());
630 } else {
631 auto callerList = abilityRecord->GetCallerRecordList();
632 if (!callerList.empty() && callerList.back()) {
633 auto caller = callerList.back()->GetCaller();
634 if (caller) {
635 perToken = caller->GetToken();
636 }
637 }
638 }
639 DelayedSingleton<AppScheduler>::GetInstance()->LoadAbility(
640 token, perToken, abilityRecord->GetAbilityInfo(), abilityRecord->GetApplicationInfo(),
641 abilityRecord->GetWant());
642 }
643
PostTimeOutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,uint32_t messageId)644 void AbilityConnectManager::PostTimeOutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, uint32_t messageId)
645 {
646 CHECK_POINTER(abilityRecord);
647 CHECK_POINTER(eventHandler_);
648 if (messageId != AbilityConnectManager::LOAD_TIMEOUT_MSG &&
649 messageId != AbilityConnectManager::CONNECT_TIMEOUT_MSG) {
650 HILOG_ERROR("Timeout task messageId is error.");
651 return;
652 }
653
654 int recordId;
655 std::string taskName;
656 int resultCode;
657 uint32_t delayTime;
658 if (messageId == AbilityManagerService::LOAD_TIMEOUT_MSG) {
659 // first load ability, There is at most one connect record.
660 recordId = abilityRecord->GetRecordId();
661 taskName = std::string("LoadTimeout_") + std::to_string(recordId);
662 resultCode = LOAD_ABILITY_TIMEOUT;
663 delayTime = AbilityManagerService::LOAD_TIMEOUT;
664 } else {
665 auto connectRecord = abilityRecord->GetConnectingRecord();
666 CHECK_POINTER(connectRecord);
667 recordId = connectRecord->GetRecordId();
668 taskName = std::string("ConnectTimeout_") + std::to_string(recordId);
669 resultCode = CONNECTION_TIMEOUT;
670 delayTime = AbilityManagerService::CONNECT_TIMEOUT;
671 }
672
673 auto timeoutTask = [abilityRecord, connectManager = shared_from_this(), resultCode]() {
674 HILOG_WARN("Connect or load ability timeout.");
675 connectManager->HandleStartTimeoutTask(abilityRecord, resultCode);
676 };
677
678 eventHandler_->PostTask(timeoutTask, taskName, delayTime);
679 }
680
HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int resultCode)681 void AbilityConnectManager::HandleStartTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord, int resultCode)
682 {
683 HILOG_DEBUG("Complete connect or load ability timeout.");
684 std::lock_guard<std::recursive_mutex> guard(Lock_);
685 CHECK_POINTER(abilityRecord);
686 auto connectingList = abilityRecord->GetConnectingRecordList();
687 for (auto &connectRecord : connectingList) {
688 if (connectRecord == nullptr) {
689 HILOG_WARN("ConnectRecord is nullptr.");
690 continue;
691 }
692 connectRecord->CompleteConnect(resultCode);
693 abilityRecord->RemoveConnectRecordFromList(connectRecord);
694 RemoveConnectionRecordFromMap(connectRecord);
695 }
696
697 if (resultCode == LOAD_ABILITY_TIMEOUT) {
698 HILOG_DEBUG("Load time out , remove target service record from services map.");
699 RemoveServiceAbility(abilityRecord);
700 }
701 if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
702 // terminate the timeout root launcher.
703 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
704 if (resultCode == LOAD_ABILITY_TIMEOUT) {
705 StartRootLauncher(abilityRecord);
706 }
707 }
708 }
709
HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)710 void AbilityConnectManager::HandleCommandTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
711 {
712 HILOG_DEBUG("HandleCommandTimeoutTask start");
713 std::lock_guard<std::recursive_mutex> guard(Lock_);
714 CHECK_POINTER(abilityRecord);
715 if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
716 HILOG_DEBUG("Handle root launcher command timeout.");
717 // terminate the timeout root launcher.
718 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(abilityRecord->GetToken());
719 }
720 HILOG_DEBUG("HandleCommandTimeoutTask end");
721 }
722
StartRootLauncher(const std::shared_ptr<AbilityRecord> & abilityRecord)723 void AbilityConnectManager::StartRootLauncher(const std::shared_ptr<AbilityRecord> &abilityRecord)
724 {
725 CHECK_POINTER(abilityRecord);
726 AbilityRequest requestInfo;
727 requestInfo.want = abilityRecord->GetWant();
728 requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
729 requestInfo.appInfo = abilityRecord->GetApplicationInfo();
730 requestInfo.restart = true;
731 requestInfo.restartCount = abilityRecord->GetRestartCount() - 1;
732
733 HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
734 StartAbilityLocked(requestInfo);
735 }
736
HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> & abilityRecord)737 void AbilityConnectManager::HandleStopTimeoutTask(const std::shared_ptr<AbilityRecord> &abilityRecord)
738 {
739 HILOG_DEBUG("Complete stop ability timeout start.");
740 std::lock_guard<std::recursive_mutex> guard(Lock_);
741 CHECK_POINTER(abilityRecord);
742 TerminateDone(abilityRecord);
743 }
744
HandleDisconnectTask(const ConnectListType & connectlist)745 void AbilityConnectManager::HandleDisconnectTask(const ConnectListType &connectlist)
746 {
747 HILOG_DEBUG("Complete disconnect ability.");
748 std::lock_guard<std::recursive_mutex> guard(Lock_);
749 for (auto &connectRecord : connectlist) {
750 if (!connectRecord) {
751 continue;
752 }
753 auto targetService = connectRecord->GetAbilityRecord();
754 if (targetService && connectRecord->GetConnectState() == ConnectionState::DISCONNECTED &&
755 targetService->GetConnectRecordList().size() > 1) {
756 HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
757 connectRecord->CompleteDisconnect(ERR_OK, false);
758 targetService->RemoveConnectRecordFromList(connectRecord);
759 RemoveConnectionRecordFromMap(connectRecord);
760 };
761 }
762 }
763
HandleTerminateDisconnectTask(const ConnectListType & connectlist)764 void AbilityConnectManager::HandleTerminateDisconnectTask(const ConnectListType& connectlist)
765 {
766 HILOG_DEBUG("Disconnect ability when terminate.");
767 std::lock_guard<std::recursive_mutex> guard(Lock_);
768 for (auto& connectRecord : connectlist) {
769 if (!connectRecord) {
770 continue;
771 }
772 auto targetService = connectRecord->GetAbilityRecord();
773 if (targetService) {
774 HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
775 connectRecord->CompleteDisconnect(ERR_OK, false);
776 targetService->RemoveConnectRecordFromList(connectRecord);
777 RemoveConnectionRecordFromMap(connectRecord);
778 };
779 }
780 }
781
DispatchInactive(const std::shared_ptr<AbilityRecord> & abilityRecord,int state)782 int AbilityConnectManager::DispatchInactive(const std::shared_ptr<AbilityRecord> &abilityRecord, int state)
783 {
784 CHECK_POINTER_AND_RETURN(eventHandler_, ERR_INVALID_VALUE);
785 if (!abilityRecord->IsAbilityState(AbilityState::INACTIVATING)) {
786 HILOG_ERROR("Ability transition life state error. expect %{public}d, actual %{public}d callback %{public}d",
787 AbilityState::INACTIVATING,
788 abilityRecord->GetAbilityState(),
789 state);
790 return ERR_INVALID_VALUE;
791 }
792 eventHandler_->RemoveEvent(AbilityManagerService::INACTIVE_TIMEOUT_MSG, abilityRecord->GetEventId());
793
794 // complete inactive
795 abilityRecord->SetAbilityState(AbilityState::INACTIVE);
796 if (abilityRecord->IsCreateByConnect()) {
797 ConnectAbility(abilityRecord);
798 } else {
799 CommandAbility(abilityRecord);
800 }
801
802 return ERR_OK;
803 }
804
DispatchTerminate(const std::shared_ptr<AbilityRecord> & abilityRecord)805 int AbilityConnectManager::DispatchTerminate(const std::shared_ptr<AbilityRecord> &abilityRecord)
806 {
807 // remove terminate timeout task
808 if (eventHandler_ != nullptr) {
809 eventHandler_->RemoveTask(std::to_string(abilityRecord->GetEventId()));
810 }
811 // complete terminate
812 TerminateDone(abilityRecord);
813 return ERR_OK;
814 }
815
ConnectAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)816 void AbilityConnectManager::ConnectAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
817 {
818 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
819 CHECK_POINTER(abilityRecord);
820 PostTimeOutTask(abilityRecord, AbilityConnectManager::CONNECT_TIMEOUT_MSG);
821 abilityRecord->ConnectAbility();
822 }
823
CommandAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)824 void AbilityConnectManager::CommandAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
825 {
826 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
827 if (eventHandler_ != nullptr) {
828 // first connect ability, There is at most one connect record.
829 int recordId = abilityRecord->GetRecordId();
830 abilityRecord->AddStartId();
831 std::string taskName = std::string("CommandTimeout_") + std::to_string(recordId) + std::string("_") +
832 std::to_string(abilityRecord->GetStartId());
833 auto timeoutTask = [abilityRecord, connectManager = shared_from_this()]() {
834 HILOG_ERROR("Command ability timeout. %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
835 connectManager->HandleCommandTimeoutTask(abilityRecord);
836 };
837 eventHandler_->PostTask(timeoutTask, taskName, AbilityManagerService::COMMAND_TIMEOUT);
838 // scheduling command ability
839 abilityRecord->CommandAbility();
840 }
841 }
842
TerminateDone(const std::shared_ptr<AbilityRecord> & abilityRecord)843 void AbilityConnectManager::TerminateDone(const std::shared_ptr<AbilityRecord> &abilityRecord)
844 {
845 BYTRACE_NAME(BYTRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
846 if (!abilityRecord->IsAbilityState(AbilityState::TERMINATING)) {
847 std::string expect = AbilityRecord::ConvertAbilityState(AbilityState::TERMINATING);
848 std::string actual = AbilityRecord::ConvertAbilityState(abilityRecord->GetAbilityState());
849 HILOG_ERROR(
850 "Transition life state error. expect %{public}s, actual %{public}s", expect.c_str(), actual.c_str());
851 return;
852 }
853 DelayedSingleton<AppScheduler>::GetInstance()->MoveToBackground(abilityRecord->GetToken());
854 }
855
IsAbilityConnected(const std::shared_ptr<AbilityRecord> & abilityRecord,const std::list<std::shared_ptr<ConnectionRecord>> & connectRecordList)856 bool AbilityConnectManager::IsAbilityConnected(const std::shared_ptr<AbilityRecord> &abilityRecord,
857 const std::list<std::shared_ptr<ConnectionRecord>> &connectRecordList)
858 {
859 auto isMatch = [abilityRecord](auto connectRecord) -> bool {
860 if (abilityRecord == nullptr || connectRecord == nullptr) {
861 return false;
862 }
863 if (abilityRecord != connectRecord->GetAbilityRecord()) {
864 return false;
865 }
866 return true;
867 };
868 return std::any_of(connectRecordList.begin(), connectRecordList.end(), isMatch);
869 }
870
RemoveConnectionRecordFromMap(const std::shared_ptr<ConnectionRecord> & connection)871 void AbilityConnectManager::RemoveConnectionRecordFromMap(const std::shared_ptr<ConnectionRecord> &connection)
872 {
873 for (auto &connectCallback : connectMap_) {
874 auto &connectList = connectCallback.second;
875 auto connectRecord = std::find(connectList.begin(), connectList.end(), connection);
876 if (connectRecord != connectList.end()) {
877 HILOG_INFO("Remove connrecord(%{public}d) from maplist.", (*connectRecord)->GetRecordId());
878 connectList.remove(connection);
879 if (connectList.empty()) {
880 HILOG_INFO("Remove connlist from map.");
881 sptr<IAbilityConnection> connect = iface_cast<IAbilityConnection>(connectCallback.first);
882 RemoveConnectDeathRecipient(connect);
883 connectMap_.erase(connectCallback.first);
884 }
885 return;
886 }
887 }
888 }
889
RemoveServiceAbility(const std::shared_ptr<AbilityRecord> & abilityRecord)890 void AbilityConnectManager::RemoveServiceAbility(const std::shared_ptr<AbilityRecord> &abilityRecord)
891 {
892 CHECK_POINTER(abilityRecord);
893 const AppExecFwk::AbilityInfo &abilityInfo = abilityRecord->GetAbilityInfo();
894 std::string element = abilityInfo.deviceId + "/" + abilityInfo.bundleName + "/" + abilityInfo.name;
895 HILOG_INFO("Remove service(%{public}s) from map.", element.c_str());
896 auto it = serviceMap_.find(element);
897 if (it != serviceMap_.end()) {
898 HILOG_INFO("Remove service(%{public}s) from map.", element.c_str());
899 serviceMap_.erase(it);
900 }
901 }
902
AddConnectDeathRecipient(const sptr<IAbilityConnection> & connect)903 void AbilityConnectManager::AddConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
904 {
905 CHECK_POINTER(connect);
906 CHECK_POINTER(connect->AsObject());
907 auto it = recipientMap_.find(connect->AsObject());
908 if (it != recipientMap_.end()) {
909 HILOG_ERROR("This death recipient has been added.");
910 return;
911 } else {
912 sptr<IRemoteObject::DeathRecipient> deathRecipient = new AbilityConnectCallbackRecipient(
913 std::bind(&AbilityConnectManager::OnCallBackDied, this, std::placeholders::_1));
914 connect->AsObject()->AddDeathRecipient(deathRecipient);
915 recipientMap_.emplace(connect->AsObject(), deathRecipient);
916 }
917 }
918
RemoveConnectDeathRecipient(const sptr<IAbilityConnection> & connect)919 void AbilityConnectManager::RemoveConnectDeathRecipient(const sptr<IAbilityConnection> &connect)
920 {
921 CHECK_POINTER(connect);
922 CHECK_POINTER(connect->AsObject());
923 auto it = recipientMap_.find(connect->AsObject());
924 if (it != recipientMap_.end()) {
925 it->first->RemoveDeathRecipient(it->second);
926 recipientMap_.erase(it);
927 return;
928 }
929 }
930
OnCallBackDied(const wptr<IRemoteObject> & remote)931 void AbilityConnectManager::OnCallBackDied(const wptr<IRemoteObject> &remote)
932 {
933 auto object = remote.promote();
934 CHECK_POINTER(object);
935 if (eventHandler_) {
936 auto task = [object, connectManager = shared_from_this()]() { connectManager->HandleCallBackDiedTask(object); };
937 eventHandler_->PostTask(task, TASK_ON_CALLBACK_DIED);
938 }
939 }
940
HandleCallBackDiedTask(const sptr<IRemoteObject> & connect)941 void AbilityConnectManager::HandleCallBackDiedTask(const sptr<IRemoteObject> &connect)
942 {
943 HILOG_INFO("Handle call back died task.");
944 std::lock_guard<std::recursive_mutex> guard(Lock_);
945 CHECK_POINTER(connect);
946 auto it = connectMap_.find(connect);
947 if (it != connectMap_.end()) {
948 ConnectListType connectRecordList = it->second;
949 for (auto &connRecord : connectRecordList) {
950 connRecord->ClearConnCallBack();
951 }
952 } else {
953 HILOG_INFO("Died object can't find from conn map.");
954 return;
955 }
956 sptr<IAbilityConnection> object = iface_cast<IAbilityConnection>(connect);
957 DisconnectAbilityLocked(object);
958 }
959
OnAbilityDied(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)960 void AbilityConnectManager::OnAbilityDied(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
961 {
962 HILOG_INFO("On ability died.");
963 CHECK_POINTER(abilityRecord);
964 if (abilityRecord->GetAbilityInfo().type != AbilityType::SERVICE &&
965 abilityRecord->GetAbilityInfo().type != AbilityType::EXTENSION) {
966 HILOG_DEBUG("Ability type is not service.");
967 return;
968 }
969 if (eventHandler_) {
970 auto task = [abilityRecord, connectManager = shared_from_this(), currentUserId]() {
971 connectManager->HandleAbilityDiedTask(abilityRecord, currentUserId);
972 };
973 eventHandler_->PostTask(task, TASK_ON_ABILITY_DIED);
974 }
975 }
976
OnTimeOut(uint32_t msgId,int64_t eventId)977 void AbilityConnectManager::OnTimeOut(uint32_t msgId, int64_t eventId)
978 {
979 HILOG_DEBUG("On timeout, msgId is %{public}d", msgId);
980 std::lock_guard<std::recursive_mutex> guard(Lock_);
981 auto abilityRecord = GetAbilityRecordByEventId(eventId);
982 if (abilityRecord == nullptr) {
983 HILOG_ERROR("AbilityConnectManager on time out event: ability record is nullptr.");
984 return;
985 }
986 HILOG_DEBUG("Ability timeout ,msg:%{public}d,name:%{public}s", msgId, abilityRecord->GetAbilityInfo().name.c_str());
987
988 switch (msgId) {
989 case AbilityManagerService::INACTIVE_TIMEOUT_MSG:
990 HandleInactiveTimeout(abilityRecord);
991 break;
992 default:
993 break;
994 }
995 }
996
HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> & ability)997 void AbilityConnectManager::HandleInactiveTimeout(const std::shared_ptr<AbilityRecord> &ability)
998 {
999 HILOG_DEBUG("HandleInactiveTimeout start");
1000 std::lock_guard<std::recursive_mutex> guard(Lock_);
1001 CHECK_POINTER(ability);
1002 if (ability->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1003 HILOG_DEBUG("Handle root launcher inactive timeout.");
1004 // terminate the timeout root launcher.
1005 DelayedSingleton<AppScheduler>::GetInstance()->AttachTimeOut(ability->GetToken());
1006 }
1007
1008 HILOG_DEBUG("HandleInactiveTimeout end");
1009 }
1010
IsAbilityNeedRestart(const std::shared_ptr<AbilityRecord> & abilityRecord)1011 bool AbilityConnectManager::IsAbilityNeedRestart(const std::shared_ptr<AbilityRecord> &abilityRecord)
1012 {
1013 auto bms = AbilityUtil::GetBundleManager();
1014 CHECK_POINTER_AND_RETURN(bms, false);
1015 std::vector<AppExecFwk::BundleInfo> bundleInfos;
1016 bool getBundleInfos = bms->GetBundleInfos(OHOS::AppExecFwk::GET_BUNDLE_DEFAULT, bundleInfos, USER_ID_NO_HEAD);
1017 if (!getBundleInfos) {
1018 HILOG_ERROR("Handle ability died task, get bundle infos failed");
1019 return false;
1020 }
1021
1022 auto GetKeepAliveAbilities = [&bundleInfos](std::vector<std::string> &keepAliveAbilities) -> void {
1023 for (size_t i = 0; i < bundleInfos.size(); i++) {
1024 if (!bundleInfos[i].isKeepAlive) {
1025 continue;
1026 }
1027 for (auto hapModuleInfo : bundleInfos[i].hapModuleInfos) {
1028 std::string mainElement;
1029 if (!hapModuleInfo.isModuleJson) {
1030 // old application model
1031 mainElement = hapModuleInfo.mainAbility;
1032 } else {
1033 // new application model
1034 mainElement = hapModuleInfo.mainElementName;
1035 }
1036 if (!mainElement.empty()) {
1037 keepAliveAbilities.push_back(mainElement);
1038 }
1039 }
1040 }
1041 };
1042
1043 auto findKeepAliveAbility = [abilityRecord](const std::string &mainElemen) {
1044 return (abilityRecord->GetAbilityInfo().name == mainElemen ||
1045 abilityRecord->GetAbilityInfo().name == AbilityConfig::PHONE_SERVICE_ABILITY_NAME ||
1046 abilityRecord->GetAbilityInfo().name == AbilityConfig::MMS_ABILITY_NAME ||
1047 abilityRecord->GetAbilityInfo().name == AbilityConfig::SYSTEM_UI_ABILITY_NAME ||
1048 abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME);
1049 };
1050
1051 std::vector<std::string> keepAliveAbilities;
1052 GetKeepAliveAbilities(keepAliveAbilities);
1053 auto findIter = find_if(keepAliveAbilities.begin(), keepAliveAbilities.end(), findKeepAliveAbility);
1054 return (findIter != keepAliveAbilities.end());
1055 }
1056
HandleAbilityDiedTask(const std::shared_ptr<AbilityRecord> & abilityRecord,int32_t currentUserId)1057 void AbilityConnectManager::HandleAbilityDiedTask(
1058 const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId)
1059 {
1060 HILOG_INFO("Handle ability died task.");
1061 std::lock_guard<std::recursive_mutex> guard(Lock_);
1062 CHECK_POINTER(abilityRecord);
1063 if (!GetServiceRecordByToken(abilityRecord->GetToken())) {
1064 HILOG_ERROR("Died ability record is not exist in service map.");
1065 return;
1066 }
1067
1068 if (IsAbilityNeedRestart(abilityRecord)) {
1069 HILOG_INFO("restart ability: %{public}s", abilityRecord->GetAbilityInfo().name.c_str());
1070 AbilityRequest requestInfo;
1071 requestInfo.want = abilityRecord->GetWant();
1072 requestInfo.abilityInfo = abilityRecord->GetAbilityInfo();
1073 requestInfo.appInfo = abilityRecord->GetApplicationInfo();
1074 requestInfo.restart = true;
1075
1076 RemoveServiceAbility(abilityRecord);
1077 if (currentUserId != userId_ &&
1078 abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1079 HILOG_WARN("delay restart root launcher until switch user.");
1080 return;
1081 }
1082
1083 if (abilityRecord->GetAbilityInfo().name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
1084 requestInfo.restartCount = abilityRecord->GetRestartCount() - 1;
1085 HILOG_DEBUG("restart root launcher, number:%{public}d", requestInfo.restartCount);
1086 }
1087
1088 StartAbilityLocked(requestInfo);
1089 return;
1090 }
1091
1092 ConnectListType connlist = abilityRecord->GetConnectRecordList();
1093 for (auto &connectRecord : connlist) {
1094 HILOG_WARN("This record complete disconnect directly. recordId:%{public}d", connectRecord->GetRecordId());
1095 connectRecord->CompleteDisconnect(ERR_OK, true);
1096 abilityRecord->RemoveConnectRecordFromList(connectRecord);
1097 RemoveConnectionRecordFromMap(connectRecord);
1098 }
1099
1100 RemoveServiceAbility(abilityRecord);
1101 }
1102
DumpState(std::vector<std::string> & info,bool isClient,const std::string & args) const1103 void AbilityConnectManager::DumpState(std::vector<std::string> &info, bool isClient, const std::string &args) const
1104 {
1105 if (!args.empty()) {
1106 auto it = std::find_if(serviceMap_.begin(), serviceMap_.end(), [&args](const auto &service) {
1107 return service.first.compare(args) == 0;
1108 });
1109 if (it != serviceMap_.end()) {
1110 info.emplace_back("uri [ " + it->first + " ]");
1111 it->second->DumpService(info, isClient);
1112 } else {
1113 info.emplace_back(args + ": Nothing to dump.");
1114 }
1115 } else {
1116 auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
1117 if (abilityMgr && abilityMgr->IsUseNewMission()) {
1118 info.emplace_back(" ExtensionRecords:");
1119 } else {
1120 info.emplace_back(" serviceAbilityRecords:");
1121 }
1122 for (auto &&service : serviceMap_) {
1123 info.emplace_back(" uri [" + service.first + "]");
1124 service.second->DumpService(info, isClient);
1125 }
1126 }
1127 }
1128
GetExtensionRunningInfos(int upperLimit,std::vector<ExtensionRunningInfo> & info,const int32_t userId,bool isPerm)1129 void AbilityConnectManager::GetExtensionRunningInfos(int upperLimit, std::vector<ExtensionRunningInfo> &info,
1130 const int32_t userId, bool isPerm)
1131 {
1132 HILOG_INFO("Get extension running info.");
1133 std::lock_guard<std::recursive_mutex> guard(Lock_);
1134 auto mgr = shared_from_this();
1135 auto queryInfo = [&info, upperLimit, userId, isPerm, mgr](ServiceMapType::reference service) {
1136 if (static_cast<int>(info.size()) >= upperLimit) {
1137 return;
1138 }
1139 auto abilityRecord = service.second;
1140 CHECK_POINTER(abilityRecord);
1141
1142 if (isPerm) {
1143 mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
1144 } else {
1145 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1146 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1147 if (callingTokenId == tokenID) {
1148 mgr->GetExtensionRunningInfo(abilityRecord, userId, info);
1149 }
1150 }
1151 };
1152 std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
1153 }
1154
GetAbilityRunningInfos(std::vector<AbilityRunningInfo> & info,bool isPerm)1155 void AbilityConnectManager::GetAbilityRunningInfos(std::vector<AbilityRunningInfo> &info, bool isPerm)
1156 {
1157 HILOG_INFO("Query running ability infos.");
1158 std::lock_guard<std::recursive_mutex> guard(Lock_);
1159
1160 auto queryInfo = [&info, isPerm](ServiceMapType::reference service) {
1161 auto abilityRecord = service.second;
1162 CHECK_POINTER(abilityRecord);
1163
1164 if (isPerm) {
1165 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1166 } else {
1167 auto callingTokenId = IPCSkeleton::GetCallingTokenID();
1168 auto tokenID = abilityRecord->GetApplicationInfo().accessTokenId;
1169 if (callingTokenId == tokenID) {
1170 DelayedSingleton<AbilityManagerService>::GetInstance()->GetAbilityRunningInfo(info, abilityRecord);
1171 }
1172 }
1173 };
1174
1175 std::for_each(serviceMap_.begin(), serviceMap_.end(), queryInfo);
1176 }
1177
GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> & abilityRecord,const int32_t userId,std::vector<ExtensionRunningInfo> & info)1178 void AbilityConnectManager::GetExtensionRunningInfo(std::shared_ptr<AbilityRecord> &abilityRecord, const int32_t userId,
1179 std::vector<ExtensionRunningInfo> &info)
1180 {
1181 ExtensionRunningInfo extensionInfo;
1182 AppExecFwk::RunningProcessInfo processInfo;
1183 extensionInfo.extension = abilityRecord->GetWant().GetElement();
1184 auto bms = AbilityUtil::GetBundleManager();
1185 CHECK_POINTER(bms);
1186 std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos;
1187 bool queryResult = IN_PROCESS_CALL(bms->QueryExtensionAbilityInfos(abilityRecord->GetWant(),
1188 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION, userId, extensionInfos));
1189 if (queryResult) {
1190 HILOG_INFO("Query Extension Ability Infos Success.");
1191 auto abilityInfo = abilityRecord->GetAbilityInfo();
1192 auto isExist = [&abilityInfo](const AppExecFwk::ExtensionAbilityInfo &extensionInfo) {
1193 HILOG_INFO("%{public}s, %{public}s", extensionInfo.bundleName.c_str(), extensionInfo.name.c_str());
1194 return extensionInfo.bundleName == abilityInfo.bundleName && extensionInfo.name == abilityInfo.name
1195 && extensionInfo.applicationInfo.uid == abilityInfo.applicationInfo.uid;
1196 };
1197 auto infoIter = std::find_if(extensionInfos.begin(), extensionInfos.end(), isExist);
1198 if (infoIter != extensionInfos.end()) {
1199 HILOG_INFO("Get target success.");
1200 extensionInfo.type = (*infoIter).type;
1201 }
1202 }
1203 DelayedSingleton<AppScheduler>::GetInstance()->
1204 GetRunningProcessInfoByToken(abilityRecord->GetToken(), processInfo);
1205 extensionInfo.pid = processInfo.pid_;
1206 extensionInfo.uid = processInfo.uid_;
1207 extensionInfo.processName = processInfo.processName_;
1208 extensionInfo.startTime = abilityRecord->GetStartTime();
1209 ConnectListType connectRecordList = abilityRecord->GetConnectRecordList();
1210 for (auto &connectRecord : connectRecordList) {
1211 CHECK_POINTER(connectRecord);
1212 auto callerAbilityRecord = Token::GetAbilityRecordByToken(connectRecord->GetToken());
1213 CHECK_POINTER(callerAbilityRecord);
1214 std::string package = callerAbilityRecord->GetAbilityInfo().bundleName;
1215 extensionInfo.clientPackage.emplace_back(package);
1216 }
1217 info.emplace_back(extensionInfo);
1218 }
1219
StopAllExtensions()1220 void AbilityConnectManager::StopAllExtensions()
1221 {
1222 HILOG_INFO("StopAllExtensions begin.");
1223 std::lock_guard<std::recursive_mutex> guard(Lock_);
1224 auto mgr = shared_from_this();
1225 auto task = [mgr](ServiceMapType::reference service) {
1226 auto abilityRecord = service.second;
1227 CHECK_POINTER(abilityRecord);
1228 if (abilityRecord->GetAbilityInfo().type == AbilityType::EXTENSION) {
1229 mgr->TerminateAbilityLocked(abilityRecord->GetToken());
1230 }
1231 };
1232 std::for_each(serviceMap_.begin(), serviceMap_.end(), task);
1233 HILOG_INFO("StopAllExtensions end.");
1234 }
1235 } // namespace AAFwk
1236 } // namespace OHOS