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