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
ConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)28 ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
29 const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
30 : state_(ConnectionState::INIT),
31 callerToken_(callerToken),
32 targetService_(targetService),
33 connCallback_(connCallback)
34 {
35 recordId_ = connectRecordId++;
36 }
37
~ConnectionRecord()38 ConnectionRecord::~ConnectionRecord()
39 {}
40
CreateConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)41 std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
42 const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
43 {
44 auto connRecord = std::make_shared<ConnectionRecord>(callerToken, targetService, connCallback);
45 CHECK_POINTER_AND_RETURN(connRecord, nullptr);
46 connRecord->SetConnectState(ConnectionState::INIT);
47 return connRecord;
48 }
49
SetConnectState(const ConnectionState & state)50 void ConnectionRecord::SetConnectState(const ConnectionState &state)
51 {
52 state_ = state;
53 }
54
GetConnectState() const55 ConnectionState ConnectionRecord::GetConnectState() const
56 {
57 return state_;
58 }
59
GetToken() const60 sptr<IRemoteObject> ConnectionRecord::GetToken() const
61 {
62 return callerToken_;
63 }
64
GetAbilityRecord() const65 std::shared_ptr<AbilityRecord> ConnectionRecord::GetAbilityRecord() const
66 {
67 return targetService_;
68 }
69
GetAbilityConnectCallback() const70 sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
71 {
72 return connCallback_;
73 }
74
ClearConnCallBack()75 void ConnectionRecord::ClearConnCallBack()
76 {
77 if (connCallback_) {
78 connCallback_.clear();
79 }
80 }
81
DisconnectAbility()82 int ConnectionRecord::DisconnectAbility()
83 {
84 if (state_ != ConnectionState::CONNECTED) {
85 HILOG_INFO("The connection has not established.");
86 return INVALID_CONNECTION_STATE;
87 }
88
89 /* set state to Disconnecting */
90 SetConnectState(ConnectionState::DISCONNECTING);
91 CHECK_POINTER_AND_RETURN(targetService_, ERR_INVALID_VALUE);
92 std::size_t connectNums = targetService_->GetConnectRecordList().size();
93 if (connectNums == 1) {
94 /* post timeout task to eventhandler */
95 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
96 if (handler == nullptr) {
97 HILOG_ERROR("fail to get AbilityEventHandler");
98 } else {
99 std::string taskName("DisconnectTimeout_");
100 taskName += std::to_string(recordId_);
101 auto disconnectTask = [connectionRecord = shared_from_this()]() {
102 HILOG_ERROR("Disconnect ability timeout");
103 connectionRecord->DisconnectTimeout();
104 };
105 handler->PostTask(disconnectTask, taskName, AbilityManagerService::DISCONNECT_TIMEOUT);
106 }
107 /* schedule disconnect to target ability */
108 targetService_->DisconnectAbility();
109 } else {
110 targetService_->RemoveConnectRecordFromList(shared_from_this());
111 SetConnectState(ConnectionState::DISCONNECTED);
112 }
113
114 return ERR_OK;
115 }
116
CompleteConnect(int resultCode)117 void ConnectionRecord::CompleteConnect(int resultCode)
118 {
119 CHECK_POINTER(targetService_);
120 if (resultCode == ERR_OK) {
121 SetConnectState(ConnectionState::CONNECTED);
122 targetService_->SetAbilityState(AbilityState::ACTIVE);
123 }
124 const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
125 AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
126 abilityInfo.name, abilityInfo.moduleName);
127 auto remoteObject = targetService_->GetConnRemoteObject();
128 if (connCallback_) {
129 HILOG_DEBUG("OnAbilityConnectDone");
130 connCallback_->OnAbilityConnectDone(element, remoteObject, resultCode);
131 }
132 DelayedSingleton<ConnectionStateManager>::GetInstance()->AddConnection(shared_from_this());
133 HILOG_INFO("result: %{public}d. connectState:%{public}d.", resultCode, state_);
134 }
135
CompleteDisconnect(int resultCode,bool isDied)136 void ConnectionRecord::CompleteDisconnect(int resultCode, bool isDied)
137 {
138 if (resultCode == ERR_OK) {
139 SetConnectState(ConnectionState::DISCONNECTED);
140 }
141 CHECK_POINTER(targetService_);
142 const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
143 AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName,
144 abilityInfo.name, abilityInfo.moduleName);
145 if (connCallback_) {
146 HILOG_DEBUG("OnAbilityDisconnectDone");
147 connCallback_->OnAbilityDisconnectDone(element, isDied ? (resultCode - 1) : resultCode);
148 }
149 DelayedSingleton<ConnectionStateManager>::GetInstance()->RemoveConnection(shared_from_this(), isDied);
150 HILOG_INFO("result: %{public}d. connectState:%{public}d.", resultCode, state_);
151 }
152
ScheduleDisconnectAbilityDone()153 void ConnectionRecord::ScheduleDisconnectAbilityDone()
154 {
155 if (state_ != ConnectionState::DISCONNECTING) {
156 HILOG_ERROR("fail to schedule disconnect ability done, current state is not disconnecting.");
157 return;
158 }
159
160 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
161 if (handler == nullptr) {
162 HILOG_ERROR("fail to get AbilityEventHandler");
163 } else {
164 std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
165 handler->RemoveTask(taskName);
166 }
167
168 CompleteDisconnect(ERR_OK, false);
169 }
170
ScheduleConnectAbilityDone()171 void ConnectionRecord::ScheduleConnectAbilityDone()
172 {
173 if (state_ != ConnectionState::CONNECTING) {
174 HILOG_ERROR("fail to schedule connect ability done, current state is not connecting.");
175 return;
176 }
177 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
178 if (handler == nullptr) {
179 HILOG_ERROR("fail to get AbilityEventHandler");
180 } else {
181 std::string taskName = std::string("ConnectTimeout_") + std::to_string(recordId_);
182 handler->RemoveTask(taskName);
183 }
184
185 CompleteConnect(ERR_OK);
186 }
187
DisconnectTimeout()188 void ConnectionRecord::DisconnectTimeout()
189 {
190 CHECK_POINTER(targetService_);
191 /* force to disconnect */
192 /* so scheduler target service disconnect done */
193 DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
194 }
195
ConvertConnectionState(const ConnectionState & state) const196 std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
197 {
198 switch (state) {
199 case ConnectionState::INIT:
200 return "INIT";
201 case ConnectionState::CONNECTING:
202 return "CONNECTING";
203 case ConnectionState::CONNECTED:
204 return "CONNECTED";
205 case ConnectionState::DISCONNECTING:
206 return "DISCONNECTING";
207 case ConnectionState::DISCONNECTED:
208 return "DISCONNECTED";
209 default:
210 return "INVALIDSTATE";
211 }
212 }
213
Dump(std::vector<std::string> & info) const214 void ConnectionRecord::Dump(std::vector<std::string> &info) const
215 {
216 info.emplace_back(" > " + GetAbilityRecord()->GetAbilityInfo().bundleName + "/" +
217 GetAbilityRecord()->GetAbilityInfo().name + " connectionState #" +
218 ConvertConnectionState(GetConnectState()));
219 }
220
AttachCallerInfo()221 void ConnectionRecord::AttachCallerInfo()
222 {
223 auto targetRecord = Token::GetAbilityRecordByToken(callerToken_);
224 if (targetRecord) {
225 callerUid_ = targetRecord->GetUid();
226 callerPid_ = targetRecord->GetPid();
227 callerName_ = targetRecord->GetAbilityInfo().bundleName;
228 return;
229 }
230
231 callerUid_ = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
232 callerPid_ = static_cast<int32_t>(IPCSkeleton::GetCallingPid());
233 callerName_ = ConnectionStateManager::GetProcessNameByPid(callerPid_);
234 }
235
GetCallerUid() const236 int32_t ConnectionRecord::GetCallerUid() const
237 {
238 return callerUid_;
239 }
240
GetCallerPid() const241 int32_t ConnectionRecord::GetCallerPid() const
242 {
243 return callerPid_;
244 }
245
GetCallerName() const246 std::string ConnectionRecord::GetCallerName() const
247 {
248 return callerName_;
249 }
250
GetTargetToken() const251 sptr<IRemoteObject> ConnectionRecord::GetTargetToken() const
252 {
253 auto targetService = targetService_;
254 if (!targetService) {
255 return nullptr;
256 }
257
258 auto token = targetService->GetToken();
259 if (!token) {
260 return nullptr;
261 }
262
263 return token->AsObject();
264 }
265
GetConnection() const266 sptr<IRemoteObject> ConnectionRecord::GetConnection() const
267 {
268 auto callback = connCallback_;
269 if (!callback) {
270 return nullptr;
271 }
272
273 return callback->AsObject();
274 }
275 } // namespace AAFwk
276 } // namespace OHOS
277