diff --git a/app/src/main/java/com/aurora/store/compose/ui/commons/MicroGInstallerPrerequisiteDialog.kt b/app/src/main/java/com/aurora/store/compose/ui/commons/MicroGInstallerPrerequisiteDialog.kt
new file mode 100644
index 000000000..7e18156a0
--- /dev/null
+++ b/app/src/main/java/com/aurora/store/compose/ui/commons/MicroGInstallerPrerequisiteDialog.kt
@@ -0,0 +1,90 @@
+/*
+ * SPDX-FileCopyrightText: 2026 Aurora OSS
+ * SPDX-FileCopyrightText: 2026 The Calyx Institute
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package com.aurora.store.compose.ui.commons
+
+import android.content.ActivityNotFoundException
+import android.content.ComponentName
+import android.content.Intent
+import android.util.Log
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewWrapper
+import com.aurora.Constants.PACKAGE_NAME_GMS
+import com.aurora.extensions.TAG
+import com.aurora.store.R
+import com.aurora.store.compose.preview.ThemePreviewProvider
+
+private const val MICROG_SETTINGS_ACTIVITY = "org.microg.gms.ui.SettingsActivity"
+
+/**
+ * Dialog informing users about the prerequisite for using the microG installer
+ * @param onConfirm Callback on confirmation
+ * @param onDismiss Callback on dismissal
+ */
+@Composable
+fun MicroGInstallerPrerequisiteDialog(onConfirm: () -> Unit = {}, onDismiss: () -> Unit = {}) {
+ val context = LocalContext.current
+
+ AlertDialog(
+ title = { Text(text = stringResource(R.string.microg_installer_prerequisite_title)) },
+ text = {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(
+ dimensionResource(R.dimen.spacing_small)
+ )
+ ) {
+ Text(text = stringResource(R.string.microg_installer_prerequisite_desc))
+ OutlinedButton (
+ onClick = {
+ try {
+ context.startActivity(
+ Intent().apply {
+ component = ComponentName(
+ PACKAGE_NAME_GMS,
+ MICROG_SETTINGS_ACTIVITY
+ )
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ }
+ )
+ } catch (_: ActivityNotFoundException) {
+ Log.i(TAG, "Unable to launch microG settings")
+ }
+ }
+ ) {
+ Text(text = stringResource(R.string.microg_installer_open_settings))
+ }
+ }
+ },
+ onDismissRequest = onDismiss,
+ confirmButton = {
+ TextButton(onClick = onConfirm) {
+ Text(text = stringResource(R.string.action_ok))
+ }
+ },
+ dismissButton = {
+ TextButton(onClick = onDismiss) {
+ Text(text = stringResource(R.string.action_cancel))
+ }
+ }
+ )
+}
+
+@PreviewWrapper(ThemePreviewProvider::class)
+@Preview
+@Composable
+private fun MicroGInstallerPrerequisiteDialogPreview() {
+ MicroGInstallerPrerequisiteDialog()
+}
diff --git a/app/src/main/java/com/aurora/store/compose/ui/preferences/installation/InstallerScreen.kt b/app/src/main/java/com/aurora/store/compose/ui/preferences/installation/InstallerScreen.kt
index 09a9a367b..cd8519a52 100644
--- a/app/src/main/java/com/aurora/store/compose/ui/preferences/installation/InstallerScreen.kt
+++ b/app/src/main/java/com/aurora/store/compose/ui/preferences/installation/InstallerScreen.kt
@@ -15,7 +15,9 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
@@ -28,6 +30,7 @@ import com.aurora.store.R
import com.aurora.store.compose.composable.InstallerListItem
import com.aurora.store.compose.composable.TopAppBar
import com.aurora.store.compose.preview.ThemePreviewProvider
+import com.aurora.store.compose.ui.commons.MicroGInstallerPrerequisiteDialog
import com.aurora.store.data.installer.AppInstaller
import com.aurora.store.data.installer.SessionInstaller
import com.aurora.store.data.model.Installer
@@ -61,6 +64,17 @@ private fun ScreenContent(
onInstallerSelected: (installer: Installer) -> Unit = {}
) {
val snackBarHostState = remember { snackBarHostState }
+ var showMicroGPrerequisite by remember { mutableStateOf(false) }
+
+ if (showMicroGPrerequisite) {
+ MicroGInstallerPrerequisiteDialog(
+ onConfirm = {
+ showMicroGPrerequisite = false
+ onInstallerSelected(Installer.MICROG)
+ },
+ onDismiss = { showMicroGPrerequisite = false }
+ )
+ }
Scaffold(
snackbarHost = {
@@ -82,7 +96,13 @@ private fun ScreenContent(
InstallerListItem(
installerInfo = installerInfo,
isSelected = installerInfo.installer == currentInstaller,
- onClick = { onInstallerSelected(installerInfo.installer) }
+ onClick = {
+ if (installerInfo.installer == Installer.MICROG) {
+ showMicroGPrerequisite = true
+ } else {
+ onInstallerSelected(installerInfo.installer)
+ }
+ }
)
}
}
diff --git a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt
index c5f73c51d..0e3d7e053 100644
--- a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt
+++ b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt
@@ -41,6 +41,7 @@ import com.aurora.store.data.installer.base.IInstaller
import com.aurora.store.data.model.Installer
import com.aurora.store.data.model.InstallerInfo
import com.aurora.store.util.PackageUtil
+import com.aurora.store.util.PackageUtil.hasMicroGCompanion
import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID
import com.topjohnwu.superuser.Shell
@@ -83,7 +84,7 @@ class AppInstaller @Inject constructor(
if (hasAuroraService(context)) ServiceInstaller.installerInfo else null,
if (hasAppManager(context)) AMInstaller.installerInfo else null,
if (hasShizukuOrSui(context)) ShizukuInstaller.installerInfo else null,
- if (hasMicroGInstaller(context)) MicroGInstaller.installerInfo else null
+ if (hasMicroGCompanion(context)) MicroGInstaller.installerInfo else null
)
/**
@@ -154,6 +155,7 @@ class AppInstaller @Inject constructor(
false
}
+ // TODO: Use microG's proposed API instead of relying on a hardcoded metadata flag that can be misleading (e.g. user can enable the installer from UI)
fun hasMicroGInstaller(context: Context): Boolean {
if (!PackageUtil.hasMicroGCompanion(context)) return false
return try {
@@ -236,7 +238,7 @@ class AppInstaller @Inject constructor(
defaultInstaller
}
- Installer.MICROG -> if (hasMicroGInstaller(context)) {
+ Installer.MICROG -> if (hasMicroGCompanion(context)) {
microGInstaller
} else {
defaultInstaller
diff --git a/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt
index aa5fabf1e..e72fcf4cb 100644
--- a/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt
+++ b/app/src/main/java/com/aurora/store/data/installer/MicroGInstaller.kt
@@ -31,6 +31,7 @@ import com.aurora.store.data.installer.base.InstallerBase
import com.aurora.store.data.model.Installer
import com.aurora.store.data.model.InstallerInfo
import com.aurora.store.data.room.download.Download
+import com.aurora.store.util.PackageUtil.hasMicroGCompanion
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
@@ -68,7 +69,7 @@ class MicroGInstaller @Inject constructor(
Log.i(TAG, "${download.packageName} already queued")
}
- AppInstaller.hasMicroGInstaller(context) -> {
+ hasMicroGCompanion(context) -> {
Log.i(TAG, "Received microG install request for ${download.packageName}")
val files = getFiles(download.packageName, download.versionCode)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bf7280757..dcc13a6a4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -469,6 +469,9 @@
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
+ Enable microG installer
+ Before using the microG installer, please ensure you have enabled it.\n\nPlay Store services → ⋮ → App Installer Settings → Allow App Installation
+ Open microG settings
Full-featured open source package manager
Requires App Manager, need adb/root mode to install when miui optimization is on
Using system APIs directly with adb/root privileges