• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FILEMANAGEMENT_FILE_API_COPY_H
17 #define FILEMANAGEMENT_FILE_API_COPY_H
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <set>
22 #include <sys/inotify.h>
23 #include <thread>
24 
25 #include "bundle_mgr_client_impl.h"
26 #include "common_func.h"
27 #include "filemgmt_libn.h"
28 #include "n_async/n_ref.h"
29 #include "task_signal.h"
30 #include "class_tasksignal/task_signal_entity.h"
31 
32 namespace OHOS {
33 namespace FileManagement {
34 namespace ModuleFileIO {
35 using namespace std;
36 using namespace OHOS::FileManagement::LibN;
37 using namespace OHOS::AppExecFwk;
38 using namespace DistributedFS::ModuleTaskSignal;
39 const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF;
40 
41 struct ReceiveInfo {
42     std::string path;                         // dir name
43     std::map<std::string, uint64_t> fileList; // filename, proceededSize
44 };
45 struct JsCallbackObject {
46     napi_env env = nullptr;
47     LibN::NRef nRef;
48     int32_t notifyFd = -1;
49     int32_t eventFd = -1;
50     std::vector<std::pair<int, std::shared_ptr<ReceiveInfo>>> wds;
51     uint64_t totalSize = 0;
52     uint64_t progressSize = 0;
53     uint64_t maxProgressSize = 0;
54     int32_t errorCode = 0;
55     std::thread notifyHandler;
56     std::mutex readMutex;
57     std::condition_variable cv;
58     std::mutex cvLock;
59     bool reading = false;
60     bool closed = false;
JsCallbackObjectJsCallbackObject61     explicit JsCallbackObject(napi_env env, LibN::NVal jsVal) : env(env), nRef(jsVal) {}
62 
CloseFdJsCallbackObject63     void CloseFd()
64     {
65         if (eventFd != -1) {
66             close(eventFd);
67             eventFd = -1;
68         }
69         if (notifyFd == -1) {
70             return;
71         }
72         for (auto item : wds) {
73             inotify_rm_watch(notifyFd, item.first);
74         }
75         close(notifyFd);
76         notifyFd = -1;
77     }
78 
~JsCallbackObjectJsCallbackObject79     ~JsCallbackObject()
80     {
81         CloseFd();
82     }
83 };
84 
85 struct FileInfos {
86     std::string srcUri;
87     std::string destUri;
88     std::string srcPath;
89     std::string destPath;
90     bool isFile = false;
91     std::chrono::steady_clock::time_point notifyTime;
92     int32_t notifyFd = -1;
93     int32_t eventFd = -1;
94     bool run = true;
95     bool hasListener = false;
96     napi_env env;
97     NVal listener;
98     NVal copySignal;
99     std::shared_ptr<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 FileInfos &infos) const
103     {
104         return (srcUri == infos.srcUri && destUri == infos.destUri);
105     }
106     bool operator<(const FileInfos &infos) const
107     {
108         if (srcUri == infos.srcUri) {
109             return destUri < infos.destUri;
110         }
111         return srcUri < infos.srcUri;
112     }
113 };
114 
115 struct UvEntry {
116     std::shared_ptr<JsCallbackObject> callback;
117     std::shared_ptr<FileInfos> fileInfos;
118     uint64_t progressSize = 0;
119     uint64_t totalSize = 0;
UvEntryUvEntry120     UvEntry(const std::shared_ptr<JsCallbackObject> &cb, std::shared_ptr<FileInfos> fileInfos)
121         : callback(cb), fileInfos(fileInfos)
122     {
123     }
UvEntryUvEntry124     explicit UvEntry(const std::shared_ptr<JsCallbackObject> &cb) : callback(cb) {}
125 };
126 
127 class Copy final {
128 public:
129     static napi_value Async(napi_env env, napi_callback_info info);
130     static std::map<FileInfos, std::shared_ptr<JsCallbackObject>> jsCbMap_;
131     static void UnregisterListener(std::shared_ptr<FileInfos> fileInfos);
132     static std::recursive_mutex mutex_;
133 
134 private:
135     // operator of napi
136     static tuple<bool, std::string> ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg);
137     static tuple<bool, NVal> GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg);
138     static tuple<bool, NVal> GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg);
139     static int CheckOrCreatePath(const std::string &destPath);
140     static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr<FileInfos> &fileInfos);
141 
142     // operator of local listener
143     static int ExecLocal(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
144     static void CopyComplete(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
145     static void WaitNotifyFinished(std::shared_ptr<JsCallbackObject> callback);
146     static void ReadNotifyEvent(std::shared_ptr<FileInfos> infos);
147     static void ReadNotifyEventLocked(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
148     static int SubscribeLocalListener(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
149     static std::shared_ptr<JsCallbackObject> RegisterListener(napi_env env, const std::shared_ptr<FileInfos> &infos);
150     static void OnFileReceive(std::shared_ptr<FileInfos> infos);
151     static void GetNotifyEvent(std::shared_ptr<FileInfos> infos);
152     static void StartNotify(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
153     static UvEntry *GetUVwork(std::shared_ptr<FileInfos> infos);
154     static void ReceiveComplete(std::shared_ptr<UvEntry> entry);
155     static std::shared_ptr<JsCallbackObject> GetRegisteredListener(std::shared_ptr<FileInfos> infos);
156     static void CloseNotifyFd(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
157     static void CloseNotifyFdLocked(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
158 
159     // operator of file
160     static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
161     static tuple<int, uint64_t> GetFileSize(const std::string &path);
162     static uint64_t GetDirSize(std::shared_ptr<FileInfos> infos, std::string path);
163     static int CopyFile(const string &src, const string &dest, std::shared_ptr<FileInfos> infos);
164     static int MakeDir(const string &path);
165     static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
166     static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr<FileInfos> infos);
167     static tuple<int, std::shared_ptr<FileInfos>> CreateFileInfos(
168         const std::string &srcUri, const std::string &destUri, NVal &listener, NVal copySignal);
169     static int ExecCopy(std::shared_ptr<FileInfos> infos);
170 
171     // operator of file size
172     static int UpdateProgressSize(const std::string &filePath,
173                                   std::shared_ptr<ReceiveInfo> receivedInfo,
174                                   std::shared_ptr<JsCallbackObject> callback);
175     static tuple<bool, int, bool> HandleProgress(
176         inotify_event *event, std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
177     static std::shared_ptr<ReceiveInfo> GetReceivedInfo(int wd, std::shared_ptr<JsCallbackObject> callback);
178     static bool CheckFileValid(const std::string &filePath, std::shared_ptr<FileInfos> infos);
179 
180     // operator of uri or path
181     static bool IsValidUri(const std::string &uri);
182     static bool IsRemoteUri(const std::string &uri);
183     static bool IsDirectory(const std::string &path);
184     static bool IsFile(const std::string &path);
185     static bool IsMediaUri(const std::string &uriPath);
186     static std::string ConvertUriToPath(const std::string &uri);
187     static std::string GetRealPath(const std::string& path);
188 };
189 } // namespace ModuleFileIO
190 } // namespace FileManagement
191 } // namespace OHOS
192 
193 #endif // FILEMANAGEMENT_FILE_API_COPY_H