1 /*
2 * Copyright (c) 2023-2025 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 #include "distributed_client.h"
16
17 #include "ability_connection_manager_listener.h"
18 #include "parcel_helper.h"
19 #include "ipc_skeleton.h"
20 #include "dtbcollabmgr_log.h"
21 #include "system_ability_definition.h"
22 #include "iservice_registry.h"
23 #include "system_ability.h"
24 #include <chrono>
25
26 namespace OHOS {
27 namespace DistributedCollab {
28 namespace {
29 const std::string TAG = "DistributedClient";
30 const std::u16string DMS_PROXY_INTERFACE_TOKEN = u"ohos.distributedschedule.accessToken";
31 static constexpr int32_t SA_TIMEOUT = 4;
32 }
33
~DistributedClient()34 DistributedClient::~DistributedClient()
35 {
36 HILOGI("destroy DistributedClient");
37 std::lock_guard<std::mutex> lock(mtx_);
38 if (listener_) {
39 auto samgrProxy =
40 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
41 if (samgrProxy != nullptr) {
42 HILOGI("unregister listener");
43 samgrProxy->UnSubscribeSystemAbility(DISTRIBUTED_SCHED_SA_ID, listener_);
44 }
45 }
46 listener_ = nullptr;
47 }
48
GetDmsProxy()49 sptr<IRemoteObject> DistributedClient::GetDmsProxy()
50 {
51 auto samgrProxy =
52 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53 if (samgrProxy == nullptr) {
54 HILOGE("fail to get samgr");
55 return nullptr;
56 }
57 sptr<IRemoteObject> dmsProxy = samgrProxy->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID);
58 if (dmsProxy != nullptr) {
59 return dmsProxy;
60 }
61 // not online, register listener and wait
62 if (listener_ == nullptr) {
63 listener_ = sptr<SystemAbilityStatusChangeListener>::MakeSptr(this);
64 }
65 int32_t ret = samgrProxy->SubscribeSystemAbility(DISTRIBUTED_SCHED_SA_ID, listener_);
66 if (ret != 0) {
67 HILOGE("fail to subscribe system ability");
68 return nullptr;
69 }
70 // waiting for service online
71 std::unique_lock<std::mutex> lock(mtx_);
72 if (!cv_.wait_for(lock, std::chrono::seconds(SA_TIMEOUT),
73 [this]() { return callbackReceived_; })) {
74 HILOGE("wait for system ability timeout");
75 return nullptr;
76 }
77 dmsProxy = samgrProxy->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID);
78 if (dmsProxy == nullptr) {
79 HILOGE("fail to get system ability after callback");
80 return nullptr;
81 }
82 return dmsProxy;
83 }
84
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)85 void DistributedClient::SystemAbilityStatusChangeListener::OnAddSystemAbility(
86 int32_t systemAbilityId, const std::string& deviceId)
87 {
88 HILOGI("OnAddSystemAbility, %{public}d", systemAbilityId);
89 if (systemAbilityId == DISTRIBUTED_SCHED_SA_ID && client_ != nullptr) {
90 std::unique_lock<std::mutex> lock(client_->mtx_);
91 client_->callbackReceived_ = true;
92 client_->cv_.notify_all();
93 }
94 }
95
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)96 void DistributedClient::SystemAbilityStatusChangeListener::OnRemoveSystemAbility(int32_t systemAbilityId,
97 const std::string& deviceId)
98 {
99 HILOGI("SystemAbility removed: %{public}d", systemAbilityId);
100 }
101
CollabMission(int32_t sessionId,const std::string & serverSocketName,const AbilityConnectionSessionInfo & sessionInfo,const ConnectOption & options,const std::string & token)102 int32_t DistributedClient::CollabMission(int32_t sessionId, const std::string& serverSocketName,
103 const AbilityConnectionSessionInfo& sessionInfo, const ConnectOption& options, const std::string& token)
104 {
105 sptr<IRemoteObject> remote = GetDmsProxy();
106 if (remote == nullptr) {
107 HILOGW("remote is nullptr");
108 return INVALID_PARAMETERS_ERR;
109 }
110 MessageParcel data;
111 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
112 HILOGW("write token failed");
113 return ERR_FLATTEN_OBJECT;
114 }
115
116 sptr<IAbilityConnectionManager> listener(new AbilityConnectionManagerListener);
117
118 PARCEL_WRITE_HELPER(data, Int32, sessionId);
119 PARCEL_WRITE_HELPER(data, String, serverSocketName);
120 PARCEL_WRITE_HELPER(data, Parcelable, &sessionInfo.localInfo_);
121 PARCEL_WRITE_HELPER(data, Parcelable, &sessionInfo.peerInfo_);
122 PARCEL_WRITE_HELPER(data, Parcelable, &options);
123 PARCEL_WRITE_HELPER(data, String, token);
124 PARCEL_WRITE_HELPER(data, RemoteObject, listener->AsObject());
125 MessageParcel reply;
126 PARCEL_TRANSACT_SYNC_RET_INT(remote, COLLAB_MESSION, data, reply);
127 }
128
NotifyPrepareResult(const std::string & token,int32_t result,int32_t sessionId,const std::string & serverSocketName)129 int32_t DistributedClient::NotifyPrepareResult(const std::string& token, int32_t result,
130 int32_t sessionId, const std::string& serverSocketName)
131 {
132 HILOGD("called");
133 sptr<IRemoteObject> remote = GetDmsProxy();
134 if (remote == nullptr) {
135 HILOGW("remote is nullptr");
136 return INVALID_PARAMETERS_ERR;
137 }
138 MessageParcel data;
139 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
140 HILOGW("write token failed");
141 return ERR_FLATTEN_OBJECT;
142 }
143
144 PARCEL_WRITE_HELPER(data, String, token);
145 PARCEL_WRITE_HELPER(data, Int32, result);
146 PARCEL_WRITE_HELPER(data, Int32, sessionId);
147 PARCEL_WRITE_HELPER(data, String, serverSocketName);
148 sptr<IAbilityConnectionManager> listener(new AbilityConnectionManagerListener);
149 PARCEL_WRITE_HELPER(data, RemoteObject, listener->AsObject());
150 MessageParcel reply;
151 PARCEL_TRANSACT_SYNC_RET_INT(remote, NOTIFY_PREPARE_RESULT, data, reply);
152 }
153
NotifyCloseCollabSession(const std::string & token)154 int32_t DistributedClient::NotifyCloseCollabSession(const std::string& token)
155 {
156 HILOGD("called.");
157 sptr<IRemoteObject> remote = GetDmsProxy();
158 if (remote == nullptr) {
159 HILOGW("remote is nullptr");
160 return INVALID_PARAMETERS_ERR;
161 }
162 MessageParcel data;
163 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
164 HILOGW("write token failed");
165 return ERR_FLATTEN_OBJECT;
166 }
167 PARCEL_WRITE_HELPER(data, String, token);
168 MessageParcel reply;
169 PARCEL_TRANSACT_SYNC_RET_INT(remote, BNOTIFY_CLOSE_COLLAB_SESSION, data, reply);
170 }
171
NotifyRejectReason(const std::string & token,const std::string & reason)172 int32_t DistributedClient::NotifyRejectReason(const std::string& token, const std::string& reason)
173 {
174 HILOGD("called.");
175 sptr<IRemoteObject> remote = GetDmsProxy();
176 if (remote == nullptr) {
177 HILOGW("remote is nullptr");
178 return INVALID_PARAMETERS_ERR;
179 }
180 MessageParcel data;
181 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
182 HILOGW("write token failed");
183 return ERR_FLATTEN_OBJECT;
184 }
185 PARCEL_WRITE_HELPER(data, String, token);
186 PARCEL_WRITE_HELPER(data, String, reason);
187 MessageParcel reply;
188 PARCEL_TRANSACT_SYNC_RET_INT(remote, NOTIFY_REJECT_REASON, data, reply);
189 }
190
GetPeerVersion(int32_t sessionId,const std::string & peerDeviceId,const std::string dmsServerToken)191 int32_t DistributedClient::GetPeerVersion(int32_t sessionId, const std::string& peerDeviceId,
192 const std::string dmsServerToken)
193 {
194 HILOGD("called.");
195 sptr<IRemoteObject> remote = GetDmsProxy();
196 if (remote == nullptr) {
197 HILOGW("remote is nullptr");
198 return INVALID_PARAMETERS_ERR;
199 }
200 MessageParcel data;
201 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
202 HILOGW("write token failed");
203 return ERR_FLATTEN_OBJECT;
204 }
205
206 sptr<IAbilityConnectionManager> listener(new AbilityConnectionManagerListener);
207 PARCEL_WRITE_HELPER(data, Int32, sessionId);
208 PARCEL_WRITE_HELPER(data, String, peerDeviceId);
209 PARCEL_WRITE_HELPER(data, String, dmsServerToken);
210 PARCEL_WRITE_HELPER(data, RemoteObject, listener->AsObject());
211 MessageParcel reply;
212 PARCEL_TRANSACT_SYNC_RET_INT(remote, GET_SINK_COLLAB_VERSION, data, reply);
213 }
214
GetWifiStatus()215 bool DistributedClient::GetWifiStatus()
216 {
217 HILOGD("called.");
218 sptr<IRemoteObject> remote = GetDmsProxy();
219 if (remote == nullptr) {
220 HILOGW("remote is nullptr");
221 return false;
222 }
223 MessageParcel data;
224 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
225 HILOGW("write token failed");
226 return false;
227 }
228
229 MessageParcel reply;
230 MessageOption option;
231 int32_t ret = remote->SendRequest(GET_WIFI_STATUS, data, reply, option);
232 if (ret != ERR_NONE) {
233 HILOGE("SendRequest transact failed");
234 return false;
235 }
236 return reply.ReadBool();
237 }
238 } // namespace AAFwk
239 } // namespace OHOS