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
}
}