Skip to content

Commit e741347

Browse files
committed
Rework installer package name logic to work below Android 9 and fix session creation below Android 12
1 parent 7885699 commit e741347

File tree

6 files changed

+39
-8
lines changed

6 files changed

+39
-8
lines changed

app/src/main/aidl/dev/zwander/installwithoptions/IShellInterface.aidl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import dev.zwander.installwithoptions.IOptionsApplier;
55
import java.util.List;
66

77
interface IShellInterface {
8-
void install(in AssetFileDescriptor[] descriptors, in int[] options, boolean splits, IOptionsApplier optionsApplier) = 1;
8+
void install(in AssetFileDescriptor[] descriptors, in int[] options, boolean splits, IOptionsApplier optionsApplier, String installerPackageName) = 1;
99

1010
void destroy() = 16777114;
1111
}

app/src/main/java/dev/zwander/installwithoptions/MainActivity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import androidx.compose.material3.Surface
4040
import androidx.compose.material3.Text
4141
import androidx.compose.material3.TextButton
4242
import androidx.compose.runtime.Composable
43+
import androidx.compose.runtime.collectAsState
4344
import androidx.compose.runtime.getValue
4445
import androidx.compose.runtime.mutableStateOf
4546
import androidx.compose.runtime.remember
@@ -158,7 +159,8 @@ fun MainContent(modifier: Modifier = Modifier) {
158159
)
159160
}
160161
is MutableOption<*> -> {
161-
when (option.value.value) {
162+
val value by option.value.collectAsState()
163+
when (value) {
162164
is String? -> {
163165
@Suppress("UNCHECKED_CAST")
164166
TextOptionItem(option = option as MutableOption<String>)

app/src/main/java/dev/zwander/installwithoptions/data/MutableOption.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.zwander.installwithoptions.data
22

3+
import android.annotation.SuppressLint
34
import android.content.pm.PackageInstaller.SessionParams
45
import android.os.Build
56
import androidx.annotation.Keep
@@ -47,7 +48,8 @@ sealed class MutableOption<T>(
4748
settings = Settings.settings,
4849
),
4950
operator = {
50-
if (!it.isNullOrBlank()) {
51+
@SuppressLint("NewApi")
52+
if (!it.isNullOrBlank() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
5153
setInstallerPackageName(it)
5254
}
5355
},

app/src/main/java/dev/zwander/installwithoptions/util/Installer.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import dev.zwander.installwithoptions.IOptionsApplier
3838
import dev.zwander.installwithoptions.R
3939
import dev.zwander.installwithoptions.data.DataModel
4040
import dev.zwander.installwithoptions.data.InstallOption
41+
import dev.zwander.installwithoptions.data.MutableOption
4142
import dev.zwander.installwithoptions.data.Settings
4243
import dev.zwander.installwithoptions.data.getMutableOptions
4344
import kotlinx.coroutines.Dispatchers
@@ -137,6 +138,7 @@ fun rememberPackageInstaller(files: List<DocumentFile>): Installer {
137138
options.map { it.value }.toIntArray(),
138139
split,
139140
applier,
141+
MutableOption.InstallerPackage.settingsKey.getValue(),
140142
)
141143
}
142144
} catch (e: Exception) {

app/src/main/java/dev/zwander/installwithoptions/util/InternalInstaller.kt

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import android.content.pm.IPackageInstallerSession
1010
import android.content.pm.IPackageManager
1111
import android.content.pm.PackageInstaller
1212
import android.content.res.AssetFileDescriptor
13+
import android.os.Build
1314
import android.os.FileBridge
1415
import android.os.ParcelFileDescriptor
1516
import android.os.ServiceManager
@@ -29,12 +30,13 @@ class InternalInstaller(private val context: Context) {
2930
options: IntArray,
3031
splits: Boolean,
3132
applier: IOptionsApplier,
33+
installerPackageName: String,
3234
) {
3335
if (splits) {
34-
installPackagesInSession(fileDescriptors, options, applier)
36+
installPackagesInSession(fileDescriptors, options, applier, installerPackageName)
3537
} else {
3638
fileDescriptors.forEach { fd ->
37-
installPackagesInSession(arrayOf(fd), options, applier)
39+
installPackagesInSession(arrayOf(fd), options, applier, installerPackageName)
3840
}
3941
}
4042
}
@@ -44,6 +46,7 @@ class InternalInstaller(private val context: Context) {
4446
fileDescriptors: Array<AssetFileDescriptor>,
4547
options: IntArray,
4648
applier: IOptionsApplier,
49+
installerPackageName: String,
4750
) {
4851
var session: IPackageInstallerSession? = null
4952

@@ -54,8 +57,23 @@ class InternalInstaller(private val context: Context) {
5457
options.reduceOrNull { acc, i -> acc or i }?.let { flags -> installFlags = flags }
5558
applier.applyOptions(this)
5659
}
57-
val sessionId =
58-
packageInstaller.createSession(params, "system", "system", UserHandle.myUserId())
60+
val sessionId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
61+
packageInstaller.createSession(params, installerPackageName, installerPackageName, UserHandle.myUserId())
62+
} else {
63+
packageInstaller::class.java
64+
.getMethod(
65+
"createSession",
66+
PackageInstaller.SessionParams::class.java,
67+
String::class.java,
68+
Int::class.java
69+
)
70+
.invoke(
71+
packageInstaller,
72+
params,
73+
installerPackageName,
74+
UserHandle.myUserId(),
75+
) as Int
76+
}
5977
session = packageInstaller.openSession(sessionId)
6078
val statusIntent = PendingIntent.getBroadcast(
6179
context, Random.nextInt(),

app/src/main/java/dev/zwander/installwithoptions/util/ShellInterface.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,19 @@ class ShellInterface(context: Context) : IShellInterface.Stub() {
3434
options: IntArray,
3535
splits: Boolean,
3636
applier: IOptionsApplier,
37+
installerPackageName: String?,
3738
) {
3839
if (Looper.myLooper() == null) {
3940
Looper.prepare()
4041
}
4142

42-
installer.installPackage(fileDescriptors, options, splits, applier)
43+
installer.installPackage(
44+
fileDescriptors,
45+
options,
46+
splits,
47+
applier,
48+
installerPackageName.takeIf { !it.isNullOrBlank() } ?: "shell",
49+
)
4350
}
4451

4552
override fun destroy() {

0 commit comments

Comments
 (0)