summaryrefslogtreecommitdiff
path: root/Source/Android
diff options
context:
space:
mode:
authorLillyJadeKatrin <lilly.kitty.1988@gmail.com>2025-06-09 23:38:49 -0400
committerLillyJadeKatrin <lilly.kitty.1988@gmail.com>2025-11-18 20:40:15 -0500
commitddced1a070848d935bd1d140eed549a4cae89566 (patch)
treea5b739800cd0c7de354b5b3f4c8990ee1c4df045 /Source/Android
parent1e0f6a557eff0b6bbad2f537e60f8308ed2c117d (diff)
RetroAchievements - Android login callback
Modify the RetroAchievements login code in Android to pass in a callback, pop a message if login fails, close the login box if it succeeds.
Diffstat (limited to 'Source/Android')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/AchievementModel.kt11
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/LoginDialog.kt20
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt4
-rw-r--r--Source/Android/app/src/main/res/layout/dialog_login.xml38
-rw-r--r--Source/Android/app/src/main/res/values/strings.xml2
-rw-r--r--Source/Android/jni/AchievementAdapter.cpp18
6 files changed, 81 insertions, 12 deletions
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 1625c98fb0..1ea53ddbec 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
@@ -2,12 +2,21 @@
package org.dolphinemu.dolphinemu.features.settings.model
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
object AchievementModel {
@JvmStatic
external fun init()
+ suspend fun asyncLogin(password: String): Boolean {
+ return withContext(Dispatchers.IO) {
+ login(password)
+ }
+ }
+
@JvmStatic
- external fun login(password: String)
+ private external fun login(password: String): Boolean
@JvmStatic
external fun logout()
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
index f49c9ff922..9f1d3efd5f 100644
--- 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
@@ -7,12 +7,15 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.launch
import org.dolphinemu.dolphinemu.databinding.DialogLoginBinding
-import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.login
+import org.dolphinemu.dolphinemu.dialogs.AlertMessage
+import org.dolphinemu.dolphinemu.features.settings.model.AchievementModel.asyncLogin
import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
-class LoginDialog : DialogFragment() {
+class LoginDialog(val parent: SettingsFragmentPresenter) : DialogFragment() {
private var _binding: DialogLoginBinding? = null
private val binding get() = _binding!!
@@ -43,9 +46,18 @@ class LoginDialog : DialogFragment() {
}
private fun onLoginClicked() {
+ binding.loginFailed.visibility = View.GONE
+ binding.loginInProgress.visibility = View.VISIBLE
StringSetting.ACHIEVEMENTS_USERNAME.setString(NativeConfig.LAYER_BASE_OR_CURRENT,
binding.usernameInput.text.toString())
- login(binding.passwordInput.text.toString())
- dismiss()
+ lifecycleScope.launch {
+ if (asyncLogin(binding.passwordInput.text.toString())) {
+ parent.loadSettingsList()
+ dismiss()
+ } else {
+ binding.loginInProgress.visibility = View.GONE
+ binding.loginFailed.visibility = View.VISIBLE
+ }
+ }
}
}
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 1594771128..e918178527 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
@@ -101,7 +101,7 @@ class SettingsFragmentPresenter(
}
}
- private fun loadSettingsList() {
+ fun loadSettingsList() {
val sl = ArrayList<SettingsItem>()
when (menuTag) {
MenuTag.SETTINGS -> addTopLevelSettings(sl)
@@ -964,7 +964,7 @@ class SettingsFragmentPresenter(
0,
false
) {
- fragmentView.showDialogFragment(LoginDialog())
+ fragmentView.showDialogFragment(LoginDialog(this))
loadSettingsList()
})
} else {
diff --git a/Source/Android/app/src/main/res/layout/dialog_login.xml b/Source/Android/app/src/main/res/layout/dialog_login.xml
index a8b2b3228c..320aed0e6a 100644
--- a/Source/Android/app/src/main/res/layout/dialog_login.xml
+++ b/Source/Android/app/src/main/res/layout/dialog_login.xml
@@ -36,7 +36,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/spacing_large"
- app:layout_constraintBottom_toTopOf="@id/button_cancel"
+ app:layout_constraintBottom_toTopOf="@id/login_in_progress"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/username">
@@ -53,6 +53,38 @@
</com.google.android.material.textfield.TextInputLayout>
+ <TextView
+ android:id="@+id/login_in_progress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:text="@string/achievements_login_in_progress"
+ android:textAlignment="center"
+ android:textColor="?attr/colorOnErrorContainer"
+ android:visibility="invisible"
+ android:clickable="false"
+ android:focusable="false"
+ app:layout_constraintBottom_toTopOf="@id/login_failed"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/password"/>
+
+ <TextView
+ android:id="@+id/login_failed"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:text="@string/achievements_login_failed"
+ android:textAlignment="center"
+ android:textColor="?attr/colorOnErrorContainer"
+ android:visibility="invisible"
+ android:clickable="false"
+ android:focusable="false"
+ app:layout_constraintBottom_toTopOf="@id/button_cancel"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/login_in_progress"/>
+
<Button
android:id="@+id/button_cancel"
android:layout_width="0dp"
@@ -62,7 +94,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_login"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/password" />
+ app:layout_constraintTop_toBottomOf="@id/login_failed" />
<Button
android:id="@+id/button_login"
@@ -73,6 +105,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_cancel"
- app:layout_constraintTop_toBottomOf="@id/password" />
+ app:layout_constraintTop_toBottomOf="@id/login_failed" />
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 90440c466e..c94073a213 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -966,4 +966,6 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="achievements_password">Password</string>
<string name="achievements_login">Log In</string>
<string name="achievements_logout">Log Out</string>
+ <string name="achievements_login_in_progress">Logging In</string>
+ <string name="achievements_login_failed">Login Failed</string>
</resources>
diff --git a/Source/Android/jni/AchievementAdapter.cpp b/Source/Android/jni/AchievementAdapter.cpp
index f3f27c8f8d..d5df74cfdc 100644
--- a/Source/Android/jni/AchievementAdapter.cpp
+++ b/Source/Android/jni/AchievementAdapter.cpp
@@ -3,8 +3,12 @@
#include <jni.h>
+#include <latch>
+#include "Common/Event.h"
+#include "Common/HookableEvent.h"
#include "Core/AchievementManager.h"
#include "jni/AndroidCommon/AndroidCommon.h"
+#include "jni/AndroidCommon/IDCache.h"
extern "C" {
@@ -14,11 +18,21 @@ Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_init(JNI
AchievementManager::GetInstance().Init(nullptr);
}
-JNIEXPORT void JNICALL
+JNIEXPORT jboolean JNICALL
Java_org_dolphinemu_dolphinemu_features_settings_model_AchievementModel_login(JNIEnv* env, jclass,
jstring password)
{
- AchievementManager::GetInstance().Login(GetJString(env, password));
+ auto& instance = AchievementManager::GetInstance();
+ bool success;
+ std::latch login_complete_event{1};
+ Common::EventHook login_hook =
+ instance.login_event.Register([&login_complete_event, &success](int result) {
+ success = (result == RC_OK);
+ login_complete_event.count_down();
+ });
+ instance.Login(GetJString(env, password));
+ login_complete_event.wait();
+ return success;
}
JNIEXPORT void JNICALL