diff options
| author | 2024-02-05 06:10:45 -0500 | |
|---|---|---|
| committer | 2024-02-08 14:13:46 -0500 | |
| commit | c8e8c614a059761d9bebd91c12ab79698493f019 (patch) | |
| tree | d3b377bc502c5bde2ea24c4cb3d19322c310aa8d /src | |
| parent | android: Move JNI setup and helpers to common (diff) | |
| download | yuzu-c8e8c614a059761d9bebd91c12ab79698493f019.tar.gz yuzu-c8e8c614a059761d9bebd91c12ab79698493f019.tar.xz yuzu-c8e8c614a059761d9bebd91c12ab79698493f019.zip | |
common: fs: Expand android macros
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/fs/fs_android.cpp | 167 | ||||
| -rw-r--r-- | src/common/fs/fs_android.h | 58 |
2 files changed, 91 insertions, 134 deletions
diff --git a/src/common/fs/fs_android.cpp b/src/common/fs/fs_android.cpp index 1dd826a4a..9a8053222 100644 --- a/src/common/fs/fs_android.cpp +++ b/src/common/fs/fs_android.cpp | |||
| @@ -1,63 +1,38 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/android/android_common.h" | ||
| 5 | #include "common/android/id_cache.h" | ||
| 6 | #include "common/assert.h" | ||
| 4 | #include "common/fs/fs_android.h" | 7 | #include "common/fs/fs_android.h" |
| 5 | #include "common/string_util.h" | 8 | #include "common/string_util.h" |
| 6 | 9 | ||
| 7 | namespace Common::FS::Android { | 10 | namespace Common::FS::Android { |
| 8 | 11 | ||
| 9 | JNIEnv* GetEnvForThread() { | ||
| 10 | thread_local static struct OwnedEnv { | ||
| 11 | OwnedEnv() { | ||
| 12 | status = g_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6); | ||
| 13 | if (status == JNI_EDETACHED) | ||
| 14 | g_jvm->AttachCurrentThread(&env, nullptr); | ||
| 15 | } | ||
| 16 | |||
| 17 | ~OwnedEnv() { | ||
| 18 | if (status == JNI_EDETACHED) | ||
| 19 | g_jvm->DetachCurrentThread(); | ||
| 20 | } | ||
| 21 | |||
| 22 | int status; | ||
| 23 | JNIEnv* env = nullptr; | ||
| 24 | } owned; | ||
| 25 | return owned.env; | ||
| 26 | } | ||
| 27 | |||
| 28 | void RegisterCallbacks(JNIEnv* env, jclass clazz) { | 12 | void RegisterCallbacks(JNIEnv* env, jclass clazz) { |
| 29 | env->GetJavaVM(&g_jvm); | 13 | env->GetJavaVM(&g_jvm); |
| 30 | native_library = clazz; | 14 | native_library = clazz; |
| 31 | 15 | ||
| 32 | #define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \ | 16 | s_get_parent_directory = env->GetStaticMethodID(native_library, "getParentDirectory", |
| 33 | F(JMethodID, JMethodName, Signature) | 17 | "(Ljava/lang/String;)Ljava/lang/String;"); |
| 34 | #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \ | 18 | s_get_filename = env->GetStaticMethodID(native_library, "getFilename", |
| 35 | F(JMethodID, JMethodName, Signature) | 19 | "(Ljava/lang/String;)Ljava/lang/String;"); |
| 36 | #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \ | 20 | s_get_size = env->GetStaticMethodID(native_library, "getSize", "(Ljava/lang/String;)J"); |
| 37 | F(JMethodID, JMethodName, Signature) | 21 | s_is_directory = env->GetStaticMethodID(native_library, "isDirectory", "(Ljava/lang/String;)Z"); |
| 38 | #define F(JMethodID, JMethodName, Signature) \ | 22 | s_file_exists = env->GetStaticMethodID(native_library, "exists", "(Ljava/lang/String;)Z"); |
| 39 | JMethodID = env->GetStaticMethodID(native_library, JMethodName, Signature); | 23 | s_open_content_uri = env->GetStaticMethodID(native_library, "openContentUri", |
| 40 | ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH) | 24 | "(Ljava/lang/String;Ljava/lang/String;)I"); |
| 41 | ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) | ||
| 42 | ANDROID_STORAGE_FUNCTIONS(FS) | ||
| 43 | #undef F | ||
| 44 | #undef FS | ||
| 45 | #undef FR | ||
| 46 | #undef FH | ||
| 47 | } | 25 | } |
| 48 | 26 | ||
| 49 | void UnRegisterCallbacks() { | 27 | void UnRegisterCallbacks() { |
| 50 | #define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID) | 28 | s_get_parent_directory = nullptr; |
| 51 | #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID) | 29 | s_get_filename = nullptr; |
| 52 | #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) | 30 | |
| 53 | #define F(JMethodID) JMethodID = nullptr; | 31 | s_get_size = nullptr; |
| 54 | ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH) | 32 | s_is_directory = nullptr; |
| 55 | ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) | 33 | s_file_exists = nullptr; |
| 56 | ANDROID_STORAGE_FUNCTIONS(FS) | 34 | |
| 57 | #undef F | 35 | s_open_content_uri = nullptr; |
| 58 | #undef FS | ||
| 59 | #undef FR | ||
| 60 | #undef FH | ||
| 61 | } | 36 | } |
| 62 | 37 | ||
| 63 | bool IsContentUri(const std::string& path) { | 38 | bool IsContentUri(const std::string& path) { |
| @@ -69,8 +44,8 @@ bool IsContentUri(const std::string& path) { | |||
| 69 | return path.find(prefix) == 0; | 44 | return path.find(prefix) == 0; |
| 70 | } | 45 | } |
| 71 | 46 | ||
| 72 | int OpenContentUri(const std::string& filepath, OpenMode openmode) { | 47 | s32 OpenContentUri(const std::string& filepath, OpenMode openmode) { |
| 73 | if (open_content_uri == nullptr) | 48 | if (s_open_content_uri == nullptr) |
| 74 | return -1; | 49 | return -1; |
| 75 | 50 | ||
| 76 | const char* mode = ""; | 51 | const char* mode = ""; |
| @@ -82,50 +57,66 @@ int OpenContentUri(const std::string& filepath, OpenMode openmode) { | |||
| 82 | UNIMPLEMENTED(); | 57 | UNIMPLEMENTED(); |
| 83 | return -1; | 58 | return -1; |
| 84 | } | 59 | } |
| 85 | auto env = GetEnvForThread(); | 60 | auto env = Common::Android::GetEnvForThread(); |
| 86 | jstring j_filepath = env->NewStringUTF(filepath.c_str()); | 61 | jstring j_filepath = Common::Android::ToJString(env, filepath); |
| 87 | jstring j_mode = env->NewStringUTF(mode); | 62 | jstring j_mode = Common::Android::ToJString(env, mode); |
| 88 | return env->CallStaticIntMethod(native_library, open_content_uri, j_filepath, j_mode); | 63 | return env->CallStaticIntMethod(native_library, s_open_content_uri, j_filepath, j_mode); |
| 64 | } | ||
| 65 | |||
| 66 | u64 GetSize(const std::string& filepath) { | ||
| 67 | if (s_get_size == nullptr) { | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | auto env = Common::Android::GetEnvForThread(); | ||
| 71 | return static_cast<u64>(env->CallStaticLongMethod( | ||
| 72 | native_library, s_get_size, | ||
| 73 | Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath))); | ||
| 74 | } | ||
| 75 | |||
| 76 | bool IsDirectory(const std::string& filepath) { | ||
| 77 | if (s_is_directory == nullptr) { | ||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | auto env = Common::Android::GetEnvForThread(); | ||
| 81 | return env->CallStaticBooleanMethod( | ||
| 82 | native_library, s_is_directory, | ||
| 83 | Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath)); | ||
| 89 | } | 84 | } |
| 90 | 85 | ||
| 91 | #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \ | 86 | bool Exists(const std::string& filepath) { |
| 92 | F(FunctionName, ReturnValue, JMethodID, Caller) | 87 | if (s_file_exists == nullptr) { |
| 93 | #define F(FunctionName, ReturnValue, JMethodID, Caller) \ | 88 | return 0; |
| 94 | ReturnValue FunctionName(const std::string& filepath) { \ | ||
| 95 | if (JMethodID == nullptr) { \ | ||
| 96 | return 0; \ | ||
| 97 | } \ | ||
| 98 | auto env = GetEnvForThread(); \ | ||
| 99 | jstring j_filepath = env->NewStringUTF(filepath.c_str()); \ | ||
| 100 | return env->Caller(native_library, JMethodID, j_filepath); \ | ||
| 101 | } | 89 | } |
| 102 | ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) | 90 | auto env = Common::Android::GetEnvForThread(); |
| 103 | #undef F | 91 | return env->CallStaticBooleanMethod( |
| 104 | #undef FR | 92 | native_library, s_file_exists, |
| 105 | 93 | Common::Android::ToJString(Common::Android::GetEnvForThread(), filepath)); | |
| 106 | #define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) \ | 94 | } |
| 107 | F(FunctionName, JMethodID, Caller) | 95 | |
| 108 | #define F(FunctionName, JMethodID, Caller) \ | 96 | std::string GetParentDirectory(const std::string& filepath) { |
| 109 | std::string FunctionName(const std::string& filepath) { \ | 97 | if (s_get_parent_directory == nullptr) { |
| 110 | if (JMethodID == nullptr) { \ | 98 | return 0; |
| 111 | return 0; \ | ||
| 112 | } \ | ||
| 113 | auto env = GetEnvForThread(); \ | ||
| 114 | jstring j_filepath = env->NewStringUTF(filepath.c_str()); \ | ||
| 115 | jstring j_return = \ | ||
| 116 | static_cast<jstring>(env->Caller(native_library, JMethodID, j_filepath)); \ | ||
| 117 | if (!j_return) { \ | ||
| 118 | return {}; \ | ||
| 119 | } \ | ||
| 120 | const jchar* jchars = env->GetStringChars(j_return, nullptr); \ | ||
| 121 | const jsize length = env->GetStringLength(j_return); \ | ||
| 122 | const std::u16string_view string_view(reinterpret_cast<const char16_t*>(jchars), length); \ | ||
| 123 | const std::string converted_string = Common::UTF16ToUTF8(string_view); \ | ||
| 124 | env->ReleaseStringChars(j_return, jchars); \ | ||
| 125 | return converted_string; \ | ||
| 126 | } | 99 | } |
| 127 | ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH) | 100 | auto env = Common::Android::GetEnvForThread(); |
| 128 | #undef F | 101 | jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod( |
| 129 | #undef FH | 102 | native_library, s_get_parent_directory, Common::Android::ToJString(env, filepath))); |
| 103 | if (!j_return) { | ||
| 104 | return {}; | ||
| 105 | } | ||
| 106 | return Common::Android::GetJString(env, j_return); | ||
| 107 | } | ||
| 108 | |||
| 109 | std::string GetFilename(const std::string& filepath) { | ||
| 110 | if (s_get_filename == nullptr) { | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | auto env = Common::Android::GetEnvForThread(); | ||
| 114 | jstring j_return = static_cast<jstring>(env->CallStaticObjectMethod( | ||
| 115 | native_library, s_get_filename, Common::Android::ToJString(env, filepath))); | ||
| 116 | if (!j_return) { | ||
| 117 | return {}; | ||
| 118 | } | ||
| 119 | return Common::Android::GetJString(env, j_return); | ||
| 120 | } | ||
| 130 | 121 | ||
| 131 | } // namespace Common::FS::Android | 122 | } // namespace Common::FS::Android |
diff --git a/src/common/fs/fs_android.h b/src/common/fs/fs_android.h index 2c9234313..b33f4beb8 100644 --- a/src/common/fs/fs_android.h +++ b/src/common/fs/fs_android.h | |||
| @@ -7,38 +7,17 @@ | |||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include <jni.h> | 8 | #include <jni.h> |
| 9 | 9 | ||
| 10 | #define ANDROID_STORAGE_FUNCTIONS(V) \ | ||
| 11 | V(OpenContentUri, int, (const std::string& filepath, OpenMode openmode), open_content_uri, \ | ||
| 12 | "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I") | ||
| 13 | |||
| 14 | #define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V) \ | ||
| 15 | V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J") \ | ||
| 16 | V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory", \ | ||
| 17 | "(Ljava/lang/String;)Z") \ | ||
| 18 | V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z") | ||
| 19 | |||
| 20 | #define ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(V) \ | ||
| 21 | V(GetParentDirectory, get_parent_directory, CallStaticObjectMethod, "getParentDirectory", \ | ||
| 22 | "(Ljava/lang/String;)Ljava/lang/String;") \ | ||
| 23 | V(GetFilename, get_filename, CallStaticObjectMethod, "getFilename", \ | ||
| 24 | "(Ljava/lang/String;)Ljava/lang/String;") | ||
| 25 | |||
| 26 | namespace Common::FS::Android { | 10 | namespace Common::FS::Android { |
| 27 | 11 | ||
| 28 | static JavaVM* g_jvm = nullptr; | 12 | static JavaVM* g_jvm = nullptr; |
| 29 | static jclass native_library = nullptr; | 13 | static jclass native_library = nullptr; |
| 30 | 14 | ||
| 31 | #define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(JMethodID) | 15 | static jmethodID s_get_parent_directory; |
| 32 | #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) F(JMethodID) | 16 | static jmethodID s_get_filename; |
| 33 | #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) F(JMethodID) | 17 | static jmethodID s_get_size; |
| 34 | #define F(JMethodID) static jmethodID JMethodID = nullptr; | 18 | static jmethodID s_is_directory; |
| 35 | ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH) | 19 | static jmethodID s_file_exists; |
| 36 | ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) | 20 | static jmethodID s_open_content_uri; |
| 37 | ANDROID_STORAGE_FUNCTIONS(FS) | ||
| 38 | #undef F | ||
| 39 | #undef FS | ||
| 40 | #undef FR | ||
| 41 | #undef FH | ||
| 42 | 21 | ||
| 43 | enum class OpenMode { | 22 | enum class OpenMode { |
| 44 | Read, | 23 | Read, |
| @@ -57,24 +36,11 @@ void UnRegisterCallbacks(); | |||
| 57 | 36 | ||
| 58 | bool IsContentUri(const std::string& path); | 37 | bool IsContentUri(const std::string& path); |
| 59 | 38 | ||
| 60 | #define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature) \ | 39 | int OpenContentUri(const std::string& filepath, OpenMode openmode); |
| 61 | F(FunctionName, Parameters, ReturnValue) | 40 | std::uint64_t GetSize(const std::string& filepath); |
| 62 | #define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters; | 41 | bool IsDirectory(const std::string& filepath); |
| 63 | ANDROID_STORAGE_FUNCTIONS(FS) | 42 | bool Exists(const std::string& filepath); |
| 64 | #undef F | 43 | std::string GetParentDirectory(const std::string& filepath); |
| 65 | #undef FS | 44 | std::string GetFilename(const std::string& filepath); |
| 66 | |||
| 67 | #define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature) \ | ||
| 68 | F(FunctionName, ReturnValue) | ||
| 69 | #define F(FunctionName, ReturnValue) ReturnValue FunctionName(const std::string& filepath); | ||
| 70 | ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR) | ||
| 71 | #undef F | ||
| 72 | #undef FR | ||
| 73 | |||
| 74 | #define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(FunctionName) | ||
| 75 | #define F(FunctionName) std::string FunctionName(const std::string& filepath); | ||
| 76 | ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH) | ||
| 77 | #undef F | ||
| 78 | #undef FH | ||
| 79 | 45 | ||
| 80 | } // namespace Common::FS::Android | 46 | } // namespace Common::FS::Android |