mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-12-16 12:08:49 +00:00
WIP re-implementation of Android Rename using native filesystem manipulation
This commit is contained in:
parent
cb66169c59
commit
c13a122527
@ -7,10 +7,12 @@ package org.citra.citra_emu
|
||||
import android.Manifest.permission
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.text.Html
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.Surface
|
||||
@ -18,7 +20,9 @@ import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.citra.citra_emu.activities.EmulationActivity
|
||||
import org.citra.citra_emu.utils.FileUtil
|
||||
@ -629,6 +633,23 @@ object NativeLibrary {
|
||||
FileUtil.getFilesName(path)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun getUserDirectory(): String {
|
||||
val preferences: SharedPreferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext)
|
||||
|
||||
val udUri = preferences.getString("CITRA_DIRECTORY", "")!!.toUri()
|
||||
val udPathSegment = udUri.lastPathSegment!!
|
||||
val udVirtualPath = udPathSegment.removePrefix("primary:")
|
||||
if (udVirtualPath == udPathSegment) {
|
||||
throw IllegalStateException("TODO: User directory must be in primary external storage, is instead: $udVirtualPath")
|
||||
}
|
||||
val userDirNativePath = Environment.getExternalStorageDirectory().absolutePath + "/" + udVirtualPath + "/"
|
||||
|
||||
return userDirNativePath
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun getSize(path: String): Long =
|
||||
@ -676,19 +697,6 @@ object NativeLibrary {
|
||||
)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun renameFile(path: String, destinationFilename: String): Boolean =
|
||||
if (FileUtil.isNativePath(path)) {
|
||||
try {
|
||||
CitraApplication.documentsTree.renameFile(path, destinationFilename)
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
FileUtil.renameFile(path, destinationFilename)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun deleteDocument(path: String): Boolean =
|
||||
|
||||
@ -190,19 +190,6 @@ class DocumentsTree {
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun renameFile(filepath: String, destinationFilename: String?): Boolean {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
try {
|
||||
val filename = URLDecoder.decode(destinationFilename, FileUtil.DECODE_METHOD)
|
||||
val newUri = DocumentsContract.renameDocument(context.contentResolver, node.uri!!, filename)
|
||||
node.rename(filename, newUri)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
error("[DocumentsTree]: Cannot rename file, error: " + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun deleteDocument(filepath: String): Boolean {
|
||||
val node = resolvePath(filepath) ?: return false
|
||||
|
||||
@ -422,18 +422,6 @@ object FileUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun renameFile(path: String, destinationFilename: String): Boolean {
|
||||
try {
|
||||
val uri = Uri.parse(path)
|
||||
DocumentsContract.renameDocument(context.contentResolver, uri, destinationFilename)
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
Log.error("[FileUtil]: Cannot rename file, error: " + e.message)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun deleteDocument(path: String): Boolean {
|
||||
try {
|
||||
|
||||
@ -150,6 +150,14 @@ std::vector<std::string> GetFilesName(const std::string& filepath) {
|
||||
return vector;
|
||||
}
|
||||
|
||||
std::string GetUserDirectory() {
|
||||
if (get_user_directory == nullptr)
|
||||
throw std::runtime_error("Unable to locate user directory: Function with ID 'get_user_directory' is missing");
|
||||
auto env = GetEnvForThread();
|
||||
auto j_user_directory = (jstring)(env->CallStaticObjectMethod(native_library, get_user_directory));
|
||||
return env->GetStringUTFChars(j_user_directory, nullptr);
|
||||
}
|
||||
|
||||
bool CopyFile(const std::string& source, const std::string& destination_path,
|
||||
const std::string& destination_filename) {
|
||||
if (copy_file == nullptr)
|
||||
@ -162,16 +170,6 @@ bool CopyFile(const std::string& source, const std::string& destination_path,
|
||||
j_destination_path, j_destination_filename);
|
||||
}
|
||||
|
||||
bool RenameFile(const std::string& source, const std::string& filename) {
|
||||
if (rename_file == nullptr)
|
||||
return false;
|
||||
auto env = GetEnvForThread();
|
||||
jstring j_source_path = env->NewStringUTF(source.c_str());
|
||||
jstring j_destination_path = env->NewStringUTF(filename.c_str());
|
||||
return env->CallStaticBooleanMethod(native_library, rename_file, j_source_path,
|
||||
j_destination_path);
|
||||
}
|
||||
|
||||
#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
||||
F(FunctionName, ReturnValue, JMethodID, Caller)
|
||||
#define F(FunctionName, ReturnValue, JMethodID, Caller) \
|
||||
|
||||
@ -19,12 +19,12 @@
|
||||
open_content_uri, "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I") \
|
||||
V(GetFilesName, std::vector<std::string>, (const std::string& filepath), get_files_name, \
|
||||
"getFilesName", "(Ljava/lang/String;)[Ljava/lang/String;") \
|
||||
V(GetUserDirectory, std::string, (), get_user_directory, "getUserDirectory", \
|
||||
"()Ljava/lang/String;") \
|
||||
V(CopyFile, bool, \
|
||||
(const std::string& source, const std::string& destination_path, \
|
||||
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")
|
||||
copy_file, "copyFile", "(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") \
|
||||
|
||||
@ -311,7 +311,9 @@ bool Rename(const std::string& srcFilename, const std::string& destFilename) {
|
||||
Common::UTF8ToUTF16W(destFilename).c_str()) == 0)
|
||||
return true;
|
||||
#elif ANDROID
|
||||
if (AndroidStorage::RenameFile(srcFilename, std::string(GetFilename(destFilename))))
|
||||
const std::string userDirLocation = AndroidStorage::GetUserDirectory();
|
||||
if (rename((userDirLocation + srcFilename).c_str(),
|
||||
(userDirLocation + destFilename).c_str()) == 0)
|
||||
return true;
|
||||
#else
|
||||
if (rename(srcFilename.c_str(), destFilename.c_str()) == 0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user