manager: use ParceledListSlice to transport List<PackageInfo>, avoiding TransactionTooLargeException.
This commit is contained in:
@@ -84,6 +84,8 @@ dependencies {
|
||||
val libsuVersion = "5.0.4"
|
||||
implementation("com.github.topjohnwu.libsu:core:$libsuVersion")
|
||||
implementation("com.github.topjohnwu.libsu:service:$libsuVersion")
|
||||
implementation("dev.rikka.rikkax.parcelablelist:parcelablelist:2.0.0")
|
||||
|
||||
implementation("com.github.alorma:compose-settings-ui-m3:0.22.0")
|
||||
|
||||
ksp("io.github.raamcosta.compose-destinations:ksp:$composeDestinationsVersion")
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<application
|
||||
android:name=".KernelSUApplication"
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
package me.weishu.kernelsu;
|
||||
|
||||
import android.content.pm.PackageInfo;
|
||||
import java.util.List;
|
||||
import rikka.parcelablelist.ParcelableListSlice;
|
||||
|
||||
interface IKsuInterface {
|
||||
List<PackageInfo> getPackages();
|
||||
ParcelableListSlice<PackageInfo> getPackages(int flags);
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.weishu.kernelsu.IKsuInterface;
|
||||
import rikka.parcelablelist.ParcelableListSlice;
|
||||
|
||||
/**
|
||||
* @author weishu
|
||||
@@ -30,10 +31,10 @@ public class KsuService extends RootService {
|
||||
|
||||
class Stub extends IKsuInterface.Stub {
|
||||
@Override
|
||||
public List<PackageInfo> getPackages() {
|
||||
List<PackageInfo> list = getInstalledPackagesAll();
|
||||
public ParcelableListSlice<PackageInfo> getPackages(int flags) {
|
||||
List<PackageInfo> list = getInstalledPackagesAll(flags);
|
||||
Log.i(TAG, "getPackages: " + list.size());
|
||||
return list;
|
||||
return new ParcelableListSlice<>(list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,28 +49,25 @@ public class KsuService extends RootService {
|
||||
List<UserHandle> userProfiles = um.getUserProfiles();
|
||||
for (UserHandle userProfile : userProfiles) {
|
||||
int userId = userProfile.hashCode();
|
||||
if (userId == 0) {
|
||||
continue;
|
||||
}
|
||||
result.add(userProfile.hashCode());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ArrayList<PackageInfo> getInstalledPackagesAll() {
|
||||
ArrayList<PackageInfo> getInstalledPackagesAll(int flags) {
|
||||
ArrayList<PackageInfo> packages = new ArrayList<>();
|
||||
for (Integer userId : getUserIds()) {
|
||||
Log.i(TAG, "getInstalledPackagesAll: " + userId);
|
||||
packages.addAll(getInstalledPackagesAsUser(userId));
|
||||
packages.addAll(getInstalledPackagesAsUser(flags, userId));
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
List<PackageInfo> getInstalledPackagesAsUser(int userId) {
|
||||
List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
|
||||
try {
|
||||
PackageManager pm = getPackageManager();
|
||||
Method getInstalledPackagesAsUser = pm.getClass().getDeclaredMethod("getInstalledPackagesAsUser", int.class, int.class);
|
||||
return (List<PackageInfo>) getInstalledPackagesAsUser.invoke(pm, 0, userId);
|
||||
return (List<PackageInfo>) getInstalledPackagesAsUser.invoke(pm, flags, userId);
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "err", e);
|
||||
}
|
||||
|
||||
@@ -105,9 +105,6 @@ class SuperUserViewModel : ViewModel() {
|
||||
val result = connectKsuService {
|
||||
Log.w(TAG, "KsuService disconnected")
|
||||
}
|
||||
val binder = result.first
|
||||
val extraPackages = IKsuInterface.Stub.asInterface(binder).packages
|
||||
stopKsuService()
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
isRefreshing = true
|
||||
@@ -118,8 +115,14 @@ class SuperUserViewModel : ViewModel() {
|
||||
Log.i(TAG, "denyList: $denyList")
|
||||
val start = SystemClock.elapsedRealtime()
|
||||
|
||||
val packages = pm.getInstalledPackages(0)
|
||||
packages.addAll(extraPackages)
|
||||
val binder = result.first
|
||||
val allPackages = IKsuInterface.Stub.asInterface(binder).getPackages(0)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
stopKsuService()
|
||||
}
|
||||
|
||||
val packages = allPackages.list
|
||||
|
||||
apps = packages.map {
|
||||
val appInfo = it.applicationInfo
|
||||
|
||||
Reference in New Issue
Block a user