|
|
@@ -1,63 +1,38 @@
|
|
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
+#include "common/android/android_common.h"
|
|
|
+#include "common/android/id_cache.h"
|
|
|
+#include "common/assert.h"
|
|
|
#include "common/fs/fs_android.h"
|
|
|
#include "common/string_util.h"
|
|
|
|
|
|
namespace Common::FS::Android {
|
|
|
|
|
|
-JNIEnv* GetEnvForThread() {
|
|
|
- thread_local static struct OwnedEnv {
|
|
|
- OwnedEnv() {
|
|
|
- status = g_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
|
|
|
- if (status == JNI_EDETACHED)
|
|
|
- g_jvm->AttachCurrentThread(&env, nullptr);
|
|
|
- }
|
|
|
-
|
|
|
- ~OwnedEnv() {
|
|
|
- if (status == JNI_EDETACHED)
|
|
|
- g_jvm->DetachCurrentThread();
|
|
|
- }
|
|
|
-
|
|
|
- int status;
|
|
|
- JNIEnv* env = nullptr;
|
|
|
- } owned;
|
|
|
- return owned.env;
|
|
|
-}
|
|
|
-
|
|
|
void RegisterCallbacks(JNIEnv* env, jclass clazz) {
|
|
|
env->GetJavaVM(&g_jvm);
|
|
|
native_library = clazz;
|
|
|
|
|
|
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \
|
|
|
- F(JMethodID, JMethodName, Signature)
|
|
|
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
|
|
- F(JMethodID, JMethodName, Signature)
|
|
|
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \
|
|
|
- F(JMethodID, JMethodName, Signature)
|
|
|
-#define F(JMethodID, JMethodName, Signature) \
|
|
|
- JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature);
|
|
|
- ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
|
|
- ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
|
|
- ANDROID_STORAGE_FUNCTIONS(FS)
|
|
|
-#undef F
|
|
|
-#undef FS
|
|
|
-#undef FR
|
|
|
-#undef FH
|
|
|
+ s_get_parent_directory = env->GetStaticMethodID(native_library, "getParentDirectory",
|
|
|
+ "(Ljava/lang/String;)Ljava/lang/String;");
|
|
|
+ s_get_filename = env->GetStaticMethodID(native_library, "getFilename",
|
|
|
+ "(Ljava/lang/String;)Ljava/lang/String;");
|
|
|
+ s_get_size = env->GetStaticMethodID(native_library, "getSize", "(Ljava/lang/String;)J");
|
|
|
+ s_is_directory = env->GetStaticMethodID(native_library, "isDirectory", "(Ljava/lang/String;)Z");
|
|
|
+ s_file_exists = env->GetStaticMethodID(native_library, "exists", "(Ljava/lang/String;)Z");
|
|
|
+ s_open_content_uri = env->GetStaticMethodID(native_library, "openContentUri",
|
|
|
+ "(Ljava/lang/String;Ljava/lang/String;)I");
|
|
|
}
|
|
|
|
|
|
void UnRegisterCallbacks() {
|
|
|
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
|
|
|
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID)
|
|
|
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID)
|
|
|
-#define F(JMethodID) JMethodID = nullptr;
|
|
|
- ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
|
|
- ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
|
|
- ANDROID_STORAGE_FUNCTIONS(FS)
|
|
|
-#undef F
|
|
|
-#undef FS
|
|
|
-#undef FR
|
|
|
-#undef FH
|
|
|
+ s_get_parent_directory = nullptr;
|
|
|
+ s_get_filename = nullptr;
|
|
|
+
|
|
|
+ s_get_size = nullptr;
|
|
|
+ s_is_directory = nullptr;
|
|
|
+ s_file_exists = nullptr;
|
|
|
+
|
|
|
+ s_open_content_uri = nullptr;
|
|
|
}
|
|
|
|
|
|
bool IsContentUri(const std::string& path) {
|
|
|
@@ -69,8 +44,8 @@ bool IsContentUri(const std::string& path) {
|
|
|
return path.find(prefix) == 0;
|
|
|
}
|
|
|
|
|
|
-int OpenContentUri(const std::string& filepath, OpenMode openmode) {
|
|
|
- if (open_content_uri == nullptr)
|
|
|
+s32 OpenContentUri(const std::string& filepath, OpenMode openmode) {
|
|
|
+ if (s_open_content_uri == nullptr)
|
|
|
return -1;
|
|
|
|
|
|
const char* mode = "";
|
|
|
@@ -82,50 +57,66 @@ int OpenContentUri(const std::string& filepath, OpenMode openmode) {
|
|
|
UNIMPLEMENTED();
|
|
|
return -1;
|
|
|
}
|
|
|
- auto env = GetEnvForThread();
|
|
|
- jstring j_filepath = env->NewStringUTF(filepath.c_str());
|
|
|
- jstring j_mode = env->NewStringUTF(mode);
|
|
|
- return env->CallStaticIntMethod(native_library, open_content_uri, j_filepath, j_mode);
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ jstring j_filepath = Common::Android::ToJString(env, filepath);
|
|
|
+ jstring j_mode = Common::Android::ToJString(env, mode);
|
|
|
+ return env->CallStaticIntMethod(native_library, s_open_content_uri, j_filepath, j_mode);
|
|
|
+}
|
|
|
+
|
|
|
+u64 GetSize(const std::string& filepath) {
|
|
|
+ if (s_get_size == nullptr) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ return static_cast<u64>(env->CallStaticLongMethod(
|
|
|
+ native_library, s_get_size,
|
|
|
+ Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath)));
|
|
|
+}
|
|
|
+
|
|
|
+bool IsDirectory(const std::string& filepath) {
|
|
|
+ if (s_is_directory == nullptr) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ return env->CallStaticBooleanMethod(
|
|
|
+ native_library, s_is_directory,
|
|
|
+ Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath));
|
|
|
}
|
|
|
|
|
|
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \
|
|
|
- F(FunctionName, ReturnValue, JMethodID, Caller)
|
|
|
-#define F(FunctionName, ReturnValue, JMethodID, Caller) \
|
|
|
- ReturnValue FunctionName(const std::string& filepath) { \
|
|
|
- if (JMethodID == nullptr) { \
|
|
|
- return 0; \
|
|
|
- } \
|
|
|
- auto env = GetEnvForThread(); \
|
|
|
- jstring j_filepath = env->NewStringUTF(filepath.c_str()); \
|
|
|
- return env->Caller(native_library, JMethodID, j_filepath); \
|
|
|
+bool Exists(const std::string& filepath) {
|
|
|
+ if (s_file_exists == nullptr) {
|
|
|
+ return 0;
|
|
|
}
|
|
|
-ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
|
|
|
-#undef F
|
|
|
-#undef FR
|
|
|
-
|
|
|
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \
|
|
|
- F(FunctionName, JMethodID, Caller)
|
|
|
-#define F(FunctionName, JMethodID, Caller) \
|
|
|
- std::string FunctionName(const std::string& filepath) { \
|
|
|
- if (JMethodID == nullptr) { \
|
|
|
- return 0; \
|
|
|
- } \
|
|
|
- auto env = GetEnvForThread(); \
|
|
|
- jstring j_filepath = env->NewStringUTF(filepath.c_str()); \
|
|
|
- jstring j_return = \
|
|
|
- static_cast<jstring>(env->Caller(native_library, JMethodID, j_filepath)); \
|
|
|
- if (!j_return) { \
|
|
|
- return {}; \
|
|
|
- } \
|
|
|
- const jchar* jchars = env->GetStringChars(j_return, nullptr); \
|
|
|
- const jsize length = env->GetStringLength(j_return); \
|
|
|
- const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length); \
|
|
|
- const std::string converted_string = Common::UTF16ToUTF8(string_view); \
|
|
|
- env->ReleaseStringChars(j_return, jchars); \
|
|
|
- return converted_string; \
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ return env->CallStaticBooleanMethod(
|
|
|
+ native_library, s_file_exists,
|
|
|
+ Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath));
|
|
|
+}
|
|
|
+
|
|
|
+std::string GetParentDirectory(const std::string& filepath) {
|
|
|
+ if (s_get_parent_directory == nullptr) {
|
|
|
+ return 0;
|
|
|
}
|
|
|
-ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
|
|
|
-#undef F
|
|
|
-#undef FH
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod(
|
|
|
+ native_library, s_get_parent_directory, Common::Android::ToJString(env, filepath)));
|
|
|
+ if (!j_return) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ return Common::Android::GetJString(env, j_return);
|
|
|
+}
|
|
|
+
|
|
|
+std::string GetFilename(const std::string& filepath) {
|
|
|
+ if (s_get_filename == nullptr) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ auto env = Common::Android::GetEnvForThread();
|
|
|
+ jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod(
|
|
|
+ native_library, s_get_filename, Common::Android::ToJString(env, filepath)));
|
|
|
+ if (!j_return) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ return Common::Android::GetJString(env, j_return);
|
|
|
+}
|
|
|
|
|
|
} // namespace Common::FS::Android
|