diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/AchievementModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/AchievementModel.kt
index 345daf54a16..6626ba0df35 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/AchievementModel.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/AchievementModel.kt
@@ -6,6 +6,12 @@ object AchievementModel {
@JvmStatic
external fun init()
+ @JvmStatic
+ external fun login(password: String)
+
+ @JvmStatic
+ external fun logout()
+
@JvmStatic
external fun shutdown()
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
index b150c845e18..29640aa92f4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
@@ -80,6 +80,18 @@ enum class StringSetting(
Settings.SECTION_GFX_SETTINGS,
"DriverLibName",
""
+ ),
+ ACHIEVEMENTS_USERNAME(
+ Settings.FILE_ACHIEVEMENTS,
+ Settings.SECTION_ACHIEVEMENTS,
+ "Username",
+ ""
+ ),
+ ACHIEVEMENTS_API_TOKEN(
+ Settings.FILE_ACHIEVEMENTS,
+ Settings.SECTION_ACHIEVEMENTS,
+ "ApiToken",
+ ""
);
override val isOverridden: Boolean
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/LoginDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/LoginDialog.kt
new file mode 100644
index 00000000000..f49c9ff9224
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/LoginDialog.kt
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.features.settings.ui
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.DialogFragment
+import org.dolphinemu.dolphinemu.databinding.DialogLoginBinding
+import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.login
+import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig
+import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
+
+class LoginDialog : DialogFragment() {
+ private var _binding: DialogLoginBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = DialogLoginBinding.inflate(inflater, container, false)
+ binding.usernameInput.setText(
+ StringSetting.ACHIEVEMENTS_USERNAME.string
+ )
+ return binding.getRoot()
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ binding.buttonCancel.setOnClickListener { onCancelClicked() }
+ binding.buttonLogin.setOnClickListener { onLoginClicked() }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
+ private fun onCancelClicked() {
+ dismiss()
+ }
+
+ private fun onLoginClicked() {
+ StringSetting.ACHIEVEMENTS_USERNAME.setString(NativeConfig.LAYER_BASE_OR_CURRENT,
+ binding.usernameInput.text.toString())
+ login(binding.passwordInput.text.toString())
+ dismiss()
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
index a5ee2f28df0..0fd8a97782b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -31,6 +31,7 @@ import org.dolphinemu.dolphinemu.features.input.ui.ProfileDialog
import org.dolphinemu.dolphinemu.features.input.ui.ProfileDialogPresenter
import org.dolphinemu.dolphinemu.features.settings.model.*
import org.dolphinemu.dolphinemu.features.settings.model.view.*
+import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.logout
import org.dolphinemu.dolphinemu.model.GpuDriverMetadata
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
import org.dolphinemu.dolphinemu.utils.*
@@ -953,6 +954,33 @@ class SettingsFragmentPresenter(
)
)
if (BooleanSetting.ACHIEVEMENTS_ENABLED.boolean) {
+ if (StringSetting.ACHIEVEMENTS_API_TOKEN.string == "") {
+ sl.add(
+ RunRunnable(
+ context,
+ R.string.achievements_login,
+ 0,
+ 0,
+ 0,
+ false
+ ) {
+ fragmentView.showDialogFragment(LoginDialog())
+ loadSettingsList()
+ })
+ } else {
+ sl.add(
+ RunRunnable(
+ context,
+ R.string.achievements_logout,
+ 0,
+ 0,
+ 0,
+ false
+ ) {
+ logout()
+ loadSettingsList()
+ })
+ }
sl.add(
SwitchSetting(
context,
diff --git a/Source/Android/app/src/main/res/layout/dialog_login.xml b/Source/Android/app/src/main/res/layout/dialog_login.xml
new file mode 100644
index 00000000000..a8b2b3228c5
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/dialog_login.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 67ac68f75ef..90440c466e9 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -962,4 +962,8 @@ It can efficiently compress both junk data and encrypted Wii data.
Enable Encore Mode
Enable Spectator Mode
Enable Progress Notifications
+ Username
+ Password
+ Log In
+ Log Out
diff --git a/Source/Android/jni/AchievementAdapter.cpp b/Source/Android/jni/AchievementAdapter.cpp
index 119ecbbd6fb..4ecb73d653c 100644
--- a/Source/Android/jni/AchievementAdapter.cpp
+++ b/Source/Android/jni/AchievementAdapter.cpp
@@ -14,6 +14,19 @@ Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_init(JNI
AchievementManager::GetInstance().Init(nullptr);
}
+JNIEXPORT void JNICALL
+Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_login(JNIEnv* env, jclass,
+ jstring password)
+{
+ AchievementManager::GetInstance().Login(GetJString(env, password));
+}
+
+JNIEXPORT void JNICALL
+Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_logout(JNIEnv* env, jclass)
+{
+ AchievementManager::GetInstance().Logout();
+}
+
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_shutdown(JNIEnv* env,
jclass)