• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #ifndef OHOS_FILE_FS_COPY_H
17 #define OHOS_FILE_FS_COPY_H
18 
19 #include <chrono>
20 #include <cstring>
21 #include <map>
22 #include <memory>
23 #include <mutex>
24 #include <set>
25 #include <sys/inotify.h>
26 #include <thread>
27 #include "utils.h"
28 #include "cj_lambda.h"
29 #include "ffi_remote_data.h"
30 #include "macro.h"
31 #include "task_signal.h"
32 #include "task_signal_impl.h"
33 #include "uni_error.h"
34 
35 extern "C" {
36 struct CProgress {
37     uint64_t processedSize;
38     uint64_t totalSize;
39 };
40 }
41 
42 namespace OHOS {
43 namespace CJSystemapi {
44 const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF;
45 struct ReceiveInfo {
46     std::string path;
47     std::map<std::string, uint64_t> fileList;
48 };
49 
50 struct CjCallbackObject {
51     int64_t callbackId = 0;
52     int32_t notifyFd = -1;
53     int32_t eventFd = -1;
54     std::function<void(CProgress)> callback;
55     std::vector<std::pair<int, std::shared_ptr<ReceiveInfo>>> wds;
56     uint64_t totalSize = 0;
57     uint64_t progressSize = 0;
58     uint64_t maxProgressSize = 0;
59     int32_t errorCode = 0;
60     std::thread notifyHandler;
CjCallbackObjectCjCallbackObject61     explicit CjCallbackObject(int64_t id) : callbackId(id)
62     {
63         if (callbackId == 0) {
64             callback = nullptr;
65             return;
66         }
67         callback = CJLambda::Create(reinterpret_cast<void(*)(CProgress)>(callbackId));
68     }
CloseFdCjCallbackObject69     void CloseFd()
70     {
71         if (eventFd != -1) {
72             close(eventFd);
73             eventFd = -1;
74         }
75         if (notifyFd == -1) {
76             return;
77         }
78         for (auto item : wds) {
79             inotify_rm_watch(notifyFd, item.first);
80         }
81         close(notifyFd);
82         notifyFd = -1;
83     }
~CjCallbackObjectCjCallbackObject84     ~CjCallbackObject()
85     {
86         CloseFd();
87     }
88 };
89 
90 struct FileInfos {
91     std::string srcUri;
92     std::string destUri;
93     std::string srcPath;
94     std::string destPath;
95     std::chrono::steady_clock::time_point notifyTime;
96     int32_t notifyFd = -1;
97     int32_t eventFd = -1;
98     bool run = true;
99     bool hasListener = false;
100     int64_t listenerId = 0;
101     int64_t copySignalId = 0;
102     int64_t exceptionCode = FileFs::ERRNO_NOERR;
103     std::shared_ptr<DistributedFS::ModuleTaskSignal::TaskSignal> taskSignal = nullptr;
104     std::set<std::string> filePaths;
105     bool operator==(const FileInfos &infos) const
106     {
107         return (srcUri == infos.srcUri && destUri == infos.destUri);
108     }
109     bool operator<(const FileInfos &infos) const
110     {
111         if (srcUri == infos.srcUri) {
112             return destUri < infos.destUri;
113         }
114         return srcUri < infos.srcUri;
115     }
116 };
117 
118 class CopyInfo : public OHOS::FFI::FFIData {
119     friend class CopyImpl;
120 public:
CopyInfo(int64_t listener,int64_t signal)121     CopyInfo(int64_t listener, int64_t signal) : listenerId(listener), signalId(signal) {}
122     ~CopyInfo();
123 private:
124     int64_t listenerId = 0;
125     int64_t signalId = 0;
126 };
127 
128 class CopyImpl final {
129 public:
130     static std::map<FileInfos, std::shared_ptr<CjCallbackObject>> cjCbMap_;
131     static std::recursive_mutex mutex_;
132     static void UnregisterListener(std::shared_ptr<FileInfos> fileInfos);
133     static void Copy(const char* srcUri, const char* destUri, sptr<CopyInfo> info);
134 private:
135     static int UpdateProgressSize(const std::string &filePath,
136                                   std::shared_ptr<ReceiveInfo> receivedInfo,
137                                   std::shared_ptr<CjCallbackObject> callback);
138     static void StartNotify(std::shared_ptr<FileInfos> infos, std::shared_ptr<CjCallbackObject> callback);
139     static bool IsRemoteUri(const std::string& uri);
140     static int64_t DoCopy(std::shared_ptr<FileInfos> infos, std::shared_ptr<CjCallbackObject> callback);
141     static int64_t ExecLocal(std::shared_ptr<FileInfos>& infos, std::shared_ptr<CjCallbackObject>& callback);
142     static void CloseNotifyFd(std::shared_ptr<FileInfos>& infos, std::shared_ptr<CjCallbackObject>& callback);
143     static void WaitNotifyFinished(std::shared_ptr<CjCallbackObject>& callback);
144     static void CopyComplete(std::shared_ptr<FileInfos>& infos, std::shared_ptr<CjCallbackObject>& callback);
145     static std::shared_ptr<FileInfos> InitCjFileInfo(
146         const std::string& srcUri, const std::string& destUri, sptr<CopyInfo> info);
147     static std::shared_ptr<CjCallbackObject> RegisterListener(std::shared_ptr<FileInfos>& infos);
148     static bool IsFile(const std::string &path);
149     static void CheckOrCreatePath(const std::string &destPath);
150     static int64_t SubscribeLocalListener(std::shared_ptr<FileInfos>& infos,
151                                           std::shared_ptr<CjCallbackObject>& callback);
152     static int ExecCopy(std::shared_ptr<FileInfos> infos);
153     static int CopyFile(const std::string &src, const std::string &dest, std::shared_ptr<FileInfos> infos);
154     static bool IsDirectory(const std::string &path);
155     static std::tuple<int, uint64_t> GetFileSize(const std::string &path);
156     static int MakeDir(const std::string &path);
157     static int CopySubDir(const std::string &srcPath, const std::string &destPath, std::shared_ptr<FileInfos> infos);
158     static int CopyDirFunc(const std::string &src, const std::string &dest, std::shared_ptr<FileInfos> infos);
159     static uint64_t GetDirSize(std::shared_ptr<FileInfos> infos, std::string path);
160     static int RecurCopyDir(const std::string &srcPath, const std::string &destPath, std::shared_ptr<FileInfos> infos);
161     static void GetNotifyEvent(std::shared_ptr<FileInfos> infos);
162     static bool CheckFileValid(const std::string &filePath, std::shared_ptr<FileInfos> infos);
163     static void OnFileReceive(std::shared_ptr<FileInfos> infos);
164     static std::shared_ptr<CjCallbackObject> GetRegisteredListener(std::shared_ptr<FileInfos> infos);
165     static std::shared_ptr<ReceiveInfo> GetReceivedInfo(int wd, std::shared_ptr<CjCallbackObject> callback);
166     static void ReadNotifyEvent(std::shared_ptr<FileInfos> infos);
167     static std::string GetRealPath(const std::string& path);
168     static std::tuple<bool, int, bool> HandleProgress(inotify_event *event,
169                                                  std::shared_ptr<FileInfos> infos,
170                                                  std::shared_ptr<CjCallbackObject> callback);
171     static void ReceiveComplete(CProgress data,
172                                 std::shared_ptr<FileInfos> infos,
173                                 std::shared_ptr<CjCallbackObject> callback);
174 };
175 }
176 }
177 
178 #endif // OHOS_FILE_FS_COPY_H
179