diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0c19329..b4cf335 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + @@ -25,8 +26,8 @@ android:name=".ManagerApplication" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" android:requestLegacyExternalStorage="true" + android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" tools:ignore="AllowBackup"> diff --git a/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt b/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt index 4f014ab..d91fce3 100644 --- a/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt +++ b/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt @@ -6,6 +6,7 @@ package com.aliucord.manager.installer.util import android.Manifest +import android.os.Build import pxb.android.axml.* object ManifestPatcher { @@ -67,10 +68,12 @@ object ManifestPatcher { "uses-sdk" -> object : NodeVisitor(nv) { override fun attr(ns: String?, name: String?, resourceId: Int, type: Int, value: Any?) { - if (name != "targetSdkVersion") + if (name == "targetSdkVersion") { + val version = if (Build.VERSION.SDK_INT >= 31) 30 else 28 + super.attr(ns, name, resourceId, type, version) + } else { super.attr(ns, name, resourceId, type, value) - - super.attr(ns, name, resourceId, type, 28) + } } } diff --git a/app/src/main/kotlin/com/aliucord/manager/installer/util/PackageInstaller.kt b/app/src/main/kotlin/com/aliucord/manager/installer/util/PackageInstaller.kt index 6bd2c91..c7c8a8c 100644 --- a/app/src/main/kotlin/com/aliucord/manager/installer/util/PackageInstaller.kt +++ b/app/src/main/kotlin/com/aliucord/manager/installer/util/PackageInstaller.kt @@ -6,18 +6,28 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.PackageInstaller +import android.content.pm.PackageInstaller.SessionParams +import android.content.pm.PackageManager import android.net.Uri import android.os.Build import com.aliucord.manager.installer.service.InstallService +import kotlinx.coroutines.delay import java.io.File -fun Application.installApks(vararg apks: File) = - packageManager.packageInstaller.installApks(this, *apks) +fun Application.installApks(silent: Boolean = false, vararg apks: File) { + val packageInstaller = packageManager.packageInstaller + val params = SessionParams(SessionParams.MODE_FULL_INSTALL).apply { + if (Build.VERSION.SDK_INT >= 31) { + setInstallScenario(PackageManager.INSTALL_SCENARIO_FAST) -fun PackageInstaller.installApks(application: Application, vararg apks: File) { - val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) - val sessionId = createSession(params) - val session = openSession(sessionId) + if (silent) { + setRequireUserAction(SessionParams.USER_ACTION_NOT_REQUIRED) + } + } + } + + val sessionId = packageInstaller.createSession(params) + val session = packageInstaller.openSession(sessionId) apks.forEach { apk -> session.openWrite(apk.name, 0, apk.length()).use { @@ -26,13 +36,13 @@ fun PackageInstaller.installApks(application: Application, vararg apks: File) { } } - val callbackIntent = Intent(application, InstallService::class.java) + val callbackIntent = Intent(this, InstallService::class.java) @SuppressLint("UnspecifiedImmutableFlag") val contentIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - PendingIntent.getService(application, 0, callbackIntent, PendingIntent.FLAG_MUTABLE) + PendingIntent.getService(this, 0, callbackIntent, PendingIntent.FLAG_MUTABLE) } else { - PendingIntent.getService(application, 0, callbackIntent, 0) + PendingIntent.getService(this, 0, callbackIntent, 0) } session.commit(contentIntent.intentSender) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/InstallViewModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/InstallViewModel.kt index de61551..5f70d47 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/InstallViewModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/InstallViewModel.kt @@ -409,12 +409,29 @@ class InstallViewModel( } step(InstallStep.SIGN_APK) { + // Align resources.arsc due to targeting api 30 for silent install + if (Build.VERSION.SDK_INT >= 31) { + for (file in apks) { + val bytes = ZipReader(file).use { + if (it.entryNames.contains("resources.arsc")) { + it.openEntry("resources.arsc")?.read() + } else { + null + } + } ?: continue + + ZipWriter(file, true).use { + it.deleteEntry("resources.arsc", true) + it.writeEntry("resources.arsc", bytes, ZipCompression.NONE, 4096) + } + } + } + apks.forEach(Signer::signApk) } step(InstallStep.INSTALL_APK) { - application.packageManager.packageInstaller - .installApks(application, *apks) + application.installApks(silent = !preferences.devMode, *apks) } patchedDir.deleteRecursively() @@ -595,12 +612,27 @@ class InstallViewModel( } step(InstallStep.SIGN_APK) { + // Align resources.arsc due to targeting api 30 for silent install + if (Build.VERSION.SDK_INT >= 31) { + val bytes = ZipReader(baseApkFile).use { + if (it.entryNames.contains("resources.arsc")) { + it.openEntry("resources.arsc")?.read() + } else { + null + } + } + + ZipWriter(baseApkFile, true).use { + it.deleteEntry("resources.arsc", true) + it.writeEntry("resources.arsc", bytes, ZipCompression.NONE, 4096) + } + } + Signer.signApk(baseApkFile) } step(InstallStep.INSTALL_APK) { - application.packageManager.packageInstaller - .installApks(application, baseApkFile) + application.installApks(silent = !preferences.devMode, baseApkFile) } patchedDir.deleteRecursively() diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/UpdaterViewModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/UpdaterViewModel.kt index eeeabfd..f11800d 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/UpdaterViewModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/viewmodel/UpdaterViewModel.kt @@ -41,18 +41,14 @@ class UpdaterViewModel( viewModelScope.launch { isWorking = true - application.externalCacheDir!!.resolve("manager.apk").apply { - delete() + application.externalCacheDir!!.resolve("manager.apk").also { + it.delete() - downloadManager.download(url, this) - application.installApks(this) - delay(10000) + downloadManager.download(url, it) + application.installApks(silent = true, it) - showDialog = false - delete() + it.delete() } - - isWorking = false } }