• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_errors.h"
19 #include "ability_manager_service.h"
20 #include "ability_util.h"
21 #include "connection_state_manager.h"
22 #include "hilog_wrapper.h"
23 
24 namespace OHOS {
25 namespace AAFwk {
26 int64_t ConnectionRecord::connectRecordId = 0;
27 #ifdef SUPPORT_ASAN
28 const int DISCONNECT_TIMEOUT_MULTIPLE = 75;
29 #else
30 const int DISCONNECT_TIMEOUT_MULTIPLE = 1;
31 #endif
32 
ConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)33 ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
34     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
35     : state_(ConnectionState::INIT),
36       callerToken_(callerToken),
37       targetService_(targetService),
38       connCallback_(connCallback)
39 {
40     recordId_ = connectRecordId++;
41 }
42 
~ConnectionRecord()43 ConnectionRecord::~ConnectionRecord()
44 {}
45 
CreateConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)46 std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
47     const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
48 {
49     auto connRecord = std::make_shared<ConnectionRecord>(callerToken, targetService, connCallback);
50     CHECK_POINTER_AND_RETURN(connRecord, nullptr);
51     connRecord->SetConnectState(ConnectionState::INIT);
52     return connRecord;
53 }
54 
SetConnectState(const ConnectionState & state)55 void ConnectionRecord::SetConnectState(const ConnectionState &state)
56 {
57     state_ = state;
58 }
59 
GetConnectState() const60 ConnectionState ConnectionRecord::GetConnectState() const
61 {
62     return state_;
63 }
64 
GetToken() const65 sptr<IRemoteObject> ConnectionRecord::GetToken() const
66 {
67     return callerToken_;
68 }
69 
GetAbilityRecord() const70 std::shared_ptr<AbilityRecord> ConnectionRecord::GetAbilityRecord() const
71 {
72     return targetService_;
73 }
74 
GetAbilityConnectCallback() const75 sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
76 {
77     return connCallback_;
78 }
79 
ClearConnCallBack()80 void ConnectionRecord::ClearConnCallBack()
81 {
82     if (connCallback_) {
83         connCallback_.clear();
84     }
85 }
86 
DisconnectAbility()87 int ConnectionRecord::DisconnectAbility()
88 {
89     if (state_ != ConnectionState::CONNECTED) {
90         HILOG_ERROR("The connection has not established, connectionState: %{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             HILOG_ERROR("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                 HILOG_ERROR("Disconnect ability 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         targetService_->DisconnectAbility();
117     } else {
118         HILOG_DEBUG("The current connection count is %{public}zu, no need to disconnect, just remove connection.",
119             connectNums);
120         targetService_->RemoveConnectRecordFromList(shared_from_this());
121         SetConnectState(ConnectionState::DISCONNECTED);
122     }
123 
124     return ERR_OK;
125 }
126 
CompleteConnect(int resultCode)127 void ConnectionRecord::CompleteConnect(int resultCode)
128 {
129     CHECK_POINTER(targetService_);
130     if (resultCode == ERR_OK) {
131         SetConnectState(ConnectionState::CONNECTED);
132         targetService_->SetAbilityState(AbilityState::ACTIVE);
133     }
134     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
135     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
136         abilityInfo.name, abilityInfo.moduleName);
137     auto remoteObject = targetService_->GetConnRemoteObject();
138     auto callback = connCallback_;
139     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
140     if (callback && handler) {
141         handler->SubmitTask([callback, element, remoteObject, resultCode] {
142             HILOG_DEBUG("OnAbilityConnectDone");
143             callback->OnAbilityConnectDone(element, remoteObject, resultCode);
144             });
145     }
146     DelayedSingleton<ConnectionStateManager>::GetInstance()->AddConnection(shared_from_this());
147     HILOG_INFO("result: %{public}d. connectState:%{public}d.", resultCode, state_);
148 }
149 
CompleteDisconnect(int resultCode,bool isDied)150 void ConnectionRecord::CompleteDisconnect(int resultCode, bool isDied)
151 {
152     if (resultCode == ERR_OK) {
153         SetConnectState(ConnectionState::DISCONNECTED);
154     }
155     CHECK_POINTER(targetService_);
156     const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
157     AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
158         abilityInfo.name, abilityInfo.moduleName);
159     auto code = isDied ? (resultCode - 1) : resultCode;
160     auto onDisconnectDoneTask = [connCallback = connCallback_, element, code]() {
161         HILOG_DEBUG("OnAbilityDisconnectDone.");
162         if (!connCallback) {
163             HILOG_DEBUG("connCallback_ is nullptr.");
164             return;
165         }
166         connCallback->OnAbilityDisconnectDone(element, code);
167     };
168     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
169     if (handler == nullptr) {
170         HILOG_ERROR("handler is nullptr.");
171         return;
172     }
173     handler->SubmitTask(onDisconnectDoneTask);
174     DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveConnection(shared_from_this(), isDied);
175     HILOG_DEBUG("result: %{public}d. connectState:%{public}d.", resultCode, state_);
176 }
177 
ScheduleDisconnectAbilityDone()178 void ConnectionRecord::ScheduleDisconnectAbilityDone()
179 {
180     if (state_ != ConnectionState::DISCONNECTING) {
181         HILOG_ERROR("fail to schedule disconnect ability done, current state is not disconnecting.");
182         return;
183     }
184 
185     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
186     if (handler == nullptr) {
187         HILOG_ERROR("fail to get AbilityTaskHandler");
188     } else {
189         std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
190         handler->CancelTask(taskName);
191     }
192 
193     CompleteDisconnect(ERR_OK, false);
194 }
195 
ScheduleConnectAbilityDone()196 void ConnectionRecord::ScheduleConnectAbilityDone()
197 {
198     if (state_ != ConnectionState::CONNECTING) {
199         HILOG_ERROR("fail to schedule connect ability done, current state is not connecting.");
200         return;
201     }
202     auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
203     if (handler == nullptr) {
204         HILOG_ERROR("fail to get AbilityTaskHandler");
205     } else {
206         std::string taskName = std::string("ConnectTimeout_") + std::to_string(recordId_);
207         handler->CancelTask(taskName);
208     }
209 
210     CompleteConnect(ERR_OK);
211 }
212 
DisconnectTimeout()213 void ConnectionRecord::DisconnectTimeout()
214 {
215     CHECK_POINTER(targetService_);
216     /* force to disconnect */
217     /* so scheduler target service disconnect done */
218     DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
219 }
220 
ConvertConnectionState(const ConnectionState & state) const221 std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
222 {
223     switch (state) {
224         case ConnectionState::INIT:
225             return "INIT";
226         case ConnectionState::CONNECTING:
227             return "CONNECTING";
228         case ConnectionState::CONNECTED:
229             return "CONNECTED";
230         case ConnectionState::DISCONNECTING:
231             return "DISCONNECTING";
232         case ConnectionState::DISCONNECTED:
233             return "DISCONNECTED";
234         default:
235             return "INVALIDSTATE";
236     }
237 }
238 
Dump(std::vector<std::string> & info) const239 void ConnectionRecord::Dump(std::vector<std::string> &info) const
240 {
241     info.emplace_back("       > " + GetAbilityRecord()->GetAbilityInfo().bundleName + "/" +
242                       GetAbilityRecord()->GetAbilityInfo().name + "   connectionState #" +
243                       ConvertConnectionState(GetConnectState()));
244 }
245 
AttachCallerInfo()246 void ConnectionRecord::AttachCallerInfo()
247 {
248     callerTokenId_ = IPCSkeleton::GetCallingTokenID(); // tokenId identifies the real caller
249     auto targetRecord = Token::GetAbilityRecordByToken(callerToken_);
250     if (targetRecord) {
251         callerUid_ = targetRecord->GetUid();
252         callerPid_ = targetRecord->GetPid();
253         callerName_ = targetRecord->GetAbilityInfo().bundleName;
254         return;
255     }
256 
257     callerUid_ = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
258     callerPid_ = static_cast<int32_t>(IPCSkeleton::GetCallingPid());
259     callerName_ = ConnectionStateManager::GetProcessNameByPid(callerPid_);
260 }
261 
GetCallerUid() const262 int32_t ConnectionRecord::GetCallerUid() const
263 {
264     return callerUid_;
265 }
266 
GetCallerPid() const267 int32_t ConnectionRecord::GetCallerPid() const
268 {
269     return callerPid_;
270 }
271 
GetCallerTokenId() const272 uint32_t ConnectionRecord::GetCallerTokenId() const
273 {
274     return callerTokenId_;
275 }
276 
GetCallerName() const277 std::string ConnectionRecord::GetCallerName() const
278 {
279     return callerName_;
280 }
281 
GetTargetToken() const282 sptr<IRemoteObject> ConnectionRecord::GetTargetToken() const
283 {
284     auto targetService = targetService_;
285     if (!targetService) {
286         return nullptr;
287     }
288 
289     auto token = targetService->GetToken();
290     if (!token) {
291         return nullptr;
292     }
293 
294     return token->AsObject();
295 }
296 
GetConnection() const297 sptr<IRemoteObject> ConnectionRecord::GetConnection() const
298 {
299     auto callback = connCallback_;
300     if (!callback) {
301         return nullptr;
302     }
303 
304     return callback->AsObject();
305 }
306 }  // namespace AAFwk
307 }  // namespace OHOS
308