diff options
| author | LillyJadeKatrin <lilly.kitty.1988@gmail.com> | 2025-06-09 23:38:49 -0400 |
|---|---|---|
| committer | LillyJadeKatrin <lilly.kitty.1988@gmail.com> | 2025-11-18 20:40:15 -0500 |
| commit | ddced1a070848d935bd1d140eed549a4cae89566 (patch) | |
| tree | a5b739800cd0c7de354b5b3f4c8990ee1c4df045 /Source/Android | |
| parent | 1e0f6a557eff0b6bbad2f537e60f8308ed2c117d (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')
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 |
