Fix binder transaction overflow in RootPackageManager
Fetch installed packages in chunks of 50 to avoid exceeding the 1MB binder transaction limit on devices with many apps.
This commit is contained in:
@@ -3,5 +3,5 @@ package io.nekohasekai.sfa.vendor;
|
|||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
|
|
||||||
interface IRootPackageManager {
|
interface IRootPackageManager {
|
||||||
List<PackageInfo> getInstalledPackages(int flags);
|
List<PackageInfo> getInstalledPackages(int flags, int offset, int limit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,8 +91,18 @@ object RootPackageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val CHUNK_SIZE = 50
|
||||||
|
|
||||||
suspend fun getInstalledPackages(flags: Int): List<PackageInfo> {
|
suspend fun getInstalledPackages(flags: Int): List<PackageInfo> {
|
||||||
val svc = bindService()
|
val svc = bindService()
|
||||||
return svc.getInstalledPackages(flags)
|
val result = mutableListOf<PackageInfo>()
|
||||||
|
var offset = 0
|
||||||
|
while (true) {
|
||||||
|
val chunk = svc.getInstalledPackages(flags, offset, CHUNK_SIZE)
|
||||||
|
if (chunk.isEmpty()) break
|
||||||
|
result.addAll(chunk)
|
||||||
|
offset += chunk.size
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import com.topjohnwu.superuser.ipc.RootService
|
|||||||
class RootPackageManagerService : RootService() {
|
class RootPackageManagerService : RootService() {
|
||||||
|
|
||||||
private val binder = object : IRootPackageManager.Stub() {
|
private val binder = object : IRootPackageManager.Stub() {
|
||||||
override fun getInstalledPackages(flags: Int): List<PackageInfo> {
|
override fun getInstalledPackages(flags: Int, offset: Int, limit: Int): List<PackageInfo> {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
val allPackages = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
packageManager.getInstalledPackages(
|
packageManager.getInstalledPackages(
|
||||||
PackageManager.PackageInfoFlags.of(flags.toLong())
|
PackageManager.PackageInfoFlags.of(flags.toLong())
|
||||||
)
|
)
|
||||||
@@ -19,6 +19,11 @@ class RootPackageManagerService : RootService() {
|
|||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
packageManager.getInstalledPackages(flags)
|
packageManager.getInstalledPackages(flags)
|
||||||
}
|
}
|
||||||
|
val endIndex = minOf(offset + limit, allPackages.size)
|
||||||
|
if (offset >= allPackages.size) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
return allPackages.subList(offset, endIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user