diff --git a/app/src/main/java/com/aurora/store/compose/navigation/NavDisplay.kt b/app/src/main/java/com/aurora/store/compose/navigation/NavDisplay.kt
index fb8c6d988..96ff65379 100644
--- a/app/src/main/java/com/aurora/store/compose/navigation/NavDisplay.kt
+++ b/app/src/main/java/com/aurora/store/compose/navigation/NavDisplay.kt
@@ -1,4 +1,5 @@
/*
+ * SPDX-FileCopyrightText: 2026 Aurora OSS
* SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later
*/
@@ -8,7 +9,10 @@ package com.aurora.store.compose.navigation
import android.content.Intent
import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation.NavDeepLinkBuilder
import androidx.navigation3.runtime.NavKey
@@ -16,6 +20,10 @@ import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
import androidx.navigation3.ui.NavDisplay
+import com.aurora.Constants.PACKAGE_NAME_GMS
+import com.aurora.extensions.toast
+import com.aurora.store.AuroraApp
+import com.aurora.store.ComposeActivity
import com.aurora.store.MainActivity
import com.aurora.store.R
import com.aurora.store.compose.ui.about.AboutScreen
@@ -33,6 +41,11 @@ import com.aurora.store.compose.ui.onboarding.OnboardingScreen
import com.aurora.store.compose.ui.preferences.installation.InstallerScreen
import com.aurora.store.compose.ui.search.SearchScreen
import com.aurora.store.compose.ui.spoof.SpoofScreen
+import com.aurora.store.data.event.InstallerEvent
+import com.aurora.store.data.model.AccountType
+import com.aurora.store.data.providers.AccountProvider
+import com.aurora.store.util.PackageUtil
+import com.aurora.store.util.Preferences
/**
* Navigation display for compose screens
@@ -58,6 +71,36 @@ fun NavDisplay(startDestination: NavKey) {
if (backstack.size == 1) activity?.finish() else backstack.removeLastOrNull()
}
+ val context = LocalContext.current
+
+ fun isMicroGAuthInvalidated(): Boolean =
+ Preferences.getBoolean(context, Preferences.PREFERENCE_AUTH_VIA_MICROG, false) &&
+ AccountProvider.getAccountType(context) == AccountType.GOOGLE &&
+ !PackageUtil.hasSupportedMicroGVariant(context)
+
+ fun handleMicroGRemoved() {
+ context.toast(R.string.microg_removed_auth_warning)
+ AccountProvider.logout(context)
+ val intent = Intent(context, ComposeActivity::class.java).apply {
+ addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ context.startActivity(intent)
+ }
+
+ // Check every time the screen resumes in case microG was removed while Aurora was in background.
+ LifecycleEventEffect(Lifecycle.Event.ON_RESUME) {
+ if (isMicroGAuthInvalidated()) handleMicroGRemoved()
+ }
+
+ // Also react immediately if the GMS package is uninstalled while Aurora is in the foreground.
+ LaunchedEffect(Unit) {
+ AuroraApp.events.installerEvent.collect { event ->
+ if (event is InstallerEvent.Uninstalled && event.packageName == PACKAGE_NAME_GMS) {
+ if (isMicroGAuthInvalidated()) handleMicroGRemoved()
+ }
+ }
+ }
+
NavDisplay(
backStack = backstack,
entryDecorators = listOf(
diff --git a/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt b/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt
index 156c4ee9f..f571a8a9f 100644
--- a/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt
+++ b/app/src/main/java/com/aurora/store/data/providers/AccountProvider.kt
@@ -80,5 +80,6 @@ object AccountProvider {
Preferences.remove(context, Constants.ACCOUNT_EMAIL_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AAS_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AUTH_PLAIN)
+ Preferences.remove(context, Preferences.PREFERENCE_AUTH_VIA_MICROG)
}
}
diff --git a/app/src/main/java/com/aurora/store/util/Preferences.kt b/app/src/main/java/com/aurora/store/util/Preferences.kt
index 38bf4f06d..73a9ec17f 100644
--- a/app/src/main/java/com/aurora/store/util/Preferences.kt
+++ b/app/src/main/java/com/aurora/store/util/Preferences.kt
@@ -48,6 +48,7 @@ object Preferences {
const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO"
const val PREFERENCE_MICROG_AUTH = "PREFERENCE_MICROG_AUTH"
+ const val PREFERENCE_AUTH_VIA_MICROG = "PREFERENCE_AUTH_VIA_MICROG"
const val PREFERENCE_DISPENSER_URLS = "PREFERENCE_DISPENSER_URLS"
const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION"
diff --git a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt
index 7b092443c..20a06c9b3 100644
--- a/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt
+++ b/app/src/main/java/com/aurora/store/viewmodel/auth/AuthViewModel.kt
@@ -35,6 +35,7 @@ import com.aurora.store.data.model.AuthState
import com.aurora.store.data.providers.AccountProvider
import com.aurora.store.data.providers.AuthProvider
import com.aurora.store.util.AC2DMTask
+import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -171,13 +172,26 @@ class AuthViewModel @Inject constructor(
_authState.value = AuthState.Verifying
if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) {
authProvider.saveAuthData(authData)
+ val tokenType =
+ if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS
AccountProvider.login(
context,
authData.email,
- authData.aasToken.ifBlank { authData.authToken },
- if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS,
+ authData.aasToken.ifBlank {
+ authData.authToken
+ },
+ tokenType,
accountType
)
+ // Record whether this Google session relies on microG's AccountManager so we
+ // can warn the user if microG is later uninstalled.
+ Preferences.putBoolean(
+ context,
+ Preferences.PREFERENCE_AUTH_VIA_MICROG,
+ accountType == AccountType.GOOGLE &&
+ tokenType == AuthHelper.Token.AUTH &&
+ PackageUtil.hasSupportedMicroGVariant(context)
+ )
_authState.value = AuthState.SignedIn
} else {
authProvider.removeAuthData(context)
diff --git a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt
index 16e24ecf9..1669913ce 100644
--- a/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt
+++ b/app/src/main/java/com/aurora/store/viewmodel/details/AppDetailsViewModel.kt
@@ -16,6 +16,7 @@ import com.aurora.extensions.TAG
import com.aurora.extensions.requiresGMS
import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.Review
+import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
import com.aurora.gplayapi.data.models.details.TestingProgramStatus
import com.aurora.gplayapi.helpers.AppDetailsHelper
import com.aurora.gplayapi.helpers.ReviewsHelper
@@ -41,6 +42,7 @@ import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_EXTENDED
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
+import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -54,8 +56,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import org.json.JSONObject
-import javax.inject.Inject
-import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
@HiltViewModel
class AppDetailsViewModel @Inject constructor(
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4b71e8316..c7df15ff0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -392,6 +392,7 @@
Best suited for devices running below Android 4.4
Installer for background installations
Requires Aurora Services to be installed as a privileged-system app
+ microG is no longer installed. Run setup again to keep things working smoothly.
Requires microG companion app to be installed
Helps you bypass App Integrity (installer only) check
Full-featured open source package manager