From e272e48e8682d655eec309efe200d59109665d86 Mon Sep 17 00:00:00 2001 From: vvb2060 Date: Sun, 16 May 2021 05:29:49 +0800 Subject: [PATCH] Install to profiles (#592) --- .../org/lsposed/manager/ConfigManager.java | 11 ++++ .../manager/ui/activity/ModulesActivity.java | 50 +++++++++++++++++-- app/src/main/res/values-zh-rCN/strings.xml | 4 ++ app/src/main/res/values/strings.xml | 4 ++ .../lspd/service/LSPManagerService.java | 7 +-- .../lsposed/lspd/service/PackageService.java | 2 +- 6 files changed, 66 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/lsposed/manager/ConfigManager.java b/app/src/main/java/org/lsposed/manager/ConfigManager.java index 8fafa5ba..36051ebd 100644 --- a/app/src/main/java/org/lsposed/manager/ConfigManager.java +++ b/app/src/main/java/org/lsposed/manager/ConfigManager.java @@ -239,6 +239,17 @@ public class ConfigManager { } } + public static boolean installExistingPackageAsUser(String packageName, int userId) { + int INSTALL_SUCCEEDED = 1; + try { + var ret = LSPManagerServiceClient.installExistingPackageAsUser(packageName, userId); + return ret == INSTALL_SUCCEEDED; + } catch (RemoteException | NullPointerException e) { + Log.e(App.TAG, Log.getStackTraceString(e)); + return false; + } + } + public static boolean isMagiskInstalled() { return Arrays.stream(System.getenv("PATH").split(File.pathSeparator)) .anyMatch(str -> new File(str, "magisk").exists()); 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 ba2d4c70..1ab0f617 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 @@ -98,7 +98,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi private final PagerAdapter pagerAdapter = new PagerAdapter(); private final ArrayList adapters = new ArrayList<>(); - private Handler uninstallHandler; + private Handler workHandler; private PackageManager pm; private ModuleUtil moduleUtil; private ModuleUtil.InstalledModule selectedModule; @@ -107,9 +107,9 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi @Override public void onCreate(Bundle savedInstanceState) { - HandlerThread uninstallThread = new HandlerThread("uninstall"); - uninstallThread.start(); - uninstallHandler = new Handler(uninstallThread.getLooper()); + HandlerThread workThread = new HandlerThread("ModulesActivity WorkHandler"); + workThread.start(); + workHandler = new Handler(workThread.getLooper()); moduleUtil = ModuleUtil.getInstance(); pm = getPackageManager(); moduleUtil.addListener(this); @@ -191,6 +191,12 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi ArrayList titles = new ArrayList<>(); for (int userId : userIds) { var adapter = new ModuleAdapter(userId, handles.get(userId)); + if (userId == 0) { + adapter.setProfiles(users.stream() + .filter(u -> u.hashCode() != 0) + .mapToInt(UserHandle::hashCode) + .toArray()); + } adapter.setHasStableIds(true); adapters.add(adapter); titles.add(getString(R.string.user_title, userId)); @@ -275,7 +281,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi .setTitle(module.getAppName()) .setMessage(R.string.module_uninstall_message) .setPositiveButton(android.R.string.ok, (dialog, which) -> - uninstallHandler.post(() -> { + workHandler.post(() -> { 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); @@ -297,6 +303,28 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi intent.putExtra("modulePackageName", module.packageName); intent.putExtra("moduleName", module.getAppName()); startActivity(intent); + return true; + } else if (item.getGroupId() == 1) { + new AlertDialog.Builder(this) + .setTitle(getString(R.string.install_to_user, itemId)) + .setMessage(getString(R.string.install_to_user_message, module.getAppName(), itemId)) + .setPositiveButton(android.R.string.ok, (dialog, which) -> + workHandler.post(() -> { + var success = ConfigManager.installExistingPackageAsUser(module.packageName, itemId); + runOnUiThread(() -> { + String text = success ? getString(R.string.module_installed, module.getAppName()) : getString(R.string.module_install_failed); + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { + Snackbar.make(binding.snackbar, text, Snackbar.LENGTH_SHORT).show(); + } else { + Toast.makeText(ModulesActivity.this, text, Toast.LENGTH_SHORT).show(); + } + }); + if (success) + moduleUtil.reloadSingleModule(module.packageName, itemId); + })) + .setNegativeButton(android.R.string.cancel, null) + .show(); + return true; } return super.onContextItemSelected(item); } @@ -343,12 +371,17 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi private final int userId; private final UserHandle userHandle; private boolean isLoaded; + private int[] profiles; ModuleAdapter(int userId, UserHandle userHandle) { this.userId = userId; this.userHandle = userHandle; } + public void setProfiles(int[] profiles) { + this.profiles = profiles; + } + @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -426,6 +459,13 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi if (userHandle == null) { menu.removeItem(R.id.menu_app_info); } + if (item.userId == 0) { + for (int profile : profiles) { + if (ModuleUtil.getInstance().getModule(item.packageName, profile) == null) { + menu.add(1, profile, 0, getString(R.string.install_to_user, profile)); + } + } + } }); holder.itemView.setOnClickListener(v -> { diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 286c5ec7..35861118 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -86,6 +86,10 @@ 已卸载%1$s 卸载失败 用户 %d + 安装到用户 %d + 要安装 %1$s 到用户 %2$d 吗?建议手动安装或多开,通过 LSPosed 强制安装可能会出现问题。 + 已安装 %1$s + 安装失败 重新优化 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7a95dc91..74cb8847 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -86,6 +86,10 @@ Uninstalled %1$s Uninstall unsuccessful User %d + Install to user %d + Want to install %1$s to user %2$d? It is recommended to install manually, forcing installation via LSPosed may cause problems. + %1$s installed + install failed Re-optimize 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 343de774..ed6cbae1 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java @@ -22,7 +22,6 @@ 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; @@ -37,7 +36,6 @@ 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 { @@ -171,9 +169,6 @@ public class LSPManagerService extends ILSPManagerService.Stub { @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; + return PackageService.installExistingPackageAsUser(packageName, userid); } } 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 1e0d4597..8b99c3f3 100644 --- a/core/src/main/java/org/lsposed/lspd/service/PackageService.java +++ b/core/src/main/java/org/lsposed/lspd/service/PackageService.java @@ -68,7 +68,6 @@ 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; @@ -256,6 +255,7 @@ public class PackageService { public static int installExistingPackageAsUser(String packageName, int userId) { IPackageManager pm = getPackageManager(); + Log.d(TAG, "about to install existing package " + packageName + "/" + userId); 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);