1 /*
2  * Copyright (c) 2023-2024 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 "distributed_file_daemon_proxy.h"
17 
18 #include <sstream>
19 
20 #include "dfs_error.h"
21 #include "ipc/distributed_file_daemon_ipc_interface_code.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "utils_log.h"
25 
26 namespace OHOS {
27 namespace Storage {
28 namespace DistributedFile {
29 using namespace std;
30 using namespace OHOS::Storage;
31 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)32 void DistributedFileDaemonProxy::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
33 {
34     LOGI("dfs service death");
35     unique_lock<mutex> lock(proxyMutex_);
36     daemonProxy_ = nullptr;
37 }
38 
SetDeathRecipient(RemoteDiedHandler handler)39 void DistributedFileDaemonProxy::DaemonDeathRecipient::SetDeathRecipient(RemoteDiedHandler handler)
40 {
41     handler_ = std::move(handler);
42 }
43 
OnRemoteDied(const wptr<IRemoteObject> & remote)44 void DistributedFileDaemonProxy::DaemonDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
45 {
46     LOGI("start");
47     if (handler_ != nullptr) {
48         handler_(remote);
49     }
50 }
51 
GetInstance()52 sptr<IDaemon> DistributedFileDaemonProxy::GetInstance()
53 {
54     LOGI("getinstance");
55     unique_lock<mutex> lock(proxyMutex_);
56     if (daemonProxy_ != nullptr) {
57         return daemonProxy_;
58     }
59 
60     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
61     if (samgr == nullptr) {
62         LOGE("Samgr is nullptr");
63         return nullptr;
64     }
65 
66     auto object = samgr->CheckSystemAbility(FILEMANAGEMENT_DISTRIBUTED_FILE_DAEMON_SA_ID);
67     if (object == nullptr) {
68         LOGE("object == nullptr");
69         return nullptr;
70     }
71 
72     if (deathRecipient_ == nullptr) {
73         deathRecipient_ = new (std::nothrow) DaemonDeathRecipient();
74         if (deathRecipient_ == nullptr) {
75             LOGE("new death recipient failed");
76             return nullptr;
77         }
78     }
79     deathRecipient_->SetDeathRecipient([](const wptr<IRemoteObject> &remote) { OnRemoteSaDied(remote); });
80     if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
81         LOGE("failed to add death recipient.");
82         return nullptr;
83     }
84 
85     daemonProxy_ = iface_cast<IDaemon>(object);
86     if (daemonProxy_ == nullptr) {
87         LOGE("service == nullptr");
88         return nullptr;
89     }
90     return daemonProxy_;
91 }
92 
OpenP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)93 int32_t DistributedFileDaemonProxy::OpenP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
94 {
95     LOGI("Open p2p connection");
96     MessageParcel data;
97     MessageParcel reply;
98     MessageOption option;
99     if (!data.WriteInterfaceToken(GetDescriptor())) {
100         LOGE("Failed to write interface token");
101         return OHOS::FileManagement::E_BROKEN_IPC;
102     }
103     if (!data.WriteCString(deviceInfo.deviceId)) {
104         LOGE("Failed to send device id");
105         return OHOS::FileManagement::E_INVAL_ARG;
106     }
107     if (!data.WriteCString(deviceInfo.deviceName)) {
108         LOGE("Failed to send device name");
109         return OHOS::FileManagement::E_INVAL_ARG;
110     }
111     if (!data.WriteCString(deviceInfo.networkId)) {
112         LOGE("Failed to send network id");
113         return OHOS::FileManagement::E_INVAL_ARG;
114     }
115     if (!data.WriteUint16(deviceInfo.deviceTypeId)) {
116         LOGE("Failed to send deviceTypeId");
117         return OHOS::FileManagement::E_INVAL_ARG;
118     }
119     if (!data.WriteUint32(deviceInfo.range)) {
120         LOGE("Failed to send range");
121         return OHOS::FileManagement::E_INVAL_ARG;
122     }
123     if (!data.WriteInt32(deviceInfo.authForm)) {
124         LOGE("Failed to send user id");
125         return OHOS::FileManagement::E_INVAL_ARG;
126     }
127     auto remote = Remote();
128     if (!remote) {
129         LOGE("remote is nullptr");
130         return OHOS::FileManagement::E_BROKEN_IPC;
131     }
132     int32_t ret = remote->SendRequest(
133         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION),
134         data, reply, option);
135     if (ret != 0) {
136         stringstream ss;
137         ss << "Failed to send out the requeset, errno:" << ret;
138         LOGE("%{public}s", ss.str().c_str());
139         return OHOS::FileManagement::E_BROKEN_IPC;
140     }
141     LOGI("Open p2p connection Success");
142     return reply.ReadInt32();
143 }
144 
CloseP2PConnection(const DistributedHardware::DmDeviceInfo & deviceInfo)145 int32_t DistributedFileDaemonProxy::CloseP2PConnection(const DistributedHardware::DmDeviceInfo &deviceInfo)
146 {
147     LOGI("Close p2p connection");
148     MessageParcel data;
149     MessageParcel reply;
150     MessageOption option;
151     if (!data.WriteInterfaceToken(GetDescriptor())) {
152         LOGE("Failed to write interface token");
153         return OHOS::FileManagement::E_BROKEN_IPC;
154     }
155     if (!data.WriteCString(deviceInfo.deviceId)) {
156         LOGE("Failed to send device id");
157         return OHOS::FileManagement::E_INVAL_ARG;
158     }
159     if (!data.WriteCString(deviceInfo.deviceName)) {
160         LOGE("Failed to send device name");
161         return OHOS::FileManagement::E_INVAL_ARG;
162     }
163     if (!data.WriteCString(deviceInfo.networkId)) {
164         LOGE("Failed to send network id");
165         return OHOS::FileManagement::E_INVAL_ARG;
166     }
167     if (!data.WriteUint16(deviceInfo.deviceTypeId)) {
168         LOGE("Failed to send deviceTypeId");
169         return OHOS::FileManagement::E_INVAL_ARG;
170     }
171     if (!data.WriteUint32(deviceInfo.range)) {
172         LOGE("Failed to send range");
173         return OHOS::FileManagement::E_INVAL_ARG;
174     }
175     if (!data.WriteInt32(deviceInfo.authForm)) {
176         LOGE("Failed to send user id");
177         return OHOS::FileManagement::E_INVAL_ARG;
178     }
179     auto remote = Remote();
180     if (!remote) {
181         LOGE("remote is nullptr");
182         return OHOS::FileManagement::E_BROKEN_IPC;
183     }
184     int32_t ret = remote->SendRequest(
185         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION),
186         data, reply, option);
187     if (ret != 0) {
188         stringstream ss;
189         ss << "Failed to send out the requeset, errno:" << ret;
190         LOGE("%{public}s", ss.str().c_str());
191         return OHOS::FileManagement::E_BROKEN_IPC;
192     }
193     LOGI("Close p2p connection Success");
194     return reply.ReadInt32();
195 }
196 
OpenP2PConnectionEx(const std::string & networkId,sptr<IFileDfsListener> remoteReverseObj)197 int32_t DistributedFileDaemonProxy::OpenP2PConnectionEx(const std::string &networkId,
198                                                         sptr<IFileDfsListener> remoteReverseObj)
199 {
200     LOGI("DistributedFileDaemonProxy::OpenP2PConnectionEx start.");
201     MessageParcel data;
202     MessageParcel reply;
203     MessageOption option;
204     if (!data.WriteInterfaceToken(GetDescriptor())) {
205         LOGE("Failed to write interface token.");
206         return OHOS::FileManagement::E_BROKEN_IPC;
207     }
208     if (!data.WriteString(networkId)) {
209         LOGE("Failed to send network id.");
210         return OHOS::FileManagement::E_INVAL_ARG;
211     }
212     if (remoteReverseObj == nullptr) {
213         LOGE("remoteReverseObj is nullptr.");
214         return OHOS::FileManagement::E_BROKEN_IPC;
215     }
216     if (!data.WriteRemoteObject(remoteReverseObj->AsObject())) {
217         LOGE("fail to WriteRemoteObject remoteReverseObj");
218         return OHOS::FileManagement::E_BROKEN_IPC;
219     }
220 
221     auto remote = Remote();
222     if (!remote) {
223         LOGE("remote is nullptr.");
224         return OHOS::FileManagement::E_BROKEN_IPC;
225     }
226     int32_t ret = remote->SendRequest(
227         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_OPEN_P2P_CONNECTION_EX),
228         data, reply, option);
229     if (ret != 0) {
230         LOGE("SendRequest failed, ret = %{public}d", ret);
231         return OHOS::FileManagement::E_BROKEN_IPC;
232     }
233     LOGI("DistributedFileDaemonProxy::OpenP2PConnectionEx success.");
234     return reply.ReadInt32();
235 }
236 
CloseP2PConnectionEx(const std::string & networkId)237 int32_t DistributedFileDaemonProxy::CloseP2PConnectionEx(const std::string &networkId)
238 {
239     LOGI("Close p2p connection");
240     MessageParcel data;
241     MessageParcel reply;
242     MessageOption option;
243     if (!data.WriteInterfaceToken(GetDescriptor())) {
244         LOGE("Failed to write interface token.");
245         return OHOS::FileManagement::E_BROKEN_IPC;
246     }
247     if (!data.WriteString(networkId)) {
248         LOGE("Failed to send device id.");
249         return OHOS::FileManagement::E_INVAL_ARG;
250     }
251     auto remote = Remote();
252     if (!remote) {
253         LOGE("remote is nullptr.");
254         return OHOS::FileManagement::E_BROKEN_IPC;
255     }
256     int32_t ret = remote->SendRequest(
257         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CLOSE_P2P_CONNECTION_EX),
258         data, reply, option);
259     if (ret != 0) {
260         LOGE("SendRequest failed, ret = %{public}d", ret);
261         return OHOS::FileManagement::E_BROKEN_IPC;
262     }
263     LOGI("DistributedFileDaemonProxy::Close p2p connection Success");
264     return reply.ReadInt32();
265 }
266 
PrepareSession(const std::string & srcUri,const std::string & dstUri,const std::string & srcDeviceId,const sptr<IRemoteObject> & listener,HmdfsInfo & info)267 int32_t DistributedFileDaemonProxy::PrepareSession(const std::string &srcUri,
268                                                    const std::string &dstUri,
269                                                    const std::string &srcDeviceId,
270                                                    const sptr<IRemoteObject> &listener,
271                                                    HmdfsInfo &info)
272 {
273     MessageParcel data;
274     MessageParcel reply;
275     MessageOption option;
276     if (!data.WriteInterfaceToken(GetDescriptor())) {
277         LOGE("Failed to write interface token");
278         return OHOS::FileManagement::E_BROKEN_IPC;
279     }
280     if (!data.WriteString(srcUri)) {
281         LOGE("Failed to send srcUri");
282         return OHOS::FileManagement::E_INVAL_ARG;
283     }
284     if (!data.WriteString(dstUri)) {
285         LOGE("Failed to send dstUri");
286         return OHOS::FileManagement::E_INVAL_ARG;
287     }
288     if (!data.WriteString(srcDeviceId)) {
289         LOGE("Failed to send remoteDeviceId");
290         return OHOS::FileManagement::E_INVAL_ARG;
291     }
292     if (!data.WriteRemoteObject(listener)) {
293         LOGE("Failed to send the listener callback stub");
294         return OHOS::FileManagement::E_INVAL_ARG;
295     }
296     if (!data.WriteString(info.copyPath)) {
297         LOGE("Failed to send info.copyPath");
298         return OHOS::FileManagement::E_INVAL_ARG;
299     }
300     if (!data.WriteBool(info.dirExistFlag)) {
301         LOGE("Failed to send info.dirExistFlag");
302         return OHOS::FileManagement::E_INVAL_ARG;
303     }
304     auto remote = Remote();
305     if (remote == nullptr) {
306         LOGE("remote is nullptr");
307         return OHOS::FileManagement::E_BROKEN_IPC;
308     }
309     int32_t ret =
310         remote->SendRequest(static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PREPARE_SESSION),
311                             data, reply, option);
312     if (!reply.ReadString(info.sessionName)) {
313         LOGE("Failed to receive info.sessionName");
314         return OHOS::FileManagement::E_INVAL_ARG;
315     }
316     if (ret != 0) {
317         LOGE("SendRequest failed, ret = %{public}d", ret);
318         return OHOS::FileManagement::E_BROKEN_IPC;
319     }
320     return reply.ReadInt32();
321 }
322 
RequestSendFile(const std::string & srcUri,const std::string & dstPath,const std::string & remoteDeviceId,const std::string & sessionName)323 int32_t DistributedFileDaemonProxy::RequestSendFile(const std::string &srcUri,
324                                                     const std::string &dstPath,
325                                                     const std::string &remoteDeviceId,
326                                                     const std::string &sessionName)
327 {
328     MessageParcel data;
329     MessageParcel reply;
330     MessageOption option;
331     if (!data.WriteInterfaceToken(GetDescriptor())) {
332         LOGE("Failed to write interface token");
333         return OHOS::FileManagement::E_BROKEN_IPC;
334     }
335     if (!data.WriteString(srcUri)) {
336         LOGE("Failed to send srcUri");
337         return OHOS::FileManagement::E_INVAL_ARG;
338     }
339     if (!data.WriteString(dstPath)) {
340         LOGE("Failed to send dstPath");
341         return OHOS::FileManagement::E_INVAL_ARG;
342     }
343     if (!data.WriteString(remoteDeviceId)) {
344         LOGE("Failed to send remoteDeviceId");
345         return OHOS::FileManagement::E_INVAL_ARG;
346     }
347     if (!data.WriteString(sessionName)) {
348         LOGE("Failed to send sessionName");
349         return OHOS::FileManagement::E_INVAL_ARG;
350     }
351     auto remote = Remote();
352     if (remote == nullptr) {
353         LOGE("remote is nullptr");
354         return OHOS::FileManagement::E_BROKEN_IPC;
355     }
356     int32_t ret = remote->SendRequest(
357         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REQUEST_SEND_FILE), data, reply,
358         option);
359     if (ret != 0) {
360         LOGE("SendRequest failed, ret = %{public}d", ret);
361         return OHOS::FileManagement::E_BROKEN_IPC;
362     }
363     return reply.ReadInt32();
364 }
365 
GetRemoteCopyInfo(const std::string & srcUri,bool & isFile,bool & isDir)366 int32_t DistributedFileDaemonProxy::GetRemoteCopyInfo(const std::string &srcUri, bool &isFile, bool &isDir)
367 {
368     MessageParcel data;
369     MessageParcel reply;
370     MessageOption option;
371     if (!data.WriteInterfaceToken(GetDescriptor())) {
372         LOGE("Failed to write interface token");
373         return OHOS::FileManagement::E_BROKEN_IPC;
374     }
375     if (!data.WriteString(srcUri)) {
376         LOGE("Failed to send srcUri");
377         return OHOS::FileManagement::E_INVAL_ARG;
378     }
379     auto remote = Remote();
380     if (remote == nullptr) {
381         LOGE("remote is nullptr");
382         return OHOS::FileManagement::E_BROKEN_IPC;
383     }
384     auto ret = remote->SendRequest(
385         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_GET_REMOTE_COPY_INFO), data, reply,
386         option);
387     if (ret != 0) {
388         LOGE("SendRequest failed, ret = %{public}d", ret);
389         return OHOS::FileManagement::E_BROKEN_IPC;
390     }
391     if (!reply.ReadBool(isFile)) {
392         LOGE("read isFile failed");
393         return OHOS::FileManagement::E_INVAL_ARG;
394     }
395     if (!reply.ReadBool(isDir)) {
396         LOGE("read isDir failed");
397         return OHOS::FileManagement::E_INVAL_ARG;
398     }
399     if (!reply.ReadInt32(ret)) {
400         LOGE("read res failed");
401         return OHOS::FileManagement::E_INVAL_ARG;
402     }
403     return ret;
404 }
405 
CancelCopyTask(const std::string & sessionName)406 int32_t DistributedFileDaemonProxy::CancelCopyTask(const std::string &sessionName)
407 {
408     MessageParcel data;
409     MessageParcel reply;
410     MessageOption option;
411     if (!data.WriteInterfaceToken(GetDescriptor())) {
412         LOGE("Failed to write interface token");
413         return OHOS::FileManagement::E_BROKEN_IPC;
414     }
415     if (!data.WriteString(sessionName)) {
416         LOGE("Failed to send sessionName");
417         return OHOS::FileManagement::E_INVAL_ARG;
418     }
419     auto remote = Remote();
420     if (remote == nullptr) {
421         LOGE("remote is nullptr");
422         return OHOS::FileManagement::E_BROKEN_IPC;
423     }
424     int32_t ret = remote->SendRequest(
425         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_CANCEL_COPY_TASK), data, reply,
426         option);
427     if (ret != 0) {
428         LOGE("SendRequest failed, ret = %{public}d", ret);
429         return OHOS::FileManagement::E_BROKEN_IPC;
430     }
431     return reply.ReadInt32();
432 }
433 
PushAsset(int32_t userId,const sptr<AssetObj> & assetObj,const sptr<IAssetSendCallback> & sendCallback)434 int32_t DistributedFileDaemonProxy::PushAsset(int32_t userId,
435                                               const sptr<AssetObj> &assetObj,
436                                               const sptr<IAssetSendCallback> &sendCallback)
437 {
438     MessageParcel data;
439     MessageParcel reply;
440     MessageOption option;
441     if (!data.WriteInterfaceToken(GetDescriptor())) {
442         LOGE("Failed to write interface token");
443         return OHOS::FileManagement::E_BROKEN_IPC;
444     }
445 
446     if (!data.WriteInt32(userId)) {
447         LOGE("Failed to send the user id");
448         return OHOS::FileManagement::E_INVAL_ARG;
449     }
450     if (!data.WriteParcelable(assetObj)) {
451         LOGE("Failed to send the assetInfoObj");
452         return OHOS::FileManagement::E_INVAL_ARG;
453     }
454     if (sendCallback == nullptr) {
455         LOGE("sendCallback is nullptr.");
456         return OHOS::FileManagement::E_INVAL_ARG;
457     }
458     if (!data.WriteRemoteObject(sendCallback->AsObject())) {
459         LOGE("Failed to send the listener callback stub");
460         return OHOS::FileManagement::E_INVAL_ARG;
461     }
462     auto remote = Remote();
463     if (remote == nullptr) {
464         LOGE("remote is nullptr");
465         return OHOS::FileManagement::E_BROKEN_IPC;
466     }
467     int32_t ret = remote->SendRequest(
468         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_PUSH_ASSET), data, reply,
469         option);
470     if (ret != 0) {
471         LOGE("UnRegisterAssetCallback failed, ret = %{public}d", ret);
472         return OHOS::FileManagement::E_BROKEN_IPC;
473     }
474     return reply.ReadInt32();
475 }
476 
RegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)477 int32_t DistributedFileDaemonProxy::RegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
478 {
479     MessageParcel data;
480     MessageParcel reply;
481     MessageOption option;
482     if (!data.WriteInterfaceToken(GetDescriptor())) {
483         LOGE("Failed to write interface token");
484         return OHOS::FileManagement::E_BROKEN_IPC;
485     }
486     if (recvCallback == nullptr) {
487         LOGE("recvCallback is nullptr.");
488         return OHOS::FileManagement::E_INVAL_ARG;
489     }
490     if (!data.WriteRemoteObject(recvCallback->AsObject())) {
491         LOGE("Failed to send the listener callback stub");
492         return OHOS::FileManagement::E_INVAL_ARG;
493     }
494     auto remote = Remote();
495     if (remote == nullptr) {
496         LOGE("remote is nullptr");
497         return OHOS::FileManagement::E_BROKEN_IPC;
498     }
499     int32_t ret = remote->SendRequest(
500         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_REGISTER_ASSET_CALLBACK), data,
501         reply, option);
502     if (ret != 0) {
503         LOGE("RegisterAssetCallback failed, ret = %{public}d", ret);
504         return OHOS::FileManagement::E_BROKEN_IPC;
505     }
506     return reply.ReadInt32();
507 }
508 
UnRegisterAssetCallback(const sptr<IAssetRecvCallback> & recvCallback)509 int32_t DistributedFileDaemonProxy::UnRegisterAssetCallback(const sptr<IAssetRecvCallback> &recvCallback)
510 {
511     MessageParcel data;
512     MessageParcel reply;
513     MessageOption option;
514     if (!data.WriteInterfaceToken(GetDescriptor())) {
515         LOGE("Failed to write interface token");
516         return OHOS::FileManagement::E_BROKEN_IPC;
517     }
518     if (recvCallback == nullptr) {
519         LOGE("recvCallback is nullptr.");
520         return OHOS::FileManagement::E_INVAL_ARG;
521     }
522     if (!data.WriteRemoteObject(recvCallback->AsObject())) {
523         LOGE("Failed to send the listener callback stub");
524         return OHOS::FileManagement::E_INVAL_ARG;
525     }
526     auto remote = Remote();
527     if (remote == nullptr) {
528         LOGE("remote is nullptr");
529         return OHOS::FileManagement::E_BROKEN_IPC;
530     }
531     int32_t ret = remote->SendRequest(
532         static_cast<uint32_t>(DistributedFileDaemonInterfaceCode::DISTRIBUTED_FILE_UN_REGISTER_ASSET_CALLBACK), data,
533         reply, option);
534     if (ret != 0) {
535         LOGE("UnRegisterAssetCallback failed, ret = %{public}d", ret);
536         return OHOS::FileManagement::E_BROKEN_IPC;
537     }
538     return reply.ReadInt32();
539 }
540 } // namespace DistributedFile
541 } // namespace Storage
542 } // namespace OHOS