auth: lets keep an eye on microG bundle uninstall

This commit is contained in:
Rahul Patel
2026-05-11 22:21:23 +05:30
parent 2ff098317e
commit 53aff0e24f
6 changed files with 64 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2026 Aurora OSS
* SPDX-FileCopyrightText: 2025 The Calyx Institute * SPDX-FileCopyrightText: 2025 The Calyx Institute
* SPDX-License-Identifier: GPL-3.0-or-later * SPDX-License-Identifier: GPL-3.0-or-later
*/ */
@@ -8,7 +9,10 @@ package com.aurora.store.compose.navigation
import android.content.Intent import android.content.Intent
import androidx.activity.compose.LocalActivity import androidx.activity.compose.LocalActivity
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation.NavDeepLinkBuilder import androidx.navigation.NavDeepLinkBuilder
import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.NavKey
@@ -16,6 +20,10 @@ import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
import androidx.navigation3.ui.NavDisplay 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.MainActivity
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.compose.ui.about.AboutScreen 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.preferences.installation.InstallerScreen
import com.aurora.store.compose.ui.search.SearchScreen import com.aurora.store.compose.ui.search.SearchScreen
import com.aurora.store.compose.ui.spoof.SpoofScreen 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 * Navigation display for compose screens
@@ -58,6 +71,36 @@ fun NavDisplay(startDestination: NavKey) {
if (backstack.size == 1) activity?.finish() else backstack.removeLastOrNull() 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( NavDisplay(
backStack = backstack, backStack = backstack,
entryDecorators = listOf( entryDecorators = listOf(

View File

@@ -80,5 +80,6 @@ object AccountProvider {
Preferences.remove(context, Constants.ACCOUNT_EMAIL_PLAIN) Preferences.remove(context, Constants.ACCOUNT_EMAIL_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AAS_PLAIN) Preferences.remove(context, Constants.ACCOUNT_AAS_PLAIN)
Preferences.remove(context, Constants.ACCOUNT_AUTH_PLAIN) Preferences.remove(context, Constants.ACCOUNT_AUTH_PLAIN)
Preferences.remove(context, Preferences.PREFERENCE_AUTH_VIA_MICROG)
} }
} }

View File

@@ -48,6 +48,7 @@ object Preferences {
const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO" const val PREFERENCE_PROXY_INFO = "PREFERENCE_PROXY_INFO"
const val PREFERENCE_MICROG_AUTH = "PREFERENCE_MICROG_AUTH" 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_DISPENSER_URLS = "PREFERENCE_DISPENSER_URLS"
const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION" const val PREFERENCE_VENDING_VERSION = "PREFERENCE_VENDING_VERSION"

View File

@@ -35,6 +35,7 @@ import com.aurora.store.data.model.AuthState
import com.aurora.store.data.providers.AccountProvider import com.aurora.store.data.providers.AccountProvider
import com.aurora.store.data.providers.AuthProvider import com.aurora.store.data.providers.AuthProvider
import com.aurora.store.util.AC2DMTask import com.aurora.store.util.AC2DMTask
import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
@@ -171,13 +172,26 @@ class AuthViewModel @Inject constructor(
_authState.value = AuthState.Verifying _authState.value = AuthState.Verifying
if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) { if (authData.authToken.isNotEmpty() && authData.deviceConfigToken.isNotEmpty()) {
authProvider.saveAuthData(authData) authProvider.saveAuthData(authData)
val tokenType =
if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS
AccountProvider.login( AccountProvider.login(
context, context,
authData.email, authData.email,
authData.aasToken.ifBlank { authData.authToken }, authData.aasToken.ifBlank {
if (authData.aasToken.isBlank()) AuthHelper.Token.AUTH else AuthHelper.Token.AAS, authData.authToken
},
tokenType,
accountType 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 _authState.value = AuthState.SignedIn
} else { } else {
authProvider.removeAuthData(context) authProvider.removeAuthData(context)

View File

@@ -16,6 +16,7 @@ import com.aurora.extensions.TAG
import com.aurora.extensions.requiresGMS import com.aurora.extensions.requiresGMS
import com.aurora.gplayapi.data.models.App import com.aurora.gplayapi.data.models.App
import com.aurora.gplayapi.data.models.Review 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.data.models.details.TestingProgramStatus
import com.aurora.gplayapi.helpers.AppDetailsHelper import com.aurora.gplayapi.helpers.AppDetailsHelper
import com.aurora.gplayapi.helpers.ReviewsHelper 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 com.aurora.store.util.Preferences.PREFERENCE_UPDATES_EXTENDED
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
@@ -54,8 +56,6 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject
import com.aurora.gplayapi.data.models.datasafety.Report as DataSafetyReport
@HiltViewModel @HiltViewModel
class AppDetailsViewModel @Inject constructor( class AppDetailsViewModel @Inject constructor(

View File

@@ -392,6 +392,7 @@
<string name="native_installer_desc">Best suited for devices running below Android 4.4</string> <string name="native_installer_desc">Best suited for devices running below Android 4.4</string>
<string name="services_installer_subtitle">Installer for background installations</string> <string name="services_installer_subtitle">Installer for background installations</string>
<string name="services_installer_desc">Requires Aurora Services to be installed as a privileged-system app</string> <string name="services_installer_desc">Requires Aurora Services to be installed as a privileged-system app</string>
<string name="microg_removed_auth_warning">microG is no longer installed. Run setup again to keep things working smoothly.</string>
<string name="microg_installer_subtitle">Requires microG companion app to be installed</string> <string name="microg_installer_subtitle">Requires microG companion app to be installed</string>
<string name="microg_installer_desc">Helps you bypass App Integrity (installer only) check</string> <string name="microg_installer_desc">Helps you bypass App Integrity (installer only) check</string>
<string name="am_installer_subtitle">Full-featured open source package manager</string> <string name="am_installer_subtitle">Full-featured open source package manager</string>