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:
世界
2026-01-02 01:00:30 +08:00
parent 6464348e78
commit 4a2ffcd080
3 changed files with 19 additions and 4 deletions

View File

@@ -3,5 +3,5 @@ package io.nekohasekai.sfa.vendor;
import android.content.pm.PackageInfo;
interface IRootPackageManager {
List<PackageInfo> getInstalledPackages(int flags);
List<PackageInfo> getInstalledPackages(int flags, int offset, int limit);
}

View File

@@ -91,8 +91,18 @@ object RootPackageManager {
}
}
private const val CHUNK_SIZE = 50
suspend fun getInstalledPackages(flags: Int): List<PackageInfo> {
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
}
}

View File

@@ -10,8 +10,8 @@ import com.topjohnwu.superuser.ipc.RootService
class RootPackageManagerService : RootService() {
private val binder = object : IRootPackageManager.Stub() {
override fun getInstalledPackages(flags: Int): List<PackageInfo> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
override fun getInstalledPackages(flags: Int, offset: Int, limit: Int): List<PackageInfo> {
val allPackages = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
packageManager.getInstalledPackages(
PackageManager.PackageInfoFlags.of(flags.toLong())
)
@@ -19,6 +19,11 @@ class RootPackageManagerService : RootService() {
@Suppress("DEPRECATION")
packageManager.getInstalledPackages(flags)
}
val endIndex = minOf(offset + limit, allPackages.size)
if (offset >= allPackages.size) {
return emptyList()
}
return allPackages.subList(offset, endIndex)
}
}