• 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 
22 namespace OHOS {
23 namespace AAFwk {
24 int64_t ConnectionRecord::connectRecordId = 0;
25 #ifdef SUPPORT_ASAN
26 const int DISCONNECT_TIMEOUT_MULTIPLE = 75;
27 #else
28 const int DISCONNECT_TIMEOUT_MULTIPLE = 1;
29 #endif
30 
ConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)31 ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
32     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
33     : state_(ConnectionState::INIT),
34       callerToken_(callerToken),
35       targetService_(targetService),
36       connCallback_(connCallback)
37 {
38     recordId_ = connectRecordId++;
39 }
40 
~ConnectionRecord()41 ConnectionRecord::~ConnectionRecord()
42 {}
43 
CreateConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)44 std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
45     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
46 {
47     auto connRecord = std::make_shared<ConnectionRecord>(callerToken, targetService, connCallback);
48     CHECK_POINTER_AND_RETURN(connRecord, nullptr);
49     connRecord->SetConnectState(ConnectionState::INIT);
50     return connRecord;
51 }
52 
SetConnectState(const ConnectionState & state)53 void ConnectionRecord::SetConnectState(const ConnectionState &state)
54 {
55     state_ = state;
56 }
57 
GetConnectState() const58 ConnectionState ConnectionRecord::GetConnectState() const
59 {
60     return state_;
61 }
62 
GetToken() const63 sptr<IRemoteObject> ConnectionRecord::GetToken() const
64 {
65     return callerToken_;
66 }
67 
GetAbilityRecord() const68 std::shared_ptr<AbilityRecord> ConnectionRecord::GetAbilityRecord() const
69 {
70     return targetService_;
71 }
72 
GetAbilityConnectCallback() const73 sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
74 {
75     std::lock_guard lock(callbackMutex_);
76     return connCallback_;
77 }
78 
ClearConnCallBack()79 void ConnectionRecord::ClearConnCallBack()
80 {
81     std::lock_guard lock(callbackMutex_);
82     if (connCallback_) {
83         connCallback_.clear();
84     }
85 }
86 
DisconnectAbility()87 int ConnectionRecord::DisconnectAbility()
88 {
89     if (state_ != ConnectionState::CONNECTED) {
90         TAG_LOGE(AAFwkTag::CONNECTION, "connection not established, state: %{public}d",
91             static_cast<int32_t>(state_));
92         return INVALID_CONNECTION_STATE;
93     }
94 
95     /* set state to Disconnecting */
96     SetConnectState(ConnectionState::DISCONNECTING);
97     CHECK_POINTER_AND_RETURN(targetService_, ERR_INVALID_VALUE);
98     std::size_t connectNums = targetService_->GetConnectRecordList().size();
99     if (connectNums == 1) {
100         /* post timeout task to taskhandler */
101         auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
102         if (handler == nullptr) {
103             TAG_LOGE(AAFwkTag::CONNECTION, "fail to get TaskHandler");
104         } else {
105             std::string taskName("DisconnectTimeout_");
106             taskName += std::to_string(recordId_);
107             auto disconnectTask = [connectionRecord = shared_from_this()]() {
108                 TAG_LOGE(AAFwkTag::CONNECTION, "Disconnect timeout");
109                 connectionRecord->DisconnectTimeout();
110             };
111             int disconnectTimeout =
112                 AmsConfigurationParameter::GetInstance().GetAppStartTimeoutTime() * DISCONNECT_TIMEOUT_MULTIPLE;
113             handler->SubmitTask(disconnectTask, taskName, disconnectTimeout);
114         }
115         /* schedule disconnect to target ability */
116         TAG_LOGI(AAFwkTag::CONNECTION, "DisconnectAbility called");
117         targetService_->DisconnectAbility();
118     } else {
119         TAG_LOGI(AAFwkTag::CONNECTION,
120             "current connection count: %{public}zu, no need disconnect, just remove", connectNums);
121         targetService_->RemoveConnectRecordFromList(shared_from_this());
122         SetConnectState(ConnectionState::DISCONNECTED);
123     }
124 
125     return ERR_OK;
126 }
127 
CompleteConnect(int resultCode)128 void ConnectionRecord::CompleteConnect(int resultCode)
129 {
130     CHECK_POINTER(targetService_);
131     if (resultCode == ERR_OK) {
132         SetConnectState(ConnectionState::CONNECTED);
133         targetService_->SetAbilityState(AbilityState::ACTIVE);
134     }
135     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
136     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
137         abilityInfo.name, abilityInfo.moduleName);
138     auto remoteObject = targetService_->GetConnRemoteObject();
139     auto callback = GetAbilityConnectCallback();
140     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
141     if (remoteObject == nullptr) {
142         TAG_LOGW(AAFwkTag::CONNECTION, "extension returned null: %{public}s", element.GetURI().c_str());
143         if (handler) {
144             SetConnectState(ConnectionState::DISCONNECTING);
145             handler->SubmitTask([service = targetService_]() {
146                 DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(
147                     service->GetToken());
148                 });
149         }
150         return;
151     }
152 
153     if (callback && handler) {
154         handler->SubmitTask([callback, element, remoteObject, resultCode] {
155             TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityConnectDone");
156             callback->OnAbilityConnectDone(element, remoteObject, resultCode);
157             });
158     }
159     DelayedSingleton<ConnectionStateManager>::GetInstance()->AddConnection(shared_from_this());
160     TAG_LOGI(AAFwkTag::CONNECTION, "result: %{public}d, connectState:%{public}d", resultCode, state_);
161 }
162 
CompleteDisconnect(int resultCode,bool isCallerDied,bool isTargetDied)163 void ConnectionRecord::CompleteDisconnect(int resultCode, bool isCallerDied, bool isTargetDied)
164 {
165     if (resultCode == ERR_OK) {
166         SetConnectState(ConnectionState::DISCONNECTED);
167     }
168     CHECK_POINTER(targetService_);
169     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
170     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
171         abilityInfo.name, abilityInfo.moduleName);
172     auto code = isTargetDied ? (resultCode - 1) : resultCode;
173     auto onDisconnectDoneTask = [connCallback = GetAbilityConnectCallback(), element, code]() {
174         TAG_LOGD(AAFwkTag::CONNECTION, "OnAbilityDisconnectDone");
175         if (!connCallback) {
176             TAG_LOGD(AAFwkTag::CONNECTION, "null connCallback");
177             return;
178         }
179         connCallback->OnAbilityDisconnectDone(element, code);
180     };
181     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
182     if (handler == nullptr) {
183         TAG_LOGE(AAFwkTag::CONNECTION, "null handler");
184         return;
185     }
186     handler->SubmitTask(onDisconnectDoneTask);
187     DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveConnection(shared_from_this(), isCallerDied);
188     TAG_LOGD(AAFwkTag::CONNECTION, "result: %{public}d, connectState:%{public}d", resultCode, state_);
189 }
190 
ScheduleDisconnectAbilityDone()191 void ConnectionRecord::ScheduleDisconnectAbilityDone()
192 {
193     if (state_ != ConnectionState::DISCONNECTING) {
194         TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not disconnecting");
195         return;
196     }
197 
198     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
199     if (handler == nullptr) {
200         TAG_LOGE(AAFwkTag::CONNECTION, "fail to get AbilityTaskHandler");
201     } else {
202         std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
203         handler->CancelTask(taskName);
204     }
205 
206     CompleteDisconnect(ERR_OK, GetAbilityConnectCallback() == nullptr);
207 }
208 
ScheduleConnectAbilityDone()209 void ConnectionRecord::ScheduleConnectAbilityDone()
210 {
211     if (state_ != ConnectionState::CONNECTING) {
212         TAG_LOGE(AAFwkTag::CONNECTION, "failed, current state not connecting");
213         return;
214     }
215     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
216     if (handler == nullptr) {
217         TAG_LOGE(AAFwkTag::CONNECTION, "fail to get AbilityTaskHandler");
218     } else {
219         std::string taskName = std::string("ConnectTimeout_") + std::to_string(recordId_);
220         handler->CancelTask(taskName);
221     }
222 
223     CompleteConnect(ERR_OK);
224 }
225 
DisconnectTimeout()226 void ConnectionRecord::DisconnectTimeout()
227 {
228     CHECK_POINTER(targetService_);
229     /* force to disconnect */
230     /* so scheduler target service disconnect done */
231     DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
232 }
233 
ConvertConnectionState(const ConnectionState & state) const234 std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
235 {
236     switch (state) {
237         case ConnectionState::INIT:
238             return "INIT";
239         case ConnectionState::CONNECTING:
240             return "CONNECTING";
241         case ConnectionState::CONNECTED:
242             return "CONNECTED";
243         case ConnectionState::DISCONNECTING:
244             return "DISCONNECTING";
245         case ConnectionState::DISCONNECTED:
246             return "DISCONNECTED";
247         default:
248             return "INVALIDSTATE";
249     }
250 }
251 
Dump(std::vector<std::string> & info) const252 void ConnectionRecord::Dump(std::vector<std::string> &info) const
253 {
254     info.emplace_back("       > " + GetAbilityRecord()->GetAbilityInfo().bundleName + "/" +
255                       GetAbilityRecord()->GetAbilityInfo().name + "   connectionState #" +
256                       ConvertConnectionState(GetConnectState()));
257 }
258 
AttachCallerInfo()259 void ConnectionRecord::AttachCallerInfo()
260 {
261     callerTokenId_ = IPCSkeleton::GetCallingTokenID(); // tokenId identifies the real caller
262     auto targetRecord = Token::GetAbilityRecordByToken(callerToken_);
263     if (targetRecord) {
264         callerUid_ = targetRecord->GetUid();
265         callerPid_ = targetRecord->GetPid();
266         callerName_ = targetRecord->GetAbilityInfo().bundleName;
267         return;
268     }
269 
270     callerUid_ = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
271     callerPid_ = static_cast<int32_t>(IPCSkeleton::GetCallingPid());
272     callerName_ = ConnectionStateManager::GetProcessNameByPid(callerPid_);
273 }
274 
GetCallerUid() const275 int32_t ConnectionRecord::GetCallerUid() const
276 {
277     return callerUid_;
278 }
279 
GetCallerPid() const280 int32_t ConnectionRecord::GetCallerPid() const
281 {
282     return callerPid_;
283 }
284 
GetCallerTokenId() const285 uint32_t ConnectionRecord::GetCallerTokenId() const
286 {
287     return callerTokenId_;
288 }
289 
GetCallerName() const290 std::string ConnectionRecord::GetCallerName() const
291 {
292     return callerName_;
293 }
294 
GetTargetToken() const295 sptr<IRemoteObject> ConnectionRecord::GetTargetToken() const
296 {
297     auto targetService = targetService_;
298     if (!targetService) {
299         return nullptr;
300     }
301 
302     auto token = targetService->GetToken();
303     if (!token) {
304         return nullptr;
305     }
306 
307     return token->AsObject();
308 }
309 
GetConnection() const310 sptr<IRemoteObject> ConnectionRecord::GetConnection() const
311 {
312     auto callback = GetAbilityConnectCallback();
313     if (!callback) {
314         return nullptr;
315     }
316 
317     return callback->AsObject();
318 }
319 }  // namespace AAFwk
320 }  // namespace OHOS
321