diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 53dcb3d0..93aff0b4 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,7 +1,7 @@ -keep class org.lsposed.manager.Constants { public static void showErrorToast(int); } --keepclasseswithmembers class org.lsposed.manager.receivers.LSPosedManagerServiceClient { +-keepclasseswithmembers class org.lsposed.manager.receivers.LSPManagerServiceClient { private static android.os.IBinder binder; } diff --git a/app/src/main/java/org/lsposed/manager/ConfigManager.java b/app/src/main/java/org/lsposed/manager/ConfigManager.java index 9b378ac6..8fafa5ba 100644 --- a/app/src/main/java/org/lsposed/manager/ConfigManager.java +++ b/app/src/main/java/org/lsposed/manager/ConfigManager.java @@ -28,7 +28,7 @@ import android.util.Log; import org.lsposed.lspd.Application; import org.lsposed.lspd.utils.ParceledListSlice; import org.lsposed.manager.adapters.ScopeAdapter; -import org.lsposed.manager.receivers.LSPosedManagerServiceClient; +import org.lsposed.manager.receivers.LSPManagerServiceClient; import java.io.File; import java.util.ArrayList; @@ -40,7 +40,7 @@ public class ConfigManager { public static int getXposedApiVersion() { try { - return LSPosedManagerServiceClient.getXposedApiVersion(); + return LSPManagerServiceClient.getXposedApiVersion(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return -1; @@ -49,7 +49,7 @@ public class ConfigManager { public static String getXposedVersionName() { try { - return LSPosedManagerServiceClient.getXposedVersionName(); + return LSPManagerServiceClient.getXposedVersionName(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return null; @@ -58,7 +58,7 @@ public class ConfigManager { public static int getXposedVersionCode() { try { - return LSPosedManagerServiceClient.getXposedVersionCode(); + return LSPManagerServiceClient.getXposedVersionCode(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return -1; @@ -68,7 +68,7 @@ public class ConfigManager { public static List getInstalledPackagesFromAllUsers(int flags, boolean filterNoProcess) { List list = new ArrayList<>(); try { - list.addAll(LSPosedManagerServiceClient.getInstalledPackagesFromAllUsers(flags, filterNoProcess)); + list.addAll(LSPManagerServiceClient.getInstalledPackagesFromAllUsers(flags, filterNoProcess)); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); } @@ -77,7 +77,7 @@ public class ConfigManager { public static String[] getEnabledModules() { try { - return LSPosedManagerServiceClient.enabledModules(); + return LSPManagerServiceClient.enabledModules(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return new String[0]; @@ -86,7 +86,7 @@ public class ConfigManager { public static boolean setModuleEnabled(String packageName, boolean enable) { try { - return enable ? LSPosedManagerServiceClient.enableModule(packageName) : LSPosedManagerServiceClient.disableModule(packageName); + return enable ? LSPManagerServiceClient.enableModule(packageName) : LSPManagerServiceClient.disableModule(packageName); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -102,7 +102,7 @@ public class ConfigManager { app.packageName = application.packageName; list.add(app); }); - return LSPosedManagerServiceClient.setModuleScope(packageName, new ParceledListSlice<>(list)); + return LSPManagerServiceClient.setModuleScope(packageName, new ParceledListSlice<>(list)); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -112,7 +112,7 @@ public class ConfigManager { public static List getModuleScope(String packageName) { List list = new ArrayList<>(); try { - List applications = LSPosedManagerServiceClient.getModuleScope(packageName).getList(); + List applications = LSPManagerServiceClient.getModuleScope(packageName).getList(); if (applications == null) { return list; } @@ -129,7 +129,7 @@ public class ConfigManager { public static boolean isResourceHookEnabled() { try { - return LSPosedManagerServiceClient.isResourceHook(); + return LSPManagerServiceClient.isResourceHook(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -138,7 +138,7 @@ public class ConfigManager { public static boolean setResourceHookEnabled(boolean enabled) { try { - LSPosedManagerServiceClient.setResourceHook(enabled); + LSPManagerServiceClient.setResourceHook(enabled); return true; } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); @@ -148,7 +148,7 @@ public class ConfigManager { public static boolean isVerboseLogEnabled() { try { - return LSPosedManagerServiceClient.isVerboseLog(); + return LSPManagerServiceClient.isVerboseLog(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -157,7 +157,7 @@ public class ConfigManager { public static boolean setVerboseLogEnabled(boolean enabled) { try { - LSPosedManagerServiceClient.setVerboseLog(enabled); + LSPManagerServiceClient.setVerboseLog(enabled); return true; } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); @@ -167,7 +167,7 @@ public class ConfigManager { public static ParcelFileDescriptor getLogs(boolean verbose) { try { - return verbose ? LSPosedManagerServiceClient.getVerboseLog() : LSPosedManagerServiceClient.getModulesLog(); + return verbose ? LSPManagerServiceClient.getVerboseLog() : LSPManagerServiceClient.getModulesLog(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return null; @@ -176,7 +176,7 @@ public class ConfigManager { public static boolean clearLogs(boolean verbose) { try { - return LSPosedManagerServiceClient.clearLogs(verbose); + return LSPManagerServiceClient.clearLogs(verbose); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -185,7 +185,7 @@ public class ConfigManager { public static PackageInfo getPackageInfo(String packageName, int flags, int userId) throws PackageManager.NameNotFoundException { try { - return LSPosedManagerServiceClient.getPackageInfo(packageName, flags, userId); + return LSPManagerServiceClient.getPackageInfo(packageName, flags, userId); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); throw new PackageManager.NameNotFoundException(); @@ -194,7 +194,7 @@ public class ConfigManager { public static boolean forceStopPackage(String packageName, int userId) { try { - LSPosedManagerServiceClient.forceStopPackage(packageName, userId); + LSPManagerServiceClient.forceStopPackage(packageName, userId); return true; } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); @@ -204,7 +204,7 @@ public class ConfigManager { public static boolean reboot(boolean confirm, String reason, boolean wait) { try { - LSPosedManagerServiceClient.reboot(confirm, reason, wait); + LSPManagerServiceClient.reboot(confirm, reason, wait); return true; } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); @@ -212,9 +212,9 @@ public class ConfigManager { } } - public static boolean uninstallPackage(String packageName) { + public static boolean uninstallPackage(String packageName, int userId) { try { - return LSPosedManagerServiceClient.uninstallPackage(packageName); + return LSPManagerServiceClient.uninstallPackage(packageName, userId); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -223,7 +223,7 @@ public class ConfigManager { public static boolean isSepolicyLoaded() { try { - return LSPosedManagerServiceClient.isSepolicyLoaded(); + return LSPManagerServiceClient.isSepolicyLoaded(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return false; @@ -232,7 +232,7 @@ public class ConfigManager { public static int[] getUsers() { try { - return LSPosedManagerServiceClient.getUsers(); + return LSPManagerServiceClient.getUsers(); } catch (RemoteException | NullPointerException e) { Log.e(App.TAG, Log.getStackTraceString(e)); return null; diff --git a/app/src/main/java/org/lsposed/manager/receivers/LSPosedManagerServiceClient.java b/app/src/main/java/org/lsposed/manager/receivers/LSPManagerServiceClient.java similarity index 92% rename from app/src/main/java/org/lsposed/manager/receivers/LSPosedManagerServiceClient.java rename to app/src/main/java/org/lsposed/manager/receivers/LSPManagerServiceClient.java index 692b4d53..3cb30c02 100644 --- a/app/src/main/java/org/lsposed/manager/receivers/LSPosedManagerServiceClient.java +++ b/app/src/main/java/org/lsposed/manager/receivers/LSPManagerServiceClient.java @@ -30,7 +30,7 @@ import org.lsposed.lspd.utils.ParceledListSlice; import java.util.List; -public class LSPosedManagerServiceClient { +public class LSPManagerServiceClient { @SuppressWarnings("FieldMayBeFinal") private static IBinder binder = null; @@ -144,9 +144,9 @@ public class LSPosedManagerServiceClient { service.reboot(confirm, reason, wait); } - public static boolean uninstallPackage(String packageName) throws RemoteException, NullPointerException { + public static boolean uninstallPackage(String packageName, int userId) throws RemoteException, NullPointerException { ensureService(); - return service.uninstallPackage(packageName); + return service.uninstallPackage(packageName, userId); } public static boolean isSepolicyLoaded() throws RemoteException, NullPointerException { @@ -158,4 +158,8 @@ public class LSPosedManagerServiceClient { ensureService(); return service.getUsers(); } + public static int installExistingPackageAsUser(String packageName, int userId) throws RemoteException, NullPointerException { + ensureService(); + return service.installExistingPackageAsUser(packageName, userId); + } } diff --git a/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java b/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java index bc86f0df..99f4a035 100644 --- a/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java +++ b/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java @@ -224,9 +224,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi @Override public void onSingleInstalledModuleReloaded() { - adapters.forEach(adapter -> { - adapter.refresh(true); - }); + adapters.forEach(adapter -> adapter.refresh(true)); } @Override @@ -278,7 +276,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi .setMessage(R.string.module_uninstall_message) .setPositiveButton(android.R.string.ok, (dialog, which) -> uninstallHandler.post(() -> { - boolean success = ConfigManager.uninstallPackage(module.packageName); + boolean success = ConfigManager.uninstallPackage(module.packageName, module.userId); runOnUiThread(() -> { String text = success ? getString(R.string.module_uninstalled, module.getAppName()) : getString(R.string.module_uninstall_failed); if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { @@ -425,6 +423,9 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi if (RepoLoader.getInstance().getOnlineModule(item.packageName) == null) { menu.removeItem(R.id.menu_repo); } + if (userHandle == null) { + menu.removeItem(R.id.menu_app_info); + } }); holder.itemView.setOnClickListener(v -> { diff --git a/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java b/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java index 2aa2c7d6..25bbe226 100644 --- a/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java +++ b/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java @@ -86,11 +86,9 @@ public final class ModuleUtil { Map, InstalledModule> modules = new HashMap<>(); for (PackageInfo pkg : ConfigManager.getInstalledPackagesFromAllUsers(PackageManager.GET_META_DATA, false)) { ApplicationInfo app = pkg.applicationInfo; - if (!app.enabled) - continue; if (app.metaData != null && app.metaData.containsKey("xposedminversion")) { - InstalledModule installed = new InstalledModule(pkg, false); + InstalledModule installed = new InstalledModule(pkg); modules.put(Pair.create(pkg.packageName, app.uid / 100000), installed); } } @@ -120,8 +118,8 @@ public final class ModuleUtil { } ApplicationInfo app = pkg.applicationInfo; - if (app.enabled && app.metaData != null && app.metaData.containsKey("xposedminversion")) { - InstalledModule module = new InstalledModule(pkg, false); + if (app.metaData != null && app.metaData.containsKey("xposedminversion")) { + InstalledModule module = new InstalledModule(pkg); installedModules.put(Pair.create(packageName, userId), module); for (ModuleListener listener : listeners) { listener.onSingleInstalledModuleReloaded(); @@ -196,19 +194,17 @@ public final class ModuleUtil { public final int minVersion; public final long installTime; public final long updateTime; - final boolean isFramework; public ApplicationInfo app; public PackageInfo pkg; private String appName; // loaded lazyily private String description; // loaded lazyily private List scopeList; // loaded lazyily - private InstalledModule(PackageInfo pkg, boolean isFramework) { + private InstalledModule(PackageInfo pkg) { this.app = pkg.applicationInfo; this.pkg = pkg; this.userId = pkg.applicationInfo.uid / 100000; this.packageName = pkg.packageName; - this.isFramework = isFramework; this.versionName = pkg.versionName; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { this.versionCode = pkg.versionCode; @@ -218,18 +214,13 @@ public final class ModuleUtil { this.installTime = pkg.firstInstallTime; this.updateTime = pkg.lastUpdateTime; - if (isFramework) { - this.minVersion = 0; - this.description = ""; + Object minVersionRaw = app.metaData.get("xposedminversion"); + if (minVersionRaw instanceof Integer) { + this.minVersion = (Integer) minVersionRaw; + } else if (minVersionRaw instanceof String) { + this.minVersion = extractIntPart((String) minVersionRaw); } else { - Object minVersionRaw = app.metaData.get("xposedminversion"); - if (minVersionRaw instanceof Integer) { - this.minVersion = (Integer) minVersionRaw; - } else if (minVersionRaw instanceof String) { - this.minVersion = extractIntPart((String) minVersionRaw); - } else { - this.minVersion = 0; - } + this.minVersion = 0; } } diff --git a/build.gradle.kts b/build.gradle.kts index 0275313f..5d18ab08 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,7 +37,7 @@ val commitCount = Git(repo).log().add(refId).call().count() val defaultManagerPackageName by extra("org.lsposed.manager") val verCode by extra(commitCount + 4200) -val verName by extra("v1.3.6") +val verName by extra("v1.3.7") val androidTargetSdkVersion by extra(30) val androidMinSdkVersion by extra(27) val androidBuildToolsVersion by extra("30.0.3") diff --git a/core/src/main/java/org/lsposed/lspd/hooker/XposedInstallerHooker.java b/core/src/main/java/org/lsposed/lspd/hooker/XposedInstallerHooker.java index 462b85fd..4b26b1b4 100644 --- a/core/src/main/java/org/lsposed/lspd/hooker/XposedInstallerHooker.java +++ b/core/src/main/java/org/lsposed/lspd/hooker/XposedInstallerHooker.java @@ -32,7 +32,7 @@ public class XposedInstallerHooker { public static void hookXposedInstaller(final ClassLoader classLoader, IBinder binder) { Utils.logI("Found LSPosed Manager, hooking it"); try { - Class serviceClass = XposedHelpers.findClass("org.lsposed.manager.receivers.LSPosedManagerServiceClient", classLoader); + Class serviceClass = XposedHelpers.findClass("org.lsposed.manager.receivers.LSPManagerServiceClient", classLoader); XposedHelpers.setStaticObjectField(serviceClass, "binder", binder); Utils.logI("Hooked LSPosed Manager"); diff --git a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java index 5d5e4059..047e8d28 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java @@ -616,10 +616,6 @@ public class ConfigManager { return uid == managerUid; } - public String getCachePath(String fileName) { - return miscPath + File.separator + "cache" + File.separator + fileName; - } - public String getPrefsPath(String fileName, int uid) { int userId = uid / PER_USER_RANGE; return miscPath + File.separator + "prefs" + (userId == 0 ? "" : String.valueOf(userId)) + File.separator + fileName; @@ -640,6 +636,10 @@ public class ConfigManager { return cachedModule.containsKey(uid % PER_USER_RANGE); } + public boolean isModule(String packageName) { + return cachedModule.containsValue(packageName); + } + private void recursivelyChown(File file, int uid, int gid) throws ErrnoException { Os.chown(file.toString(), uid, gid); if (file.isDirectory()) { diff --git a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java index ca08ca87..343de774 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java @@ -22,6 +22,7 @@ package org.lsposed.lspd.service; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; +import android.graphics.Bitmap; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -36,6 +37,7 @@ import org.lsposed.lspd.BuildConfig; import org.lsposed.lspd.ILSPManagerService; import org.lsposed.lspd.utils.ParceledListSlice; +import static org.lsposed.lspd.service.PackageService.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; import static org.lsposed.lspd.service.ServiceManager.TAG; public class LSPManagerService extends ILSPManagerService.Stub { @@ -148,9 +150,9 @@ public class LSPManagerService extends ILSPManagerService.Stub { } @Override - public boolean uninstallPackage(String packageName) throws RemoteException { + public boolean uninstallPackage(String packageName, int userId) throws RemoteException { try { - return PackageService.uninstallPackage(new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST)); + return PackageService.uninstallPackage(new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST), userId); } catch (InterruptedException | InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) { Log.e(TAG, e.getMessage(), e); return false; @@ -166,4 +168,12 @@ public class LSPManagerService extends ILSPManagerService.Stub { public int[] getUsers() throws RemoteException { return UserService.getUsers(); } + + @Override + public int installExistingPackageAsUser(String packageName, int userid) { + if (ConfigManager.getInstance().isModule(packageName)) { + return PackageService.installExistingPackageAsUser(packageName, userid); + } + return INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME; + } } diff --git a/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java b/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java index b7464a51..02c7e586 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java @@ -96,7 +96,6 @@ public class LSPosedService extends ILSPosedService.Stub { ApplicationInfo applicationInfo = PackageService.getApplicationInfo(packageName, PackageManager.GET_META_DATA, 0); boolean isXposedModule = applicationInfo != null && - applicationInfo.enabled && applicationInfo.metaData != null && applicationInfo.metaData.containsKey("xposedminversion"); diff --git a/core/src/main/java/org/lsposed/lspd/service/PackageService.java b/core/src/main/java/org/lsposed/lspd/service/PackageService.java index cdb8aa6e..1e0d4597 100644 --- a/core/src/main/java/org/lsposed/lspd/service/PackageService.java +++ b/core/src/main/java/org/lsposed/lspd/service/PackageService.java @@ -65,6 +65,12 @@ import java.util.stream.Collectors; import hidden.HiddenApiBridge; public class PackageService { + + static final int INSTALL_FAILED_INTERNAL_ERROR = -110; + static final int INSTALL_REASON_UNKNOWN = 0; + static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106; + + private static IPackageManager pm = null; private static IBinder binder = null; private static final IBinder.DeathRecipient recipient = new IBinder.DeathRecipient() { @@ -231,10 +237,11 @@ public class PackageService { } } - public static boolean uninstallPackage(VersionedPackage versionedPackage) throws RemoteException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + public static boolean uninstallPackage(VersionedPackage versionedPackage, int userId) throws RemoteException, InterruptedException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { CountDownLatch latch = new CountDownLatch(1); final boolean[] result = {false}; - pm.getPackageInstaller().uninstall(versionedPackage, null, 0x00000002, new IntentSenderAdaptor() { + var flag = userId == -1 ? 0x00000002 : 0; //PackageManager.DELETE_ALL_USERS = 0x00000002; UserHandle ALL = new UserHandle(-1); + pm.getPackageInstaller().uninstall(versionedPackage, null, flag, new IntentSenderAdaptor() { @Override public void send(Intent intent) { int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); @@ -242,11 +249,21 @@ public class PackageService { Log.d(TAG, intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)); latch.countDown(); } - }.getIntentSender(), 0); + }.getIntentSender(), userId == -1 ? 0 : userId); latch.await(); return result[0]; } + public static int installExistingPackageAsUser(String packageName, int userId) { + IPackageManager pm = getPackageManager(); + if (pm == null) return INSTALL_FAILED_INTERNAL_ERROR; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return pm.installExistingPackageAsUser(packageName, userId, 0, INSTALL_REASON_UNKNOWN, null); + } else { + return pm.installExistingPackageAsUser(packageName, userId, 0, INSTALL_REASON_UNKNOWN); + } + } + @SuppressWarnings("JavaReflectionMemberAccess") public static synchronized boolean installManagerIfAbsent(String packageName, File apkFile) { IPackageManager pm = getPackageManager(); @@ -264,7 +281,7 @@ public class PackageService { if (versionMatch && signatureMatch && pkgInfo.versionCode >= BuildConfig.VERSION_CODE) return false; if (!signatureMatch || !versionMatch && pkgInfo.versionCode > BuildConfig.VERSION_CODE) - uninstallPackage(new VersionedPackage(pkgInfo.packageName, pkgInfo.versionCode)); + uninstallPackage(new VersionedPackage(pkgInfo.packageName, pkgInfo.versionCode), -1); } // Install manager @@ -282,7 +299,7 @@ public class PackageService { } PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL); int installFlags = HiddenApiBridge.PackageInstaller_SessionParams_installFlags(params); - installFlags |= 0x00000004/*PackageManager.INSTALL_ALLOW_TEST*/ | 0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/; + installFlags |= 0x00000002/*PackageManager.INSTALL_REPLACE_EXISTING*/; HiddenApiBridge.PackageInstaller_SessionParams_installFlags(params, installFlags); int sessionId = installer.createSession(params); diff --git a/hiddenapi-stubs/src/main/java/android/content/pm/IPackageManager.java b/hiddenapi-stubs/src/main/java/android/content/pm/IPackageManager.java index a376f10c..751e6973 100644 --- a/hiddenapi-stubs/src/main/java/android/content/pm/IPackageManager.java +++ b/hiddenapi-stubs/src/main/java/android/content/pm/IPackageManager.java @@ -5,6 +5,10 @@ import android.os.IBinder; import android.os.IInterface; import android.os.RemoteException; +import androidx.annotation.RequiresApi; + +import java.util.List; + public interface IPackageManager extends IInterface { ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) @@ -48,6 +52,13 @@ public interface IPackageManager extends IInterface { IPackageInstaller getPackageInstaller() throws RemoteException; + int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason); + + @RequiresApi(29) + int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason, List whiteListedPermissions); + abstract class Stub extends Binder implements IPackageManager { public static IPackageManager asInterface(IBinder obj) { diff --git a/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl b/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl index 0876d191..d7c4682b 100644 --- a/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl +++ b/manager-service/src/main/aidl/org/lsposed/lspd/ILSPManagerService.aidl @@ -43,9 +43,11 @@ interface ILSPManagerService { void reboot(boolean confirm, String reason, boolean wait) = 24; - boolean uninstallPackage(String packageName) = 25; + boolean uninstallPackage(String packageName, int userId) = 25; boolean isSepolicyLoaded() = 26; int[] getUsers() = 27; + + int installExistingPackageAsUser(String packageName, int userId) = 28; }