1 /*
2 * Copyright (c) 2023 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 "tunnel_client.h"
17
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21
22 #include "iremote_broker.h"
23 #include "iremote_object.h"
24
25 #include "devicestatus_define.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "TunnelClient"
29
30 namespace OHOS {
31 namespace Msdp {
32 namespace DeviceStatus {
33
~TunnelClient()34 TunnelClient::~TunnelClient()
35 {
36 std::lock_guard lock(mutex_);
37 if (devicestatusProxy_ != nullptr) {
38 auto remoteObject = devicestatusProxy_->AsObject();
39 if (remoteObject != nullptr) {
40 remoteObject->RemoveDeathRecipient(deathRecipient_);
41 }
42 }
43 }
44
Enable(Intention intention,ParamBase & data,ParamBase & reply)45 int32_t TunnelClient::Enable(Intention intention, ParamBase &data, ParamBase &reply)
46 {
47 CALL_DEBUG_ENTER;
48 MessageParcel dataParcel;
49 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
50 FI_HILOGE("WriteInterfaceToken fail");
51 return RET_ERR;
52 }
53 if (!data.Marshalling(dataParcel)) {
54 FI_HILOGE("ParamBase::Marshalling fail");
55 return RET_ERR;
56 }
57 if (Connect() != RET_OK) {
58 FI_HILOGE("Can not connect to IntentionService");
59 return RET_ERR;
60 }
61 MessageParcel replyParcel;
62 {
63 std::lock_guard lock(mutex_);
64 CHKPR(devicestatusProxy_, RET_ERR);
65 int32_t ret = devicestatusProxy_->Enable(intention, dataParcel, replyParcel);
66 if (ret != RET_OK) {
67 FI_HILOGE("proxy::Enable fail");
68 return RET_ERR;
69 }
70 }
71 if (!reply.Unmarshalling(replyParcel)) {
72 FI_HILOGE("ParamBase::Unmarshalling fail");
73 return RET_ERR;
74 }
75 return RET_OK;
76 }
77
Disable(Intention intention,ParamBase & data,ParamBase & reply)78 int32_t TunnelClient::Disable(Intention intention, ParamBase &data, ParamBase &reply)
79 {
80 CALL_DEBUG_ENTER;
81 MessageParcel dataParcel;
82 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
83 FI_HILOGE("WriteInterfaceToken fail");
84 return RET_ERR;
85 }
86 if (!data.Marshalling(dataParcel)) {
87 FI_HILOGE("ParamBase::Marshalling fail");
88 return RET_ERR;
89 }
90 if (Connect() != RET_OK) {
91 FI_HILOGE("Can not connect to IntentionService");
92 return RET_ERR;
93 }
94 MessageParcel replyParcel;
95 {
96 std::lock_guard lock(mutex_);
97 CHKPR(devicestatusProxy_, RET_ERR);
98 int32_t ret = devicestatusProxy_->Disable(intention, dataParcel, replyParcel);
99 if (ret != RET_OK) {
100 FI_HILOGE("proxy::Disable fail");
101 return RET_ERR;
102 }
103 }
104 if (!reply.Unmarshalling(replyParcel)) {
105 FI_HILOGE("ParamBase::Unmarshalling fail");
106 return RET_ERR;
107 }
108 return RET_OK;
109 }
110
Start(Intention intention,ParamBase & data,ParamBase & reply)111 int32_t TunnelClient::Start(Intention intention, ParamBase &data, ParamBase &reply)
112 {
113 CALL_DEBUG_ENTER;
114 MessageParcel dataParcel;
115 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
116 FI_HILOGE("WriteInterfaceToken fail");
117 return RET_ERR;
118 }
119 if (!data.Marshalling(dataParcel)) {
120 FI_HILOGE("ParamBase::Marshalling fail");
121 return RET_ERR;
122 }
123 if (Connect() != RET_OK) {
124 FI_HILOGE("Can not connect to IntentionService");
125 return RET_ERR;
126 }
127 MessageParcel replyParcel;
128 {
129 std::lock_guard lock(mutex_);
130 CHKPR(devicestatusProxy_, RET_ERR);
131 int32_t ret = devicestatusProxy_->Start(intention, dataParcel, replyParcel);
132 if (ret != RET_OK) {
133 FI_HILOGE("proxy::Start fail");
134 return ret;
135 }
136 }
137 if (!reply.Unmarshalling(replyParcel)) {
138 FI_HILOGE("ParamBase::Unmarshalling fail");
139 return RET_ERR;
140 }
141 return RET_OK;
142 }
143
Stop(Intention intention,ParamBase & data,ParamBase & reply)144 int32_t TunnelClient::Stop(Intention intention, ParamBase &data, ParamBase &reply)
145 {
146 CALL_DEBUG_ENTER;
147 MessageParcel dataParcel;
148 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
149 FI_HILOGE("WriteInterfaceToken fail");
150 return RET_ERR;
151 }
152 if (!data.Marshalling(dataParcel)) {
153 FI_HILOGE("ParamBase::Marshalling fail");
154 return RET_ERR;
155 }
156 if (Connect() != RET_OK) {
157 FI_HILOGE("Can not connect to IntentionService");
158 return RET_ERR;
159 }
160 MessageParcel replyParcel;
161 {
162 std::lock_guard lock(mutex_);
163 CHKPR(devicestatusProxy_, RET_ERR);
164 int32_t ret = devicestatusProxy_->Stop(intention, dataParcel, replyParcel);
165 if (ret != RET_OK) {
166 FI_HILOGE("proxy::Stop fail");
167 return RET_ERR;
168 }
169 }
170 if (!reply.Unmarshalling(replyParcel)) {
171 FI_HILOGE("ParamBase::Unmarshalling fail");
172 return RET_ERR;
173 }
174 return RET_OK;
175 }
176
AddWatch(Intention intention,uint32_t id,ParamBase & data,ParamBase & reply)177 int32_t TunnelClient::AddWatch(Intention intention, uint32_t id, ParamBase &data, ParamBase &reply)
178 {
179 CALL_DEBUG_ENTER;
180 MessageParcel dataParcel;
181 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
182 FI_HILOGE("WriteInterfaceToken fail");
183 return RET_ERR;
184 }
185 if (!data.Marshalling(dataParcel)) {
186 FI_HILOGE("ParamBase::Marshalling fail");
187 return RET_ERR;
188 }
189 if (Connect() != RET_OK) {
190 FI_HILOGE("Can not connect to IntentionService");
191 return RET_ERR;
192 }
193 MessageParcel replyParcel;
194 {
195 std::lock_guard lock(mutex_);
196 CHKPR(devicestatusProxy_, RET_ERR);
197 int32_t ret = devicestatusProxy_->AddWatch(intention, id, dataParcel, replyParcel);
198 if (ret != RET_OK) {
199 FI_HILOGE("proxy::AddWatch fail");
200 return ret;
201 }
202 }
203 if (!reply.Unmarshalling(replyParcel)) {
204 FI_HILOGE("ParamBase::Unmarshalling fail");
205 return RET_ERR;
206 }
207 return RET_OK;
208 }
209
RemoveWatch(Intention intention,uint32_t id,ParamBase & data,ParamBase & reply)210 int32_t TunnelClient::RemoveWatch(Intention intention, uint32_t id, ParamBase &data, ParamBase &reply)
211 {
212 CALL_DEBUG_ENTER;
213 MessageParcel dataParcel;
214 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
215 FI_HILOGE("WriteInterfaceToken fail");
216 return RET_ERR;
217 }
218 if (!data.Marshalling(dataParcel)) {
219 FI_HILOGE("ParamBase::Marshalling fail");
220 return RET_ERR;
221 }
222 if (Connect() != RET_OK) {
223 FI_HILOGE("Can not connect to IntentionService");
224 return RET_ERR;
225 }
226 MessageParcel replyParcel;
227 {
228 std::lock_guard lock(mutex_);
229 CHKPR(devicestatusProxy_, RET_ERR);
230 int32_t ret = devicestatusProxy_->RemoveWatch(intention, id, dataParcel, replyParcel);
231 if (ret != RET_OK) {
232 FI_HILOGE("proxy::RemoveWatch fail");
233 return ret;
234 }
235 }
236 if (!reply.Unmarshalling(replyParcel)) {
237 FI_HILOGE("ParamBase::Unmarshalling fail");
238 return RET_ERR;
239 }
240 return RET_OK;
241 }
242
SetParam(Intention intention,uint32_t id,ParamBase & data,ParamBase & reply)243 int32_t TunnelClient::SetParam(Intention intention, uint32_t id, ParamBase &data, ParamBase &reply)
244 {
245 CALL_DEBUG_ENTER;
246 MessageParcel dataParcel;
247 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
248 FI_HILOGE("WriteInterfaceToken fail");
249 return RET_ERR;
250 }
251 if (!data.Marshalling(dataParcel)) {
252 FI_HILOGE("ParamBase::Marshalling fail");
253 return RET_ERR;
254 }
255 if (Connect() != RET_OK) {
256 FI_HILOGE("Can not connect to IntentionService");
257 return RET_ERR;
258 }
259 MessageParcel replyParcel;
260 {
261 std::lock_guard lock(mutex_);
262 CHKPR(devicestatusProxy_, RET_ERR);
263 int32_t ret = devicestatusProxy_->SetParam(intention, id, dataParcel, replyParcel);
264 if (ret != RET_OK) {
265 FI_HILOGE("proxy::SetParam fail");
266 return ret;
267 }
268 }
269 if (!reply.Unmarshalling(replyParcel)) {
270 FI_HILOGE("ParamBase::Unmarshalling fail");
271 return RET_ERR;
272 }
273 return RET_OK;
274 }
275
GetParam(Intention intention,uint32_t id,ParamBase & data,ParamBase & reply)276 int32_t TunnelClient::GetParam(Intention intention, uint32_t id, ParamBase &data, ParamBase &reply)
277 {
278 CALL_DEBUG_ENTER;
279 MessageParcel dataParcel;
280 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
281 FI_HILOGE("WriteInterfaceToken fail");
282 return RET_ERR;
283 }
284 if (!data.Marshalling(dataParcel)) {
285 FI_HILOGE("ParamBase::Marshalling fail");
286 return RET_ERR;
287 }
288 if (Connect() != RET_OK) {
289 FI_HILOGE("Can not connect to IntentionService");
290 return RET_ERR;
291 }
292 MessageParcel replyParcel;
293 {
294 std::lock_guard lock(mutex_);
295 CHKPR(devicestatusProxy_, RET_ERR);
296 int32_t ret = devicestatusProxy_->GetParam(intention, id, dataParcel, replyParcel);
297 if (ret != RET_OK) {
298 FI_HILOGE("proxy::GetParam fail");
299 return RET_ERR;
300 }
301 }
302 if (!reply.Unmarshalling(replyParcel)) {
303 FI_HILOGE("ParamBase::Unmarshalling fail");
304 return RET_ERR;
305 }
306 return RET_OK;
307 }
308
Control(Intention intention,uint32_t id,ParamBase & data,ParamBase & reply)309 int32_t TunnelClient::Control(Intention intention, uint32_t id, ParamBase &data, ParamBase &reply)
310 {
311 CALL_DEBUG_ENTER;
312 MessageParcel dataParcel;
313 if (!dataParcel.WriteInterfaceToken(IIntention::GetDescriptor())) {
314 FI_HILOGE("WriteInterfaceToken fail");
315 return RET_ERR;
316 }
317 if (!data.Marshalling(dataParcel)) {
318 FI_HILOGE("ParamBase::Marshalling fail");
319 return RET_ERR;
320 }
321 if (Connect() != RET_OK) {
322 FI_HILOGE("Can not connect to IntentionService");
323 return RET_ERR;
324 }
325 MessageParcel replyParcel;
326 {
327 std::lock_guard lock(mutex_);
328 CHKPR(devicestatusProxy_, RET_ERR);
329 int32_t ret = devicestatusProxy_->Control(intention, id, dataParcel, replyParcel);
330 if (ret != RET_OK) {
331 FI_HILOGE("proxy::Control fail");
332 return RET_ERR;
333 }
334 }
335 if (!reply.Unmarshalling(replyParcel)) {
336 FI_HILOGE("ParamBase::Unmarshalling fail");
337 return RET_ERR;
338 }
339 return RET_OK;
340 }
341
Connect()342 ErrCode TunnelClient::Connect()
343 {
344 CALL_INFO_TRACE;
345 std::lock_guard lock(mutex_);
346 if (devicestatusProxy_ != nullptr) {
347 return RET_OK;
348 }
349
350 sptr<ISystemAbilityManager> sa = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
351 CHKPR(sa, E_DEVICESTATUS_GET_SYSTEM_ABILITY_MANAGER_FAILED);
352
353 sptr<IRemoteObject> remoteObject = sa->CheckSystemAbility(MSDP_DEVICESTATUS_SERVICE_ID);
354 CHKPR(remoteObject, E_DEVICESTATUS_GET_SERVICE_FAILED);
355
356 deathRecipient_ = sptr<DeathRecipient>::MakeSptr(shared_from_this());
357 CHKPR(deathRecipient_, ERR_NO_MEMORY);
358
359 if (remoteObject->IsProxyObject()) {
360 if (!remoteObject->AddDeathRecipient(deathRecipient_)) {
361 FI_HILOGE("Add death recipient to DeviceStatus service failed");
362 return E_DEVICESTATUS_ADD_DEATH_RECIPIENT_FAILED;
363 }
364 }
365
366 devicestatusProxy_ = iface_cast<IIntention>(remoteObject);
367 FI_HILOGI("Connecting IntentionService success");
368 return RET_OK;
369 }
370
ResetProxy(const wptr<IRemoteObject> & remote)371 void TunnelClient::ResetProxy(const wptr<IRemoteObject> &remote)
372 {
373 CALL_DEBUG_ENTER;
374 std::lock_guard lock(mutex_);
375 CHKPV(devicestatusProxy_);
376 auto serviceRemote = devicestatusProxy_->AsObject();
377 if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
378 serviceRemote->RemoveDeathRecipient(deathRecipient_);
379 devicestatusProxy_ = nullptr;
380 }
381 }
382
DeathRecipient(std::shared_ptr<TunnelClient> parent)383 TunnelClient::DeathRecipient::DeathRecipient(std::shared_ptr<TunnelClient> parent)
384 : parent_(parent)
385 {}
386
OnRemoteDied(const wptr<IRemoteObject> & remote)387 void TunnelClient::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
388 {
389 CALL_DEBUG_ENTER;
390 std::shared_ptr<TunnelClient> parent = parent_.lock();
391 CHKPV(parent);
392 CHKPV(remote);
393 parent->ResetProxy(remote);
394 FI_HILOGD("Recv death notice");
395 }
396 } // namespace DeviceStatus
397 } // namespace Msdp
398 } // namespace OHOS
399