Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;
import java.util.List;

/**
Expand Down Expand Up @@ -104,6 +105,24 @@ public void testUnlockUnknownAchievement() {
assertFalse("Unknown achievement unlock should return false", result);
}

/**
* Test that setUiNotifier keeps a strong reference until explicitly cleared.
*/
@Test
public void testSetUiNotifierStoresStrongReference() throws Exception {
AchievementManager.UiNotifier notifier = message -> {};

achievementManager.setUiNotifier(notifier);

Field uiNotifierField = AchievementManager.class.getDeclaredField("uiNotifier");
uiNotifierField.setAccessible(true);
assertSame("UiNotifier should be stored strongly", notifier, uiNotifierField.get(achievementManager));

achievementManager.setUiNotifier(null);

assertNull("UiNotifier should clear when set to null", uiNotifierField.get(achievementManager));
}

// ==================== PROGRESSION ACHIEVEMENTS TESTS ====================

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class AchievementManager private constructor(context: Context) {
private val achievements: MutableMap<String?, Achievement?>?
private var unlockListener: AchievementUnlockListener? = null
private var currentActivity: WeakReference<Activity?>? = null
private var uiNotifier: WeakReference<UiNotifier?>? = null
private var uiNotifier: UiNotifier? = null

fun interface UiNotifier {
fun showMessage(message: String)
Expand Down Expand Up @@ -84,17 +84,19 @@ class AchievementManager private constructor(context: Context) {
fun setCurrentActivity(activity: Activity?) {
this.currentActivity = WeakReference<Activity?>(activity)
// Create Android UiNotifier adapter when activity is set
if (activity != null) {
this.uiNotifier = if (activity != null) {
val ctx = this.context
this.uiNotifier = WeakReference(UiNotifier { message ->
UiNotifier { message ->
Handler(Looper.getMainLooper()).post {
try {
Toast.makeText(ctx, message, Toast.LENGTH_LONG).show()
} catch (e: Exception) {
e(e, "[UPDATE_NUDGE] Failed to show toast")
}
}
})
}
} else {
null
}
// Show any pending update nudge now that we have an activity
if (activity != null && pendingNudgeVersion != null) {
Expand All @@ -108,7 +110,7 @@ class AchievementManager private constructor(context: Context) {
* Use this on non-Android platforms (KMP/iOS) instead of setCurrentActivity.
*/
fun setUiNotifier(notifier: UiNotifier?) {
this.uiNotifier = if (notifier != null) WeakReference(notifier) else null
this.uiNotifier = notifier
}

/**
Expand All @@ -135,7 +137,7 @@ class AchievementManager private constructor(context: Context) {

private fun showUpdateNudgeInternal(version: String?) {
val message = context.getString(R.string.update_available_nudge, version)
uiNotifier?.get()?.showMessage(message) ?: d("[UPDATE_NUDGE] No UiNotifier available, cannot show nudge: version=%s", version)
uiNotifier?.showMessage(message) ?: d("[UPDATE_NUDGE] No UiNotifier available, cannot show nudge: version=%s", version)
}

/**
Expand Down