mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-05-12 15:49:39 -06:00
android: Fix incorrect implementation of FileUtil::Rename
This commit is contained in:
parent
f7eaf13a4d
commit
ec9a782aab
@ -689,6 +689,19 @@ object NativeLibrary {
|
||||
FileUtil.renameFile(path, destinationFilename)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun moveFile(filename: String, sourceDirPath: String, destinationDirPath: String): Boolean =
|
||||
if (FileUtil.isNativePath(sourceDirPath)) {
|
||||
try {
|
||||
CitraApplication.documentsTree.moveFile(filename, sourceDirPath, destinationDirPath)
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
FileUtil.moveFile(filename, sourceDirPath, destinationDirPath)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun deleteDocument(path: String): Boolean =
|
||||
|
||||
@ -191,7 +191,7 @@ class DocumentsTree {
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun renameFile(filepath: String, destinationFilename: String?): Boolean {
|
||||
fun renameFile(filepath: String, destinationFilename: String): Boolean {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
try {
|
||||
val filename = URLDecoder.decode(destinationFilename, FileUtil.DECODE_METHOD)
|
||||
@ -203,6 +203,20 @@ class DocumentsTree {
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun moveFile(filename: String, sourceDirPath: String, destDirPath: String): Boolean {
|
||||
val sourceFileNode = resolvePath(sourceDirPath + "/" + filename) ?: return false
|
||||
val sourceDirNode = resolvePath(sourceDirPath) ?: return false
|
||||
val destDirNode = resolvePath(destDirPath) ?: return false
|
||||
try {
|
||||
val newUri = DocumentsContract.moveDocument(context.contentResolver, sourceFileNode.uri!!, sourceDirNode.uri!!, destDirNode.uri!!)
|
||||
sourceFileNode.rename(filename, newUri)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
error("[DocumentsTree]: Cannot move file, error: " + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun deleteDocument(filepath: String): Boolean {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -11,6 +11,7 @@ import android.net.Uri
|
||||
import android.provider.DocumentsContract
|
||||
import android.system.Os
|
||||
import android.util.Pair
|
||||
import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import org.citra.citra_emu.CitraApplication
|
||||
import org.citra.citra_emu.model.CheapDocument
|
||||
@ -434,6 +435,20 @@ object FileUtil {
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun moveFile(filename: String, sourceDirUriString: String, destDirUriString: String): Boolean {
|
||||
try {
|
||||
val sourceFileUri = ("$sourceDirUriString%2F$filename").toUri()
|
||||
val sourceDirUri = sourceDirUriString.toUri()
|
||||
val destDirUri = destDirUriString.toUri()
|
||||
DocumentsContract.moveDocument(context.contentResolver, sourceFileUri, sourceDirUri, destDirUri)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
Log.error("[FileUtil]: Cannot move file, error: " + e.message)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteDocument(path: String): Boolean {
|
||||
try {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "common/android_storage.h"
|
||||
#include "common/file_util.h"
|
||||
|
||||
namespace AndroidStorage {
|
||||
JNIEnv* GetEnvForThread() {
|
||||
@ -172,6 +173,32 @@ bool RenameFile(const std::string& source, const std::string& filename) {
|
||||
j_destination_path);
|
||||
}
|
||||
|
||||
bool MoveFile(const std::string& filename, const std::string& source_dir_path,
|
||||
const std::string& destination_dir_path) {
|
||||
if (move_file == nullptr)
|
||||
return false;
|
||||
auto env = GetEnvForThread();
|
||||
jstring j_filename = env->NewStringUTF(filename.c_str());
|
||||
jstring j_source_dir_path = env->NewStringUTF(source_dir_path.c_str());
|
||||
jstring j_destination_dir_path = env->NewStringUTF(destination_dir_path.c_str());
|
||||
return env->CallStaticBooleanMethod(native_library, move_file, j_filename, j_source_dir_path,
|
||||
j_destination_dir_path);
|
||||
}
|
||||
|
||||
bool MoveAndRenameFile(const std::string& src_full_path, const std::string& dest_full_path) {
|
||||
const auto src_filename = std::string(FileUtil::GetFilename(src_full_path));
|
||||
const auto src_parent_path = std::string(FileUtil::GetParentPath(src_full_path));
|
||||
const auto dest_filename = std::string(FileUtil::GetFilename(dest_full_path));
|
||||
const auto dest_parent_path = std::string(FileUtil::GetParentPath(dest_full_path));
|
||||
|
||||
bool result = AndroidStorage::MoveFile(src_filename, src_parent_path, dest_parent_path);
|
||||
if (result == false) {
|
||||
return false;
|
||||
}
|
||||
result = AndroidStorage::RenameFile((dest_parent_path + src_filename), dest_filename);
|
||||
return result;
|
||||
}
|
||||
|
||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
||||
F(FunctionName, ReturnValue, JMethodID, Caller)
|
||||
#define F(FunctionName, ReturnValue, JMethodID, Caller) \
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2023 Citra Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -24,7 +24,11 @@
|
||||
const std::string& destination_filename), \
|
||||
copy_file, "copyFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z") \
|
||||
V(RenameFile, bool, (const std::string& source, const std::string& filename), rename_file, \
|
||||
"renameFile", "(Ljava/lang/String;Ljava/lang/String;)Z")
|
||||
"renameFile", "(Ljava/lang/String;Ljava/lang/String;)Z") \
|
||||
V(MoveFile, bool, \
|
||||
(const std::string& filename, const std::string& source_dir_path, \
|
||||
const std::string& destination_dir_path), \
|
||||
move_file, "moveFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z")
|
||||
#define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V) \
|
||||
V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory", \
|
||||
"(Ljava/lang/String;)Z") \
|
||||
@ -44,6 +48,7 @@ ANDROID_STORAGE_FUNCTIONS(FS)
|
||||
#undef F
|
||||
#undef FS
|
||||
#undef FR
|
||||
bool MoveAndRenameFile(const std::string& src_full_path, const std::string& dest_full_path);
|
||||
// Reference:
|
||||
// https://developer.android.com/reference/android/os/ParcelFileDescriptor#parseMode(java.lang.String)
|
||||
enum class AndroidOpenMode {
|
||||
|
||||
@ -304,20 +304,20 @@ bool DeleteDir(const std::string& filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Rename(const std::string& srcFilename, const std::string& destFilename) {
|
||||
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFilename, destFilename);
|
||||
bool Rename(const std::string& srcFullPath, const std::string& destFullPath) {
|
||||
LOG_TRACE(Common_Filesystem, "{} --> {}", srcFullPath, destFullPath);
|
||||
#ifdef _WIN32
|
||||
if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(),
|
||||
Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
|
||||
if (_wrename(Common::UTF8ToUTF16W(srcFullPath).c_str(),
|
||||
Common::UTF8ToUTF16W(destFullPath).c_str()) == 0)
|
||||
return true;
|
||||
#elif ANDROID
|
||||
if (AndroidStorage::RenameFile(srcFilename, std::string(GetFilename(destFilename))))
|
||||
if (AndroidStorage::MoveAndRenameFile(srcFullPath, destFullPath))
|
||||
return true;
|
||||
#else
|
||||
if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
|
||||
if (rename(srcFullPath.c_str(), destFullPath.c_str()) == 0)
|
||||
return true;
|
||||
#endif
|
||||
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFilename, destFilename,
|
||||
LOG_ERROR(Common_Filesystem, "failed {} --> {}: {}", srcFullPath, destFullPath,
|
||||
GetLastErrorMsg());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -136,13 +136,13 @@ bool Delete(const std::string& filename);
|
||||
// Deletes a directory filename, returns true on success
|
||||
bool DeleteDir(const std::string& filename);
|
||||
|
||||
// renames file srcFilename to destFilename, returns true on success
|
||||
bool Rename(const std::string& srcFilename, const std::string& destFilename);
|
||||
// Renames file srcFullPath to destFullPath, returns true on success
|
||||
bool Rename(const std::string& srcFullPath, const std::string& destFullPath);
|
||||
|
||||
// copies file srcFilename to destFilename, returns true on success
|
||||
// Copies file srcFilename to destFilename, returns true on success
|
||||
bool Copy(const std::string& srcFilename, const std::string& destFilename);
|
||||
|
||||
// creates an empty file filename, returns true on success
|
||||
// Creates an empty file filename, returns true on success
|
||||
bool CreateEmptyFile(const std::string& filename);
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user