ソースを参照

common: fs: Expand android macros

t895 2 年 前
コミット
c8e8c614a0
2 ファイル変更91 行追加134 行削除
  1. 79 88
      src/common/fs/fs_android.cpp
  2. 12 46
      src/common/fs/fs_android.h

+ 79 - 88
src/common/fs/fs_android.cpp

@@ -1,63 +1,38 @@
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 // 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/fs/fs_android.h"
 #include "common/string_util.h"
 #include "common/string_util.h"
 
 
 namespace Common::FS::Android {
 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) {
 void RegisterCallbacks(JNIEnv* env, jclass clazz) {
     env->GetJavaVM(&g_jvm);
     env->GetJavaVM(&g_jvm);
     native_library = clazz;
     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() {
 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) {
 bool IsContentUri(const std::string& path) {
@@ -69,8 +44,8 @@ bool IsContentUri(const std::string& path) {
     return path.find(prefix) == 0;
     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;
         return -1;
 
 
     const char* mode = "";
     const char* mode = "";
@@ -82,50 +57,66 @@ int OpenContentUri(const std::string& filepath, OpenMode openmode) {
         UNIMPLEMENTED();
         UNIMPLEMENTED();
         return -1;
         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
 } // namespace Common::FS::Android

+ 12 - 46
src/common/fs/fs_android.h

@@ -7,38 +7,17 @@
 #include <vector>
 #include <vector>
 #include <jni.h>
 #include <jni.h>
 
 
-#define ANDROID_STORAGE_FUNCTIONS(V)                                                               \
-    V(OpenContentUri, int, (const std::string& filepath, OpenMode openmode), open_content_uri,     \
-      "openContentUri", "(Ljava/lang/String;Ljava/lang/String;)I")
-
-#define ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(V)                                                 \
-    V(GetSize, std::uint64_t, get_size, CallStaticLongMethod, "getSize", "(Ljava/lang/String;)J")  \
-    V(IsDirectory, bool, is_directory, CallStaticBooleanMethod, "isDirectory",                     \
-      "(Ljava/lang/String;)Z")                                                                     \
-    V(Exists, bool, file_exists, CallStaticBooleanMethod, "exists", "(Ljava/lang/String;)Z")
-
-#define ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(V)                                                    \
-    V(GetParentDirectory, get_parent_directory, CallStaticObjectMethod, "getParentDirectory",      \
-      "(Ljava/lang/String;)Ljava/lang/String;")                                                    \
-    V(GetFilename, get_filename, CallStaticObjectMethod, "getFilename",                            \
-      "(Ljava/lang/String;)Ljava/lang/String;")
-
 namespace Common::FS::Android {
 namespace Common::FS::Android {
 
 
 static JavaVM* g_jvm = nullptr;
 static JavaVM* g_jvm = nullptr;
 static jclass native_library = nullptr;
 static jclass native_library = nullptr;
 
 
-#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) static 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
+static jmethodID s_get_parent_directory;
+static jmethodID s_get_filename;
+static jmethodID s_get_size;
+static jmethodID s_is_directory;
+static jmethodID s_file_exists;
+static jmethodID s_open_content_uri;
 
 
 enum class OpenMode {
 enum class OpenMode {
     Read,
     Read,
@@ -57,24 +36,11 @@ void UnRegisterCallbacks();
 
 
 bool IsContentUri(const std::string& path);
 bool IsContentUri(const std::string& path);
 
 
-#define FS(FunctionName, ReturnValue, Parameters, JMethodID, JMethodName, Signature)               \
-    F(FunctionName, Parameters, ReturnValue)
-#define F(FunctionName, Parameters, ReturnValue) ReturnValue FunctionName Parameters;
-ANDROID_STORAGE_FUNCTIONS(FS)
-#undef F
-#undef FS
-
-#define FR(FunctionName, ReturnValue, JMethodID, Caller, JMethodName, Signature)                   \
-    F(FunctionName, ReturnValue)
-#define F(FunctionName, ReturnValue) ReturnValue FunctionName(const std::string& filepath);
-ANDROID_SINGLE_PATH_DETERMINE_FUNCTIONS(FR)
-#undef F
-#undef FR
-
-#define FH(FunctionName, JMethodID, Caller, JMethodName, Signature) F(FunctionName)
-#define F(FunctionName) std::string FunctionName(const std::string& filepath);
-ANDROID_SINGLE_PATH_HELPER_FUNCTIONS(FH)
-#undef F
-#undef FH
+int OpenContentUri(const std::string& filepath, OpenMode openmode);
+std::uint64_t GetSize(const std::string& filepath);
+bool IsDirectory(const std::string& filepath);
+bool Exists(const std::string& filepath);
+std::string GetParentDirectory(const std::string& filepath);
+std::string GetFilename(const std::string& filepath);
 
 
 } // namespace Common::FS::Android
 } // namespace Common::FS::Android