diff --git a/filemanagement_aafwk.gni b/filemanagement_aafwk.gni index 67a8ad862c7f5e85144356a55cfbb5e43ed5ec07..8524a52686d6b15a35d6901348c33c91c8fb88de 100644 --- a/filemanagement_aafwk.gni +++ b/filemanagement_aafwk.gni @@ -17,3 +17,9 @@ ability_runtime_kits_path = "${ability_runtime_path}/frameworks/kits" ability_runtime_services_path = "${ability_runtime_path}/services" ability_runtime_napi_path = "${ability_runtime_path}/frameworks/js/napi" access_token_path = "//base/security/access_token" +foundation_f = "/f" +foundation_oundation = "oundation" +filemanagement = "filemanagement" +file_api = "file_api" +file_api_path = + "/${foundation_f}${foundation_oundation}/${filemanagement}/${file_api}" diff --git a/frameworks/innerkits/file_access/include/file_access_ext_ability.h b/frameworks/innerkits/file_access/include/file_access_ext_ability.h index 158b689573f8598bc5a4f3814822922c4021226d..83722e756032ac9dbedbb9d5a1b6662a20a425f0 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_ability.h @@ -47,6 +47,7 @@ public: virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile); virtual int Delete(const Uri &sourceFile); virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile); + virtual int Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result); virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile); virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec); @@ -67,4 +68,4 @@ private: }; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_ACCESS_EXT_ABILITY_H \ No newline at end of file +#endif // FILE_ACCESS_EXT_ABILITY_H diff --git a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h index 8c079705b0f23a7c0a2d20e0c6d6e48bc525aa61..a75e632d3a2f2131f4ebb082db23beba988fb565 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_proxy.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_proxy.h @@ -41,6 +41,7 @@ public: virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; virtual int Delete(const Uri &sourceFile) override; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + virtual int Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) override; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) override; diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub.h b/frameworks/innerkits/file_access/include/file_access_ext_stub.h index 3c42652f3bf698e1f013cda9d9b00f313b49e1bb..d8800b6949ea1b470f22141c8c5bf9561bb9a266 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub.h @@ -40,6 +40,7 @@ private: ErrCode CmdMkdir(MessageParcel &data, MessageParcel &reply); ErrCode CmdDelete(MessageParcel &data, MessageParcel &reply); ErrCode CmdMove(MessageParcel &data, MessageParcel &reply); + ErrCode CmdCopy(MessageParcel &data, MessageParcel &reply); ErrCode CmdRename(MessageParcel &data, MessageParcel &reply); ErrCode CmdListFile(MessageParcel &data, MessageParcel &reply); ErrCode CmdScanFile(MessageParcel &data, MessageParcel &reply); @@ -55,4 +56,4 @@ private: }; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_ACCESS_EXT_STUB_H \ No newline at end of file +#endif // FILE_ACCESS_EXT_STUB_H diff --git a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h index 281c254211d5ec077c67b0a6f5e50a025c0b1d05..8785db6568fac477043fff46d6577dd35c0fe447 100644 --- a/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h +++ b/frameworks/innerkits/file_access/include/file_access_ext_stub_impl.h @@ -39,6 +39,7 @@ public: int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + int Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) override; @@ -57,4 +58,4 @@ private: }; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_ACCESS_EXT_STUB_IMPL_H \ No newline at end of file +#endif // FILE_ACCESS_EXT_STUB_IMPL_H diff --git a/frameworks/innerkits/file_access/include/file_access_extension_info.h b/frameworks/innerkits/file_access/include/file_access_extension_info.h index d1bfd225d6633dff9c553d9fd2da38369044a109..613313b4ea89f5873400ff0de0d3b57fbe7b5226 100644 --- a/frameworks/innerkits/file_access/include/file_access_extension_info.h +++ b/frameworks/innerkits/file_access/include/file_access_extension_info.h @@ -169,6 +169,54 @@ public: return info; } }; + +struct CopyResult : public virtual OHOS::Parcelable { +public: + std::string uri { "" }; + int32_t errCode { 0 }; + std::string errMsg { "" }; + + CopyResult() = default; + CopyResult(std::string uri, int32_t errCode, std::string errMsg) + : uri(uri), errCode(errCode), errMsg(errMsg) + {} + + bool ReadFromParcel(Parcel &parcel) + { + uri = parcel.ReadString(); + errCode = parcel.ReadInt32(); + errMsg = parcel.ReadString(); + return true; + } + + virtual bool Marshalling(Parcel &parcel) const override + { + if (!parcel.WriteString(uri)) { + return false; + } + if (!parcel.WriteInt32(errCode)) { + return false; + } + if (!parcel.WriteString(errMsg)) { + return false; + } + return true; + } + + static CopyResult *Unmarshalling(Parcel &parcel) + { + CopyResult *result = new (std::nothrow)CopyResult(); + if (result == nullptr) { + return nullptr; + } + + if (!result->ReadFromParcel(parcel)) { + delete result; + result = nullptr; + } + return result; + } +}; } // namespace FileAccessFwk } // namespace OHOS #endif // FILE_ACCESS_EXTENSION_INFO_H \ No newline at end of file diff --git a/frameworks/innerkits/file_access/include/file_access_helper.h b/frameworks/innerkits/file_access/include/file_access_helper.h index 30af9962d15f2992befb0f0aea16b96c5c636e9d..1f1d6e60753fdcad0d6344cb8dfdf9037b8552b7 100644 --- a/frameworks/innerkits/file_access/include/file_access_helper.h +++ b/frameworks/innerkits/file_access/include/file_access_helper.h @@ -75,6 +75,7 @@ public: int Mkdir(Uri &parent, const std::string &displayName, Uri &newDir); int Delete(Uri &selectFile); int Move(Uri &sourceFile, Uri &targetParent, Uri &newFile); + int Copy(Uri &sourceUri, Uri &destUri, std::vector ©Result); int Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile); int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec); @@ -100,6 +101,10 @@ private: std::shared_ptr GetConnectInfo(const std::string &bundleName); + int CopyInMediaOrExternal(Uri &sourceUri, Uri &destUri, std::vector ©Result); + int CopyToMediaLibrary(Uri& sourceUri, Uri& destUri, std::vector& copyResult); + int CopyToExternalStorage(Uri& sourceUri, Uri& destUri, std::vector& copyResult); + sptr token_ = nullptr; std::unordered_map> cMap_; diff --git a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h index 7b17c1639b857a06295e9572b9e6c02d65444f96..a8a1656f7540e5d96c32b7ff6722d6b24beaf6e5 100644 --- a/frameworks/innerkits/file_access/include/ifile_access_ext_base.h +++ b/frameworks/innerkits/file_access/include/ifile_access_ext_base.h @@ -41,6 +41,7 @@ public: CMD_MKDIR, CMD_DELETE, CMD_MOVE, + CMD_COPY, CMD_RENAME, CMD_LIST_FILE, CMD_SCAN_FILE, @@ -57,6 +58,7 @@ public: virtual int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) = 0; virtual int Delete(const Uri &sourceFile) = 0; virtual int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) = 0; + virtual int Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) = 0; virtual int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) = 0; virtual int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) = 0; diff --git a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h index 8c3eb4d9f05f82a4472e2dc0cd3b36f79214d6c7..c884b61d3e949337644b2cd8128446674f3a30ac 100644 --- a/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h +++ b/frameworks/innerkits/file_access/include/js_file_access_ext_ability.h @@ -65,6 +65,7 @@ public: int Mkdir(const Uri &parent, const std::string &displayName, Uri &newFile) override; int Delete(const Uri &sourceFile) override; int Move(const Uri &sourceFile, const Uri &targetParent, Uri &newFile) override; + int Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) override; int Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) override; int ListFile(const FileInfo &fileInfo, const int64_t offset, const int64_t maxCount, const FileFilter &filter, std::vector &fileInfoVec) override; @@ -84,4 +85,4 @@ private: }; } // namespace FileAccessFwk } // namespace OHOS -#endif // JS_FILE_ACCESS_EXT_ABILITY_H \ No newline at end of file +#endif // JS_FILE_ACCESS_EXT_ABILITY_H diff --git a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp index 5c6fedc4f315ba755dd5f7fd36fb660b50851f95..3164a2a7296d1a82d4eee377190599c50a5784a4 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_ability.cpp @@ -91,6 +91,12 @@ int FileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, U return EPERM; } +int FileAccessExtAbility::Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) +{ + HILOG_ERROR("FileAccessExtAbility::Copy Undefined operation"); + return EPERM; +} + int FileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) { HILOG_ERROR("FileAccessExtAbility::Rename Undefined operation"); @@ -194,4 +200,4 @@ int FileAccessExtAbility::Notify(const NotifyMessage& message) return ret; } } // namespace FileAccessFwk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp index 04caffb001e97dc78f78eaf167a8cfa35a030d5a..c17e9e73e241d30fdb67fa6cb1790b9b0da18098 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_proxy.cpp @@ -307,6 +307,64 @@ int FileAccessExtProxy::Move(const Uri &sourceFile, const Uri &targetParent, Uri return ERR_OK; } +int FileAccessExtProxy::Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) +{ + HILOG_ERROR("FileAccessExtProxy::Copy -------- Enter"); + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Copy"); + MessageParcel data; + if (!data.WriteInterfaceToken(FileAccessExtProxy::GetDescriptor())) { + HILOG_ERROR("WriteInterfaceToken failed"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + if (!data.WriteParcelable(&sourceUri)) { + HILOG_ERROR("fail to WriteParcelable uri"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + if (!data.WriteParcelable(&destUri)) { + HILOG_ERROR("fail to WriteParcelable targetParent"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + MessageParcel reply; + MessageOption option; + int err = Remote()->SendRequest(CMD_COPY, data, reply, option); + if (err != ERR_OK) { + HILOG_ERROR("fail to SendRequest. err: %{public}d", err); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return err; + } + + int copyRet = E_IPCS; + if (!reply.ReadInt32(copyRet)) { // Copy 返回值 + HILOG_ERROR("fail to ReadInt32 ret"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + int count = 0; + if (!reply.ReadInt32(count)) { // vector元素个数 + HILOG_ERROR("Copy operation failed to Read count"); + return E_IPCS; + } + + copyResult.clear(); + for (int i = 0; i < count; i++) { // read CopyResult + std::unique_ptr copyResultPtr(reply.ReadParcelable()); + if (copyResultPtr != nullptr) { + copyResult.push_back(std::move(*copyResultPtr)); + } + } + + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return copyRet; + +} + int FileAccessExtProxy::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Rename"); diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp index a5ba5dcf0b34c3094c40df8b8bd47360d47fd4b8..5efbc5a9d2d3cc0a42f6cffdec2337093c738cfd 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub.cpp @@ -45,6 +45,7 @@ FileAccessExtStub::FileAccessExtStub() stubFuncMap_[CMD_MKDIR] = &FileAccessExtStub::CmdMkdir; stubFuncMap_[CMD_DELETE] = &FileAccessExtStub::CmdDelete; stubFuncMap_[CMD_MOVE] = &FileAccessExtStub::CmdMove; + stubFuncMap_[CMD_COPY] = &FileAccessExtStub::CmdCopy; stubFuncMap_[CMD_RENAME] = &FileAccessExtStub::CmdRename; stubFuncMap_[CMD_LIST_FILE] = &FileAccessExtStub::CmdListFile; stubFuncMap_[CMD_SCAN_FILE] = &FileAccessExtStub::CmdScanFile; @@ -270,6 +271,53 @@ ErrCode FileAccessExtStub::CmdMove(MessageParcel &data, MessageParcel &reply) return ERR_OK; } +ErrCode FileAccessExtStub::CmdCopy(MessageParcel &data, MessageParcel &reply) +{ + HILOG_ERROR("FileAccessExtStub::Copy -------- Enter"); + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdCopy"); + std::shared_ptr sourceUri(data.ReadParcelable()); + if (sourceUri == nullptr) { + HILOG_ERROR("Parameter Copy fail to ReadParcelable sourceUri"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + std::shared_ptr destUri(data.ReadParcelable()); + if (destUri == nullptr) { + HILOG_ERROR("Parameter Copy fail to ReadParcelable destUri"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + std::vector copyResult; + int ret = Copy(*sourceUri, *destUri, copyResult); + if (!reply.WriteInt32(ret)) { + HILOG_ERROR("fail to WriteInt32 value of copy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + if (!reply.WriteInt32(copyResult.size())) { + HILOG_ERROR("fail to WriteParcelable size of copy result"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + for (auto &cr: copyResult) { + if (!reply.WriteParcelable(&cr)) { + HILOG_ERROR("fail to WriteParcelable CopyResult"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + HILOG_DEBUG("copyResult.uri: %{public}s", cr.uri.c_str()); + HILOG_DEBUG("copyResult.errCode: %{public}d", cr.errCode); + HILOG_DEBUG("copyResult.errMsg: %{public}s", cr.errMsg.c_str()); + } + + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_OK; +} + ErrCode FileAccessExtStub::CmdRename(MessageParcel &data, MessageParcel &reply) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CmdRename"); @@ -607,4 +655,4 @@ ErrCode FileAccessExtStub::CmdUnregisterNotify(MessageParcel &data, MessageParce return ERR_OK; } } // namespace FileAccessFwk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp index 355ac1b70513999481fb8afaabf6182e3c537033..a5b592d52172c7c06e79cff0af271dfc80def628 100644 --- a/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp +++ b/frameworks/innerkits/file_access/src/file_access_ext_stub_impl.cpp @@ -98,6 +98,21 @@ int FileAccessExtStubImpl::Move(const Uri &sourceFile, const Uri &targetParent, return ret; } +int FileAccessExtStubImpl::Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) +{ + HILOG_ERROR("FileAccessExtStubImpl::Copy -------- Enter"); + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Copy"); + if (extension_ == nullptr) { + HILOG_ERROR("Copy get extension failed."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + int ret = extension_->Copy(sourceUri, destUri, copyResult); + HILOG_DEBUG("Copy return value is %{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; +} + int FileAccessExtStubImpl::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Rename"); @@ -234,4 +249,4 @@ int FileAccessExtStubImpl::UnregisterNotify(sptr ¬ify) return ret; } } // namespace FileAccessFwk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/file_access_helper.cpp b/frameworks/innerkits/file_access/src/file_access_helper.cpp index 117c3882fa2afc1416778cf29d1034e531251107..ff90b06d054bf52e48af30bb8810a703331cfe7b 100644 --- a/frameworks/innerkits/file_access/src/file_access_helper.cpp +++ b/frameworks/innerkits/file_access/src/file_access_helper.cpp @@ -14,6 +14,15 @@ */ #include "file_access_helper.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "bundle_constants.h" #include "bundle_mgr_proxy.h" @@ -30,6 +39,17 @@ namespace OHOS { namespace FileAccessFwk { std::vector FileAccessHelper::wants_; +const std::string ROOT_MEDIA_DIR = "/storage/media/local/files"; +const std::string ROOT_EXTERNAL_DIR = "/data/storage/el1/bundle/storage_daemon"; +const std::string EXTERNAL_BUNDLE_NAME = "com.ohos.UserFile.NotExistBundleName"; + +sptr externalFileExtProxy; +sptr mediaFileExtProxy; + +enum CopyDirection { + MEDIALIBRARY_TO_EXTERNALSTORAGE, + EXTERNALSTORAGE_TO_MEDIALIBRARY, +}; static int GetUserId() { @@ -61,8 +81,11 @@ static bool GetBundleNameFromPath(const std::string &path, std::string &bundleNa static bool CheckUri(Uri &uri) { - HILOG_DEBUG("Uri : %{public}s.", uri.ToString().c_str()); + //HILOG_DEBUG("Uri : %{public}s.", uri.ToString().c_str()); + //std::string schemeStr = std::string(uri.GetScheme()); + HILOG_INFO("Uri : %{public}s.", uri.ToString().c_str()); // TODO: delete 3 lines std::string schemeStr = std::string(uri.GetScheme()); + HILOG_INFO("schemeStr : %{public}s.", schemeStr.c_str()); if (schemeStr.compare(SCHEME_NAME) != 0) { HILOG_ERROR("Uri scheme error."); return false; @@ -593,6 +616,328 @@ int FileAccessHelper::Move(Uri &sourceFile, Uri &targetParent, Uri &newFile) return ERR_OK; } +bool IsMediaUri(Uri &uri) +{ + HILOG_DEBUG("IsMediaUri uri: %{public}s", uri.ToString().c_str()); + string path = uri.GetPath(); + HILOG_DEBUG("IsMediaUri path: %{public}s", path.c_str()); + std::size_t len = MEDIA_BNUDLE_NAME_ALIAS.length(); + if (path.length() > len) { + string media = path.substr(1, len); + return (media == MEDIA_BNUDLE_NAME_ALIAS); + } + return false; +} + +bool IsDirectory(sptr proxy, Uri &uri) +{ + FileAccessFwk::FileInfo fileInfo; + int ret = proxy->GetFileInfoFromUri(uri, fileInfo); + if (ret != ERR_FAF_SUCCESS) { + HILOG_ERROR("get FileInfo from uri error, code:%{public}d", ret); + return false; + } + if (fileInfo.mode & DOCUMENT_FLAG_REPRESENTS_DIR) { + HILOG_DEBUG("%{public}s is not dir", uri.ToString().c_str()); + return true; + } + return false; +} + +std::string GetDisplayName(sptr proxy, Uri &uri) +{ + FileAccessFwk::FileInfo fileInfo; + int ret = proxy->GetFileInfoFromUri(uri, fileInfo); + if (ret != ERR_FAF_SUCCESS) { + HILOG_ERROR("get FileInfo from uri error, code:%{public}d", ret); + return ""; + } + + return fileInfo.fileName; +} + +bool GetAbsolutePathByUri(sptr proxy, Uri &uri, string &absPath) +{ + FileAccessFwk::FileInfo fileInfo; + int ret = proxy->GetFileInfoFromUri(uri, fileInfo); + if (ret != ERR_FAF_SUCCESS) { + HILOG_ERROR("get FileInfo from uri error, code:%{public}d", ret); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return false; + } + + std::string path = fileInfo.relativePath + "/" + fileInfo.fileName; + if ((path.length() >= PATH_MAX)) { + HILOG_ERROR("path len is error, the len is: [%{public}zu]", path.length()); + return false; + } + + char tmpPath[PATH_MAX] = {0}; + if (realpath(path.c_str(), tmpPath) == nullptr) { + if (IsMediaUri(uri)) { + absPath = ROOT_MEDIA_DIR + '/' + fileInfo.relativePath + "/" + fileInfo.fileName; + } else { + absPath = ROOT_EXTERNAL_DIR + '/' + fileInfo.relativePath + "/" + fileInfo.fileName; + } + return true; + } + absPath = tmpPath; + return true; +} + +int GetUriByRelativePath(sptr proxy, std::string &pathname, Uri &uri) +{ + FileInfo fileInfo; + int ret = proxy->GetFileInfoFromRelativePath(pathname, fileInfo); + if (ret != ERR_FAF_SUCCESS) { + HILOG_ERROR("GetFileInfoFromRelativePath get result error, code:%{public}d", ret); + return ret; + } + + Uri tmpUri {fileInfo.uri}; + uri = tmpUri; + return ERR_FAF_SUCCESS; +} + +// single file copy +// copy source file to dest directory + +int CopyFile(std::string &sourcePath, Uri &destUri, Uri &newUri, CopyDirection direction) +{ + HILOG_DEBUG("FileAccessHelper::CopyFileTo Enter"); + sptr proxy; + if (direction == CopyDirection::MEDIALIBRARY_TO_EXTERNALSTORAGE) { + proxy = externalFileExtProxy; + } else if (direction == CopyDirection::EXTERNALSTORAGE_TO_MEDIALIBRARY) { + proxy = mediaFileExtProxy; + } + + int rFd = open(sourcePath.c_str(), O_RDONLY); + if (rFd < 0) { + HILOG_ERROR("OpenFile get result error, code:%{public}d", rFd); + return rFd; + } + + std::string sourceFileName; + auto pos = sourcePath.rfind('/'); + if (pos != std::string::npos) { + sourceFileName = sourcePath.substr(pos + 1); + } + + int ret = proxy->CreateFile(destUri, sourceFileName, newUri); + if (ret != ERR_FAF_SUCCESS) { + // TODO: 判断是否成功,也许有同名文件 + HILOG_ERROR("OpenFile get result error, code:%{public}d", ret); + return ret; + } + HILOG_DEBUG("CopyFile: sourceFileName = %{public}s", sourceFileName.c_str()); + + int wFd; + ret = proxy->OpenFile(newUri, WRITE, wFd); + if (ret != ERR_FAF_SUCCESS) { + HILOG_ERROR("OpenFile get result error, code:%{public}d", ret); + return ret; + } + + struct stat statBuf; + if ((ret = fstat(rFd, &statBuf)) < 0) { + return ret; + } + + int64_t size = statBuf.st_size; + HILOG_DEBUG("CopyFile: size = %{public}" PRId64, size); + if ((ret = sendfile(wFd, rFd, 0, size) < 0)) { + return ret; + } + HILOG_DEBUG("FileAccessHelper::CopyFileTo Exit"); + return ERR_FAF_SUCCESS; +} + +int CopyDirectory(std::string &sourcePath, Uri &destUri, std::vector ©Result, CopyDirection direction) +{ + HILOG_DEBUG("CopyDirectory ---------------------- Enter"); + sptr proxy; + if (direction == CopyDirection::MEDIALIBRARY_TO_EXTERNALSTORAGE) { + proxy = externalFileExtProxy; + } else if (direction == CopyDirection::EXTERNALSTORAGE_TO_MEDIALIBRARY) { + proxy = mediaFileExtProxy; + } + + DIR *dir; + struct dirent *dirent; + if ((dir = opendir(sourcePath.c_str())) == nullptr ) { + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_FAF_FAIL; + } + + HILOG_DEBUG("CopyDirectory ---------------------- zhufeng"); + int ret = ERR_FAF_FAIL; + while((dirent = readdir(dir)) != nullptr) { + if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { + continue; + } + + struct stat statBuf; + std::string sPath = sourcePath + dirent->d_name; + if (stat(sPath.c_str(), &statBuf) < 0) { + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ERR_FAF_FAIL; + } + HILOG_DEBUG("CopyDirectory: sPath = %{public}s", sPath.c_str()); + + if (S_ISDIR(statBuf.st_mode)) { + Uri dUri {""}; + proxy->Mkdir(destUri, dirent->d_name, dUri); + ret = CopyDirectory(sPath, dUri, copyResult, direction); // 递归 + } else if (S_ISREG(statBuf.st_mode)) { + Uri newUri {""}; + ret = CopyFile(sPath, destUri, newUri, CopyDirection::MEDIALIBRARY_TO_EXTERNALSTORAGE); + } + } + closedir(dir); + HILOG_DEBUG("CopyDirectory ---------------------- Exit"); + return ret; +} + +// form media library to external storage +int FileAccessHelper::CopyToExternalStorage(Uri &sourceUri, Uri &destUri, std::vector ©Result) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CopyToExternalStorage"); + mediaFileExtProxy = GetProxyByUri(sourceUri); + if (mediaFileExtProxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + externalFileExtProxy = GetProxyByUri(destUri); + if (externalFileExtProxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + HILOG_DEBUG("CopyToExternalStorage ---------------------- zhufeng"); + int ret = ERR_FAF_FAIL; + Uri newUri {""}; + std::string sourcePath; + GetAbsolutePathByUri(mediaFileExtProxy, sourceUri, sourcePath); + HILOG_DEBUG("CopyToExternalStorage : sourcePath = %{public}s", sourcePath.c_str()); + if (IsDirectory(mediaFileExtProxy, sourceUri)) { // copy directory + std::string srcDisplayName = GetDisplayName(mediaFileExtProxy, sourceUri); + HILOG_DEBUG("CopyToExternalStorage : srcDisplayName = %{public}s", srcDisplayName.c_str()); + externalFileExtProxy->Mkdir(destUri, srcDisplayName, newUri); + // TODO: 判断是否成功,也许有同名目录 + ret = CopyDirectory(sourcePath, newUri, copyResult, CopyDirection::MEDIALIBRARY_TO_EXTERNALSTORAGE); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + } else { // copy file + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + HILOG_DEBUG("sourceUri: %{public}s, destUri: %{public}s", sourceUri.ToString().c_str(), destUri.ToString().c_str()); + ret = CopyFile(sourcePath, destUri, newUri, CopyDirection::MEDIALIBRARY_TO_EXTERNALSTORAGE); + } + return ret; +} + +int FileAccessHelper::CopyToMediaLibrary(Uri &sourceUri, Uri &destUri, std::vector ©Result) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "CopyToMediaLibrary"); + externalFileExtProxy = GetProxyByUri(sourceUri); + if (externalFileExtProxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + mediaFileExtProxy = GetProxyByUri(destUri); + if (mediaFileExtProxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + + HILOG_DEBUG("CopyToMediaLibrary ---------------------- zhufeng"); + //datashare:///com.ohos.UserFile.ExternalFileManager/data/storage/el1/bundle/storage_daemon/dir/filename + // const BUNDLE_NAME = 'com.ohos.UserFile.ExternalFileManager'; + int ret = ERR_FAF_FAIL; + Uri newUri {""}; + std::string sourcePath; + GetAbsolutePathByUri(externalFileExtProxy, sourceUri, sourcePath); + HILOG_DEBUG("CopyToMediaLibrary : sourcePath = %{public}s", sourcePath.c_str()); + if (IsDirectory(externalFileExtProxy, sourceUri)) { // copy directory + std::string srcDisplayName = GetDisplayName(externalFileExtProxy, sourceUri); + HILOG_DEBUG("CopyToMediaLibrary : srcDisplayName = %{public}s", srcDisplayName.c_str()); + mediaFileExtProxy->Mkdir(destUri, srcDisplayName, newUri); + // TODO: 判断是否成功,也许有同名目录 + ret = CopyDirectory(sourcePath, newUri, copyResult, CopyDirection::EXTERNALSTORAGE_TO_MEDIALIBRARY); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + } else { // copy file + HILOG_DEBUG("sourceUri: %{public}s, destUri: %{public}s", sourceUri.ToString().c_str(), destUri.ToString().c_str()); + ret = CopyFile(sourcePath, destUri, newUri, CopyDirection::EXTERNALSTORAGE_TO_MEDIALIBRARY); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + } + return ret ; +} + +int FileAccessHelper::CopyInMediaOrExternal(Uri &sourceUri, Uri &destUri, std::vector ©Result) +{ + HILOG_DEBUG("FileAccessHelper::CopyInMediaOrExternal Enter"); + sptr proxy = GetProxyByUri(sourceUri); + if (proxy == nullptr) { + HILOG_ERROR("failed with invalid fileAccessExtProxy"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_IPCS; + } + HILOG_DEBUG("CopyInMediaOrExternal ---------------------- zhufeng"); + int ret = proxy->Copy(sourceUri, destUri, copyResult); + if (ret != ERR_FAF_SUCCESS) { + HILOG_INFO("Copy error, code:%{public}d", ret); + } + HILOG_DEBUG("FileAccessHelper::CopyInMediaOrExternal Exit"); + return ret; +} + +int FileAccessHelper::Copy(Uri &sourceUri, Uri &destUri, std::vector ©Result) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Copy"); + HILOG_ERROR("sourceUri: %{public}s, destUri: %{public}s", sourceUri.ToString().c_str(), destUri.ToString().c_str()); + if (!IsSystemApp()) { + HILOG_ERROR("FileAccessHelper::Copy check IsSystemAppByFullTokenID failed"); + return E_PERMISSION_SYS; + } + + if (!CheckUri(sourceUri)) { + HILOG_ERROR("sourceUri(%{public}s) format check error.", sourceUri.ToString().c_str()); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_URIS; + } + if (!CheckUri(destUri)) { + HILOG_ERROR("destUri(%{public}s) format check error.", destUri.ToString().c_str()); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return E_URIS; + } + + HILOG_DEBUG("ready to copy"); + int ret = ERR_FAF_FAIL; + if ((IsMediaUri(sourceUri) && IsMediaUri(destUri)) + || (!IsMediaUri(sourceUri) && !IsMediaUri(destUri))) { // external to external, media to media + HILOG_DEBUG("CopyInMediaOrExternal"); + ret = CopyInMediaOrExternal(sourceUri, destUri, copyResult); + } else if (IsMediaUri(sourceUri) && !IsMediaUri(destUri)) { // media to external + HILOG_DEBUG("CopyToExternalStorage"); + ret = CopyToExternalStorage(sourceUri, destUri, copyResult); + } else if (!IsMediaUri(sourceUri) && IsMediaUri(destUri)) { // external to media + HILOG_DEBUG("CopyToMediaLibrary"); + ret = CopyToMediaLibrary(sourceUri, destUri, copyResult); + } + for (auto cr : copyResult) { + HILOG_ERROR("Copy: cr.uri = %{public}s", cr.uri.c_str()); + HILOG_ERROR("Copy: cr.errCode = %{public}d", cr.errCode); + HILOG_ERROR("Copy: cr.errMsg = %{public}s", cr.errMsg.c_str()); + } + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return ret; +} + int FileAccessHelper::Rename(Uri &sourceFile, const std::string &displayName, Uri &newFile) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Rename"); @@ -954,4 +1299,4 @@ FileAccessDeathRecipient::~FileAccessDeathRecipient() { } } // namespace FileAccessFwk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp index b0e3b877563bf1dd22068a2f8ee75659f0b23db7..e9b1e8f7e7338c836316c22015524ca4e6662637 100644 --- a/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp +++ b/frameworks/innerkits/file_access/src/js_file_access_ext_ability.cpp @@ -635,6 +635,187 @@ int JsFileAccessExtAbility::Move(const Uri &sourceFile, const Uri &targetParent, return ERR_OK; } +// { external storage error code, { FAF error code, error message } } +enum { + E_PERM = 1, + E_NOENT, + E_SRCH, + E_INTR, + E_IO, + E_NXIO, + E_2BIG, + E_BADF, + E_CHILD, + E_AGAIN, + E_NOMEM, + E_ACCES, + E_FAULT, + E_BUSY, + E_EXIST, + E_XDEV, + E_NODEV, + E_NOTDIR, + E_ISDIR, + E_INVAL, + E_NFILE, + E_MFILE, + E_TXTBSY, + E_FBIG, + E_NOSPC, + E_SPIPE, + E_ROFS, + E_MLINK, + E_DEADLK, + E_NAMETOOLONG, + E_NOSYS, + E_NOTEMPTY, + E_LOOP, + E_WOULDBLOCK, + E_BADR, + E_NOSTR, + E_NODATA, + E_OVERFLOW, + E_BADFD, + E_RESTART, + E_DQUOT, + E_UKERR, + E_NOLCK +}; +constexpr int FILEIO_BASE_ERR = 13900000; +const std::unordered_map> extFAFErrCodeMap { + { ERR_OK, { OHOS::FileAccessFwk::ERR_FAF_SUCCESS, "Copy succeed" } }, + //{ ERR_ERROR, { OHOS::FileAccessFwk::ERR_FAF_FAIL, "Copy failed" } }, + { FILEIO_BASE_ERR + E_PERM, { OHOS::FileAccessFwk::ERR_FAF_PERM, "" } }, + { FILEIO_BASE_ERR + E_NOENT, { OHOS::FileAccessFwk::ERR_FAF_NOENT, "" } }, + { FILEIO_BASE_ERR + E_EXIST, { OHOS::FileAccessFwk::ERR_FAF_EXIST, "" } }, + { FILEIO_BASE_ERR + E_NOMEM, { OHOS::FileAccessFwk::ERR_FAF_NOMEM, "" } }, + //{ FILEIO_BASE_ERR + E_BADF, { OHOS::FileAccessFwk::ERR_FAF_BADF, "Bad file descriptor" } }, + { FILEIO_BASE_ERR + E_NOTDIR, { OHOS::FileAccessFwk::ERR_FAF_NOTDIR, "Not a directory" } }, + { FILEIO_BASE_ERR + E_ISDIR, { OHOS::FileAccessFwk::ERR_FAF_NOTDIR, "Is a directory" } }, +}; + +std::pair TranslateErrCodeToFAF(int32_t errCode) +{ + int32_t code; + std::string msg; + if (extFAFErrCodeMap.find(errCode) != extFAFErrCodeMap.end()) { + code = extFAFErrCodeMap.at(errCode).first; + if (extFAFErrCodeMap.at(errCode).second.empty()) { + int32_t fafErrCode =extFAFErrCodeMap.at(errCode).first; + msg = FAFErrCodeTable.at(fafErrCode); + } else { + msg = extFAFErrCodeMap.at(errCode).second; + } + } else { + code = errCode; + msg = ""; + } + return std::make_pair(code, msg); +} + +void FillCopyResult(CopyResult &cr, int32_t errCode, std::string uri) +{ + cr.uri = uri; + std::tie(cr.errCode, cr.errMsg) = TranslateErrCodeToFAF(errCode); +} + +static bool ParserGetJsCopyResult(NativeEngine &engine, NativeValue *nativeValue, std::vector &result, int32_t retVal) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "ParserGetJsCopyResult"); + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult ----------------> Enter"); + NativeObject *obj = ConvertNativeValueTo(nativeValue); + if (obj == nullptr) { + HILOG_ERROR("Convert js object fail."); + return false; + } + + bool ret = ConvertFromJsValue(engine, obj->GetProperty("code"), retVal); + NativeArray *nativeArray = ConvertNativeValueTo(obj->GetProperty("result")); + if (!ret || nativeArray == nullptr) { + HILOG_ERROR("nativeArray is nullptr"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + // FIXME: 转换失败,返回什么好 + return false; + } + + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult Line: %{public}d", __LINE__); + for (uint32_t i = 0; i < nativeArray->GetLength(); i++) { + NativeValue *nativeCopyResult = nativeArray->GetElement(i); + if (nativeCopyResult == nullptr) { + HILOG_ERROR("get native FileInfo fail."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + // FIXME: 获取元素失败,返回什么好 + return false; + } + + obj = ConvertNativeValueTo(nativeCopyResult); // ????????????????????????? + if (obj == nullptr) { + HILOG_ERROR("Convert js object fail."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + // FIXME: 获取元素失败,返回什么好 + return false; + } + + CopyResult cr; + ret = ret && ConvertFromJsValue(engine, obj->GetProperty("uri"), cr.uri); + ret = ret && ConvertFromJsValue(engine, obj->GetProperty("errCode"), cr.errCode); + ret = ret && ConvertFromJsValue(engine, obj->GetProperty("errMsg"), cr.errMsg); + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult uri : %{public}s", cr.uri.c_str()); + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult errCode : %{public}d", cr.errCode); + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult errMsg : %{public}s", cr.errMsg.c_str()); + if (!ret) { + HILOG_ERROR("Convert js value fail."); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + // FIXME: 获取元素失败,返回什么好 + return ret; + } + + result.emplace_back(std::move(cr)); + } + + HILOG_ERROR("JsFileAccessExtAbility:ParserGetJsCopyResult ----------------> Exit"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return true; +} + +int JsFileAccessExtAbility::Copy(const Uri &sourceUri, const Uri &destUri, std::vector ©Result) +{ + StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Copy"); + HILOG_ERROR("sourceUri: %{public}s, destUri: %{public}s", sourceUri.ToString().c_str(), destUri.ToString().c_str()); + // checkUri + auto argParser = [sourceUri, destUri](NativeEngine &engine, NativeValue* argv[], size_t &argc) -> bool { + HILOG_ERROR("JsFileAccessExtAbility:argParser ----------------> Enter"); + NativeValue *srcNativeUri = engine.CreateString(sourceUri.ToString().c_str(), + sourceUri.ToString().length()); + NativeValue *dstNativeUri = engine.CreateString(destUri.ToString().c_str(), destUri.ToString().length()); + if (srcNativeUri == nullptr || dstNativeUri == nullptr) { + HILOG_ERROR("create sourceUri uri native js value fail."); + return false; + } + argv[ARGC_ZERO] = srcNativeUri; + argv[ARGC_ONE] = dstNativeUri; + argc = ARGC_TWO; + return true; + }; + + int copyRetVal; + auto retParser = [©Result, ©RetVal](NativeEngine &engine, NativeValue *result) -> bool { + HILOG_ERROR("JsFileAccessExtAbility:retParser ----------------> Enter"); + return ParserGetJsCopyResult(engine, result, copyResult, copyRetVal); + }; + + auto errCode = CallJsMethod("copy", jsRuntime_, jsObj_.get(), argParser, retParser); + if (errCode != ERR_OK) { + HILOG_ERROR("CallJsMethod error, code:%{public}d.", errCode); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return errCode; + } + + HILOG_ERROR("JsFileAccessExtAbility:Copy ----------------> Exit"); + FinishTrace(HITRACE_TAG_FILEMANAGEMENT); + return copyRetVal; +} + int JsFileAccessExtAbility::Rename(const Uri &sourceFile, const std::string &displayName, Uri &newFile) { StartTrace(HITRACE_TAG_FILEMANAGEMENT, "Rename"); diff --git a/frameworks/innerkits/file_access/test/unittest/BUILD.gn b/frameworks/innerkits/file_access/test/unittest/BUILD.gn index 3d03347d5943366c9a830c6bf589fdd39ed2ca76..b19af97d07363d041f97df0c78193998a960d8ba 100644 --- a/frameworks/innerkits/file_access/test/unittest/BUILD.gn +++ b/frameworks/innerkits/file_access/test/unittest/BUILD.gn @@ -49,6 +49,7 @@ ohos_unittest("medialibrary_file_access_test") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "ipc_js:rpc", "samgr:samgr_proxy", diff --git a/frameworks/innerkits/file_access/test/unittest/external_file_access_test.cpp b/frameworks/innerkits/file_access/test/unittest/external_file_access_test.cpp index 858c9c2d23b824e7992fe852027bc25c05d7f805..932d17bec03b4aaad48b466995216d2d3a5d78a4 100644 --- a/frameworks/innerkits/file_access/test/unittest/external_file_access_test.cpp +++ b/frameworks/innerkits/file_access/test/unittest/external_file_access_test.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "accesstoken_kit.h" #include "context_impl.h" @@ -1759,6 +1760,103 @@ HWTEST_F(FileExtensionHelperTest, external_file_access_Move_0013, testing::ext:: GTEST_LOG_(INFO) << "FileExtensionHelperTest-end external_file_access_Move_0013"; } +/** + * @tc.number: user_file_service_external_file_access_Copy_0000 + * @tc.name: external_file_access_Copy_0000 + * @tc.desc: Test function of Move interface for FAILED because of GetProxyByUri failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: SR000H0387 + */ +HWTEST_F(FileExtensionHelperTest, external_file_access_Copy_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FileExtensionHelperTest-begin external_file_access_Copy_0000"; + try { + vector info; + int result = g_fah->GetRoots(info); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri parentUri(info[0].uri); + Uri srcDir(""); + Uri destDir(""); + result = g_fah->Mkdir(parentUri, "Copy_0000_src", srcDir); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri newFile(""); + result = g_fah->CreateFile(srcDir, "src.txt", newFile); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + result = g_fah->Mkdir(parentUri, "Copy_0000_dest", destDir); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + std::vector resultVect; + HILOG_ERROR("Copy_0000 : newFile = %{public}s destDir = %{public}s", newFile.ToString().c_str(), destDir.ToString().c_str()); + result = g_fah->Copy(newFile, destDir, resultVect); + for (auto cr : resultVect) { + HILOG_ERROR("Copy_0000 : cr.uri = %{public}s", cr.uri.c_str()); + HILOG_ERROR("Copy_0000 : cr.errCode = %{public}d", cr.errCode); + HILOG_ERROR("Copy_0000 : cr.errMsg = %{public}s", cr.errMsg.c_str()); + } + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + //result = g_fah->Delete(srcDir); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + //result = g_fah->Delete(destDir); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + } catch (...) { + GTEST_LOG_(ERROR) << "external_file_access_Copy_0000 occurs an exception."; + } + GTEST_LOG_(INFO) << "FileExtensionHelperTest-end external_file_access_Copy_0000"; +} + +/** + * @tc.number: user_file_service_external_file_access_Copy_0001 + * @tc.name: external_file_access_Copy_0001 + * @tc.desc: Test function of Move interface for FAILED because of GetProxyByUri failed. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: SR000H0387 + */ +HWTEST_F(FileExtensionHelperTest, external_file_access_Copy_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FileExtensionHelperTest-begin external_file_access_Copy_0001"; + try { + vector info; + int result = g_fah->GetRoots(info); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri parentUri(info[0].uri); + Uri srcDir(""); + Uri destDir(""); + result = g_fah->Mkdir(parentUri, "Copy_0001_src", srcDir); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri aUri(""); + result = g_fah->CreateFile(srcDir, "a.txt", aUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri bUri(""); + result = g_fah->CreateFile(srcDir, "b.txt", bUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + result = g_fah->Mkdir(parentUri, "Copy_0001_dest", destDir); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + std::vector resultVect; + HILOG_ERROR("Copy_0001 : newFile = %{public}s destDir = %{public}s", srcDir.ToString().c_str(), destDir.ToString().c_str()); + result = g_fah->Copy(srcDir, destDir, resultVect); + for (auto cr : resultVect) { + HILOG_ERROR("Copy_0001 : cr.uri = %{public}s", cr.uri.c_str()); + HILOG_ERROR("Copy_0001 : cr.errCode = %{public}d", cr.errCode); + HILOG_ERROR("Copy_0001 : cr.errMsg = %{public}s", cr.errMsg.c_str()); + } + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + //result = g_fah->Delete(srcDir); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + //result = g_fah->Delete(destDir); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + } catch (...) { + GTEST_LOG_(ERROR) << "external_file_access_Copy_0001 occurs an exception."; + } + GTEST_LOG_(INFO) << "FileExtensionHelperTest-end external_file_access_Copy_0001"; +} + /** * @tc.number: user_file_service_external_file_access_Rename_0000 * @tc.name: external_file_access_Rename_0000 diff --git a/frameworks/innerkits/file_access/test/unittest/medialibrary_file_access_test.cpp b/frameworks/innerkits/file_access/test/unittest/medialibrary_file_access_test.cpp index c33661e8a24d19b48e45d2f9e5c70cb048e424ad..19904a1e05b68e9c3ebbc897e7d53ce0fe634ad4 100644 --- a/frameworks/innerkits/file_access/test/unittest/medialibrary_file_access_test.cpp +++ b/frameworks/innerkits/file_access/test/unittest/medialibrary_file_access_test.cpp @@ -1259,7 +1259,7 @@ HWTEST_F(FileAccessHelperTest, medialibrary_file_access_Move_0009, testing::ext: result = g_fah->Mkdir(g_newDirUri, "test2", newDirUriTest2); EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); Uri testUri(""); - size_t fileNumbers = 2000; + size_t fileNumbers = 2; for (size_t i = 0; i < fileNumbers; i++) { string fileName = "test" + ToString(i) + ".txt"; result = g_fah->CreateFile(newDirUriTest1, fileName, testUri); @@ -1373,6 +1373,148 @@ HWTEST_F(FileAccessHelperTest, medialibrary_file_access_Move_0011, testing::ext: GTEST_LOG_(INFO) << "FileAccessHelperTest-end medialibrary_file_access_Move_0011"; } +/** + * @tc.number: user_file_service_medialibrary_file_access_Copy_0000 + * @tc.name: medialibrary_file_access_Copy_0000 + * @tc.desc: Test function of Copy interface + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: SR000H0386 + */ +HWTEST_F(FileAccessHelperTest, medialibrary_file_access_Copy_0000, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FileAccessHelperTest-begin medialibrary_file_access_Copy_0000"; + try { + //Uri parentUri{"datashare:///media/file/6"}; + Uri srcUri{""}; + int result = g_fah->Mkdir(g_newDirUri, "Copy_0000_src", srcUri); // g_newDirUri对应开发板目录: /storage/media/100/local/files/Download/ + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri aUri{""}; + result = g_fah->CreateFile(srcUri, "a.txt", aUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + int fd; + result = g_fah->OpenFile(aUri, WRITE_READ, fd); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + std::string aBuff = "Copy test content for a.txt"; + ssize_t aSize = write(fd, aBuff.c_str(), aBuff.size()); + EXPECT_EQ(aSize, aBuff.size()); + close(fd); + + Uri destUri(""); + result = g_fah->Mkdir(g_newDirUri, "Copy_0000_dest", destUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + vector resultVect; + result = g_fah->Copy(aUri, destUri, resultVect); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + //result = g_fah->Delete(srcUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + //result = g_fah->Delete(destUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + } catch (...) { + GTEST_LOG_(ERROR) << "medialibrary_file_access_Copy_0000 occurs an exception."; + } + GTEST_LOG_(INFO) << "FileAccessHelperTest-end medialibrary_file_access_Copy_0000"; +} + +/** + * @tc.number: user_file_service_medialibrary_file_access_Copy_0001 + * @tc.name: medialibrary_file_access_Copy_0001 + * @tc.desc: Test function of Copy interface + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: SR000H0386 + */ +HWTEST_F(FileAccessHelperTest, medialibrary_file_access_Copy_0001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FileAccessHelperTest-begin medialibrary_file_access_Copy_0001"; + try { + Uri srcUri{""}; + int result = g_fah->Mkdir(g_newDirUri, "Copy_0001_src", srcUri); // g_newDirUri对应开发板目录: /storage/media/100/local/files/Download/ + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri aUri{""}; + result = g_fah->CreateFile(srcUri, "a.txt", aUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + int fd; + result = g_fah->OpenFile(aUri, WRITE_READ, fd); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + std::string aBuff = "Copy test content for a.txt"; + ssize_t aSize = write(fd, aBuff.c_str(), aBuff.size()); + EXPECT_EQ(aSize, aBuff.size()); + close(fd); + + Uri bUri{""}; + result = g_fah->CreateFile(srcUri, "b.txt", bUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + result = g_fah->OpenFile(bUri, WRITE_READ, fd); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + std::string bBuff = "Copy test content for b.txt"; + ssize_t bSize = write(fd, bBuff.c_str(), bBuff.size()); + EXPECT_EQ(bSize, bBuff.size()); + close(fd); + + Uri destUri(""); + result = g_fah->Mkdir(g_newDirUri, "Copy_0001_dest", destUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + vector resultVect; + result = g_fah->Copy(srcUri, destUri, resultVect); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + //result = g_fah->Delete(srcUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + //result = g_fah->Delete(destUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + } catch (...) { + GTEST_LOG_(ERROR) << "medialibrary_file_access_Copy_0001 occurs an exception."; + } + GTEST_LOG_(INFO) << "FileAccessHelperTest-end medialibrary_file_access_Copy_0001"; +} + +/** + * @tc.number: user_file_service_medialibrary_file_access_Copy_0002 + * @tc.name: medialibrary_file_access_Copy_0002 + * @tc.desc: Test function of Copy interface + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + * @tc.require: SR000H0386 + */ +HWTEST_F(FileAccessHelperTest, medialibrary_file_access_Copy_0002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "FileAccessHelperTest-begin medialibrary_file_access_Copy_0002"; + try { + //Uri parentUri{"datashare:///media/file/6"}; + Uri srcUri{""}; + int result = g_fah->Mkdir(g_newDirUri, "Copy_0002_src", srcUri); // g_newDirUri对应开发板目录: /storage/media/100/local/files/Download/ + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + Uri aUri{""}; + result = g_fah->CreateFile(srcUri, "a.txt", aUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + Uri destUri(""); + result = g_fah->Mkdir(g_newDirUri, "Copy_0002_dest", destUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + + result = g_fah->Delete(aUri); + EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + vector resultVect; + result = g_fah->Copy(aUri, destUri, resultVect); + EXPECT_NE(result, OHOS::FileAccessFwk::ERR_OK); + + //result = g_fah->Delete(srcUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + ////result = g_fah->Delete(destUri); + //EXPECT_EQ(result, OHOS::FileAccessFwk::ERR_OK); + } catch (...) { + GTEST_LOG_(ERROR) << "medialibrary_file_access_Copy_0002 occurs an exception."; + } + GTEST_LOG_(INFO) << "FileAccessHelperTest-end medialibrary_file_access_Copy_0002"; +} + /** * @tc.number: user_file_service_medialibrary_file_access_Rename_0000 * @tc.name: medialibrary_file_access_Rename_0000 @@ -2529,4 +2671,4 @@ HWTEST_F(FileAccessHelperTest, medialibrary_file_access_GetFileInfoFromRelativeP } GTEST_LOG_(INFO) << "FileAccessHelperTest-end medialibrary_file_access_GetFileInfoFromRelativePath_0004"; } -} // namespace \ No newline at end of file +} // namespace diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp index 152c66d290f8d3eae1ef762bc94dae18fd6feb0c..4897f87118ff7d2c2684dc0496ca3a966491fab4 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.cpp @@ -228,6 +228,7 @@ napi_value FileAccessHelperInit(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("createFile", NAPI_CreateFile), DECLARE_NAPI_FUNCTION("delete", NAPI_Delete), DECLARE_NAPI_FUNCTION("move", NAPI_Move), + DECLARE_NAPI_FUNCTION("copy", NAPI_Copy), DECLARE_NAPI_FUNCTION("rename", NAPI_Rename), DECLARE_NAPI_FUNCTION("getRoots", NAPI_GetRoots), DECLARE_NAPI_FUNCTION("access", NAPI_Access), @@ -602,6 +603,113 @@ napi_value NAPI_Move(napi_env env, napi_callback_info info) return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; } +napi_value CreateObjectArray(napi_env env, std::vector result) +{ + HILOG_INFO("CreateObjectArray() Enter"); + uint32_t status = napi_ok; + napi_value copyResultArray = nullptr; + status = napi_create_array_with_length(env, result.size(), ©ResultArray); + if (status != napi_ok) { + return nullptr; + } + + for (size_t i = 0; i < result.size(); i++) { + CopyResult &cr = result.at(i); + HILOG_INFO("NAPI_COPY: cr.uri: %{public}s", cr.uri.c_str()); + HILOG_INFO("NAPI_COPY: cr.errCode: %{public}d", cr.errCode); + HILOG_INFO("NAPI_COPY: cr.errMsg: %{public}s", cr.errMsg.c_str()); + + napi_value crVal; + status |= napi_create_object(env, &crVal); + napi_value tmpVal; + status |= napi_create_string_utf8(env, cr.uri.c_str(), cr.uri.length(), &tmpVal); + status |= napi_set_named_property(env, crVal, "uri", tmpVal); + status |= napi_create_int32(env, cr.errCode, &tmpVal); + status |= napi_set_named_property(env, crVal, "errCode", tmpVal); + status |= napi_create_string_utf8(env, cr.errMsg.c_str(), cr.errMsg.length(), &tmpVal); + status |= napi_set_named_property(env, crVal, "errMsg", tmpVal); + status |= napi_set_element(env, copyResultArray, i, crVal); + if (status != napi_ok) { + return nullptr; + } + } + HILOG_INFO("CreateObjectArray() Exit"); + return copyResultArray; +} + +napi_value NAPI_Copy(napi_env env, napi_callback_info info) +{ + HILOG_INFO("NAPI_COPY Enter"); + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::TWO, NARG_CNT::THREE)) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + + bool retStatus = false; + std::unique_ptr srcChar; + std::tie(retStatus, srcChar, std::ignore) = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); + if (!retStatus) { + NError(EINVAL).ThrowErr(env); + } + std::string srcStr (srcChar.get()); + HILOG_INFO("NAPI_COPY: srcStr: %{public}s", srcStr.c_str()); + + std::unique_ptr destChar; + std::tie(retStatus, destChar, std::ignore) = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); + if (!retStatus) { + NError(EINVAL).ThrowErr(env); + } + std::string destStr (destChar.get()); + HILOG_INFO("NAPI_COPY: destStr: %{public}s", destStr.c_str()); + + HILOG_INFO("NAPI_COPY -------------------->"); + FileAccessHelper *fileAccessHelper = GetFileAccessHelper(env, funcArg.GetThisVar()); + if (fileAccessHelper == nullptr) { + return nullptr; + } + + HILOG_INFO("NAPI_COPY -------------------->"); + auto result = std::make_shared>(); + if (result == nullptr) { + NError(E_GETRESULT).ThrowErr(env); + return nullptr; + } + + HILOG_INFO("NAPI_COPY -------------------->"); + auto cbExec = [srcStr, destStr, result, fileAccessHelper]() -> NError { + HILOG_INFO("NAPI_COPY -------------------->"); + OHOS::Uri srcUri(srcStr); + HILOG_INFO("NAPI_COPY cpExec: srcUri: %{public}s", srcUri.ToString().c_str()); + OHOS::Uri destUri(destStr); + HILOG_INFO("NAPI_COPY cpExec: destUri: %{public}s", destUri.ToString().c_str()); + int retVal = fileAccessHelper->Copy(srcUri, destUri, *result); + return NError(retVal); + }; + auto cbComplete = [result](napi_env env, NError err) -> NVal { + HILOG_INFO("NAPI_COPY -------------------->"); + if (err) { + NError(ERR_FAF_FAIL).ThrowErr(env, FAFErrCodeTable.at(ERR_FAF_FAIL)); + // return { env, CreateObjectArray(env, result) }; + } + return { env, CreateObjectArray(env, *result) }; + }; + + HILOG_INFO("NAPI_COPY -------------------->"); + const std::string procedureName = "copy"; + NVal thisVar(env, funcArg.GetThisVar()); + if (funcArg.GetArgc() == NARG_CNT::TWO) { + return NAsyncWorkPromise(env, thisVar).Schedule(procedureName, cbExec, cbComplete).val_; + } + + NVal cb(env, funcArg[NARG_POS::THIRD]); + if (!cb.TypeIs(napi_function)) { + NError(EINVAL).ThrowErr(env); + return nullptr; + } + return NAsyncWorkCallback(env, thisVar, cb).Schedule(procedureName, cbExec, cbComplete).val_; +} + napi_value NAPI_Rename(napi_env env, napi_callback_info info) { NFuncArg funcArg(env, info); @@ -986,4 +1094,4 @@ napi_value NAPI_Off(napi_env env, napi_callback_info info) return NVal::CreateUndefined(env).val_; } } // namespace FileAccessFwk -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h index e29f3d39839b7833cc70f1127feb64a0e324bf10..7d8f7df48c5724b6d6b2249b6547e7d0a667a3e1 100644 --- a/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h +++ b/interfaces/kits/napi/file_access_module/napi_fileaccess_helper.h @@ -29,6 +29,7 @@ namespace FileAccessFwk { napi_value NAPI_Mkdir(napi_env env, napi_callback_info info); napi_value NAPI_Delete(napi_env env, napi_callback_info info); napi_value NAPI_Move(napi_env env, napi_callback_info info); + napi_value NAPI_Copy(napi_env env, napi_callback_info info); napi_value NAPI_Rename(napi_env env, napi_callback_info info); napi_value NAPI_GetRoots(napi_env env, napi_callback_info info); napi_value NAPI_Access(napi_env env, napi_callback_info info); @@ -39,4 +40,4 @@ namespace FileAccessFwk { void InitOpenFlags(napi_env env, napi_value exports); } // namespace FileAccessFwk } // namespace OHOS -#endif // NAPI_FILEACCESS_HELPER_H \ No newline at end of file +#endif // NAPI_FILEACCESS_HELPER_H diff --git a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts index 0954189d63ace389f204a68a561d8ad765f14ce3..3c79caf71dcc3be1686bdf30823013d1d78e373f 100644 --- a/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts +++ b/services/file_extension_hap/entry/src/main/ets/FileExtensionAbility/FileExtensionAbility.ts @@ -365,6 +365,142 @@ export default class FileExtAbility extends Extension { }; } + copy(sourceFileUri, destParentUri) { + hilog.error(DOMAIN_CODE, TAG, 'copy enter '); + if (!this.checkUri(sourceFileUri) || !this.checkUri(destParentUri)) { + return { + uri: "", + code: E_URIS, + }; + } + + let displayName = this.getFileName(sourceFileUri); + let newFileUri = this.genNewFileUri(destParentUri, displayName); + let oldPath = this.getPath(sourceFileUri); + let newPath = this.getPath(newFileUri); + hilog.error(DOMAIN_CODE, TAG, displayName + "|" + newFileUri + "|" +oldPath + "|" + newPath); + if (oldPath == newPath) { + let copyResult = [ + { + uri: sourceFileUri, + errCode: E_GETRESULT, + errMsg: 'The source and destination paths are the same', + }, + ]; + return { + result: copyResult, + code: ERR_ERROR + }; + } else if (newPath.indexOf(oldPath) == 0) { + let copyResult = [ + { + uri: sourceFileUri, + errCode: E_GETRESULT, + errMsg: 'copy to a subdirectory of the source directory', + }, + ]; + return { + result: copyResult, + code: ERR_ERROR + }; + } + try { + // Throw an exception when the source file does not exist + fileio.accessSync(oldPath); + let stat = fileio.statSync(this.getPath(destParentUri)); + if (!stat || !stat.isDirectory()) { + let copyResult = [ + { + uri: sourceFileUri, + errCode: E_GETRESULT, + errMsg: 'The destination is not a directory', + }, + ]; + return { + result: copyResult, + code: ERR_ERROR + }; + } + // If not across devices, use fileio.renameSync to move + // TODO: 未完成 + /* + if (!this.isCrossDeviceLink(sourceFileUri, destParentUri)) { + fileio.renameSync(oldPath, newPath); + hilog.error(DOMAIN_CODE, TAG, 'copy CrossDeviceLink renameSync-------------------------->'); + let copyResult = [ + { + uri: newFileUri, + errCode: ERR_OK, + errMsg: '', + } + ]; + return { + result: copyResult, + code: ERR_OK + }; + }*/ + } catch (e) { + hilog.error(DOMAIN_CODE, TAG, 'copy error ' + e.message); + let copyResult = [ + { + uri: sourceFileUri, + errCode: e.code, + errMsg: e.message, + }, + ]; + return { + result: copyResult, + code: ERR_ERROR + }; + } + + hilog.error(DOMAIN_CODE, TAG, 'FileExtensionAbility copy -------------------------->'); + /** + * Recursive source directory + * If it is a directory, create a new directory. + * If it is a file, copy the file. + */ + let copyResult = []; + let retVal = ERR_OK; + this.recurseDir(oldPath, function (filePath, isDirectory, hasNextFile) { + try { + let newFilePath = filePath.replace(oldPath, newPath); + if (isDirectory) { + try { + // If the target directory already has a directory with the same name, it will not be created + fileio.accessSync(newFilePath); + } catch (e) { + fileio.mkdirSync(newFilePath); + } + } else { + fileio.copyFileSync(filePath, newFilePath); + // oldPath如果是目录,一个CopyResult,还是目录下每一个文件一个CopyResult + hilog.error(DOMAIN_CODE, TAG, 'copyFileSync ----------->'); + copyResult.push({ + uri: newFileUri, + errCode: ERR_OK, + errMsg: 'Copy success', + }); + } + } catch (e) { + hilog.error(DOMAIN_CODE, TAG, 'copy error ' + e.message); + copyResult.push({ + uri: sourceFileUri, + errCode: e.code, + errMsg: e.message, + }); + retVal = ERR_ERROR; + } + }); + hilog.error(DOMAIN_CODE, TAG, copyResult.uri); + hilog.error(DOMAIN_CODE, TAG, copyResult.errCode); + hilog.error(DOMAIN_CODE, TAG, copyResult.errMsg); + return { + result: copyResult, + code: retVal + }; + } + rename(sourceFileUri, displayName) { if (!this.checkUri(sourceFileUri)) { return { @@ -538,4 +674,4 @@ export default class FileExtAbility extends Extension { code: ERR_OK, }; } -}; \ No newline at end of file +}; diff --git a/utils/file_access_framework_errno.h b/utils/file_access_framework_errno.h index e3d7928598c9180e79cef28f865ffbabde7b272a..6c02a8d893c94df1326d19782e0adb0709b804a7 100644 --- a/utils/file_access_framework_errno.h +++ b/utils/file_access_framework_errno.h @@ -16,6 +16,8 @@ #ifndef FILE_ACCESS_FRAMEWORK_ERRNO_H #define FILE_ACCESS_FRAMEWORK_ERRNO_H +#include +#include #include "errors.h" namespace OHOS { @@ -36,6 +38,52 @@ enum { E_PERMISSION = 201, // Permission verification failed E_PERMISSION_SYS // is not system app }; + +// General error code for FAF +enum { + ERR_FAF_SUCCESS = 0, + ERR_FAF_FAIL, + ERR_FAF_PERM, + ERR_FAF_NOENT, + ERR_FAF_INTR, + ERR_FAF_IO, + ERR_FAF_NXIO, + ERR_FAF_2BIG, + ERR_FAF_NOMEM, + ERR_FAF_ACCES, + ERR_FAF_FAULT, + ERR_FAF_BUSY, + ERR_FAF_EXIST, + ERR_FAF_NOTDIR, + ERR_FAF_INVAL, + ERR_FAF_FBIG, + ERR_FAF_NOSPC, + ERR_FAF_ROFS, + ERR_FAF_NAMETOOLONG, +}; + +// {FAF error code, error message} +const std::unordered_map FAFErrCodeTable = { + { ERR_FAF_SUCCESS, "Execute succeed" }, + { ERR_FAF_FAIL, "Execute failed" }, + { ERR_FAF_PERM, "Operation not permitted" }, + { ERR_FAF_NOENT, "No such file or directory" }, + { ERR_FAF_INTR, "Interrupted system call" }, + { ERR_FAF_IO, "I/O error" }, + { ERR_FAF_NXIO, "No such device or address" }, + { ERR_FAF_2BIG, "Arg list too long" }, + { ERR_FAF_NOMEM, "Out of memory" }, + { ERR_FAF_ACCES, "Permission denied" }, + { ERR_FAF_FAULT, "Bad address" }, + { ERR_FAF_BUSY, "Device or resource busy" }, + { ERR_FAF_EXIST, "File exists" }, + { ERR_FAF_NOTDIR, "Not a directory" }, + { ERR_FAF_INVAL, "Invalid argument" }, + { ERR_FAF_FBIG, "File too large" }, + { ERR_FAF_NOSPC, "No space left on device" }, + { ERR_FAF_ROFS, "Read-only file system" }, + { ERR_FAF_NAMETOOLONG, "File name too long" } +}; } // namespace FileAccessFwk } // namespace OHOS -#endif // FILE_ACCESS_FRAMEWORK_ERRNO_H \ No newline at end of file +#endif // FILE_ACCESS_FRAMEWORK_ERRNO_H