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 "hilog_wrapper.h"
19 #include "ability_util.h"
20 #include "ability_manager_errors.h"
21 #include "ability_manager_service.h"
22
23 namespace OHOS {
24 namespace AAFwk {
25 int64_t ConnectionRecord::connectRecordId = 0;
26
ConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)27 ConnectionRecord::ConnectionRecord(const sptr<IRemoteObject> &callerToken,
28 const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
29 : state_(ConnectionState::INIT),
30 callerToken_(callerToken),
31 targetService_(targetService),
32 connCallback_(connCallback)
33 {
34 recordId_ = connectRecordId++;
35 }
36
~ConnectionRecord()37 ConnectionRecord::~ConnectionRecord()
38 {}
39
CreateConnectionRecord(const sptr<IRemoteObject> & callerToken,const std::shared_ptr<AbilityRecord> & targetService,const sptr<IAbilityConnection> & connCallback)40 std::shared_ptr<ConnectionRecord> ConnectionRecord::CreateConnectionRecord(const sptr<IRemoteObject> &callerToken,
41 const std::shared_ptr<AbilityRecord> &targetService, const sptr<IAbilityConnection> &connCallback)
42 {
43 auto connRecord = std::make_shared<ConnectionRecord>(callerToken, targetService, connCallback);
44 CHECK_POINTER_AND_RETURN(connRecord, nullptr);
45 connRecord->SetConnectState(ConnectionState::INIT);
46 return connRecord;
47 }
48
SetConnectState(const ConnectionState & state)49 void ConnectionRecord::SetConnectState(const ConnectionState &state)
50 {
51 state_ = state;
52 }
53
GetConnectState() const54 ConnectionState ConnectionRecord::GetConnectState() const
55 {
56 return state_;
57 }
58
GetToken() const59 sptr<IRemoteObject> ConnectionRecord::GetToken() const
60 {
61 return callerToken_;
62 }
63
GetAbilityRecord() const64 std::shared_ptr<AbilityRecord> ConnectionRecord::GetAbilityRecord() const
65 {
66 return targetService_;
67 }
68
GetAbilityConnectCallback() const69 sptr<IAbilityConnection> ConnectionRecord::GetAbilityConnectCallback() const
70 {
71 return connCallback_;
72 }
73
ClearConnCallBack()74 void ConnectionRecord::ClearConnCallBack()
75 {
76 if (connCallback_) {
77 connCallback_.clear();
78 }
79 }
80
DisconnectAbility()81 int ConnectionRecord::DisconnectAbility()
82 {
83 if (state_ != ConnectionState::CONNECTED) {
84 HILOG_INFO("The connection has not established.");
85 return INVALID_CONNECTION_STATE;
86 }
87
88 /* set state to Disconnecting */
89 SetConnectState(ConnectionState::DISCONNECTING);
90 CHECK_POINTER_AND_RETURN(targetService_, ERR_INVALID_VALUE);
91 int connectNums = targetService_->GetConnectRecordList().size();
92 if (connectNums == 1) {
93 /* post timeout task to eventhandler */
94 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
95 if (handler == nullptr) {
96 HILOG_ERROR("fail to get AbilityEventHandler");
97 } else {
98 std::string taskName("DisconnectTimeout_");
99 taskName += std::to_string(recordId_);
100 auto disconnectTask = [connectionRecord = shared_from_this()]() {
101 HILOG_ERROR("Disconnect ability timeout");
102 connectionRecord->DisconnectTimeout();
103 };
104 handler->PostTask(disconnectTask, taskName, AbilityManagerService::DISCONNECT_TIMEOUT);
105 }
106 /* schedule disconnect to target ability */
107 targetService_->DisconnectAbility();
108 } else {
109 SetConnectState(ConnectionState::DISCONNECTED);
110 }
111
112 return ERR_OK;
113 }
114
CompleteConnect(int resultCode)115 void ConnectionRecord::CompleteConnect(int resultCode)
116 {
117 CHECK_POINTER(targetService_);
118 if (resultCode == ERR_OK) {
119 SetConnectState(ConnectionState::CONNECTED);
120 targetService_->SetAbilityState(AbilityState::ACTIVE);
121 }
122 const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
123 AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name);
124 auto remoteObject = targetService_->GetConnRemoteObject();
125 if (connCallback_) {
126 connCallback_->OnAbilityConnectDone(element, remoteObject, resultCode);
127 }
128 HILOG_INFO("result: %{public}d. connectstate:%{public}d.", resultCode, state_);
129 }
130
CompleteDisconnect(int resultCode)131 void ConnectionRecord::CompleteDisconnect(int resultCode)
132 {
133 if (resultCode == ERR_OK) {
134 SetConnectState(ConnectionState::DISCONNECTED);
135 }
136 CHECK_POINTER(targetService_);
137 const AppExecFwk::AbilityInfo &abilityInfo = targetService_->GetAbilityInfo();
138 AppExecFwk::ElementName element(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name);
139 if (connCallback_) {
140 connCallback_->OnAbilityDisconnectDone(element, resultCode);
141 }
142 HILOG_INFO("result: %{public}d. connectstate:%{public}d.", resultCode, state_);
143 }
144
ScheduleDisconnectAbilityDone()145 void ConnectionRecord::ScheduleDisconnectAbilityDone()
146 {
147 if (state_ != ConnectionState::DISCONNECTING) {
148 HILOG_ERROR("fail to schedule disconnect ability done, current state is not disconnecting.");
149 return;
150 }
151
152 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
153 if (handler == nullptr) {
154 HILOG_ERROR("fail to get AbilityEventHandler");
155 } else {
156 std::string taskName = std::string("DisconnectTimeout_") + std::to_string(recordId_);
157 handler->RemoveTask(taskName);
158 }
159
160 CompleteDisconnect(ERR_OK);
161 }
162
ScheduleConnectAbilityDone()163 void ConnectionRecord::ScheduleConnectAbilityDone()
164 {
165 if (state_ != ConnectionState::CONNECTING) {
166 HILOG_ERROR("fail to schedule connect ability done, current state is not connecting.");
167 return;
168 }
169 auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetEventHandler();
170 if (handler == nullptr) {
171 HILOG_ERROR("fail to get AbilityEventHandler");
172 } else {
173 std::string taskName = std::string("ConnectTimeout_") + std::to_string(recordId_);
174 handler->RemoveTask(taskName);
175 }
176
177 CompleteConnect(ERR_OK);
178 }
179
DisconnectTimeout()180 void ConnectionRecord::DisconnectTimeout()
181 {
182 CHECK_POINTER(targetService_);
183 /* force to disconnect */
184 /* so scheduler target service disconnect done */
185 DelayedSingleton<AbilityManagerService>::GetInstance()->ScheduleDisconnectAbilityDone(targetService_->GetToken());
186 }
187
ConvertConnectionState(const ConnectionState & state) const188 std::string ConnectionRecord::ConvertConnectionState(const ConnectionState &state) const
189 {
190 switch (state) {
191 case ConnectionState::INIT:
192 return "INIT";
193 case ConnectionState::CONNECTING:
194 return "CONNECTING";
195 case ConnectionState::CONNECTED:
196 return "CONNECTED";
197 case ConnectionState::DISCONNECTING:
198 return "DISCONNECTING";
199 case ConnectionState::DISCONNECTED:
200 return "DISCONNECTED";
201 default:
202 return "INVALIDSTATE";
203 }
204 }
205
Dump(std::vector<std::string> & info) const206 void ConnectionRecord::Dump(std::vector<std::string> &info) const
207 {
208 info.emplace_back(" > " + GetAbilityRecord()->GetAbilityInfo().bundleName + "/" +
209 GetAbilityRecord()->GetAbilityInfo().name + " connectionState #" +
210 ConvertConnectionState(GetConnectState()));
211 }
212 } // namespace AAFwk
213 } // namespace OHOS