• 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 
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