manager: use ParceledListSlice to transport List<PackageInfo>, avoiding TransactionTooLargeException.

This commit is contained in:
tiann
2023-04-18 18:04:49 +08:00
parent 2bc84014c2
commit 2bfd4d71d8
5 changed files with 20 additions and 21 deletions

View File

@@ -84,6 +84,8 @@ dependencies {
val libsuVersion = "5.0.4" val libsuVersion = "5.0.4"
implementation("com.github.topjohnwu.libsu:core:$libsuVersion") implementation("com.github.topjohnwu.libsu:core:$libsuVersion")
implementation("com.github.topjohnwu.libsu:service:$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") implementation("com.github.alorma:compose-settings-ui-m3:0.22.0")
ksp("io.github.raamcosta.compose-destinations:ksp:$composeDestinationsVersion") ksp("io.github.raamcosta.compose-destinations:ksp:$composeDestinationsVersion")

View File

@@ -2,10 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<application <application
android:name=".KernelSUApplication" android:name=".KernelSUApplication"
android:allowBackup="true" android:allowBackup="true"

View File

@@ -2,8 +2,8 @@
package me.weishu.kernelsu; package me.weishu.kernelsu;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import java.util.List; import rikka.parcelablelist.ParcelableListSlice;
interface IKsuInterface { interface IKsuInterface {
List<PackageInfo> getPackages(); ParcelableListSlice<PackageInfo> getPackages(int flags);
} }

View File

@@ -18,6 +18,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import me.weishu.kernelsu.IKsuInterface; import me.weishu.kernelsu.IKsuInterface;
import rikka.parcelablelist.ParcelableListSlice;
/** /**
* @author weishu * @author weishu
@@ -30,10 +31,10 @@ public class KsuService extends RootService {
class Stub extends IKsuInterface.Stub { class Stub extends IKsuInterface.Stub {
@Override @Override
public List<PackageInfo> getPackages() { public ParcelableListSlice<PackageInfo> getPackages(int flags) {
List<PackageInfo> list = getInstalledPackagesAll(); List<PackageInfo> list = getInstalledPackagesAll(flags);
Log.i(TAG, "getPackages: " + list.size()); 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(); List<UserHandle> userProfiles = um.getUserProfiles();
for (UserHandle userProfile : userProfiles) { for (UserHandle userProfile : userProfiles) {
int userId = userProfile.hashCode(); int userId = userProfile.hashCode();
if (userId == 0) {
continue;
}
result.add(userProfile.hashCode()); result.add(userProfile.hashCode());
} }
return result; return result;
} }
ArrayList<PackageInfo> getInstalledPackagesAll() { ArrayList<PackageInfo> getInstalledPackagesAll(int flags) {
ArrayList<PackageInfo> packages = new ArrayList<>(); ArrayList<PackageInfo> packages = new ArrayList<>();
for (Integer userId : getUserIds()) { for (Integer userId : getUserIds()) {
Log.i(TAG, "getInstalledPackagesAll: " + userId); Log.i(TAG, "getInstalledPackagesAll: " + userId);
packages.addAll(getInstalledPackagesAsUser(userId)); packages.addAll(getInstalledPackagesAsUser(flags, userId));
} }
return packages; return packages;
} }
List<PackageInfo> getInstalledPackagesAsUser(int userId) { List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
try { try {
PackageManager pm = getPackageManager(); PackageManager pm = getPackageManager();
Method getInstalledPackagesAsUser = pm.getClass().getDeclaredMethod("getInstalledPackagesAsUser", int.class, int.class); 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) { } catch (Throwable e) {
Log.e(TAG, "err", e); Log.e(TAG, "err", e);
} }

View File

@@ -105,9 +105,6 @@ class SuperUserViewModel : ViewModel() {
val result = connectKsuService { val result = connectKsuService {
Log.w(TAG, "KsuService disconnected") Log.w(TAG, "KsuService disconnected")
} }
val binder = result.first
val extraPackages = IKsuInterface.Stub.asInterface(binder).packages
stopKsuService()
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
isRefreshing = true isRefreshing = true
@@ -118,8 +115,14 @@ class SuperUserViewModel : ViewModel() {
Log.i(TAG, "denyList: $denyList") Log.i(TAG, "denyList: $denyList")
val start = SystemClock.elapsedRealtime() val start = SystemClock.elapsedRealtime()
val packages = pm.getInstalledPackages(0) val binder = result.first
packages.addAll(extraPackages) val allPackages = IKsuInterface.Stub.asInterface(binder).getPackages(0)
withContext(Dispatchers.Main) {
stopKsuService()
}
val packages = allPackages.list
apps = packages.map { apps = packages.map {
val appInfo = it.applicationInfo val appInfo = it.applicationInfo