• 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     uint64_t totalSize = 0;
49     uint64_t progressSize = 0;
50     uint64_t maxProgressSize = 0;
JsCallbackObjectJsCallbackObject51     explicit JsCallbackObject(napi_env env, LibN::NVal jsVal) : env(env), nRef(jsVal) {}
52 };
53 
54 struct FileInfos {
55     std::string srcUri;
56     std::string destUri;
57     std::string srcPath;
58     std::string destPath;
59     bool isFile = false;
60     std::chrono::steady_clock::time_point notifyTime;
61     int32_t notifyFd = -1;
62     int32_t eventFd = -1;
63     bool run = true;
64     bool hasListener = false;
65     napi_env env;
66     NVal listener;
67     NVal copySignal;
68     std::shared_ptr<TaskSignal> taskSignal = nullptr;
69     std::set<std::string> filePaths;
70     int exceptionCode = ERRNO_NOERR;    // notify copy thread or listener thread has exceptions.
71     bool operator==(const FileInfos &infos) const
72     {
73         return (srcUri == infos.srcUri && destUri == infos.destUri);
74     }
75     bool operator<(const FileInfos &infos) const
76     {
77         if (srcUri == infos.srcUri) {
78             return destUri < infos.destUri;
79         }
80         return srcUri < infos.srcUri;
81     }
82 };
83 
84 struct UvEntry {
85     std::shared_ptr<JsCallbackObject> callback;
86     std::shared_ptr<FileInfos> fileInfos;
87     uint64_t progressSize = 0;
88     uint64_t totalSize = 0;
UvEntryUvEntry89     UvEntry(const std::shared_ptr<JsCallbackObject> &cb, std::shared_ptr<FileInfos> fileInfos)
90         : callback(cb), fileInfos(fileInfos)
91     {
92     }
UvEntryUvEntry93     explicit UvEntry(const std::shared_ptr<JsCallbackObject> &cb) : callback(cb) {}
94 };
95 
96 class Copy final {
97 public:
98     static napi_value Async(napi_env env, napi_callback_info info);
99     static std::map<FileInfos, std::shared_ptr<JsCallbackObject>> jsCbMap_;
100     static void UnregisterListener(std::shared_ptr<FileInfos> fileInfos);
101     static std::recursive_mutex mutex_;
102 
103 private:
104     // operator of napi
105     static tuple<bool, std::string> ParseJsOperand(napi_env env, NVal pathOrFdFromJsArg);
106     static tuple<bool, NVal> GetListenerFromOptionArg(napi_env env, const NFuncArg &funcArg);
107     static tuple<bool, NVal> GetCopySignalFromOptionArg(napi_env env, const NFuncArg &funcArg);
108     static int CheckOrCreatePath(const std::string &destPath);
109     static int ParseJsParam(napi_env env, NFuncArg &funcArg, std::shared_ptr<FileInfos> &fileInfos);
110 
111     // operator of local listener
112     static int ExecLocal(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
113     static void CopyComplete(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
114     static void WaitNotifyFinished(std::shared_ptr<JsCallbackObject> callback);
115     static void ReadNotifyEvent(std::shared_ptr<FileInfos> infos);
116     static void ReadNotifyEventLocked(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
117     static int SubscribeLocalListener(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
118     static std::shared_ptr<JsCallbackObject> RegisterListener(napi_env env, const std::shared_ptr<FileInfos> &infos);
119     static void OnFileReceive(std::shared_ptr<FileInfos> infos);
120     static void GetNotifyEvent(std::shared_ptr<FileInfos> infos);
121     static void StartNotify(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
122     static UvEntry *GetUVwork(std::shared_ptr<FileInfos> infos);
123     static void ReceiveComplete(std::shared_ptr<UvEntry> entry);
124     static std::shared_ptr<JsCallbackObject> GetRegisteredListener(std::shared_ptr<FileInfos> infos);
125     static void CloseNotifyFd(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
126     static void CloseNotifyFdLocked(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
127 
128     // operator of file
129     static int RecurCopyDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
130     static tuple<int, uint64_t> GetFileSize(const std::string &path);
131     static uint64_t GetDirSize(std::shared_ptr<FileInfos> infos, std::string path);
132     static int CopyFile(const string &src, const string &dest, std::shared_ptr<FileInfos> infos);
133     static int MakeDir(const string &path);
134     static int CopySubDir(const string &srcPath, const string &destPath, std::shared_ptr<FileInfos> infos);
135     static int CopyDirFunc(const string &src, const string &dest, std::shared_ptr<FileInfos> infos);
136     static tuple<int, std::shared_ptr<FileInfos>> CreateFileInfos(
137         const std::string &srcUri, const std::string &destUri, NVal &listener, NVal copySignal);
138     static int32_t ExecCopy(std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
139 
140     // operator of file size
141     static int UpdateProgressSize(const std::string &filePath,
142                                   std::shared_ptr<ReceiveInfo> receivedInfo,
143                                   std::shared_ptr<JsCallbackObject> callback);
144     static tuple<bool, int, bool> HandleProgress(
145         inotify_event *event, std::shared_ptr<FileInfos> infos, std::shared_ptr<JsCallbackObject> callback);
146     static std::shared_ptr<ReceiveInfo> GetReceivedInfo(int wd, std::shared_ptr<JsCallbackObject> callback);
147     static bool CheckFileValid(const std::string &filePath, std::shared_ptr<FileInfos> infos);
148 
149     // operator of uri or path
150     static bool IsValidUri(const std::string &uri);
151     static bool IsRemoteUri(const std::string &uri);
152     static bool IsDirectory(const std::string &path);
153     static bool IsFile(const std::string &path);
154     static bool IsMediaUri(const std::string &uriPath);
155     static std::string ConvertUriToPath(const std::string &uri);
156     static std::string GetRealPath(const std::string& path);
157 };
158 } // namespace ModuleFileIO
159 } // namespace FileManagement
160 } // namespace OHOS
161 
162 #endif // FILEMANAGEMENT_FILE_API_COPY_H