Install to profiles (#592)
This commit is contained in:
parent
d395365e2c
commit
e272e48e86
|
|
@ -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() {
|
public static boolean isMagiskInstalled() {
|
||||||
return Arrays.stream(System.getenv("PATH").split(File.pathSeparator))
|
return Arrays.stream(System.getenv("PATH").split(File.pathSeparator))
|
||||||
.anyMatch(str -> new File(str, "magisk").exists());
|
.anyMatch(str -> new File(str, "magisk").exists());
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
private final PagerAdapter pagerAdapter = new PagerAdapter();
|
private final PagerAdapter pagerAdapter = new PagerAdapter();
|
||||||
private final ArrayList<ModuleAdapter> adapters = new ArrayList<>();
|
private final ArrayList<ModuleAdapter> adapters = new ArrayList<>();
|
||||||
|
|
||||||
private Handler uninstallHandler;
|
private Handler workHandler;
|
||||||
private PackageManager pm;
|
private PackageManager pm;
|
||||||
private ModuleUtil moduleUtil;
|
private ModuleUtil moduleUtil;
|
||||||
private ModuleUtil.InstalledModule selectedModule;
|
private ModuleUtil.InstalledModule selectedModule;
|
||||||
|
|
@ -107,9 +107,9 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
HandlerThread uninstallThread = new HandlerThread("uninstall");
|
HandlerThread workThread = new HandlerThread("ModulesActivity WorkHandler");
|
||||||
uninstallThread.start();
|
workThread.start();
|
||||||
uninstallHandler = new Handler(uninstallThread.getLooper());
|
workHandler = new Handler(workThread.getLooper());
|
||||||
moduleUtil = ModuleUtil.getInstance();
|
moduleUtil = ModuleUtil.getInstance();
|
||||||
pm = getPackageManager();
|
pm = getPackageManager();
|
||||||
moduleUtil.addListener(this);
|
moduleUtil.addListener(this);
|
||||||
|
|
@ -191,6 +191,12 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
ArrayList<String> titles = new ArrayList<>();
|
ArrayList<String> titles = new ArrayList<>();
|
||||||
for (int userId : userIds) {
|
for (int userId : userIds) {
|
||||||
var adapter = new ModuleAdapter(userId, handles.get(userId));
|
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);
|
adapter.setHasStableIds(true);
|
||||||
adapters.add(adapter);
|
adapters.add(adapter);
|
||||||
titles.add(getString(R.string.user_title, userId));
|
titles.add(getString(R.string.user_title, userId));
|
||||||
|
|
@ -275,7 +281,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
.setTitle(module.getAppName())
|
.setTitle(module.getAppName())
|
||||||
.setMessage(R.string.module_uninstall_message)
|
.setMessage(R.string.module_uninstall_message)
|
||||||
.setPositiveButton(android.R.string.ok, (dialog, which) ->
|
.setPositiveButton(android.R.string.ok, (dialog, which) ->
|
||||||
uninstallHandler.post(() -> {
|
workHandler.post(() -> {
|
||||||
boolean success = ConfigManager.uninstallPackage(module.packageName, module.userId);
|
boolean success = ConfigManager.uninstallPackage(module.packageName, module.userId);
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
String text = success ? getString(R.string.module_uninstalled, module.getAppName()) : getString(R.string.module_uninstall_failed);
|
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("modulePackageName", module.packageName);
|
||||||
intent.putExtra("moduleName", module.getAppName());
|
intent.putExtra("moduleName", module.getAppName());
|
||||||
startActivity(intent);
|
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);
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
@ -343,12 +371,17 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
private final int userId;
|
private final int userId;
|
||||||
private final UserHandle userHandle;
|
private final UserHandle userHandle;
|
||||||
private boolean isLoaded;
|
private boolean isLoaded;
|
||||||
|
private int[] profiles;
|
||||||
|
|
||||||
ModuleAdapter(int userId, UserHandle userHandle) {
|
ModuleAdapter(int userId, UserHandle userHandle) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.userHandle = userHandle;
|
this.userHandle = userHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProfiles(int[] profiles) {
|
||||||
|
this.profiles = profiles;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
|
@ -426,6 +459,13 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi
|
||||||
if (userHandle == null) {
|
if (userHandle == null) {
|
||||||
menu.removeItem(R.id.menu_app_info);
|
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 -> {
|
holder.itemView.setOnClickListener(v -> {
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@
|
||||||
<string name="module_uninstalled">已卸载%1$s</string>
|
<string name="module_uninstalled">已卸载%1$s</string>
|
||||||
<string name="module_uninstall_failed">卸载失败</string>
|
<string name="module_uninstall_failed">卸载失败</string>
|
||||||
<string name="user_title">用户 %d</string>
|
<string name="user_title">用户 %d</string>
|
||||||
|
<string name="install_to_user">安装到用户 %d</string>
|
||||||
|
<string name="install_to_user_message">要安装 %1$s 到用户 %2$d 吗?建议手动安装或多开,通过 LSPosed 强制安装可能会出现问题。</string>
|
||||||
|
<string name="module_installed">已安装 %1$s</string>
|
||||||
|
<string name="module_install_failed">安装失败</string>
|
||||||
|
|
||||||
<!-- AppListActivity -->
|
<!-- AppListActivity -->
|
||||||
<string name="compile_speed">重新优化</string>
|
<string name="compile_speed">重新优化</string>
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,10 @@
|
||||||
<string name="module_uninstalled">Uninstalled %1$s</string>
|
<string name="module_uninstalled">Uninstalled %1$s</string>
|
||||||
<string name="module_uninstall_failed">Uninstall unsuccessful</string>
|
<string name="module_uninstall_failed">Uninstall unsuccessful</string>
|
||||||
<string name="user_title">User %d</string>
|
<string name="user_title">User %d</string>
|
||||||
|
<string name="install_to_user">Install to user %d</string>
|
||||||
|
<string name="install_to_user_message">Want to install %1$s to user %2$d? It is recommended to install manually, forcing installation via LSPosed may cause problems.</string>
|
||||||
|
<string name="module_installed">%1$s installed</string>
|
||||||
|
<string name="module_install_failed">install failed</string>
|
||||||
|
|
||||||
<!-- AppListActivity -->
|
<!-- AppListActivity -->
|
||||||
<string name="compile_speed">Re-optimize</string>
|
<string name="compile_speed">Re-optimize</string>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ package org.lsposed.lspd.service;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.VersionedPackage;
|
import android.content.pm.VersionedPackage;
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
|
@ -37,7 +36,6 @@ import org.lsposed.lspd.BuildConfig;
|
||||||
import org.lsposed.lspd.ILSPManagerService;
|
import org.lsposed.lspd.ILSPManagerService;
|
||||||
import org.lsposed.lspd.utils.ParceledListSlice;
|
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;
|
import static org.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
|
|
||||||
public class LSPManagerService extends ILSPManagerService.Stub {
|
public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
|
|
@ -171,9 +169,6 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int installExistingPackageAsUser(String packageName, int userid) {
|
public int installExistingPackageAsUser(String packageName, int userid) {
|
||||||
if (ConfigManager.getInstance().isModule(packageName)) {
|
|
||||||
return PackageService.installExistingPackageAsUser(packageName, userid);
|
return PackageService.installExistingPackageAsUser(packageName, userid);
|
||||||
}
|
}
|
||||||
return INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@ public class PackageService {
|
||||||
|
|
||||||
static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
|
static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
|
||||||
static final int INSTALL_REASON_UNKNOWN = 0;
|
static final int INSTALL_REASON_UNKNOWN = 0;
|
||||||
static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
|
|
||||||
|
|
||||||
|
|
||||||
private static IPackageManager pm = null;
|
private static IPackageManager pm = null;
|
||||||
|
|
@ -256,6 +255,7 @@ public class PackageService {
|
||||||
|
|
||||||
public static int installExistingPackageAsUser(String packageName, int userId) {
|
public static int installExistingPackageAsUser(String packageName, int userId) {
|
||||||
IPackageManager pm = getPackageManager();
|
IPackageManager pm = getPackageManager();
|
||||||
|
Log.d(TAG, "about to install existing package " + packageName + "/" + userId);
|
||||||
if (pm == null) return INSTALL_FAILED_INTERNAL_ERROR;
|
if (pm == null) return INSTALL_FAILED_INTERNAL_ERROR;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
return pm.installExistingPackageAsUser(packageName, userId, 0, INSTALL_REASON_UNKNOWN, null);
|
return pm.installExistingPackageAsUser(packageName, userId, 0, INSTALL_REASON_UNKNOWN, null);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue