diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2e17f1c7d7f78d2ff70daed2e1d28e919a12a51 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "copy_ani.h" + +#include "ani_helper.h" +#include "ani_signature.h" +#include "copy_core.h" +#include "error_handler.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "fs_task_signal.h" +#include "progress_listener_ani.h" +#include "task_signal_listener_ani.h" +#include "task_signal_wrapper.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +static bool ParseListenerFromOptionArg(ani_env *env, const ani_object &options, CopyOptions &opts) +{ + ani_ref prog; + if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "progressListener", &prog)) { + HILOGE("Illegal options.progressListener type"); + return false; + } + + ani_boolean isUndefined = true; + env->Reference_IsUndefined(prog, &isUndefined); + if (isUndefined) { + return true; + } + + ani_ref cbRef; + if (ANI_OK != env->GlobalReference_Create(prog, &cbRef)) { + HILOGE("Failed to create reference"); + return false; + } + + ani_vm *vm = nullptr; + env->GetVM(&vm); + auto listener = CreateSharedPtr(vm, cbRef); + if (listener == nullptr) { + HILOGE("Failed to request heap memory."); + return false; + } + + opts.progressListener = move(listener); + return true; +} + +static bool ParseCopySignalFromOptionArg(ani_env *env, const ani_object &options, CopyOptions &opts) +{ + ani_ref prog; + if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "copySignal", &prog)) { + HILOGE("Illegal options.CopySignal type"); + return false; + } + + ani_boolean isUndefined = true; + env->Reference_IsUndefined(prog, &isUndefined); + if (isUndefined) { + return true; + } + + auto taskSignal = CreateSharedPtr(); + if (taskSignal == nullptr) { + HILOGE("Failed to request heap memory."); + return false; + } + + auto signalObj = static_cast(prog); + ani_vm *vm = nullptr; + env->GetVM(&vm); + auto listener = CreateSharedPtr(vm, signalObj, taskSignal); + if (listener == nullptr) { + HILOGE("Failed to request heap memory."); + return false; + } + + auto result = FsTaskSignal::Constructor(taskSignal, listener); + if (!result.IsSuccess()) { + return false; + } + + auto copySignal = result.GetData().value(); + auto succ = TaskSignalWrapper::Wrap(env, signalObj, copySignal.get()); + if (!succ) { + return false; + } + + opts.copySignal = move(copySignal); + return true; +} + +static tuple> ParseOptions(ani_env *env, ani_object &options) +{ + ani_boolean isUndefined; + env->Reference_IsUndefined(options, &isUndefined); + if (isUndefined) { + return { true, nullopt }; + } + + CopyOptions opts; + auto succ = ParseListenerFromOptionArg(env, options, opts); + if (!succ) { + return { false, nullopt }; + } + + succ = ParseCopySignalFromOptionArg(env, options, opts); + if (!succ) { + return { false, nullopt }; + } + + return { true, make_optional(move(opts)) }; +} + +void CopyAni::CopySync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string srcUri, ani_string destUri, ani_object options) +{ + auto [succSrc, src] = TypeConverter::ToUTF8String(env, srcUri); + auto [succDest, dest] = TypeConverter::ToUTF8String(env, destUri); + auto [succOpts, opts] = ParseOptions(env, options); + + if (!succSrc) { + HILOGE("The first argument requires uri"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + if (!succDest) { + HILOGE("The second argument requires uri"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + if (!succOpts) { + HILOGE("The third argument requires listener function"); + ErrorHandler::Throw(env, E_PARAMS); + return; + } + + auto ret = CopyCore::DoCopy(src, dest, opts); + if (!ret.IsSuccess()) { + HILOGE("DoCopy failed!"); + const FsError &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..fbbcf9d08f1ed635028dd993e03f7bddfd36f00e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_ani.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class CopyAni final { +public: + static void CopySync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string srcUri, ani_string destUri, ani_object options); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae59411014fc32a4910040b9e6aa1ee79f2adf25 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "copy_dir_ani.h" + +#include + +#include "ani_signature.h" +#include "copy_dir_core.h" +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +static tuple ToConflictFiles(ani_env *env, const ConflictFiles &files) +{ + auto classDesc = FS::ConflictFilesInner::classDesc.c_str(); + ani_class cls; + ani_status ret; + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{public}s, err: %{public}d", classDesc, ret); + return { false, nullptr }; + } + + auto ctorDesc = FS::ConflictFilesInner::ctorDesc.c_str(); + auto ctorSig = FS::ConflictFilesInner::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{public}s constructor method, err: %{public}d", classDesc, ret); + return { false, nullptr }; + } + + auto [succSrc, src] = TypeConverter::ToAniString(env, files.srcFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles srcFiles to ani string failed!"); + return { false, nullptr }; + } + + auto [succDest, dest] = TypeConverter::ToAniString(env, files.destFiles); + if (!succSrc) { + HILOGE("Convert ConflictFiles destFiles to ani string failed!"); + return { false, nullptr }; + } + + ani_object obj; + if ((ret = env->Object_New(cls, ctor, &obj, src, dest)) != ANI_OK) { + HILOGE("Create ConflictFiles object failed!, err: %{public}d", ret); + return { false, nullptr }; + } + + return { true, obj }; +} + +static tuple> ToConflictFilesArray( + ani_env *env, const optional> &errFiles) +{ + if (!errFiles.has_value()) { + return { true, nullopt }; + } + auto classDesc = BuiltInTypes::Array::classDesc.c_str(); + ani_class cls = nullptr; + ani_status ret; + + if ((ret = env->FindClass(classDesc, &cls)) != ANI_OK) { + HILOGE("Cannot find class %{public}s, err: %{public}d", classDesc, ret); + return { false, nullopt }; + } + + auto ctorDesc = BuiltInTypes::Array::ctorDesc.c_str(); + auto ctorSig = BuiltInTypes::Array::ctorSig.c_str(); + ani_method ctor; + if ((ret = env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) != ANI_OK) { + HILOGE("Cannot find class %{public}s constructor method, err: %{public}d", classDesc, ret); + return { false, nullopt }; + } + + ani_object arr; + auto files = errFiles.value(); + if ((ret = env->Object_New(cls, ctor, &arr, files.size())) != ANI_OK) { + HILOGE("Create Array failed!, err: %{public}d", ret); + return { false, nullopt }; + } + + auto setterDesc = BuiltInTypes::Array::setterDesc.c_str(); + auto setterSig = BuiltInTypes::Array::objectSetterSig.c_str(); + ani_size index = 0; + for (const auto &errFile : files) { + auto [succ, fileObj] = ToConflictFiles(env, errFile); + if (!succ) { + return { false, nullopt }; + } + + if ((ret = env->Object_CallMethodByName_Void(arr, setterDesc, setterSig, index, fileObj)) != ANI_OK) { + HILOGE("Add element to Array failed, err: %{public}d", ret); + return { false, nullopt }; + } + index++; + } + + return { true, make_optional(move(arr)) }; +} + +void CopyDirAni::CopyDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode) +{ + error_code errCode; + + auto [succSrc, srcPath] = TypeConverter::ToUTF8String(env, src); + if (!succSrc) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succDest, destPath] = TypeConverter::ToUTF8String(env, dest); + if (!succDest) { + HILOGE("Invalid dest, errCode = %{public}d", errCode.value()); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [succMode, optMode] = TypeConverter::ToOptionalInt32(env, mode); + if (!succMode) { + HILOGE("Invalid mode"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [fsResult, errFiles] = CopyDirCore::DoCopyDir(srcPath, destPath, optMode); + if (!fsResult.IsSuccess()) { + HILOGE("DoCopyFile failed!"); + auto [succ, errData] = ToConflictFilesArray(env, errFiles); + if (!succ) { + HILOGE("Convert conflict files array failed"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return; + } + const FsError &err = fsResult.GetError(); + ErrorHandler::Throw(env, err, errData); + return; + } +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..469b5fe414a01499ffd620f73057772ad3be80ea --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/copy_dir_ani.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { +class CopyDirAni final { +public: + static void CopyDirSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string src, ani_string dest, ani_object mode); +}; +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_COPY_DIR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f96b42800a59e52b0ea0ac3e92511c16e6f930dd --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.cpp @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "copy_dir_core.h" + +#include +#include +#include +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +static int RecurCopyDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles); + +static bool EndWithSlash(const string &src) +{ + return src.back() == '/'; +} + +static bool AllowToCopy(const string &src, const string &dest) +{ + if (src == dest) { + HILOGE("Failed to copy file, the same path"); + return false; + } + if (EndWithSlash(src) ? dest.find(src) == 0 : dest.find(src + "/") == 0) { + HILOGE("Failed to copy file, dest is under src"); + return false; + } + if (filesystem::path(src).parent_path() == dest) { + HILOGE("Failed to copy file, src's parent path is dest"); + return false; + } + return true; +} + +static tuple ParseAndCheckOperand(const string &src, const string &dest, const optional &mode) +{ + error_code errCode; + if (!filesystem::is_directory(filesystem::status(src, errCode))) { + HILOGE("Invalid src, errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + if (!filesystem::is_directory(filesystem::status(dest, errCode))) { + HILOGE("Invalid dest, errCode = %{public}d", errCode.value()); + return { false, 0 }; + } + if (!AllowToCopy(src, dest)) { + return { false, 0 }; + } + int32_t modeValue = 0; + if (mode.has_value()) { + modeValue = mode.value(); + if (modeValue < COPYMODE_MIN || modeValue > COPYMODE_MAX) { + HILOGE("Invalid mode"); + return { false, 0 }; + } + } + return { true, modeValue }; +} + +static int MakeDir(const string &path) +{ + filesystem::path destDir(path); + error_code errCode; + if (!filesystem::create_directory(destDir, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +struct NameList { + struct dirent **namelist = { nullptr }; + int direntNum = 0; +}; + +static int RemoveFile(const string &destPath) +{ + filesystem::path destFile(destPath); + error_code errCode; + if (!filesystem::remove(destFile, errCode)) { + HILOGE("Failed to remove file with path, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static void Deleter(struct NameList *arg) +{ + for (int i = 0; i < arg->direntNum; i++) { + free((arg->namelist)[i]); + (arg->namelist)[i] = nullptr; + } + free(arg->namelist); + arg->namelist = nullptr; + delete arg; + arg = nullptr; +} + +static int CopyFile(const string &src, const string &dest, const int mode) +{ + filesystem::path dstPath(dest); + error_code errCode; + if (filesystem::exists(dstPath, errCode)) { + int ret = (mode == DIRMODE_FILE_COPY_THROW_ERR) ? EEXIST : RemoveFile(dest); + if (ret) { + HILOGE("Failed to copy file due to existing destPath with throw err"); + return ret; + } + } + if (errCode.value() != ERRNO_NOERR) { + HILOGE("Fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + filesystem::path srcPath(src); + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + +static int CopySubDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles) +{ + error_code errCode; + if (!filesystem::exists(destPath, errCode) && errCode.value() == ERRNO_NOERR) { + int res = MakeDir(destPath); + if (res != ERRNO_NOERR) { + HILOGE("Failed to mkdir"); + return res; + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("Fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + return RecurCopyDir(srcPath, destPath, mode, errfiles); +} + +static int FilterFunc(const struct dirent *filename) +{ + if (string_view(filename->d_name) == "." || string_view(filename->d_name) == "..") { + return DISMATCH; + } + return MATCH; +} + +static int RecurCopyDir( + const string &srcPath, const string &destPath, const int mode, vector &errfiles) +{ + unique_ptr pNameList = { new (nothrow) struct NameList, Deleter }; + if (pNameList == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int num = scandir(srcPath.c_str(), &(pNameList->namelist), FilterFunc, alphasort); + if (num < 0) { + HILOGE("Scandir fail errno is %{public}d", errno); + return errno; + } + pNameList->direntNum = num; + + for (int i = 0; i < num; i++) { + if ((pNameList->namelist[i])->d_type == DT_DIR) { + string srcTemp = srcPath + '/' + string((pNameList->namelist[i])->d_name); + string destTemp = destPath + '/' + string((pNameList->namelist[i])->d_name); + int res = CopySubDir(srcTemp, destTemp, mode, errfiles); + if (res == ERRNO_NOERR) { + continue; + } + return res; + } else { + string src = srcPath + '/' + string((pNameList->namelist[i])->d_name); + string dest = destPath + '/' + string((pNameList->namelist[i])->d_name); + int res = CopyFile(src, dest, mode); + if (res == EEXIST) { + errfiles.emplace_back(src, dest); + continue; + } else if (res == ERRNO_NOERR) { + continue; + } else { + HILOGE("Failed to copy file for error %{public}d", res); + return res; + } + } + } + return ERRNO_NOERR; +} + +static int CopyDirFunc(const string &src, const string &dest, const int mode, vector &errfiles) +{ + size_t found = string(src).rfind('/'); + if (found == string::npos) { + return EINVAL; + } + string dirName = string(src).substr(found); + string destStr = dest + dirName; + error_code errCode; + if (!filesystem::exists(destStr, errCode) && errCode.value() == ERRNO_NOERR) { + int res = MakeDir(destStr); + if (res != ERRNO_NOERR) { + HILOGE("Failed to mkdir"); + return res; + } + } else if (errCode.value() != ERRNO_NOERR) { + HILOGE("Fs exists fail, errcode is %{public}d", errCode.value()); + return errCode.value(); + } + int res = RecurCopyDir(src, destStr, mode, errfiles); + if (!errfiles.empty() && res == ERRNO_NOERR) { + return EEXIST; + } + return res; +} + +struct CopyDirResult CopyDirCore::DoCopyDir(const string &src, const string &dest, const optional &mode) +{ + auto [succ, modeValue] = ParseAndCheckOperand(src, dest, mode); + if (!succ) { + return { FsResult::Error(EINVAL), nullopt }; + } + + vector errfiles = {}; + int ret = CopyDirFunc(src, dest, modeValue, errfiles); + if (ret == EEXIST && modeValue == DIRMODE_FILE_COPY_THROW_ERR) { + return { FsResult::Error(EEXIST), make_optional>(move(errfiles)) }; + } else if (ret) { + return { FsResult::Error(ret), nullopt }; + } + return { FsResult::Success(), nullopt }; +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h new file mode 100644 index 0000000000000000000000000000000000000000..e031e2a1d396195c5a7d22d3fcbd122fe6422d04 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_dir_core.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_DIR_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_DIR_CORE_H + +#include +#include + +#include "filemgmt_libfs.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; + +constexpr int COPYMODE_MIN = 0; +constexpr int COPYMODE_MAX = 1; +constexpr int COPYDIR_DEFAULT_PERM = 0770; + +constexpr int DISMATCH = 0; +constexpr int MATCH = 1; + +enum ModeOfCopyDir { DIRMODE_FILE_COPY_THROW_ERR = 0, DIRMODE_FILE_COPY_REPLACE }; + +struct CopyDirResult { + FsResult fsResult; + optional> errFiles; +}; + +class CopyDirCore final { +public: + static struct CopyDirResult DoCopyDir( + const string &src, const string &dest, const optional &mode = nullopt); +}; + +struct ConflictFiles { + string srcFiles; + string destFiles; + ConflictFiles(const string &src, const string &dest) : srcFiles(src), destFiles(dest) {} + ~ConflictFiles() = default; +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_DIR_CORE_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ca3d9d9a150e27a821e6c894d1cef07f884d1116 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "progress_listener_ani.h" + +#include +#include "ani_helper.h" +#include "ani_signature.h" +#include "file_utils.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { +using namespace std; +using namespace OHOS::FileManagement::ModuleFileIO::ANI::AniSignature; + +static ani_object WrapCopyProgress(ani_env *env, uint64_t progressSize, uint64_t totalSize) +{ + auto classDesc = FS::ProgressInner::classDesc.c_str(); + ani_class cls; + if (ANI_OK != env->FindClass(classDesc, &cls)) { + HILOGE("Cannot find class %{private}s", classDesc); + return nullptr; + } + auto ctorDesc = FS::ProgressInner::ctorDesc.c_str(); + auto ctorSig = FS::ProgressInner::ctorSig.c_str(); + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, ctorDesc, ctorSig, &ctor)) { + HILOGE("Cannot find constructor method for class %{private}s", classDesc); + return nullptr; + } + + const ani_double aniProgressSize = static_cast(progressSize <= MAX_VALUE ? progressSize : 0); + const ani_double aniTotalSize = static_cast(totalSize <= MAX_VALUE ? totalSize : 0); + + ani_object obj; + if (ANI_OK != env->Object_New(cls, ctor, &obj, aniProgressSize, aniTotalSize)) { + HILOGE("Create %{private}s object failed!", classDesc); + return nullptr; + } + return obj; +} + +static void SendCopyProgress(ani_vm *vm, ani_ref listener, uint64_t progressSize, uint64_t totalSize) +{ + if (vm == nullptr) { + HILOGE("Cannot send copy progress because the vm is null."); + return; + } + if (listener == nullptr) { + HILOGE("Cannot send copy progress because the listener is null."); + return; + } + ani_env *env = AniHelper::GetThreadEnv(vm); + if (env == nullptr) { + HILOGE("Cannot send copy progress because the env is null."); + return; + } + auto evtObj = WrapCopyProgress(env, progressSize, totalSize); + if (evtObj == nullptr) { + HILOGE("Create copy progress obj failed!"); + return; + } + vector args = { static_cast(evtObj) }; + auto argc = args.size(); + ani_ref result; + auto cbObj = static_cast(listener); + auto status = env->FunctionalObject_Call(cbObj, argc, args.data(), &result); + if (status != ANI_OK) { + HILOGE("Failed to call FunctionalObject_Call, status: %{public}d", static_cast(status)); + return; + } +} + +void ProgressListenerAni::InvokeListener(uint64_t progressSize, uint64_t totalSize) const +{ + auto localVm = vm; + auto localListener = listener; + auto task = [localVm, localListener, progressSize, totalSize]() { + SendCopyProgress(localVm, localListener, progressSize, totalSize); + }; + AniHelper::SendEventToMainThread(task); +} + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..ccff55493d0203fe6271de928effbffd76cc3989 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/ani/progress_listener_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H + +#include +#include +#include "i_progress_listener.h" + +namespace OHOS::FileManagement::ModuleFileIO::ANI { + +class ProgressListenerAni final : public IProgressListener { +public: + ProgressListenerAni(ani_vm *vm, const ani_ref &listener) : vm(vm), listener(listener) {} + void InvokeListener(uint64_t progressSize, uint64_t totalSize) const override; + +private: + ani_vm *vm; + ani_ref listener; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO::ANI +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_ANI_PROGRESS_LISTENER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h new file mode 100644 index 0000000000000000000000000000000000000000..f51f4f421562c0e603d9fea87025c27a425a7f72 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/i_progress_listener.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H + +#include + +namespace OHOS::FileManagement::ModuleFileIO { +const uint64_t MAX_VALUE = 0x7FFFFFFFFFFFFFFF; + +class IProgressListener { +public: + virtual ~IProgressListener() = default; + virtual void InvokeListener(uint64_t progressSize, uint64_t totalSize) const = 0; +}; + +} // namespace OHOS::FileManagement::ModuleFileIO +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_I_PROGRESS_LISTENER_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d37af815284c5dfcf9de7546361326ed9387c0d5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "trans_listener_core.h" + +#include +#include +#include + +#include "dfs_event_dfx.h" +#include "ipc_skeleton.h" +#include "sandbox_helper.h" +#include "uri.h" +#include "utils_log.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace OHOS::AppFileService; +using namespace AppFileService::ModuleFileUri; +const std::string NETWORK_PARA = "?networkid="; +const std::string FILE_MANAGER_AUTHORITY = "docs"; +const std::string MEDIA_AUTHORITY = "media"; +const std::string DISTRIBUTED_PATH = "/data/storage/el2/distributedfiles/"; +std::atomic TransListenerCore::getSequenceId_ = 0; + +void TransListenerCore::RmDir(const std::string &path) +{ + HILOGI("RmDirm path : %{public}s", GetAnonyString(path).c_str()); + std::filesystem::path pathName(path); + std::error_code errCode; + if (std::filesystem::exists(pathName, errCode)) { + std::filesystem::remove_all(pathName, errCode); + if (errCode.value() != 0) { + HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); + } + } else { + HILOGE("pathName is not exists, error code: %{public}d", errCode.value()); + } +} + +std::string TransListenerCore::CreateDfsCopyPath() +{ + std::random_device rd; + std::string random = std::to_string(rd()); + while (std::filesystem::exists(DISTRIBUTED_PATH + random)) { + random = std::to_string(rd()); + } + return random; +} + +int TransListenerCore::HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId) +{ + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + RmDir(disSandboxPath); + } + auto it = softbusErr2ErrCodeTable.find(copyEvent.errorCode); + if (it == softbusErr2ErrCodeTable.end()) { + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, RadarReporter::SEND_FILE_ERROR, + RadarReporter::CONCURRENT_ID, currentId, RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); + return EIO; + } + if (copyEvent.errorCode != DFS_CANCEL_SUCCESS) { + HILOGE("HandleCopyFailure failed, copyEvent.errorCode = %{public}d.", copyEvent.errorCode); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, RadarReporter::SEND_FILE_ERROR, + RadarReporter::CONCURRENT_ID, currentId, RadarReporter::PACKAGE_NAME, to_string(copyEvent.errorCode)); + } + return it->second; +} + +int TransListenerCore::WaitForCopyResult(TransListenerCore *transListener) +{ + if (transListener == nullptr) { + HILOGE("transListener is nullptr"); + return FAILED; + } + std::unique_lock lock(transListener->cvMutex_); + transListener->cv_.wait(lock, [&transListener]() { + return transListener->copyEvent_.copyResult == SUCCESS || transListener->copyEvent_.copyResult == FAILED; + }); + return transListener->copyEvent_.copyResult; +} + +int TransListenerCore::CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + std::shared_ptr fileInfos, std::shared_ptr callback) +{ + HILOGI("CopyFileFromSoftBus begin."); + std::string currentId = "CopyFile_" + std::to_string(getpid()) + "_" + std::to_string(getSequenceId_); + ++getSequenceId_; + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::PACKAGE_NAME, std::to_string(getpid()), + RadarReporter::CONCURRENT_ID, currentId); + sptr transListener = new (std::nothrow) TransListenerCore(); + if (transListener == nullptr) { + HILOGE("new trans listener failed"); + return ENOMEM; + } + transListener->callback_ = std::move(callback); + + Storage::DistributedFile::HmdfsInfo info {}; + Uri uri(destUri); + info.authority = uri.GetAuthority(); + info.sandboxPath = SandboxHelper::Decode(uri.GetPath()); + std::string disSandboxPath; + auto ret = PrepareCopySession(srcUri, destUri, transListener, info, disSandboxPath); + if (ret != ERRNO_NOERR) { + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::PREPARE_COPY_SESSION_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(ret)); + return EIO; + } + if (fileInfos->taskSignal != nullptr) { + fileInfos->taskSignal->SetFileInfoOfRemoteTask(info.sessionName, fileInfos->srcPath); + } + auto copyResult = WaitForCopyResult(transListener); + if (copyResult == FAILED) { + return HandleCopyFailure(transListener->copyEvent_, info, disSandboxPath, currentId); + } + if (info.authority == FILE_MANAGER_AUTHORITY || info.authority == MEDIA_AUTHORITY) { + HILOGW("Public or media path not copy"); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); + return ERRNO_NOERR; + } + + ret = CopyToSandBox(srcUri, disSandboxPath, info.sandboxPath, currentId); + RmDir(disSandboxPath); + if (ret != ERRNO_NOERR) { + HILOGE("CopyToSandBox failed, ret = %{public}d.", ret); + return EIO; + } + return ERRNO_NOERR; +} + +int32_t TransListenerCore::PrepareCopySession(const std::string &srcUri, const std::string &destUri, + TransListenerCore *transListener, Storage::DistributedFile::HmdfsInfo &info, std::string &disSandboxPath) +{ + std::string tmpDir; + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + tmpDir = CreateDfsCopyPath(); + disSandboxPath = DISTRIBUTED_PATH + tmpDir; + std::error_code errCode; + if (!std::filesystem::create_directory(disSandboxPath, errCode)) { + HILOGE("Create dir failed, error code: %{public}d", errCode.value()); + return errCode.value(); + } + + auto pos = info.sandboxPath.rfind('/'); + if (pos == std::string::npos) { + HILOGE("invalid file path"); + return EIO; + } + auto sandboxDir = info.sandboxPath.substr(0, pos); + if (std::filesystem::exists(sandboxDir, errCode)) { + info.dirExistFlag = true; + } + } + + info.copyPath = tmpDir; + auto networkId = GetNetworkIdFromUri(srcUri); + HILOGI("dfs PrepareSession begin."); + auto ret = Storage::DistributedFile::DistributedFileDaemonManager::GetInstance().PrepareSession( + srcUri, destUri, networkId, transListener, info); + if (ret != ERRNO_NOERR) { + HILOGE("PrepareSession failed, ret = %{public}d.", ret); + if (info.authority != FILE_MANAGER_AUTHORITY && info.authority != MEDIA_AUTHORITY) { + RmDir(disSandboxPath); + } + return EIO; + } + return ERRNO_NOERR; +} + +int32_t TransListenerCore::CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, + const std::string &sandboxPath, const std::string ¤tId) +{ + std::error_code errCode; + if (std::filesystem::exists(sandboxPath) && std::filesystem::is_directory(sandboxPath)) { + HILOGI("Copy dir"); + std::filesystem::copy(disSandboxPath, sandboxPath, + std::filesystem::copy_options::recursive | std::filesystem::copy_options::update_existing, errCode); + if (errCode.value() != 0) { + HILOGE("Copy dir failed: errCode: %{public}d", errCode.value()); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(errCode.value())); + return EIO; + } + } else { + HILOGI("Copy file."); + Uri uri(srcUri); + auto fileName = GetFileName(uri.GetPath()); + if (fileName.empty()) { + HILOGE("Get filename failed"); + RmDir(disSandboxPath); + return EIO; + } + std::filesystem::copy( + disSandboxPath + fileName, sandboxPath, std::filesystem::copy_options::update_existing, errCode); + if (errCode.value() != 0) { + HILOGE("Copy file failed: errCode: %{public}d", errCode.value()); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_FAILED, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, + RadarReporter::COPY_TO_SANDBOX_ERROR, RadarReporter::CONCURRENT_ID, currentId, + RadarReporter::PACKAGE_NAME, to_string(errCode.value())); + return EIO; + } + } + HILOGI("Copy file success."); + RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS, + RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId); + return ERRNO_NOERR; +} + +std::string TransListenerCore::GetFileName(const std::string &path) +{ + auto pos = path.find_last_of('/'); + if (pos == std::string::npos) { + HILOGE("invalid path"); + return ""; + } + return SandboxHelper::Decode(path.substr(pos)); +} + +std::string TransListenerCore::GetNetworkIdFromUri(const std::string &uri) +{ + return uri.substr(uri.find(NETWORK_PARA) + NETWORK_PARA.size(), uri.size()); +} + +void TransListenerCore::CallbackComplete(std::shared_ptr entry) +{ + if (entry == nullptr) { + HILOGE("entry pointer is nullptr."); + return; + } + + if (entry->callback == nullptr) { + HILOGE("entry callback pointer is nullptr."); + return; + } + + auto listener = entry->callback->listener; + if (listener == nullptr) { + HILOGE("listener pointer is nullptr."); + return; + } + listener->InvokeListener(entry->progressSize, entry->totalSize); +} + +int32_t TransListenerCore::OnFileReceive(uint64_t totalBytes, uint64_t processedBytes) +{ + std::lock_guard lock(callbackMutex_); + if (callback_ == nullptr) { + HILOGE("Failed to parse watcher callback"); + return ENOMEM; + } + + std::shared_ptr entry = std::make_shared(callback_); + if (entry == nullptr) { + HILOGE("entry ptr is nullptr"); + return ENOMEM; + } + entry->progressSize = processedBytes; + entry->totalSize = totalBytes; + CallbackComplete(entry); + return ERRNO_NOERR; +} + +int32_t TransListenerCore::OnFinished(const std::string &sessionName) +{ + { + std::lock_guard lock(callbackMutex_); + callback_ = nullptr; + } + { + std::lock_guard lock(cvMutex_); + copyEvent_.copyResult = SUCCESS; + cv_.notify_all(); + } + return ERRNO_NOERR; +} + +int32_t TransListenerCore::OnFailed(const std::string &sessionName, int32_t errorCode) +{ + HILOGI("OnFailed, errorCode is %{public}d", errorCode); + { + std::lock_guard lock(callbackMutex_); + callback_ = nullptr; + } + { + std::lock_guard lock(cvMutex_); + copyEvent_.copyResult = FAILED; + copyEvent_.errorCode = errorCode; + cv_.notify_all(); + } + return ERRNO_NOERR; +} +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h new file mode 100644 index 0000000000000000000000000000000000000000..9688e794034b49af885e6fd22df7c844339effcd --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/copy_listener/trans_listener_core.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H + +#include + +#include "copy_core.h" +#include "distributed_file_daemon_manager.h" +#include "file_trans_listener_stub.h" +#include "file_uri.h" +#include "hmdfs_info.h" +#include "uv.h" + +constexpr int NONE = 0; +constexpr int SUCCESS = 1; +constexpr int FAILED = 2; +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +struct CopyEvent { + int copyResult = NONE; + int32_t errorCode = 0; +}; +class TransListenerCore : public Storage::DistributedFile::FileTransListenerStub { +public: + int32_t OnFileReceive(uint64_t totalBytes, uint64_t processedBytes) override; + int32_t OnFinished(const std::string &sessionName) override; + int32_t OnFailed(const std::string &sessionName, int32_t errorCode) override; + static int CopyFileFromSoftBus(const std::string &srcUri, const std::string &destUri, + std::shared_ptr fileInfos, std::shared_ptr callback); + +private: + static std::string GetNetworkIdFromUri(const std::string &uri); + static void CallbackComplete(std::shared_ptr entry); + static void RmDir(const std::string &path); + static std::string CreateDfsCopyPath(); + static std::string GetFileName(const std::string &path); + static int32_t CopyToSandBox(const std::string &srcUri, const std::string &disSandboxPath, + const std::string &sandboxPath, const std::string ¤tId); + static int32_t PrepareCopySession(const std::string &srcUri, const std::string &destUri, + TransListenerCore *transListener, Storage::DistributedFile::HmdfsInfo &info, std::string &disSandboxPath); + static int HandleCopyFailure(CopyEvent ©Event, const Storage::DistributedFile::HmdfsInfo &info, + const std::string &disSandboxPath, const std::string ¤tId); + static int WaitForCopyResult(TransListenerCore *transListener); + static std::atomic getSequenceId_; + std::mutex cvMutex_; + std::condition_variable cv_; + CopyEvent copyEvent_; + std::mutex callbackMutex_; + std::shared_ptr callback_; +}; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_COPY_LISTENER_TRANS_LISTENER_CORE_H diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad9b034bbe2f62190612326f63bccdd83cae8cb6 --- /dev/null +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_dir_core_test.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "copy_dir_core.h" + +namespace OHOS::FileManagement::ModuleFileIO::Test { +using namespace testing; +using namespace testing::ext; +using namespace std; + +class CopyDirCoreTest : public testing::Test { +public: + static filesystem::path g_srcPath; + static filesystem::path g_destPath; + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); + + void CreateTestFile(const filesystem::path& path, const string& content = "test") + { + ofstream file(path); + file << content; + } +}; + +filesystem::path CopyDirCoreTest::g_srcPath; +filesystem::path CopyDirCoreTest::g_destPath; + +void CopyDirCoreTest::SetUpTestCase(void) +{ + g_srcPath = filesystem::temp_directory_path() / "src/"; + g_destPath = filesystem::temp_directory_path() / "dest/"; + filesystem::create_directory(g_srcPath); + filesystem::create_directory(g_destPath); + GTEST_LOG_(INFO) << "SetUpTestCase"; +} + +void CopyDirCoreTest::TearDownTestCase(void) +{ + GTEST_LOG_(INFO) << "TearDownTestCase"; + filesystem::remove_all(g_srcPath); + filesystem::remove_all(g_destPath); +} + +void CopyDirCoreTest::SetUp(void) +{ + GTEST_LOG_(INFO) << "SetUp"; +} + +void CopyDirCoreTest::TearDown(void) +{ + GTEST_LOG_(INFO) << "TearDown"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_001 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with empty directory. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_001, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_001"; + + string src = g_srcPath.string() + "/test01"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_001"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_002 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with invalid mode. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_002, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_002"; + + string src = g_srcPath.string() + "/test02"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + + int invalidMode = COPYMODE_MAX + 1; + auto result = CopyDirCore::DoCopyDir(src, dest, optional(invalidMode)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_002"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_003 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with non-existent source. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_003, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_003"; + + string src = g_srcPath.string() + "/non_existent"; + string dest = g_destPath.string(); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_003"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_004 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with invalid destination. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_004, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_004"; + + string src = g_srcPath.string(); + string dest = g_destPath.string() + "/invalid_file.txt"; + filesystem::path(dest).remove_filename(); + filesystem::create_directories(filesystem::path(dest).parent_path()); + ofstream(dest).close(); // 创建文件而非目录 + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_004"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_005 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with same source and destination. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_005, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_005"; + + string src = g_srcPath.string(); + string dest = g_srcPath.string(); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_005"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_006 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with files. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_006, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_006"; + + string src = g_srcPath.string() + "/test06"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + CreateTestFile(src + "/file2.txt", "content2"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_006"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_007 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with subdirectories. + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_007, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_007"; + + string src = g_srcPath.string() + "/test07"; + string dest = g_destPath.string(); + filesystem::create_directories(src + "/subdir1"); + filesystem::create_directories(src + "/subdir2"); + CreateTestFile(src + "/subdir1/file1.txt", "sub1_content1"); + CreateTestFile(src + "/subdir2/file2.txt", "sub2_content2"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional()); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_007"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_008 + * @tc.desc: Test function of DoCopyDir() interface for FAILED with existing files (throw error mode). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_008, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_008"; + + string src = g_srcPath.string() + "/test08"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + + string destDir = dest + "/" + filesystem::path(src).filename().string(); + filesystem::create_directories(destDir); + CreateTestFile(destDir + "/file1.txt", "existing_content"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional(DIRMODE_FILE_COPY_THROW_ERR)); + + EXPECT_FALSE(result.fsResult.IsSuccess()); + EXPECT_TRUE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_008"; +} + +/** + * @tc.name: CopyDirCoreTest_DoCopyDir_009 + * @tc.desc: Test function of DoCopyDir() interface for SUCCESS with existing files (overwrite mode). + * @tc.size: MEDIUM + * @tc.type: FUNC + * @tc.level Level 1 + */ +HWTEST_F(CopyDirCoreTest, CopyDirCoreTest_DoCopyDir_009, testing::ext::TestSize.Level1) +{ + GTEST_LOG_(INFO) << "CopyDirCoreTest-begin CopyDirCoreTest_DoCopyDir_009"; + + string src = g_srcPath.string() + "/test09"; + string dest = g_destPath.string(); + filesystem::create_directories(src); + CreateTestFile(src + "/file1.txt", "content1"); + + string destDir = dest + "/" + filesystem::path(src).filename().string(); + filesystem::create_directories(destDir); + CreateTestFile(destDir + "/file1.txt", "existing_content"); + + auto result = CopyDirCore::DoCopyDir(src, dest, optional(DIRMODE_FILE_COPY_REPLACE)); + + EXPECT_TRUE(result.fsResult.IsSuccess()); + EXPECT_FALSE(result.errFiles.has_value()); + + GTEST_LOG_(INFO) << "CopyDirCoreTest-end CopyDirCoreTest_DoCopyDir_009"; +} + +} // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp index af533602a0dff305542607889773d097d046636d..0988ca22a3815e325a40c453a109f469ee2d9630 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_mock_test.cpp @@ -23,7 +23,7 @@ using namespace testing; using namespace testing::ext; using namespace std; -class CopyFileCoreTest : public testing::Test { +class CopyFileCoreMockTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); @@ -32,40 +32,40 @@ public: static inline shared_ptr uvfs = nullptr; }; -void CopyFileCoreTest::SetUpTestCase(void) +void CopyFileCoreMockTest::SetUpTestCase(void) { uvfs = std::make_shared(); Uvfs::ins = uvfs; GTEST_LOG_(INFO) << "SetUpTestCase"; } -void CopyFileCoreTest::TearDownTestCase(void) +void CopyFileCoreMockTest::TearDownTestCase(void) { Uvfs::ins = nullptr; uvfs = nullptr; GTEST_LOG_(INFO) << "TearDownTestCase"; } -void CopyFileCoreTest::SetUp(void) +void CopyFileCoreMockTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; } -void CopyFileCoreTest::TearDown(void) +void CopyFileCoreMockTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_001 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_001 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_001"; FileInfo src; FileInfo dest; @@ -74,19 +74,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSi auto res = CopyFileCore::DoCopyFile(src, dest, mode); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_001"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_003 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_003 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_003, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_003, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_003"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_003"; FileInfo src; FileInfo dest; @@ -98,44 +98,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_003, testing::ext::TestSi auto res = CopyFileCore::DoCopyFile(src, dest); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_003"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_003"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_004 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_005 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_004, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_005, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_004"; - - FileInfo src; - FileInfo dest; - src.isPath = true; - dest.isPath = false; - src.fdg = make_unique(1); - - EXPECT_CALL(*uvfs, uv_fs_open(_, _, _, _, _, _)).Times(1).WillOnce(Return(1)); - - auto res = CopyFileCore::DoCopyFile(src, dest); - EXPECT_EQ(res.IsSuccess(), false); - - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_004"; -} - -/** - * @tc.name: CopyFileCoreTest_DoCopyFile_005 - * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for FALSE. - * @tc.size: MEDIUM - * @tc.type: FUNC - * @tc.level Level 1 - */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_005, testing::ext::TestSize.Level1) -{ - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_005"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_005"; FileInfo src; FileInfo dest; @@ -151,19 +126,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_005, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_005"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_005"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_006 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_006 * @tc.desc: Test function of CopyFileCore::OpenFile.OpenCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_006, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_006, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_006"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_006"; FileInfo src; FileInfo dest; @@ -179,19 +154,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_006, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), true); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_006"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_006"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_007 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_007 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_007, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_007, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_007"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_007"; FileInfo src; FileInfo dest; @@ -208,19 +183,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_007, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_007"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_007"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_008 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_008 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_008, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_008, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_008"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_008"; FileInfo src; FileInfo dest; @@ -237,19 +212,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_008, testing::ext::TestSi EXPECT_EQ(res.IsSuccess(), false); close(fd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_008"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_008"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_009 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_009 * @tc.desc: Test function of CopyFileCore::OpenFile.TruncateCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_009, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_009, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_009"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_009"; FileInfo src; FileInfo dest; @@ -270,19 +245,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_009, testing::ext::TestSi close(srcfd); close(destfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_009"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_009"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0010 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0010 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for false. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0010, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0010, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0010"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0010"; FileInfo src; FileInfo dest; @@ -303,19 +278,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0010, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0010"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0010"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0011 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0011 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for false. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0011, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0011, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0011"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0011"; FileInfo src; FileInfo dest; @@ -336,19 +311,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0011, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0011"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0011"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0012 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0012 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for SUCCESS. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0012, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0012, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0012"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0012"; FileInfo src; FileInfo dest; @@ -369,19 +344,19 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0012, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), true); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0012"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0012"; } /** - * @tc.name: CopyFileCoreTest_DoCopyFile_0013 + * @tc.name: CopyFileCoreMockTest_DoCopyFile_0013 * @tc.desc: Test function of CopyFileCore::OpenFile.SendFileCore interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0013, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_0013, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_0013"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_0013"; FileInfo src; FileInfo dest; @@ -402,7 +377,7 @@ HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_0013, testing::ext::TestS EXPECT_EQ(res.IsSuccess(), false); close(srcfd); - GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_0013"; + GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_0013"; } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file diff --git a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp index 8d14cda0e678a7535acb7e9908dc71075e572693..343446bc7fb3dabca537db9b70413d249fc8317d 100644 --- a/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp +++ b/interfaces/test/unittest/js/mod_fs/properties/copy_file_core_test.cpp @@ -22,7 +22,7 @@ using namespace testing; using namespace testing::ext; using namespace std; -class CopyFileCoreMockTest : public testing::Test { +class CopyFileCoreTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); @@ -30,36 +30,36 @@ public: void TearDown(); }; -void CopyFileCoreMockTest::SetUpTestCase(void) +void CopyFileCoreTest::SetUpTestCase(void) { GTEST_LOG_(INFO) << "SetUpTestCase"; } -void CopyFileCoreMockTest::TearDownTestCase(void) +void CopyFileCoreTest::TearDownTestCase(void) { GTEST_LOG_(INFO) << "TearDownTestCase"; } -void CopyFileCoreMockTest::SetUp(void) +void CopyFileCoreTest::SetUp(void) { GTEST_LOG_(INFO) << "SetUp"; } -void CopyFileCoreMockTest::TearDown(void) +void CopyFileCoreTest::TearDown(void) { GTEST_LOG_(INFO) << "TearDown"; } /** - * @tc.name: CopyFileCoreMockTest_DoCopyFile_001 + * @tc.name: CopyFileCoreTest_DoCopyFile_001 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_001, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_001"; FileInfo src; FileInfo dest; @@ -68,19 +68,19 @@ HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_001, testing::ext auto res = CopyFileCore::DoCopyFile(src, dest, mode); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_001"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_001"; } /** - * @tc.name: CopyFileCoreMockTest_DoCopyFile_002 + * @tc.name: CopyFileCoreTest_DoCopyFile_002 * @tc.desc: Test function of CopyFileCore::ValidMode interface for FALSE. * @tc.size: MEDIUM * @tc.type: FUNC * @tc.level Level 1 */ -HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_002, testing::ext::TestSize.Level1) +HWTEST_F(CopyFileCoreTest, CopyFileCoreTest_DoCopyFile_002, testing::ext::TestSize.Level1) { - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-begin CopyFileCoreMockTest_DoCopyFile_002"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-begin CopyFileCoreTest_DoCopyFile_002"; FileInfo src; FileInfo dest; @@ -92,7 +92,7 @@ HWTEST_F(CopyFileCoreMockTest, CopyFileCoreMockTest_DoCopyFile_002, testing::ext auto res = CopyFileCore::DoCopyFile(src, dest); EXPECT_EQ(res.IsSuccess(), false); - GTEST_LOG_(INFO) << "CopyFileCoreMockTest-end CopyFileCoreMockTest_DoCopyFile_002"; + GTEST_LOG_(INFO) << "CopyFileCoreTest-end CopyFileCoreTest_DoCopyFile_002"; } } // namespace OHOS::FileManagement::ModuleFileIO::Test \ No newline at end of file