• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "connection_record.h"
17 
18 #include "ability_manager_service.h"
19 #include "ability_util.h"
20 #include "connection_state_manager.h"
21 #include "ui_service_extension_connection_constants.h"
22 
23 namespace OHOS {
24 namespace AAFwk {
25 int64_t ConnectionRecord::connectRecordId = 0;
26 #ifdef SUPPORT_ASAN
27 const int DISCONNECT_TIMEOUT_MULTIPLE = 75;
28 #else
29 const int DISCONNECT_TIMEOUT_MULTIPLE = 1;
30 #endif
31 
ConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback,std::shared_ptr<AbilityConnectManager> abilityConnectManager)32 ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
33     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback,
34     std::shared_ptr<AbilityConnectManager> abilityConnectManager)
35     : state_(ConnectionState::INIT),
36       callerToken_(callerToken),
37       targetService_(targetService),
38       connCallback_(connCallback),
39       abilityConnectManager_(abilityConnectManager)
40 {
41     recordId_ = connectRecordId++;
42 }
43 
~ConnectionRecord()44 ConnectionRecord::~ConnectionRecord()
45 {}
46 
CreateConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback,std::shared_ptr<AbilityConnectManager> abilityConnectManager)47 std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
48     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback,
49     std::shared_ptr<AbilityConnectManager> abilityConnectManager)
50 {
51     auto connRecord = std::make_shared<ConnectionRecord>(
52         callerToken, targetService, connCallback, abilityConnectManager);
53     CHECK_POINTER_AND_RETURN(connRecord, nullptr);
54     connRecord->SetConnectState(ConnectionState::INIT);
55     return connRecord;
56 }
57 
SetConnectState(const ConnectionState & state)58 void ConnectionRecord::SetConnectState(const ConnectionState &state)
59 {
60     state_ = state;
61 }
62 
GetConnectState() const63 ConnectionState ConnectionRecord::GetConnectState() const
64 {
65     return state_;
66 }
67 
GetToken() const68 sptr<IRemoteObject> ConnectionRecord::GetToken() const
69 {
70     return callerToken_;
71 }
72 
GetAbilityRecord() const73 std::shared_ptr<AbilityRecord> ConnectionRecord::GetAbilityRecord() const
74 {
75     return targetService_;
76 }
77 
GetAbilityConnectCallback() const78 sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
79 {
80     std::lock_guard lock(callbackMutex_);
81     return connCallback_;
82 }
83 
ClearConnCallBack()84 void ConnectionRecord::ClearConnCallBack()
85 {
86     std::lock_guard lock(callbackMutex_);
87     if (connCallback_) {
88         connCallback_.clear();
89     }
90 }
91 
DisconnectAbility()92 int ConnectionRecord::DisconnectAbility()
93 {
94     if (state_ != ConnectionState::CONNECTED) {
95         TAG_LOGE(AAFwkTag::CONNECTION, "connection not established, state: %{public}d",
96             static_cast<int32_t>(state_));
97         return INVALID_CONNECTION_STATE;
98     }
99 
100     /* set state to Disconnecting */
101     SetConnectState(ConnectionState::DISCONNECTING);
102     CHECK_POINTER_AND_RETURN(targetService_, ERR_INVALID_VALUE);
103     std::size_t connectNums = targetService_->GetConnectRecordList().size();
104     AppExecFwk::ExtensionAbilityType extAbilityType = targetService_->GetAbilityInfo().extensionAbilityType;
105     bool isAbilityUIServiceExt = (extAbilityType == AppExecFwk::ExtensionAbilityType::UI_SERVICE);
106     if (connectNums == 1 || isAbilityUIServiceExt) {
107         /* post timeout task to taskhandler */
108         auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
109         if (handler == nullptr) {
110             TAG_LOGE(AAFwkTag::CONNECTION, "null handler");
111         } else {
112             std::string taskName("DisconnectTimeout_");
113             taskName += std::to_string(recordId_);
114             auto disconnectTask = [connectionRecord = shared_from_this()]() {
115                 TAG_LOGE(AAFwkTag::CONNECTION, "Disconnect timeout");
116                 connectionRecord->DisconnectTimeout();
117             };
118             int disconnectTimeout =
119                 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * DISCONNECT_TIMEOUT_MULTIPLE;
120             handler->SubmitTask(disconnectTask, taskName, disconnectTimeout);
121         }
122         /* schedule disconnect to target ability */
123         if (isAbilityUIServiceExt) {
124             TAG_LOGI(AAFwkTag::CONNECTION, "Disconnect UIServiceExtension ability, set correct want");
125             targetService_->DisconnectAbilityWithWant(GetConnectWant());
126         } else {
127             TAG_LOGI(AAFwkTag::CONNECTION, "DisconnectAbility called");
128             targetService_->DisconnectAbility();
129         }
130     } else {
131         TAG_LOGI(AAFwkTag::CONNECTION,
132             "current connection count: %{public}zu, %{public}s:%{public}s no need disconnect, just remove",
133             connectNums, targetService_->GetAbilityInfo().bundleName.c_str(),
134             targetService_->GetAbilityInfo().name.c_str());
135         targetService_->RemoveConnectRecordFromList(shared_from_this());
136         SetConnectState(ConnectionState::DISCONNECTED);
137     }
138 
139     return ERR_OK;
140 }
141 
CompleteConnect()142 void ConnectionRecord::CompleteConnect()
143 {
144     SetConnectState(ConnectionState::CONNECTED);
145     CHECK_POINTER(targetService_);
146     targetService_->SetAbilityState(AbilityState::ACTIVE);
147     TAG_LOGI(AAFwkTag::ABILITYMGR, "Connect,%{public}s", targetService_->GetAbilityInfo().name.c_str());
148     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
149     AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceId(), abilityInfo.bundleName,
150         abilityInfo.name, abilityInfo.moduleName);
151     auto remoteObject = targetService_->GetConnRemoteObject();
152     auto callback = GetAbilityConnectCallback();
153     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
154     if (remoteObject == nullptr) {
155         TAG_LOGW(AAFwkTag::CONNECTION, "null remoteObject: %{public}s", element.GetURI().c_str());
156         if (handler) {
157             SetConnectState(ConnectionState::DISCONNECTING);
158             handler->SubmitTask([service = targetService_]() {
159                 DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(
160                     service->GetToken());
161                 });
162         }
163         return;
164     }
165 
166     if (callback && handler) {
167         handler->SubmitTask([callback, element, remoteObject, weakConnectionRecord = weak_from_this(),
168             weakConnectManager = abilityConnectManager_] {
169             TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityConnectDone");
170             auto ret = ConnectionRecord::CallOnAbilityConnectDone(callback, element, remoteObject, ERR_OK);
171             if (ret != ERR_OK) {
172                 TAG_LOGE(AAFwkTag::CONNECTION, "OnAbilityConnectDone failed");
173                 auto connectionRecord = weakConnectionRecord.lock();
174                 CHECK_POINTER(connectionRecord);
175                 auto abilityConnectManager = weakConnectManager.lock();
176                 CHECK_POINTER(abilityConnectManager);
177                 abilityConnectManager->HandleExtensionDisconnectTask(connectionRecord);
178             }
179         });
180     }
181     DelayedSingleton<ConnectionStateManager>::GetInstance()->AddConnection(shared_from_this());
182     TAG_LOGI(AAFwkTag::CONNECTION, "connectState:%{public}d", state_);
183 }
184 
CallOnAbilityConnectDone(sptr<IAbilityConnection> callback,const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)185 int32_t ConnectionRecord::CallOnAbilityConnectDone(sptr<IAbilityConnection> callback,
186     const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
187 {
188     CHECK_POINTER_AND_RETURN(callback, ERR_INVALID_VALUE);
189     sptr<IRemoteObject> obj = callback->AsObject();
190     CHECK_POINTER_AND_RETURN(obj, ERR_INVALID_VALUE);
191     if (!obj->IsProxyObject()) {
192         callback->OnAbilityConnectDone(element, remoteObject, ERR_OK);
193         return ERR_OK;
194     }
195     MessageParcel data;
196     MessageParcel reply;
197     MessageOption option(MessageOption::TF_ASYNC);
198 
199     if (!data.WriteInterfaceToken(IAbilityConnection::GetDescriptor())) {
200         TAG_LOGE(AAFwkTag::ABILITYMGR, "WriteInterfaceToken fail");
201         return ERR_FLATTEN_OBJECT;
202     }
203 
204     if (!data.WriteParcelable(&element)) {
205         TAG_LOGE(AAFwkTag::ABILITYMGR, "element error");
206         return ERR_FLATTEN_OBJECT;
207     }
208 
209     if (!data.WriteRemoteObject(remoteObject)) {
210         TAG_LOGE(AAFwkTag::ABILITYMGR, "remoteObject error");
211         return ERR_FLATTEN_OBJECT;
212     }
213 
214     if (!data.WriteInt32(resultCode)) {
215         TAG_LOGE(AAFwkTag::ABILITYMGR, "resultCode error");
216         return ERR_FLATTEN_OBJECT;
217     }
218 
219     int32_t ret = obj->SendRequest(IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
220     if (ret != ERR_OK) {
221         TAG_LOGE(AAFwkTag::ABILITYMGR, "fail. ret: %{public}d", ret);
222     }
223     return ret;
224 }
225 
CompleteDisconnect(int resultCode,bool isCallerDied,bool isTargetDied)226 void ConnectionRecord::CompleteDisconnect(int resultCode, bool isCallerDied, bool isTargetDied)
227 {
228     if (resultCode == ERR_OK) {
229         SetConnectState(ConnectionState::DISCONNECTED);
230     }
231     CHECK_POINTER(targetService_);
232     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
233     AppExecFwk::ElementName element(targetService_->GetWant().GetDeviceId(), abilityInfo.bundleName,
234         abilityInfo.name, abilityInfo.moduleName);
235     auto code = isTargetDied ? (resultCode - 1) : resultCode;
236     auto onDisconnectDoneTask = [connCallback = GetAbilityConnectCallback(), element, code]() {
237         TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityDisconnectDone");
238         if (!connCallback) {
239             TAG_LOGD(AAFwkTag::CONNECTION, "null connCallback");
240             return;
241         }
242         connCallback->OnAbilityDisconnectDone(element, code);
243     };
244     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
245     if (handler == nullptr) {
246         TAG_LOGE(AAFwkTag::CONNECTION, "null handler");
247         return;
248     }
249     handler->SubmitTask(onDisconnectDoneTask);
250     DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveConnection(shared_from_this(), isCallerDied);
251     TAG_LOGD(AAFwkTag::CONNECTION, "result: %{public}d, connectState:%{public}d", resultCode, state_);
252 }
253 
ScheduleDisconnectAbilityDone()254 void ConnectionRecord::ScheduleDisconnectAbilityDone()
255 {
256     if (state_ != ConnectionState::DISCONNECTING) {
257         TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not disconnecting");
258         return;
259     }
260 
261     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
262     if (handler == nullptr) {
263         TAG_LOGE(AAFwkTag::CONNECTION, "fail to get AbilityTaskHandler");
264     } else {
265         std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
266         handler->CancelTask(taskName);
267     }
268 
269     CompleteDisconnect(ERR_OK, GetAbilityConnectCallback() == nullptr);
270 }
271 
ScheduleConnectAbilityDone()272 void ConnectionRecord::ScheduleConnectAbilityDone()
273 {
274     if (state_ != ConnectionState::CONNECTING) {
275         TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not connecting");
276         return;
277     }
278 
279     sptr<IRemoteObject> hostproxy = nullptr;
280     if (connectWant_.HasParameter(UISERVICEHOSTPROXY_KEY)) {
281         hostproxy = connectWant_.GetRemoteObject(UISERVICEHOSTPROXY_KEY);
282     }
283     auto element = connectWant_.GetElement();
284     Want::ClearWant(&connectWant_);
285     connectWant_.SetElement(element);
286     if (hostproxy != nullptr) {
287         connectWant_.SetParam(UISERVICEHOSTPROXY_KEY, hostproxy);
288     }
289 
290     CancelConnectTimeoutTask();
291 
292     CompleteConnect();
293 }
294 
CancelConnectTimeoutTask()295 void ConnectionRecord::CancelConnectTimeoutTask()
296 {
297     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
298     if (handler == nullptr) {
299         TAG_LOGE(AAFwkTag::CONNECTION, "fail to get AbilityTaskHandler");
300     } else {
301         std::string taskName = std::string("ConnectTimeout_") + std::to_string(recordId_);
302         TAG_LOGI(AAFwkTag::ABILITYMGR, "CancelConnectTimeoutTask taskName:%{public}s", taskName.c_str());
303         handler->CancelTask(taskName);
304     }
305 }
306 
DisconnectTimeout()307 void ConnectionRecord::DisconnectTimeout()
308 {
309     CHECK_POINTER(targetService_);
310     /* force to disconnect */
311     /* so scheduler target service disconnect done */
312     DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
313 }
314 
ConvertConnectionState(const ConnectionState & state) const315 std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
316 {
317     switch (state) {
318         case ConnectionState::INIT:
319             return "INIT";
320         case ConnectionState::CONNECTING:
321             return "CONNECTING";
322         case ConnectionState::CONNECTED:
323             return "CONNECTED";
324         case ConnectionState::DISCONNECTING:
325             return "DISCONNECTING";
326         case ConnectionState::DISCONNECTED:
327             return "DISCONNECTED";
328         default:
329             return "INVALIDSTATE";
330     }
331 }
332 
Dump(std::vector<std::string> & info) const333 void ConnectionRecord::Dump(std::vector<std::string> &info) const
334 {
335     info.emplace_back("       > " + GetAbilityRecord()->GetAbilityInfo().bundleName + "/" +
336                       GetAbilityRecord()->GetAbilityInfo().name + "   connectionState #" +
337                       ConvertConnectionState(GetConnectState()));
338 }
339 
AttachCallerInfo()340 void ConnectionRecord::AttachCallerInfo()
341 {
342     callerTokenId_ = IPCSkeleton::GetCallingTokenID(); // tokenId identifies the real caller
343     auto targetRecord = Token::GetAbilityRecordByToken(callerToken_);
344     if (targetRecord) {
345         callerUid_ = targetRecord->GetUid();
346         callerPid_ = targetRecord->GetPid();
347         callerName_ = targetRecord->GetAbilityInfo().bundleName;
348         return;
349     }
350 
351     callerUid_ = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
352     callerPid_ = static_cast<int32_t>(IPCSkeleton::GetCallingPid());
353     callerName_ = ConnectionStateManager::GetProcessNameByPid(callerPid_);
354 }
355 
GetCallerUid() const356 int32_t ConnectionRecord::GetCallerUid() const
357 {
358     return callerUid_;
359 }
360 
GetCallerPid() const361 int32_t ConnectionRecord::GetCallerPid() const
362 {
363     return callerPid_;
364 }
365 
GetCallerTokenId() const366 uint32_t ConnectionRecord::GetCallerTokenId() const
367 {
368     return callerTokenId_;
369 }
370 
GetCallerName() const371 std::string ConnectionRecord::GetCallerName() const
372 {
373     return callerName_;
374 }
375 
GetTargetToken() const376 sptr<IRemoteObject> ConnectionRecord::GetTargetToken() const
377 {
378     auto targetService = targetService_;
379     if (!targetService) {
380         return nullptr;
381     }
382 
383     auto token = targetService->GetToken();
384     if (!token) {
385         return nullptr;
386     }
387 
388     return token->AsObject();
389 }
390 
GetConnection() const391 sptr<IRemoteObject> ConnectionRecord::GetConnection() const
392 {
393     auto callback = GetAbilityConnectCallback();
394     if (!callback) {
395         return nullptr;
396     }
397 
398     return callback->AsObject();
399 }
400 
SetConnectWant(const Want & want)401 void ConnectionRecord::SetConnectWant(const Want &want)
402 {
403     connectWant_ = want;
404 }
405 
GetConnectWant() const406 Want ConnectionRecord::GetConnectWant() const
407 {
408     return connectWant_;
409 }
410 }  // namespace AAFwk
411 }  // namespace OHOS
412