• 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 <set>
20 #include <sys/inotify.h>
21 #include <thread>
22 #include <chrono>
23 
24 #include "bundle_mgr_client_impl.h"
25 #include "common_func.h"
26 #include "filemgmt_libn.h"
27 #include "n_async/n_ref.h"
28 
29 namespace OHOS {
30 namespace FileManagement {
31 namespace ModuleFileIO {
32 using namespace std;
33 using namespace OHOS::FileManagement::LibN;
34 using namespace OHOS::AppExecFwk;
35 struct ReceiveInfo {
36     std::string path;                         // dir name
37     std::map<std::string, uint64_t> fileList; // filename, proceededSize
38 };
39 struct JsCallbackObject {
40     napi_env env = nullptr;
41     LibN::NRef nRef;
42     int32_t notifyFd = -1;
43     int32_t eventFd = -1;
44     std::vector<std::pair<int, std::shared_ptr<ReceiveInfo>>> wds;
45     uint64_t totalSize = 0;
46     uint64_t progressSize = 0;
47     uint64_t maxProgressSize = 0;
48     std::thread notifyHandler;
JsCallbackObjectJsCallbackObject49     explicit JsCallbackObject(napi_env env, LibN::NVal jsVal) : env(env), nRef(jsVal) {}
50 
CloseFdJsCallbackObject51     void CloseFd()
52     {
53         if (eventFd != -1) {
54             close(eventFd);
55             eventFd = -1;
56         }
57         if (notifyFd == -1) {
58             return;
59         }
60         for (auto item : wds) {
61             inotify_rm_watch(notifyFd, item.first);
62         }
63         close(notifyFd);
64         notifyFd = -1;
65     }
66 
~JsCallbackObjectJsCallbackObject67     ~JsCallbackObject()
68     {
69         CloseFd();
70     }
71 };
72 
73 struct FileInfos {
74     std::string srcUri;
75     std::string destUri;
76     std::string srcPath;
77     std::string destPath;
78     std::chrono::steady_clock::time_point notifyTime;
79     int32_t notifyFd = -1;
80     int32_t eventFd = -1;
81     bool run = true;
82     bool hasListener = false;
83     napi_env env;
84     NVal listener;
85     std::set<std::string> filePaths;
86     int exceptionCode = ERRNO_NOERR;    // notify copy thread or listener thread has exceptions.
87     bool operator==(const FileInfos &infos) const
88     {
89         return (srcUri == infos.srcUri && destUri == infos.destUri);
90     }
91     bool operator<(const FileInfos &infos) const
92     {
93         if (srcUri == infos.srcUri) {
94             return destUri < infos.destUri;
95         }
96         return srcUri < infos.srcUri;
97     }
98 };
99 
100 struct UvEntry {
101     std::shared_ptr<JsCallbackObject> callback;
102     std::shared_ptr<FileInfos> fileInfos;
103     uint64_t progressSize = 0;
104     uint64_t totalSize = 0;
UvEntryUvEntry105     UvEntry(const std::shared_ptr<JsCallbackObject> &cb, std::shared_ptr<FileInfos> fileInfos)
106         : callback(cb), fileInfos(fileInfos)
107     {
108     }
UvEntryUvEntry109     explicit UvEntry(const std::shared_ptr<JsCallbackObject> &cb) : callback(cb) {}
110 };
111 
112 class Copy final {
113 public:
114     static napi_value Async(napi_env env, napi_callback_info info);
115     static std::map<FileInfos, std::shared_ptr<JsCallbackObject>> jsCbMap_;
116     static void UnregisterListener(std::shared_ptr<FileInfos> fileInfos);
117     static std::recursive_mutex mutex_;
118 
119 private:
120     // operator of napi
121     static tuple<bool, std::string> ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg);
122     static tuple<bool, NVal> GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg);
123     static void CheckOrCreatePath(const std::string &destPath);
124     static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr<FileInfos> &fileInfos);
125 
126     // operator of local listener
127     static int ExecLocal(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
128     static void CopyComplete(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
129     static void WaitNotifyFinished(std::shared_ptr<JsCallbackObject> callback);
130     static void ReadNotifyEvent(std::shared_ptr<FileInfos> infos);
131     static int SubscribeLocalListener(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
132     static std::shared_ptr<JsCallbackObject> RegisterListener(napi_env env, const std::shared_ptr<FileInfos> &infos);
133     static void OnFileReceive(std::shared_ptr<FileInfos> infos);
134     static void GetNotifyEvent(std::shared_ptr<FileInfos> infos);
135     static void StartNotify(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
136     static uv_work_t *GetUVwork(std::shared_ptr<FileInfos> infos);
137     static void ReceiveComplete(uv_work_t *work, int stat);
138     static std::shared_ptr<JsCallbackObject> GetRegisteredListener(std::shared_ptr<FileInfos> infos);
139     static void CloseNotifyFd(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
140 
141     // operator of file
142     static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
143     static tuple<int, uint64_t> GetFileSize(const std::string &path);
144     static uint64_t GetDirSize(std::shared_ptr<FileInfos> infos, std::string path);
145     static int CopyFile(const string &src, const string &dest);
146     static int MakeDir(const string &path);
147     static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
148     static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr<FileInfos> infos);
149     static tuple<int, std::shared_ptr<FileInfos>> CreateFileInfos(
150         const std::string &srcUri, const std::string &destUri, NVal &listener);
151     static int ExecCopy(std::shared_ptr<FileInfos> infos);
152 
153     // operator of file size
154     static int UpdateProgressSize(const std::string &filePath,
155                                   std::shared_ptr<ReceiveInfo> receivedInfo,
156                                   std::shared_ptr<JsCallbackObject> callback);
157     static tuple<bool, int, bool> HandleProgress(
158         inotify_event *event, std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
159     static std::shared_ptr<ReceiveInfo> GetReceivedInfo(int wd, std::shared_ptr<JsCallbackObject> callback);
160     static bool CheckFileValid(const std::string &filePath, std::shared_ptr<FileInfos> infos);
161 
162     // operator of uri or path
163     static bool IsValidUri(const std::string &uri);
164     static bool IsRemoteUri(const std::string &uri);
165     static bool IsDirectory(const std::string &path);
166     static bool IsFile(const std::string &path);
167     static std::string ConvertUriToPath(const std::string &uri);
168     static std::string GetRealPath(const std::string& path);
169 };
170 } // namespace ModuleFileIO
171 } // namespace FileManagement
172 } // namespace OHOS
173 
174 #endif // FILEMANAGEMENT_FILE_API_COPY_H
175