#include "android_settings_interface.h" #include "android_host_interface.h" #include "common/assert.h" #include "common/log.h" #include "common/string.h" #include "common/string_util.h" #include Log_SetChannel(AndroidSettingsInterface); ALWAYS_INLINE TinyString GetSettingKey(const char* section, const char* key) { return TinyString::FromFormat("%s/%s", section, key); } AndroidSettingsInterface::AndroidSettingsInterface(jobject java_context) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); jclass c_preference_manager = env->FindClass("androidx/preference/PreferenceManager"); jclass c_set = env->FindClass("java/util/Set"); jmethodID m_get_default_shared_preferences = env->GetStaticMethodID(c_preference_manager, "getDefaultSharedPreferences", "(Landroid/content/Context;)Landroid/content/SharedPreferences;"); Assert(c_preference_manager && c_set && m_get_default_shared_preferences); m_java_shared_preferences = env->CallStaticObjectMethod(c_preference_manager, m_get_default_shared_preferences, java_context); Assert(m_java_shared_preferences); m_java_shared_preferences = env->NewGlobalRef(m_java_shared_preferences); jclass c_shared_preferences = env->GetObjectClass(m_java_shared_preferences); m_get_boolean = env->GetMethodID(c_shared_preferences, "getBoolean", "(Ljava/lang/String;Z)Z"); m_get_int = env->GetMethodID(c_shared_preferences, "getInt", "(Ljava/lang/String;I)I"); m_get_float = env->GetMethodID(c_shared_preferences, "getFloat", "(Ljava/lang/String;F)F"); m_get_string = env->GetMethodID(c_shared_preferences, "getString", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); m_get_string_set = env->GetMethodID(c_shared_preferences, "getStringSet", "(Ljava/lang/String;Ljava/util/Set;)Ljava/util/Set;"); m_set_to_array = env->GetMethodID(c_set, "toArray", "()[Ljava/lang/Object;"); Assert(m_get_boolean && m_get_int && m_get_float && m_get_string && m_get_string_set && m_set_to_array); } AndroidSettingsInterface::~AndroidSettingsInterface() { if (m_java_shared_preferences) AndroidHelpers::GetJNIEnv()->DeleteGlobalRef(m_java_shared_preferences); } void AndroidSettingsInterface::Clear() { Log_ErrorPrint("Not implemented"); } int AndroidSettingsInterface::GetIntValue(const char* section, const char* key, int default_value /*= 0*/) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); #if 0 return static_cast(env->CallIntMethod(m_java_shared_preferences, m_get_int, env->NewStringUTF(GetSettingKey(section, key)), default_value)); #else // Some of these settings are string lists... jstring string_object = reinterpret_cast( env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)), env->NewStringUTF(TinyString::FromFormat("%d", default_value)))); if (!string_object) return default_value; const char* data = env->GetStringUTFChars(string_object, nullptr); Assert(data != nullptr); std::optional value = StringUtil::FromChars(data); env->ReleaseStringUTFChars(string_object, data); return value.value_or(default_value); #endif } float AndroidSettingsInterface::GetFloatValue(const char* section, const char* key, float default_value /*= 0.0f*/) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); #if 0 return static_cast(env->CallFloatMethod(m_java_shared_preferences, m_get_float, env->NewStringUTF(GetSettingKey(section, key)), default_value)); #else // Some of these settings are string lists... jstring string_object = reinterpret_cast( env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)), env->NewStringUTF(TinyString::FromFormat("%f", default_value)))); if (!string_object) return default_value; const char* data = env->GetStringUTFChars(string_object, nullptr); Assert(data != nullptr); std::optional value = StringUtil::FromChars(data); env->ReleaseStringUTFChars(string_object, data); return value.value_or(default_value); #endif } bool AndroidSettingsInterface::GetBoolValue(const char* section, const char* key, bool default_value /*= false*/) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); return static_cast(env->CallBooleanMethod(m_java_shared_preferences, m_get_boolean, env->NewStringUTF(GetSettingKey(section, key)), default_value)); } std::string AndroidSettingsInterface::GetStringValue(const char* section, const char* key, const char* default_value /*= ""*/) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); jobject string_object = env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)), env->NewStringUTF(default_value)); return AndroidHelpers::JStringToString(env, reinterpret_cast(string_object)); } void AndroidSettingsInterface::SetIntValue(const char* section, const char* key, int value) { Log_ErrorPrintf("SetIntValue(\"%s\", \"%s\", %d) not implemented", section, key, value); } void AndroidSettingsInterface::SetFloatValue(const char* section, const char* key, float value) { Log_ErrorPrintf("SetFloatValue(\"%s\", \"%s\", %f) not implemented", section, key, value); } void AndroidSettingsInterface::SetBoolValue(const char* section, const char* key, bool value) { Log_ErrorPrintf("SetBoolValue(\"%s\", \"%s\", %u) not implemented", section, key, static_cast(value)); } void AndroidSettingsInterface::SetStringValue(const char* section, const char* key, const char* value) { Log_ErrorPrintf("SetStringValue(\"%s\", \"%s\", \"%s\") not implemented", section, key, value); } void AndroidSettingsInterface::DeleteValue(const char* section, const char* key) { Log_ErrorPrintf("DeleteValue(\"%s\", \"%s\") not implemented", section, key); } std::vector AndroidSettingsInterface::GetStringList(const char* section, const char* key) { JNIEnv* env = AndroidHelpers::GetJNIEnv(); jobject values_set = env->CallObjectMethod(m_java_shared_preferences, m_get_string_set, env->NewStringUTF(GetSettingKey(section, key)), nullptr); if (!values_set) return {}; jobjectArray values_array = reinterpret_cast(env->CallObjectMethod(values_set, m_set_to_array)); if (!values_array) return {}; jsize size = env->GetArrayLength(values_array); std::vector values; values.reserve(size); for (jsize i = 0; i < size; i++) values.push_back( AndroidHelpers::JStringToString(env, reinterpret_cast(env->GetObjectArrayElement(values_array, i)))); return values; } void AndroidSettingsInterface::SetStringList(const char* section, const char* key, const std::vector& items) { Log_ErrorPrintf("SetStringList(\"%s\", \"%s\") not implemented", section, key); } bool AndroidSettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item) { Log_ErrorPrintf("RemoveFromStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item); return false; } bool AndroidSettingsInterface::AddToStringList(const char* section, const char* key, const char* item) { Log_ErrorPrintf("AddToStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item); return false; }