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