• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H
17 #define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <set>
22 #include <thread>
23 #include <sys/inotify.h>
24 
25 #include "bundle_mgr_client_impl.h"
26 #include "filemgmt_libfs.h"
27 #include "filemgmt_libhilog.h"
28 #include "fs_task_signal.h"
29 #include "i_progress_listener.h"
30 
31 namespace OHOS {
32 namespace FileManagement {
33 namespace ModuleFileIO {
34 using namespace std;
35 using namespace OHOS::AppExecFwk;
36 using namespace DistributedFS::ModuleTaskSignal;
37 
38 struct CopyOptions {
39     shared_ptr<IProgressListener> progressListener;
40     FsTaskSignal* copySignal = nullptr;
41 };
42 
43 struct ReceiveInfo {
44     std::string path;                         // dir name
45     std::map<std::string, uint64_t> fileList; // filename, proceededSize
46 };
47 
48 struct FsCallbackObject {
49     std::shared_ptr<IProgressListener> listener = nullptr;
50     int32_t notifyFd = -1;
51     int32_t eventFd = -1;
52     std::vector<std::pair<int, std::shared_ptr<ReceiveInfo>>> wds;
53     uint64_t totalSize = 0;
54     uint64_t progressSize = 0;
55     uint64_t maxProgressSize = 0;
56     int32_t errorCode = 0;
57     std::thread notifyHandler;
58     std::mutex readMutex;
59     std::condition_variable cv;
60     std::mutex cvLock;
61     bool reading = false;
62     bool closed = false;
FsCallbackObjectFsCallbackObject63     explicit FsCallbackObject(std::shared_ptr<IProgressListener> listener) : listener(listener) {}
64 
CloseFdFsCallbackObject65     void CloseFd()
66     {
67         if (eventFd != -1) {
68             close(eventFd);
69             eventFd = -1;
70         }
71         if (notifyFd == -1) {
72             return;
73         }
74         for (auto item : wds) {
75             inotify_rm_watch(notifyFd, item.first);
76         }
77         close(notifyFd);
78         notifyFd = -1;
79     }
80 
~FsCallbackObjectFsCallbackObject81     ~FsCallbackObject()
82     {
83         CloseFd();
84     }
85 };
86 
87 struct FsFileInfos {
88     std::string srcUri;
89     std::string destUri;
90     std::string srcPath;
91     std::string destPath;
92     bool isFile = false;
93     std::chrono::steady_clock::time_point notifyTime;
94     int32_t notifyFd = -1;
95     int32_t eventFd = -1;
96     bool run = true;
97     bool hasListener = false;
98     std::shared_ptr<IProgressListener> listener = nullptr;
99     TaskSignal* taskSignal = nullptr;
100     std::set<std::string> filePaths;
101     int exceptionCode = ERRNO_NOERR; // notify copy thread or listener thread has exceptions.
102     bool operator==(const FsFileInfos &infos) const
103     {
104         return (srcUri == infos.srcUri && destUri == infos.destUri);
105     }
106     bool operator<(const FsFileInfos &infos) const
107     {
108         if (srcUri == infos.srcUri) {
109             return destUri < infos.destUri;
110         }
111         return srcUri < infos.srcUri;
112     }
113 };
114 
115 struct FsUvEntry {
116     std::shared_ptr<FsCallbackObject> callback;
117     std::shared_ptr<FsFileInfos> fileInfos;
118     uint64_t progressSize = 0;
119     uint64_t totalSize = 0;
FsUvEntryFsUvEntry120     FsUvEntry(const std::shared_ptr<FsCallbackObject> &cb, std::shared_ptr<FsFileInfos> fileInfos)
121         : callback(cb), fileInfos(fileInfos) {}
122 
FsUvEntryFsUvEntry123     explicit FsUvEntry(const std::shared_ptr<FsCallbackObject> &cb) : callback(cb) {}
124 };
125 
126 class CopyCore final {
127 public:
128     static FsResult<void> DoCopy(const string &src, const string &dest, std::optional<CopyOptions> &options);
129 
130 private:
131     // operator of params
132     static bool ValidOperand(std::string uriStr);
133     static int CheckOrCreatePath(const std::string &destPath);
134     static bool ValidParams(const string &src, const string &dest);
135 
136     // operator of local listener
137     static std::shared_ptr<FsCallbackObject> RegisterListener(const std::shared_ptr<FsFileInfos> &infos);
138     static std::shared_ptr<FsCallbackObject> GetRegisteredListener(std::shared_ptr<FsFileInfos> infos);
139     static void UnregisterListener(std::shared_ptr<FsFileInfos> fileInfos);
140     static int ExecLocal(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
141     static void CopyComplete(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
142     static void WaitNotifyFinished(std::shared_ptr<FsCallbackObject> callback);
143     static void ReadNotifyEvent(std::shared_ptr<FsFileInfos> infos);
144     static void ReadNotifyEventLocked(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
145     static int SubscribeLocalListener(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
146     static void OnFileReceive(std::shared_ptr<FsFileInfos> infos);
147     static void GetNotifyEvent(std::shared_ptr<FsFileInfos> infos);
148     static void StartNotify(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
149     static FsUvEntry *GetUVEntry(std::shared_ptr<FsFileInfos> infos);
150     static void ReceiveComplete(std::shared_ptr<FsUvEntry> entry);
151     static void CloseNotifyFd(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
152     static void CloseNotifyFdLocked(std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
153 
154     // operator of file
155     static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr<FsFileInfos> infos);
156     static tuple<int, uint64_t> GetFileSize(const std::string &path);
157     static uint64_t GetDirSize(std::shared_ptr<FsFileInfos> infos, std::string path);
158     static int CopyFile(const string &src, const string &dest, std::shared_ptr<FsFileInfos> infos);
159     static int MakeDir(const string &path);
160     static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr<FsFileInfos> infos);
161     static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr<FsFileInfos> infos);
162     static tuple<int, std::shared_ptr<FsFileInfos>> CreateFileInfos(
163         const std::string &srcUri, const std::string &destUri, const std::optional<CopyOptions> &options);
164     static int ExecCopy(std::shared_ptr<FsFileInfos> infos);
165 
166     // operator of file size
167     static int UpdateProgressSize(const std::string &filePath, std::shared_ptr<ReceiveInfo> receivedInfo,
168         std::shared_ptr<FsCallbackObject> callback);
169     static tuple<bool, int, bool> HandleProgress(
170         inotify_event *event, std::shared_ptr<FsFileInfos> infos, std::shared_ptr<FsCallbackObject> callback);
171     static std::shared_ptr<ReceiveInfo> GetReceivedInfo(int wd, std::shared_ptr<FsCallbackObject> callback);
172     static bool CheckFileValid(const std::string &filePath, std::shared_ptr<FsFileInfos> infos);
173 
174     // operator of uri or path
175     static bool IsValidUri(const std::string &uri);
176     static bool IsRemoteUri(const std::string &uri);
177     static bool IsDirectory(const std::string &path);
178     static bool IsFile(const std::string &path);
179     static bool IsMediaUri(const std::string &uriPath);
180     static std::string ConvertUriToPath(const std::string &uri);
181     static std::string GetRealPath(const std::string &path);
182 
183     static std::recursive_mutex mutex_;
184     static std::map<FsFileInfos, std::shared_ptr<FsCallbackObject>> callbackMap_;
185 };
186 } // namespace ModuleFileIO
187 } // namespace FileManagement
188 } // namespace OHOS
189 
190 #endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_CORE_H