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