Add microG Installer
This commit is contained in:
@@ -119,6 +119,13 @@
|
||||
android:exported="false"
|
||||
android:theme="@style/AppTheme.Translucent" />
|
||||
|
||||
<activity
|
||||
android:name=".data.activity.MicroGInstallerActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/AppTheme.Translucent" />
|
||||
|
||||
<!-- DownloadWorker -->
|
||||
<service
|
||||
android:name="androidx.work.impl.foreground.SystemForegroundService"
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.aurora.store.data.activity
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import com.aurora.Constants.PACKAGE_NAME_PLAY_STORE
|
||||
import com.aurora.extensions.isTAndAbove
|
||||
import com.aurora.store.BuildConfig
|
||||
import com.aurora.store.data.installer.MicroGInstaller.Companion.buildMicroGInstallIntent
|
||||
import java.io.File
|
||||
|
||||
class MicroGInstallerActivity : Activity() {
|
||||
|
||||
companion object {
|
||||
private val TAG = MicroGInstallerActivity::class.java.simpleName
|
||||
private const val REQUEST_CODE = 1001
|
||||
const val EXTRA_FILES = "extra_files"
|
||||
const val EXTRA_PACKAGE_NAME = "extra_package_name"
|
||||
|
||||
fun launch(context: Context, packageName: String, files: List<File>) {
|
||||
val uris = files.map { file ->
|
||||
val uri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"${BuildConfig.APPLICATION_ID}.fileProvider",
|
||||
file
|
||||
)
|
||||
|
||||
context.grantUriPermission(
|
||||
PACKAGE_NAME_PLAY_STORE,
|
||||
uri,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
uri
|
||||
}
|
||||
|
||||
val intent = Intent(context, MicroGInstallerActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
putExtra(EXTRA_PACKAGE_NAME, packageName)
|
||||
putExtra(EXTRA_FILES, ArrayList(uris))
|
||||
}
|
||||
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val files: ArrayList<Uri>? = if (isTAndAbove) {
|
||||
intent.getParcelableArrayListExtra(EXTRA_FILES, Uri::class.java)
|
||||
} else {
|
||||
intent.getParcelableArrayListExtra(EXTRA_FILES)
|
||||
}
|
||||
|
||||
if (files.isNullOrEmpty()) {
|
||||
Log.e(TAG, "No files provided, cannot proceed with MicroG installation")
|
||||
return finish()
|
||||
}
|
||||
|
||||
startActivityForResult(
|
||||
buildMicroGInstallIntent(files),
|
||||
REQUEST_CODE
|
||||
)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
// TODO: Handle result if needed
|
||||
finish()
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,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
|
||||
@@ -52,7 +53,8 @@ class AppInstaller @Inject constructor(
|
||||
private val rootInstaller: RootInstaller,
|
||||
private val serviceInstaller: ServiceInstaller,
|
||||
private val amInstaller: AMInstaller,
|
||||
private val shizukuInstaller: ShizukuInstaller
|
||||
private val shizukuInstaller: ShizukuInstaller,
|
||||
private val microGInstaller: MicroGInstaller
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -73,7 +75,8 @@ class AppInstaller @Inject constructor(
|
||||
if (hasRootAccess()) RootInstaller.installerInfo else null,
|
||||
if (hasAuroraService(context)) ServiceInstaller.installerInfo else null,
|
||||
if (hasAppManager(context)) AMInstaller.installerInfo else null,
|
||||
if (hasShizukuOrSui(context)) ShizukuInstaller.installerInfo else null
|
||||
if (hasShizukuOrSui(context)) ShizukuInstaller.installerInfo else null,
|
||||
if (hasMicroGCompanion(context)) MicroGInstaller.installerInfo else null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -106,6 +109,7 @@ class AppInstaller @Inject constructor(
|
||||
Installer.SERVICE -> hasAuroraService(context)
|
||||
Installer.AM -> false // We cannot check if AppManager has ability to auto-update
|
||||
Installer.SHIZUKU -> isOAndAbove && hasShizukuOrSui(context) && hasShizukuPerm()
|
||||
Installer.MICROG -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +180,7 @@ class AppInstaller @Inject constructor(
|
||||
defaultInstaller
|
||||
}
|
||||
}
|
||||
Installer.MICROG -> if(hasMicroGCompanion(context)) microGInstaller else defaultInstaller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Aurora Store
|
||||
* Copyright (C) 2021, Rahul Kumar Patel <whyorean@gmail.com>
|
||||
*
|
||||
* Aurora Store is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Aurora Store is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Aurora Store. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.aurora.store.data.installer
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.aurora.Constants.PACKAGE_NAME_PLAY_STORE
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.activity.MicroGInstallerActivity
|
||||
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
|
||||
|
||||
@Singleton
|
||||
class MicroGInstaller @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) : InstallerBase(context) {
|
||||
|
||||
companion object {
|
||||
val installerInfo: InstallerInfo
|
||||
get() = InstallerInfo(
|
||||
id = 6,
|
||||
installer = Installer.MICROG,
|
||||
packageNames = listOf(PACKAGE_NAME_PLAY_STORE),
|
||||
installerPackageNames = listOf(PACKAGE_NAME_PLAY_STORE),
|
||||
title = R.string.pref_install_mode_microg,
|
||||
subtitle = R.string.microg_installer_subtitle,
|
||||
description = R.string.microg_installer_desc
|
||||
)
|
||||
|
||||
fun buildMicroGInstallIntent(uris: ArrayList<Uri>): Intent {
|
||||
return Intent("org.microg.vending.action.INSTALL_PACKAGE").apply {
|
||||
setPackage(PACKAGE_NAME_PLAY_STORE)
|
||||
setType("application/vnd.android.package-archive")
|
||||
putExtra(Intent.EXTRA_STREAM, uris)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val TAG = MicroGInstaller::class.java.simpleName
|
||||
|
||||
override fun install(download: Download) {
|
||||
super.install(download)
|
||||
|
||||
when {
|
||||
isAlreadyQueued(download.packageName) -> {
|
||||
Log.i(TAG, "${download.packageName} already queued")
|
||||
}
|
||||
|
||||
hasMicroGCompanion(context) -> {
|
||||
Log.i(TAG, "Received microG install request for ${download.packageName}")
|
||||
|
||||
val files = getFiles(download.packageName, download.versionCode)
|
||||
MicroGInstallerActivity.launch(context, download.packageName, files)
|
||||
|
||||
Log.i(TAG, "Sent install request to microG installer for ${download.packageName}")
|
||||
}
|
||||
|
||||
else -> {
|
||||
postError(
|
||||
download.packageName,
|
||||
context.getString(R.string.installer_status_failure),
|
||||
context.getString(R.string.installer_microg_misconfigured)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ enum class Installer {
|
||||
ROOT,
|
||||
SERVICE,
|
||||
AM,
|
||||
SHIZUKU
|
||||
SHIZUKU,
|
||||
MICROG
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ object PackageUtil {
|
||||
|
||||
private const val VERSION_CODE_MICRO_G: Long = 240913402
|
||||
private const val VERSION_CODE_MICRO_G_HUAWEI: Long = 240913007
|
||||
private const val VERSION_CODE_MICROG_COMPANION_MIN: Long = 84022620
|
||||
private const val MICROG_INSTALL_ACTIVITY = "org.microg.vending.installer.AppInstallActivity"
|
||||
|
||||
fun getAllValidPackages(context: Context): List<PackageInfo> {
|
||||
return context.packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
|
||||
@@ -109,6 +111,26 @@ object PackageUtil {
|
||||
}
|
||||
}
|
||||
|
||||
fun hasActivity(context: Context, packageName: String, activityName: String): Boolean {
|
||||
val intent = Intent()
|
||||
intent.setClassName(packageName, activityName)
|
||||
|
||||
val resolveInfo = context.packageManager.resolveActivity(intent, 0)
|
||||
return resolveInfo != null
|
||||
}
|
||||
|
||||
fun hasMicroGCompanion(context: Context): Boolean {
|
||||
return isInstalled(
|
||||
context,
|
||||
PACKAGE_NAME_PLAY_STORE,
|
||||
VERSION_CODE_MICROG_COMPANION_MIN
|
||||
) && hasActivity(
|
||||
context,
|
||||
PACKAGE_NAME_PLAY_STORE,
|
||||
MICROG_INSTALL_ACTIVITY
|
||||
)
|
||||
}
|
||||
|
||||
fun isInstalled(context: Context, packageName: String, versionCode: Long? = null): Boolean {
|
||||
return try {
|
||||
val packageInfo = getPackageInfo(context, packageName, PackageManager.GET_META_DATA)
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
<string name="installer_service_available">"Aurora Services is available and ready to install."</string>
|
||||
<string name="installer_service_unavailable">Install Aurora Services 1.0.9 or above, or change the installer.</string>
|
||||
<string name="installer_service_misconfigured">Set up Aurora Services and grant all permissions first.</string>
|
||||
<string name="installer_microg_misconfigured">MicroG installer failed to install app, likely due to misconfiguration.</string>
|
||||
<string name="installer_status_failure">"Installer failed"</string>
|
||||
<string name="installer_status_failure_blocked">"Installation was blocked"</string>
|
||||
<string name="installer_status_failure_session">"Could not create session"</string>
|
||||
@@ -211,6 +212,7 @@
|
||||
<string name="pref_install_mode_root">"Root installer"</string>
|
||||
<string name="pref_install_mode_services">"Aurora Services (Deprecated)"</string>
|
||||
<string name="pref_install_mode_session">"Session installer"</string>
|
||||
<string name="pref_install_mode_microg">"MicroG installer"</string>
|
||||
<string name="pref_install_mode_summary">"Select mode of APK installation"</string>
|
||||
<string name="pref_install_mode_title">"Installation method"</string>
|
||||
<string name="pref_vending_version_title">Google Play version</string>
|
||||
@@ -387,6 +389,8 @@
|
||||
<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_desc">Requires Aurora Services to be installed as a privileged-system app</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="am_installer_subtitle">Full-featured open source package manager</string>
|
||||
<string name="am_installer_desc">Requires App Manager, need adb/root mode to install when miui optimization is on</string>
|
||||
<string name="shizuku_installer_subtitle">Using system APIs directly with adb/root privileges</string>
|
||||
|
||||
Reference in New Issue
Block a user