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