diff --git a/Bcore/src/main/aidl/top/niunaijun/blackbox/core/system/pm/IBXposedManagerService.aidl b/Bcore/src/main/aidl/top/niunaijun/blackbox/core/system/pm/IBXposedManagerService.aidl deleted file mode 100644 index 86fa504..0000000 --- a/Bcore/src/main/aidl/top/niunaijun/blackbox/core/system/pm/IBXposedManagerService.aidl +++ /dev/null @@ -1,14 +0,0 @@ -// IBXposedManagerService.aidl - -package top.niunaijun.blackbox.core.system.pm; - -import java.util.List; -import top.niunaijun.blackbox.entity.pm.InstalledModule; - -interface IBXposedManagerService { - boolean isXPEnable(); - void setXPEnable(boolean enable); - boolean isModuleEnable(String packageName); - void setModuleEnable(String packageName, boolean enable); - List getInstalledModules(); -} \ No newline at end of file diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/BlackBoxCore.java b/Bcore/src/main/java/top/niunaijun/blackbox/BlackBoxCore.java index 7b1e977..aeb3859 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/BlackBoxCore.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/BlackBoxCore.java @@ -46,14 +46,14 @@ import top.niunaijun.blackbox.core.system.user.BUserHandle; import top.niunaijun.blackbox.core.system.user.BUserInfo; import top.niunaijun.blackbox.entity.pm.InstallOption; import top.niunaijun.blackbox.entity.pm.InstallResult; -import top.niunaijun.blackbox.entity.pm.InstalledModule; + import top.niunaijun.blackbox.fake.delegate.ContentProviderDelegate; import top.niunaijun.blackbox.fake.frameworks.BActivityManager; import top.niunaijun.blackbox.fake.frameworks.BJobManager; import top.niunaijun.blackbox.fake.frameworks.BPackageManager; import top.niunaijun.blackbox.fake.frameworks.BStorageManager; import top.niunaijun.blackbox.fake.frameworks.BUserManager; -import top.niunaijun.blackbox.fake.frameworks.BXposedManager; + import top.niunaijun.blackbox.fake.hook.HookManager; import top.niunaijun.blackbox.proxy.ProxyManifest; import top.niunaijun.blackbox.utils.FileUtils; @@ -62,7 +62,7 @@ import top.niunaijun.blackbox.utils.Slog; import top.niunaijun.blackbox.utils.SimpleCrashFix; import top.niunaijun.blackbox.utils.compat.BuildCompat; import top.niunaijun.blackbox.utils.compat.BundleCompat; -import top.niunaijun.blackbox.utils.compat.XposedParserCompat; + import top.niunaijun.blackbox.utils.provider.ProviderCall; import top.niunaijun.blackbox.utils.StackTraceFilter; import top.niunaijun.blackbox.utils.SocialMediaAppCrashPrevention; @@ -239,7 +239,7 @@ public class BlackBoxCore extends ClientConfiguration { ServiceManager.STORAGE_MANAGER, ServiceManager.USER_MANAGER, ServiceManager.JOB_MANAGER, - ServiceManager.XPOSED_MANAGER, + ServiceManager.ACCOUNT_MANAGER, ServiceManager.LOCATION_MANAGER, ServiceManager.NOTIFICATION_MANAGER @@ -270,7 +270,7 @@ public class BlackBoxCore extends ClientConfiguration { ServiceManager.STORAGE_MANAGER, ServiceManager.USER_MANAGER, ServiceManager.JOB_MANAGER, - ServiceManager.XPOSED_MANAGER, + ServiceManager.ACCOUNT_MANAGER, ServiceManager.LOCATION_MANAGER, ServiceManager.NOTIFICATION_MANAGER @@ -303,7 +303,7 @@ public class BlackBoxCore extends ClientConfiguration { ServiceManager.STORAGE_MANAGER, ServiceManager.USER_MANAGER, ServiceManager.JOB_MANAGER, - ServiceManager.XPOSED_MANAGER, + ServiceManager.ACCOUNT_MANAGER, ServiceManager.LOCATION_MANAGER, ServiceManager.NOTIFICATION_MANAGER @@ -1239,58 +1239,9 @@ public class BlackBoxCore extends ClientConfiguration { return getBPackageManager().installPackageAsUser(apk.toString(), InstallOption.installByStorage().makeUriFile(), userId); } - public InstallResult installXPModule(File apk) { - return getBPackageManager().installPackageAsUser(apk.getAbsolutePath(), InstallOption.installByStorage().makeXposed(), BUserHandle.USER_XPOSED); - } - public InstallResult installXPModule(Uri apk) { - return getBPackageManager().installPackageAsUser(apk.toString(), InstallOption.installByStorage() - .makeXposed() - .makeUriFile(), BUserHandle.USER_XPOSED); - } - public InstallResult installXPModule(String packageName) { - try { - PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, 0); - String path = packageInfo.applicationInfo.sourceDir; - return getBPackageManager().installPackageAsUser(path, InstallOption.installBySystem().makeXposed(), BUserHandle.USER_XPOSED); - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return new InstallResult().installError(e.getMessage()); - } - } - public void uninstallXPModule(String packageName) { - uninstallPackage(packageName); - } - - public boolean isXPEnable() { - return BXposedManager.get().isXPEnable(); - } - - public void setXPEnable(boolean enable) { - BXposedManager.get().setXPEnable(enable); - } - - public boolean isXposedModule(File file) { - return XposedParserCompat.isXPModule(file.getAbsolutePath()); - } - - public boolean isInstalledXposedModule(String packageName) { - return isInstalled(packageName, BUserHandle.USER_XPOSED); - } - - public boolean isModuleEnable(String packageName) { - return BXposedManager.get().isModuleEnable(packageName); - } - - public void setModuleEnable(String packageName, boolean enable) { - BXposedManager.get().setModuleEnable(packageName, enable); - } - - public List getInstalledXPModules() { - return BXposedManager.get().getInstalledModules(); - } public List getInstalledApplications(int flags, int userId) { return getBPackageManager().getInstalledApplications(flags, userId); @@ -1384,10 +1335,7 @@ public class BlackBoxCore extends ClientConfiguration { return mClientConfiguration.isHideRoot(); } - @Override - public boolean isHideXposed() { - return mClientConfiguration.isHideXposed(); - } + @Override public String getHostPackageName() { diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java index dae7c7b..ae8721f 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java @@ -70,10 +70,10 @@ import top.niunaijun.blackbox.core.env.VirtualRuntime; import top.niunaijun.blackbox.core.system.user.BUserHandle; import top.niunaijun.blackbox.entity.AppConfig; import top.niunaijun.blackbox.entity.am.ReceiverData; -import top.niunaijun.blackbox.entity.pm.InstalledModule; + import top.niunaijun.blackbox.fake.delegate.AppInstrumentation; import top.niunaijun.blackbox.fake.delegate.ContentProviderDelegate; -import top.niunaijun.blackbox.fake.frameworks.BXposedManager; + import top.niunaijun.blackbox.fake.hook.HookManager; import top.niunaijun.blackbox.fake.service.HCallbackProxy; import top.niunaijun.blackbox.utils.Reflector; @@ -1055,40 +1055,7 @@ public class BActivityThread extends IBActivityThread.Stub { } } - public void loadXposed(Context context) { - String vPackageName = getAppPackageName(); - String vProcessName = getAppProcessName(); - if (!TextUtils.isEmpty(vPackageName) && !TextUtils.isEmpty(vProcessName) && BXposedManager.get().isXPEnable()) { - assert vPackageName != null; - assert vProcessName != null; - boolean isFirstApplication = vPackageName.equals(vProcessName); - - List installedModules = BXposedManager.get().getInstalledModules(); - for (InstalledModule installedModule : installedModules) { - if (!installedModule.enable) { - continue; - } - try { - // Remove all PineXposed.loadModule and PineXposed.onPackageLoad calls - } catch (Throwable e) { - String msg = "Failed to load Xposed module: " + installedModule.getApplication().packageName - + " (" + installedModule.getApplication().sourceDir + ")\n" - + android.util.Log.getStackTraceString(e); - android.util.Log.e("BlackBoxXposed", msg); - // Optionally, collect errors for UI display - // XposedErrorLogger.logModuleError(installedModule.getApplication().packageName, msg); - } - } - try { - // Remove all PineXposed.onPackageLoad calls - } catch (Throwable ignored) { - } - } - if (BlackBoxCore.get().isHideXposed()) { - NativeCore.hideXposed(); - } - } @Override public IBinder getActivityThread() { diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/app/configuration/ClientConfiguration.java b/Bcore/src/main/java/top/niunaijun/blackbox/app/configuration/ClientConfiguration.java index c4aa3e6..875b266 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/app/configuration/ClientConfiguration.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/app/configuration/ClientConfiguration.java @@ -16,9 +16,7 @@ public abstract class ClientConfiguration { return false; } - public boolean isHideXposed() { - return false; - } + public abstract String getHostPackageName(); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/env/AppSystemEnv.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/env/AppSystemEnv.java index 36b1c3a..2e570f0 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/env/AppSystemEnv.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/env/AppSystemEnv.java @@ -20,7 +20,7 @@ import top.niunaijun.blackbox.utils.compat.BuildCompat; public class AppSystemEnv { private static final List sSystemPackages = new ArrayList<>(); private static final List sSuPackages = new ArrayList<>(); - private static final List sXposedPackages = new ArrayList<>(); + private static final List sPreInstallPackages = new ArrayList<>(); static { @@ -52,7 +52,7 @@ public class AppSystemEnv { sSuPackages.add("com.thirdparty.superuser"); sSuPackages.add("com.yellowes.su"); - sXposedPackages.add("de.robv.android.xposed.installer"); + // sPreInstallPackages.add("com.huawei.hwid"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && Build.VERSION.SDK_INT < 29){ @@ -73,8 +73,6 @@ public class AppSystemEnv { public static boolean isBlackPackage(String packageName) { if (BlackBoxCore.get().isHideRoot() && sSuPackages.contains(packageName)) { return true; - } else if (BlackBoxCore.get().isHideXposed() && sXposedPackages.contains(packageName)) { - return true; } return false; } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java index cbcf447..e2edaa7 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java @@ -21,7 +21,7 @@ import top.niunaijun.blackbox.core.system.notification.BNotificationManagerServi import top.niunaijun.blackbox.core.system.os.BStorageManagerService; import top.niunaijun.blackbox.core.system.pm.BPackageInstallerService; import top.niunaijun.blackbox.core.system.pm.BPackageManagerService; -import top.niunaijun.blackbox.core.system.pm.BXposedManagerService; + import top.niunaijun.blackbox.core.system.user.BUserHandle; import top.niunaijun.blackbox.core.system.user.BUserManagerService; import top.niunaijun.blackbox.entity.pm.InstallOption; @@ -64,7 +64,7 @@ public class BlackBoxSystem { mServices.add(BJobManagerService.get()); mServices.add(BStorageManagerService.get()); mServices.add(BPackageInstallerService.get()); - mServices.add(BXposedManagerService.get()); + mServices.add(BProcessManagerService.get()); mServices.add(BAccountManagerService.get()); mServices.add(BLocationManagerService.get()); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/ServiceManager.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/ServiceManager.java index 46b8d92..eb10f69 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/ServiceManager.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/ServiceManager.java @@ -13,7 +13,7 @@ import top.niunaijun.blackbox.core.system.location.BLocationManagerService; import top.niunaijun.blackbox.core.system.notification.BNotificationManagerService; import top.niunaijun.blackbox.core.system.os.BStorageManagerService; import top.niunaijun.blackbox.core.system.pm.BPackageManagerService; -import top.niunaijun.blackbox.core.system.pm.BXposedManagerService; + import top.niunaijun.blackbox.core.system.user.BUserManagerService; /** @@ -31,7 +31,7 @@ public class ServiceManager { public static final String PACKAGE_MANAGER = "package_manager"; public static final String STORAGE_MANAGER = "storage_manager"; public static final String USER_MANAGER = "user_manager"; - public static final String XPOSED_MANAGER = "xposed_manager"; + public static final String ACCOUNT_MANAGER = "account_manager"; public static final String LOCATION_MANAGER = "location_manager"; public static final String NOTIFICATION_MANAGER = "notification_manager"; @@ -59,7 +59,7 @@ public class ServiceManager { mCaches.put(PACKAGE_MANAGER, BPackageManagerService.get()); mCaches.put(STORAGE_MANAGER, BStorageManagerService.get()); mCaches.put(USER_MANAGER, BUserManagerService.get()); - mCaches.put(XPOSED_MANAGER, BXposedManagerService.get()); + mCaches.put(ACCOUNT_MANAGER, BAccountManagerService.get()); mCaches.put(LOCATION_MANAGER, BLocationManagerService.get()); mCaches.put(NOTIFICATION_MANAGER, BNotificationManagerService.get()); @@ -75,7 +75,7 @@ public class ServiceManager { BlackBoxCore.get().getService(PACKAGE_MANAGER); BlackBoxCore.get().getService(STORAGE_MANAGER); BlackBoxCore.get().getService(USER_MANAGER); - BlackBoxCore.get().getService(XPOSED_MANAGER); + BlackBoxCore.get().getService(ACCOUNT_MANAGER); BlackBoxCore.get().getService(LOCATION_MANAGER); BlackBoxCore.get().getService(NOTIFICATION_MANAGER); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageManagerService.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageManagerService.java index 8756852..950687f 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageManagerService.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageManagerService.java @@ -44,7 +44,7 @@ import top.niunaijun.blackbox.utils.AbiUtils; import top.niunaijun.blackbox.utils.FileUtils; import top.niunaijun.blackbox.utils.Slog; import top.niunaijun.blackbox.utils.compat.PackageParserCompat; -import top.niunaijun.blackbox.utils.compat.XposedParserCompat; + import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; @@ -533,9 +533,7 @@ public class BPackageManagerService extends IBPackageManagerService.Stub impleme BPackageSettings ps = mPackages.get(packageName); if (ps == null) return; - if (ps.installOption.isFlag(InstallOption.FLAG_XPOSED) && userId != BUserHandle.USER_XPOSED) { - return; - } + if (!isInstalled(packageName, userId)) { return; } @@ -566,15 +564,6 @@ public class BPackageManagerService extends IBPackageManagerService.Stub impleme if (ps == null) return; BProcessManagerService.get().killAllByPackageName(packageName); - if (ps.installOption.isFlag(InstallOption.FLAG_XPOSED)) { - for (BUserInfo user : BUserManagerService.get().getAllUsers()) { - int i = BPackageInstallerService.get().uninstallPackageAsUser(ps, true, user.id); - if (i < 0) { - continue; - } - onPackageUninstalled(packageName, true, user.id); - } - } else { for (Integer userId : ps.getUserIds()) { int i = BPackageInstallerService.get().uninstallPackageAsUser(ps, true, userId); if (i < 0) { @@ -582,7 +571,6 @@ public class BPackageManagerService extends IBPackageManagerService.Stub impleme } onPackageUninstalled(packageName, true, userId); } - } mSettings.removePackage(packageName); mComponentResolver.removeAllComponents(ps.pkg); } @@ -680,12 +668,7 @@ public class BPackageManagerService extends IBPackageManagerService.Stub impleme apkFile = new File(file); } - if (option.isFlag(InstallOption.FLAG_XPOSED) && userId != BUserHandle.USER_XPOSED) { - return new InstallResult().installError("Please install the XP module in XP module management"); - } - if (option.isFlag(InstallOption.FLAG_XPOSED) && !XposedParserCompat.isXPModule(apkFile.getAbsolutePath())) { - return new InstallResult().installError("not a XP module"); - } + PackageInfo packageArchiveInfo = BlackBoxCore.getPackageManager().getPackageArchiveInfo(apkFile.getAbsolutePath(), 0); if (packageArchiveInfo == null) { diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageSettings.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageSettings.java index 0e21ea4..c4571be 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageSettings.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BPackageSettings.java @@ -77,11 +77,7 @@ public class BPackageSettings implements Parcelable { } state = new BPackageUserState(state); // xp模块所有用户可见、如果开启的话 - if (installOption.isFlag(InstallOption.FLAG_XPOSED) && - BXposedManagerService.get().isModuleEnable(pkg.packageName) && - BXposedManagerService.get().isXPEnable()) { - state.installed = true; - } + if (userId == BUserHandle.USER_ALL) { state.installed = true; } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BXposedManagerService.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BXposedManagerService.java deleted file mode 100644 index 35895c6..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/BXposedManagerService.java +++ /dev/null @@ -1,174 +0,0 @@ -package top.niunaijun.blackbox.core.system.pm; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Parcel; - -import androidx.core.util.AtomicFile; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import top.niunaijun.blackbox.core.env.BEnvironment; -import top.niunaijun.blackbox.core.system.ISystemService; -import top.niunaijun.blackbox.core.system.user.BUserHandle; -import top.niunaijun.blackbox.entity.pm.InstalledModule; -import top.niunaijun.blackbox.entity.pm.XposedConfig; -import top.niunaijun.blackbox.utils.CloseUtils; -import top.niunaijun.blackbox.utils.FileUtils; -import top.niunaijun.blackbox.utils.compat.XposedParserCompat; - -/** - * updated by alex5402 on 5/2/21. - * * ∧_∧ - * (`・ω・∥ - * 丶 つ0 - * しーJ - * - */ -public class BXposedManagerService extends IBXposedManagerService.Stub implements ISystemService, PackageMonitor { - private static final BXposedManagerService sService = new BXposedManagerService(); - - private XposedConfig mXposedConfig; - private final Object mLock = new Object(); - private BPackageManagerService mPms; - private final Map mCacheModule = new HashMap<>(); - - public static BXposedManagerService get() { - return sService; - } - - public BXposedManagerService() { - } - - @Override - public void systemReady() { - loadModuleStateLr(); - mPms = BPackageManagerService.get(); - mPms.addPackageMonitor(this); - } - - @Override - public boolean isXPEnable() { - synchronized (mLock) { - return mXposedConfig.enable; - } - } - - @Override - public void setXPEnable(boolean enable) { - synchronized (mLock) { - mXposedConfig.enable = enable; - saveModuleStateLw(); - } - } - - @Override - public boolean isModuleEnable(String packageName) { - synchronized (mLock) { - Boolean enable = mXposedConfig.moduleState.get(packageName); - return enable != null && enable; - } - } - - @Override - public void setModuleEnable(String packageName, boolean enable) { - synchronized (mLock) { - if (!mPms.isInstalled(packageName, BUserHandle.USER_XPOSED)) { - return; - } - mXposedConfig.moduleState.put(packageName, enable); - saveModuleStateLw(); - } - } - - @Override - public List getInstalledModules() { - List installedApplications = mPms.getInstalledApplications(PackageManager.GET_META_DATA, BUserHandle.USER_XPOSED); - synchronized (mCacheModule) { - for (ApplicationInfo installedApplication : installedApplications) { - if (mCacheModule.containsKey(installedApplication.packageName)) - continue; - InstalledModule installedModule = XposedParserCompat.parseModule(installedApplication); - if (installedModule != null) { - mCacheModule.put(installedApplication.packageName, installedModule); - } - } - ArrayList installedModules = new ArrayList<>(mCacheModule.values()); - for (InstalledModule installedModule : installedModules) { - installedModule.enable = isModuleEnable(installedModule.packageName); - } - return installedModules; - } - } - - private void loadModuleStateLr() { - File xpModuleConf = BEnvironment.getXPModuleConf(); - if (!xpModuleConf.exists()) { - mXposedConfig = new XposedConfig(); - saveModuleStateLw(); - return; - } - Parcel parcel = null; - try { - parcel = FileUtils.readToParcel(xpModuleConf); - mXposedConfig = new XposedConfig(parcel); - } catch (Exception e) { - e.printStackTrace(); - } finally { - if (parcel != null) { - parcel.recycle(); - } - } - } - - private void saveModuleStateLw() { - Parcel parcel = Parcel.obtain(); - AtomicFile atomicFile = new AtomicFile(BEnvironment.getXPModuleConf()); - FileOutputStream fileOutputStream = null; - try { - mXposedConfig.writeToParcel(parcel, 0); - parcel.setDataPosition(0); - fileOutputStream = atomicFile.startWrite(); - FileUtils.writeParcelToOutput(parcel, fileOutputStream); - atomicFile.finishWrite(fileOutputStream); - } catch (Exception ignored) { - atomicFile.failWrite(fileOutputStream); - } finally { - parcel.recycle(); - CloseUtils.close(fileOutputStream); - } - } - - @Override - public void onPackageUninstalled(String packageName, boolean removeApp, int userId) { - if (userId != BUserHandle.USER_XPOSED && userId != BUserHandle.USER_ALL) { - return; - } - synchronized (mCacheModule) { - mCacheModule.remove(packageName); - } - synchronized (mLock) { - mXposedConfig.moduleState.remove(packageName); - saveModuleStateLw(); - } - } - - @Override - public void onPackageInstalled(String packageName, int userId) { - if (userId != BUserHandle.USER_XPOSED && userId != BUserHandle.USER_ALL) { - return; - } - synchronized (mCacheModule) { - mCacheModule.remove(packageName); - } - synchronized (mLock) { - mXposedConfig.moduleState.put(packageName, false); - saveModuleStateLw(); - } - } -} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/user/BUserHandle.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/user/BUserHandle.java index fe959b0..beadd4d 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/user/BUserHandle.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/user/BUserHandle.java @@ -60,7 +60,7 @@ public final class BUserHandle implements Parcelable { public static final int USER_CURRENT_OR_SELF = -3; - public static final int USER_XPOSED = -4; + /** * @hide A user handle to indicate that we would like to send to the current diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstallOption.java b/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstallOption.java index 7f08d1e..e7db4bd 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstallOption.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstallOption.java @@ -14,7 +14,7 @@ import android.os.Parcelable; public class InstallOption implements Parcelable { public static final int FLAG_SYSTEM = 1; public static final int FLAG_STORAGE = 1 << 1; - public static final int FLAG_XPOSED = 1 << 2; + public static final int FLAG_URI_FILE = 1 << 3; public int flags = 0; @@ -31,10 +31,7 @@ public class InstallOption implements Parcelable { return installOption; } - public InstallOption makeXposed() { - this.flags |= FLAG_XPOSED; - return this; - } + public InstallOption makeUriFile() { this.flags |= FLAG_URI_FILE; diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstalledModule.java b/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstalledModule.java deleted file mode 100644 index 7c12410..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/InstalledModule.java +++ /dev/null @@ -1,72 +0,0 @@ -package top.niunaijun.blackbox.entity.pm; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Parcel; -import android.os.Parcelable; - -import top.niunaijun.blackbox.BlackBoxCore; -import top.niunaijun.blackbox.core.system.user.BUserHandle; - -/** - * updated by alex5402 on 5/2/21. - * * ∧_∧ - * (`・ω・∥ - * 丶 つ0 - * しーJ - * - */ -public class InstalledModule implements Parcelable { - public String packageName; - public String name; - public String desc; - public String main; - public boolean enable; - - public InstalledModule() { - } - - - public ApplicationInfo getApplication() { - return BlackBoxCore.getBPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA, BUserHandle.USER_XPOSED); - } - - public PackageInfo getPackageInfo() { - return BlackBoxCore.getBPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA, BUserHandle.USER_XPOSED); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(this.packageName); - dest.writeString(this.name); - dest.writeString(this.desc); - dest.writeString(this.main); - dest.writeByte(this.enable ? (byte) 1 : (byte) 0); - } - - protected InstalledModule(Parcel in) { - this.packageName = in.readString(); - this.name = in.readString(); - this.desc = in.readString(); - this.main = in.readString(); - this.enable = in.readByte() != 0; - } - - public static final Creator CREATOR = new Creator() { - @Override - public InstalledModule createFromParcel(Parcel source) { - return new InstalledModule(source); - } - - @Override - public InstalledModule[] newArray(int size) { - return new InstalledModule[size]; - } - }; -} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/XposedConfig.java b/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/XposedConfig.java deleted file mode 100644 index 3b72059..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/entity/pm/XposedConfig.java +++ /dev/null @@ -1,61 +0,0 @@ -package top.niunaijun.blackbox.entity.pm; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.HashMap; -import java.util.Map; - -/** - * updated by alex5402 on 5/2/21. - * * ∧_∧ - * (`・ω・∥ - * 丶 つ0 - * しーJ - * - */ -public class XposedConfig implements Parcelable { - public boolean enable; - public Map moduleState = new HashMap<>(); - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeByte(this.enable ? (byte) 1 : (byte) 0); - dest.writeInt(this.moduleState.size()); - for (Map.Entry entry : this.moduleState.entrySet()) { - dest.writeString(entry.getKey()); - dest.writeValue(entry.getValue()); - } - } - - public XposedConfig() { - } - - public XposedConfig(Parcel in) { - this.enable = in.readByte() != 0; - int mModuleStateSize = in.readInt(); - this.moduleState = new HashMap(mModuleStateSize); - for (int i = 0; i < mModuleStateSize; i++) { - String key = in.readString(); - Boolean value = (Boolean) in.readValue(Boolean.class.getClassLoader()); - this.moduleState.put(key, value); - } - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - @Override - public XposedConfig createFromParcel(Parcel source) { - return new XposedConfig(source); - } - - @Override - public XposedConfig[] newArray(int size) { - return new XposedConfig[size]; - } - }; -} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java index 6252e48..2c91bed 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java @@ -118,7 +118,7 @@ public final class AppInstrumentation extends BaseInstrumentationDelegate implem @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { ContextCompat.fix(context); - BActivityThread.currentActivityThread().loadXposed(context); + return super.newApplication(cl, className, context); } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/frameworks/BXposedManager.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/frameworks/BXposedManager.java deleted file mode 100644 index a6f7959..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/frameworks/BXposedManager.java +++ /dev/null @@ -1,74 +0,0 @@ -package top.niunaijun.blackbox.fake.frameworks; - -import android.os.RemoteException; - -import java.util.Collections; -import java.util.List; - -import top.niunaijun.blackbox.core.system.ServiceManager; -import top.niunaijun.blackbox.core.system.pm.IBXposedManagerService; -import top.niunaijun.blackbox.entity.pm.InstalledModule; - -/** - * updated by alex5402 on 5/2/21. - * * ∧_∧ - * (`・ω・∥ - * 丶 つ0 - * しーJ - * - */ -public class BXposedManager extends BlackManager { - private static final BXposedManager sXposedManager = new BXposedManager(); - - public static BXposedManager get() { - return sXposedManager; - } - - @Override - protected String getServiceName() { - return ServiceManager.XPOSED_MANAGER; - } - - public boolean isXPEnable() { - try { - return getService().isXPEnable(); - } catch (RemoteException e) { - e.printStackTrace(); - } - return false; - } - - public void setXPEnable(boolean enable) { - try { - getService().setXPEnable(enable); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - public boolean isModuleEnable(String packageName) { - try { - return getService().isModuleEnable(packageName); - } catch (RemoteException e) { - e.printStackTrace(); - } - return false; - } - - public void setModuleEnable(String packageName, boolean enable) { - try { - getService().setModuleEnable(packageName, enable); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - public List getInstalledModules() { - try { - return getService().getInstalledModules(); - } catch (RemoteException e) { - e.printStackTrace(); - } - return Collections.emptyList(); - } -} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/utils/XposedErrorLogger.java b/Bcore/src/main/java/top/niunaijun/blackbox/utils/XposedErrorLogger.java deleted file mode 100644 index 9b9d7b6..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/utils/XposedErrorLogger.java +++ /dev/null @@ -1,20 +0,0 @@ -package top.niunaijun.blackbox.utils; - -import java.util.HashMap; -import java.util.Map; - -public class XposedErrorLogger { - private static final Map moduleErrors = new HashMap<>(); - - public static void logModuleError(String packageName, String error) { - moduleErrors.put(packageName, error); - } - - public static String getModuleError(String packageName) { - return moduleErrors.get(packageName); - } - - public static Map getAllModuleErrors() { - return new HashMap<>(moduleErrors); - } -} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/XposedParserCompat.java b/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/XposedParserCompat.java deleted file mode 100644 index 6fa5db0..0000000 --- a/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/XposedParserCompat.java +++ /dev/null @@ -1,87 +0,0 @@ -package top.niunaijun.blackbox.utils.compat; - -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import top.niunaijun.blackbox.BlackBoxCore; -import top.niunaijun.blackbox.entity.pm.InstalledModule; -import top.niunaijun.blackbox.utils.CloseUtils; - -/** - * updated by alex5402 on 5/2/21. - * * ∧_∧ - * (`・ω・∥ - * 丶 つ0 - * しーJ - * - */ -public class XposedParserCompat { - - public static InstalledModule parseModule(ApplicationInfo applicationInfo) { - try { - PackageManager packageManager = BlackBoxCore.getPackageManager(); - InstalledModule module = new InstalledModule(); - module.packageName = applicationInfo.packageName; - module.enable = false; - module.desc = applicationInfo.metaData.getString("xposeddescription"); - module.name = applicationInfo.loadLabel(packageManager).toString(); - module.main = readMain(applicationInfo.sourceDir); - return module; - } catch (RuntimeException e) { - return null; - } - } - - public static boolean isXPModule(String file) { - try { - String s = readMain(file); - return s != null; - } catch (Throwable ignored) { - return false; - } - } - - private static String readMain(String apk) { - ZipFile zipFile = null; - try { - zipFile = new ZipFile(new File(apk)); - ZipEntry entry = zipFile.getEntry("assets/xposed_init"); - if (entry == null) { - throw new RuntimeException(); - } - return getInputStreamContent(zipFile.getInputStream(entry)).trim(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - CloseUtils.close(zipFile); - } - return null; - } - - private static String getInputStreamContent(InputStream stream) { - BufferedReader reader = null; - StringBuilder builder = new StringBuilder(); - try { - reader = new BufferedReader(new InputStreamReader(stream)); - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith("#")) - continue; - builder.append(line).append("\n"); - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - CloseUtils.close(reader); - } - return builder.toString(); - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a1303db..3fcf9bf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -35,7 +35,7 @@ - + () - - /** - * Safely load app label with fallback to package name - */ + + /** Safely load app label with fallback to package name */ private fun safeLoadAppLabel(applicationInfo: ApplicationInfo): String { return try { BlackBoxCore.getPackageManager().getApplicationLabel(applicationInfo).toString() @@ -40,30 +34,41 @@ class AppsRepository { applicationInfo.packageName // Fallback to package name } } - - /** - * Safely load app icon with fallback to null - */ - private fun safeLoadAppIcon(applicationInfo: ApplicationInfo): android.graphics.drawable.Drawable? { + + /** Safely load app icon with fallback to null */ + private fun safeLoadAppIcon( + applicationInfo: ApplicationInfo + ): android.graphics.drawable.Drawable? { return try { // Check if we should skip icon loading to save memory if (MemoryManager.shouldSkipIconLoading()) { - Log.w(TAG, "Memory usage high (${MemoryManager.getMemoryUsagePercentage()}%), skipping icon for ${applicationInfo.packageName}") + Log.w( + TAG, + "Memory usage high (${MemoryManager.getMemoryUsagePercentage()}%), skipping icon for ${applicationInfo.packageName}" + ) return null } - + val icon = BlackBoxCore.getPackageManager().getApplicationIcon(applicationInfo) - + // Optimize icon for memory efficiency if (icon is android.graphics.drawable.BitmapDrawable) { val bitmap = icon.bitmap // If icon is too large, scale it down to save memory if (bitmap.width > 96 || bitmap.height > 96) { try { - val scaledBitmap = android.graphics.Bitmap.createScaledBitmap(bitmap, 96, 96, true) - android.graphics.drawable.BitmapDrawable(BlackBoxCore.getPackageManager().getResourcesForApplication(applicationInfo.packageName), scaledBitmap) + val scaledBitmap = + android.graphics.Bitmap.createScaledBitmap(bitmap, 96, 96, true) + android.graphics.drawable.BitmapDrawable( + BlackBoxCore.getPackageManager() + .getResourcesForApplication(applicationInfo.packageName), + scaledBitmap + ) } catch (e: Exception) { - Log.w(TAG, "Failed to scale icon for ${applicationInfo.packageName}: ${e.message}") + Log.w( + TAG, + "Failed to scale icon for ${applicationInfo.packageName}: ${e.message}" + ) icon } } else { @@ -72,7 +77,6 @@ class AppsRepository { } else { icon } - } catch (e: Exception) { Log.w(TAG, "Failed to load icon for ${applicationInfo.packageName}: ${e.message}") null // Fallback to null icon @@ -83,35 +87,45 @@ class AppsRepository { try { synchronized(mInstalledList) { val installedApplications: List = - BlackBoxCore.getPackageManager().getInstalledApplications(0) + BlackBoxCore.getPackageManager().getInstalledApplications(0) val installedList = mutableListOf() for (installedApplication in installedApplications) { try { val file = File(installedApplication.sourceDir) - if ((installedApplication.flags and ApplicationInfo.FLAG_SYSTEM) != 0) continue + if ((installedApplication.flags and ApplicationInfo.FLAG_SYSTEM) != 0) + continue if (!AbiUtils.isSupport(file)) continue // Filter out BlackBox apps to prevent cloning if (BlackBoxCore.get().isBlackBoxApp(installedApplication.packageName)) { - Log.d(TAG, "Filtering out BlackBox app: ${installedApplication.packageName}") + Log.d( + TAG, + "Filtering out BlackBox app: ${installedApplication.packageName}" + ) continue } - val isXpModule = BlackBoxCore.get().isXposedModule(file) + val isXpModule = false - val info = AppInfo( - safeLoadAppLabel(installedApplication), - safeLoadAppIcon(installedApplication), // Remove the !! operator to allow null icons - installedApplication.packageName, - installedApplication.sourceDir, - isXpModule - ) + val info = + AppInfo( + safeLoadAppLabel(installedApplication), + safeLoadAppIcon( + installedApplication + ), // Remove the !! operator to allow null icons + installedApplication.packageName, + installedApplication.sourceDir, + isXpModule + ) installedList.add(info) } catch (e: Exception) { - Log.e(TAG, "Error processing app ${installedApplication.packageName}: ${e.message}") + Log.e( + TAG, + "Error processing app ${installedApplication.packageName}: ${e.message}" + ) } } this.mInstalledList.clear() @@ -123,24 +137,25 @@ class AppsRepository { } fun getInstalledAppList( - userID: Int, - loadingLiveData: MutableLiveData, - appsLiveData: MutableLiveData> + userID: Int, + loadingLiveData: MutableLiveData, + appsLiveData: MutableLiveData> ) { try { loadingLiveData.postValue(true) synchronized(mInstalledList) { val blackBoxCore = BlackBoxCore.get() Log.d(TAG, mInstalledList.joinToString(",")) - val newInstalledList = mInstalledList.map { - InstalledAppBean( - it.name, - it.icon, // Remove the !! operator to allow null icons - it.packageName, - it.sourceDir, - blackBoxCore.isInstalled(it.packageName, userID) - ) - } + val newInstalledList = + mInstalledList.map { + InstalledAppBean( + it.name, + it.icon, // Remove the !! operator to allow null icons + it.packageName, + it.sourceDir, + blackBoxCore.isInstalled(it.packageName, userID) + ) + } appsLiveData.postValue(newInstalledList) loadingLiveData.postValue(false) } @@ -151,87 +166,70 @@ class AppsRepository { } } - fun getInstalledModuleList( - loadingLiveData: MutableLiveData, - appsLiveData: MutableLiveData> - ) { - try { - loadingLiveData.postValue(true) - synchronized(mInstalledList) { - val blackBoxCore = BlackBoxCore.get() - val moduleList = mInstalledList.filter { - it.isXpModule - }.map { - InstalledAppBean( - it.name, - it.icon, // Remove the !! operator to allow null icons - it.packageName, - it.sourceDir, - blackBoxCore.isInstalledXposedModule(it.packageName) - ) - } - appsLiveData.postValue(moduleList) - loadingLiveData.postValue(false) - } - } catch (e: Exception) { - Log.e(TAG, "Error in getInstalledModuleList: ${e.message}") - loadingLiveData.postValue(false) - appsLiveData.postValue(emptyList()) - } - } - fun getVmInstallList(userId: Int, appsLiveData: MutableLiveData>) { try { // Check memory status before starting if (MemoryManager.isMemoryCritical()) { - Log.w(TAG, "Memory critical (${MemoryManager.getMemoryUsagePercentage()}%), forcing garbage collection") + Log.w( + TAG, + "Memory critical (${MemoryManager.getMemoryUsagePercentage()}%), forcing garbage collection" + ) MemoryManager.forceGarbageCollectionIfNeeded() } - + val blackBoxCore = BlackBoxCore.get() - + // Add debugging for users val users = blackBoxCore.users Log.d(TAG, "getVmInstallList: userId=$userId, total users=${users.size}") - users.forEach { user -> - Log.d(TAG, "User: id=${user.id}, name=${user.name}") - } - - val sortListData = - AppManager.mRemarkSharedPreferences.getString("AppList$userId", "") + users.forEach { user -> Log.d(TAG, "User: id=${user.id}, name=${user.name}") } + + val sortListData = AppManager.mRemarkSharedPreferences.getString("AppList$userId", "") val sortList = sortListData?.split(",") // Add retry mechanism for getting installed applications var applicationList: List? = null var retryCount = 0 val maxRetries = 3 - + while (applicationList == null && retryCount < maxRetries) { try { applicationList = blackBoxCore.getInstalledApplications(0, userId) if (applicationList == null) { - Log.w(TAG, "getVmInstallList: Attempt ${retryCount + 1} returned null, retrying...") + Log.w( + TAG, + "getVmInstallList: Attempt ${retryCount + 1} returned null, retrying..." + ) retryCount++ Thread.sleep(100) // Small delay before retry } } catch (e: Exception) { - Log.e(TAG, "getVmInstallList: Error getting applications on attempt ${retryCount + 1}: ${e.message}") + Log.e( + TAG, + "getVmInstallList: Error getting applications on attempt ${retryCount + 1}: ${e.message}" + ) retryCount++ if (retryCount < maxRetries) { Thread.sleep(200) // Longer delay for errors } } } - + // Add null check for applicationList if (applicationList == null) { - Log.e(TAG, "getVmInstallList: applicationList is null for userId=$userId after $maxRetries attempts") + Log.e( + TAG, + "getVmInstallList: applicationList is null for userId=$userId after $maxRetries attempts" + ) appsLiveData.postValue(emptyList()) return } - + // Add debugging - Log.d(TAG, "getVmInstallList: userId=$userId, applicationList.size=${applicationList.size}") + Log.d( + TAG, + "getVmInstallList: userId=$userId, applicationList.size=${applicationList.size}" + ) if (applicationList.isNotEmpty()) { Log.d(TAG, "First app: ${applicationList.first().packageName}") } else { @@ -239,19 +237,20 @@ class AppsRepository { } val appInfoList = mutableListOf() - + // Sort the application list if sort data exists - val sortedApplicationList = if (!sortList.isNullOrEmpty()) { - try { - applicationList.sortedWith(AppsSortComparator(sortList)) - } catch (e: Exception) { - Log.e(TAG, "getVmInstallList: Error sorting applications: ${e.message}") - applicationList // Return unsorted list if sorting fails - } - } else { - applicationList - } - + val sortedApplicationList = + if (!sortList.isNullOrEmpty()) { + try { + applicationList.sortedWith(AppsSortComparator(sortList)) + } catch (e: Exception) { + Log.e(TAG, "getVmInstallList: Error sorting applications: ${e.message}") + applicationList // Return unsorted list if sorting fails + } + } else { + applicationList + } + // Process each application with enhanced error handling sortedApplicationList.forEachIndexed { index, applicationInfo -> try { @@ -262,50 +261,73 @@ class AppsRepository { MemoryManager.forceGarbageCollectionIfNeeded() } } - + // Add null check for applicationInfo if (applicationInfo == null) { - Log.w(TAG, "getVmInstallList: Skipping null applicationInfo at index $index") + Log.w( + TAG, + "getVmInstallList: Skipping null applicationInfo at index $index" + ) return@forEachIndexed } - + // Validate package name if (applicationInfo.packageName.isNullOrBlank()) { - Log.w(TAG, "getVmInstallList: Skipping app with null/blank package name at index $index") + Log.w( + TAG, + "getVmInstallList: Skipping app with null/blank package name at index $index" + ) return@forEachIndexed } - - val info = AppInfo( - safeLoadAppLabel(applicationInfo), - safeLoadAppIcon(applicationInfo), // Remove the !! operator to allow null icons - applicationInfo.packageName, - applicationInfo.sourceDir ?: "", - isInstalledXpModule(applicationInfo.packageName) - ) + + val info = + AppInfo( + safeLoadAppLabel(applicationInfo), + safeLoadAppIcon( + applicationInfo + ), // Remove the !! operator to allow null icons + applicationInfo.packageName, + applicationInfo.sourceDir ?: "", + false + ) appInfoList.add(info) - + // Log progress for large lists if (index > 0 && index % 50 == 0) { - Log.d(TAG, "getVmInstallList: Processed $index/${sortedApplicationList.size} apps - ${MemoryManager.getMemoryInfo()}") + Log.d( + TAG, + "getVmInstallList: Processed $index/${sortedApplicationList.size} apps - ${MemoryManager.getMemoryInfo()}" + ) } - } catch (e: Exception) { - Log.e(TAG, "getVmInstallList: Error processing app at index $index (${applicationInfo?.packageName}): ${e.message}") + Log.e( + TAG, + "getVmInstallList: Error processing app at index $index (${applicationInfo?.packageName}): ${e.message}" + ) // Continue processing other apps instead of failing completely } } - Log.d(TAG, "getVmInstallList: processed ${appInfoList.size} apps - ${MemoryManager.getMemoryInfo()}") - + Log.d( + TAG, + "getVmInstallList: processed ${appInfoList.size} apps - ${MemoryManager.getMemoryInfo()}" + ) + // If no virtual apps found, show empty list (correct behavior for new users) // Do NOT load regular installed apps as fallback - this causes the bug if (appInfoList.isEmpty()) { - Log.d(TAG, "getVmInstallList: No virtual apps found for userId=$userId, showing empty list (correct for new users)") + Log.d( + TAG, + "getVmInstallList: No virtual apps found for userId=$userId, showing empty list (correct for new users)" + ) } else { - Log.d(TAG, "getVmInstallList: Showing ${appInfoList.size} virtual apps for userId=$userId") + Log.d( + TAG, + "getVmInstallList: Showing ${appInfoList.size} virtual apps for userId=$userId" + ) } - + // Post the result safely try { appsLiveData.postValue(appInfoList) @@ -317,14 +339,19 @@ class AppsRepository { try { appsLiveData.postValue(appInfoList) } catch (e2: Exception) { - Log.e(TAG, "getVmInstallList: Fallback posting also failed: ${e2.message}") + Log.e( + TAG, + "getVmInstallList: Fallback posting also failed: ${e2.message}" + ) } } } catch (e3: Exception) { - Log.e(TAG, "getVmInstallList: Could not schedule fallback posting: ${e3.message}") + Log.e( + TAG, + "getVmInstallList: Could not schedule fallback posting: ${e3.message}" + ) } } - } catch (e: Exception) { Log.e(TAG, "Error in getVmInstallList: ${e.message}") try { @@ -335,37 +362,30 @@ class AppsRepository { } } - private fun isInstalledXpModule(packageName: String): Boolean { - return try { - BlackBoxCore.get().installedXPModules.forEach { - if (packageName == it.packageName) { - return@isInstalledXpModule true - } - } - false - } catch (e: Exception) { - Log.e(TAG, "Error checking Xposed module: ${e.message}") - false - } - } - fun installApk(source: String, userId: Int, resultLiveData: MutableLiveData) { try { // Check if this is an attempt to install BlackBox app - if (source.contains("blackbox") || source.contains("niunaijun") || - source.contains("vspace") || source.contains("virtual")) { + if (source.contains("blackbox") || + source.contains("niunaijun") || + source.contains("vspace") || + source.contains("virtual") + ) { // Additional check for the actual BlackBox app try { val blackBoxCore = BlackBoxCore.get() val hostPackageName = BlackBoxCore.getHostPkg() - + // If it's a file path, try to check the package name if (!URLUtil.isValidUrl(source)) { val file = File(source) if (file.exists()) { - val packageInfo = BlackBoxCore.getPackageManager().getPackageArchiveInfo(source, 0) + val packageInfo = + BlackBoxCore.getPackageManager() + .getPackageArchiveInfo(source, 0) if (packageInfo != null && packageInfo.packageName == hostPackageName) { - resultLiveData.postValue("Cannot install BlackBox app from within BlackBox. This would create infinite recursion and is not allowed for security reasons.") + resultLiveData.postValue( + "Cannot install BlackBox app from within BlackBox. This would create infinite recursion and is not allowed for security reasons." + ) return } } @@ -374,14 +394,15 @@ class AppsRepository { Log.w(TAG, "Could not verify if this is BlackBox app: ${e.message}") } } - + val blackBoxCore = BlackBoxCore.get() - val installResult = if (URLUtil.isValidUrl(source)) { - val uri = Uri.parse(source) - blackBoxCore.installPackageAsUser(uri, userId) - } else { - blackBoxCore.installPackageAsUser(source, userId) - } + val installResult = + if (URLUtil.isValidUrl(source)) { + val uri = Uri.parse(source) + blackBoxCore.installPackageAsUser(uri, userId) + } else { + blackBoxCore.installPackageAsUser(source, userId) + } if (installResult.success) { updateAppSortList(userId, installResult.packageName, true) @@ -428,10 +449,7 @@ class AppsRepository { } } - /** - * 倒序递归扫描用户, - * 如果用户是空的,就删除用户,删除用户备注,删除应用排序列表 - */ + /** 倒序递归扫描用户, 如果用户是空的,就删除用户,删除用户备注,删除应用排序列表 */ private fun scanUser() { try { val blackBoxCore = BlackBoxCore.get() @@ -465,8 +483,7 @@ class AppsRepository { */ private fun updateAppSortList(userID: Int, pkg: String, isAdd: Boolean) { try { - val savedSortList = - AppManager.mRemarkSharedPreferences.getString("AppList$userID", "") + val savedSortList = AppManager.mRemarkSharedPreferences.getString("AppList$userID", "") val sortList = linkedSetOf() if (savedSortList != null) { @@ -488,14 +505,11 @@ class AppsRepository { } } - /** - * 保存排序后的apk顺序 - */ + /** 保存排序后的apk顺序 */ fun updateApkOrder(userID: Int, dataList: List) { try { AppManager.mRemarkSharedPreferences.edit().apply { - putString("AppList$userID", - dataList.joinToString(",") { it.packageName }) + putString("AppList$userID", dataList.joinToString(",") { it.packageName }) apply() } } catch (e: Exception) { diff --git a/app/src/main/java/top/niunaijun/blackboxa/data/XpRepository.kt b/app/src/main/java/top/niunaijun/blackboxa/data/XpRepository.kt deleted file mode 100644 index 03659c2..0000000 --- a/app/src/main/java/top/niunaijun/blackboxa/data/XpRepository.kt +++ /dev/null @@ -1,59 +0,0 @@ -package top.niunaijun.blackboxa.data - -import android.net.Uri -import android.webkit.URLUtil -import androidx.lifecycle.MutableLiveData -import top.niunaijun.blackbox.BlackBoxCore -import top.niunaijun.blackbox.BlackBoxCore.getPackageManager -import top.niunaijun.blackboxa.R -import top.niunaijun.blackboxa.bean.XpModuleInfo -import top.niunaijun.blackboxa.util.getString - -/** - * - * @Description: - * @Author: wukaicheng - * @CreateDate: 2021/5/2 20:55 - */ -class XpRepository { - fun getInstallModules(modulesLiveData: MutableLiveData>) { - val moduleList = BlackBoxCore.get().installedXPModules - val result = mutableListOf() - moduleList.forEach { - val info = XpModuleInfo( - it.name, - it.desc, - it.packageName, - it.packageInfo.versionName.toString(), - it.enable, - it.application.loadIcon(getPackageManager()) - ) - result.add(info) - } - - modulesLiveData.postValue(result) - } - - fun installModule(source: String, resultLiveData: MutableLiveData) { - val blackBoxCore = BlackBoxCore.get() - - val installResult = if (URLUtil.isValidUrl(source)) { - val uri = Uri.parse(source) - blackBoxCore.installXPModule(uri) - } else { - //source == packageName - blackBoxCore.installXPModule(source) - } - - if(installResult.success){ - resultLiveData.postValue(getString(R.string.install_success)) - }else{ - resultLiveData.postValue(getString(R.string.install_fail, installResult.msg)) - } - } - - fun unInstallModule(packageName: String, resultLiveData: MutableLiveData) { - BlackBoxCore.get().uninstallXPModule(packageName) - resultLiveData.postValue(getString(R.string.remove_success)) - } -} \ No newline at end of file diff --git a/app/src/main/java/top/niunaijun/blackboxa/util/InjectionUtil.kt b/app/src/main/java/top/niunaijun/blackboxa/util/InjectionUtil.kt index 7efb86f..64750b7 100644 --- a/app/src/main/java/top/niunaijun/blackboxa/util/InjectionUtil.kt +++ b/app/src/main/java/top/niunaijun/blackboxa/util/InjectionUtil.kt @@ -3,12 +3,12 @@ package top.niunaijun.blackboxa.util import top.niunaijun.blackboxa.data.AppsRepository import top.niunaijun.blackboxa.data.FakeLocationRepository import top.niunaijun.blackboxa.data.GmsRepository -import top.niunaijun.blackboxa.data.XpRepository + import top.niunaijun.blackboxa.view.apps.AppsFactory import top.niunaijun.blackboxa.view.fake.FakeLocationFactory import top.niunaijun.blackboxa.view.gms.GmsFactory import top.niunaijun.blackboxa.view.list.ListFactory -import top.niunaijun.blackboxa.view.xp.XpFactory + /** * @@ -20,7 +20,7 @@ object InjectionUtil { private val appsRepository = AppsRepository() - private val xpRepository = XpRepository() + private val gmsRepository = GmsRepository() @@ -34,9 +34,6 @@ object InjectionUtil { return ListFactory(appsRepository) } - fun getXpFactory():XpFactory{ - return XpFactory(xpRepository) - } fun getGmsFactory():GmsFactory{ return GmsFactory(gmsRepository) diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/list/ListActivity.kt b/app/src/main/java/top/niunaijun/blackboxa/view/list/ListActivity.kt index c732ae8..36ff22a 100644 --- a/app/src/main/java/top/niunaijun/blackboxa/view/list/ListActivity.kt +++ b/app/src/main/java/top/niunaijun/blackboxa/view/list/ListActivity.kt @@ -19,7 +19,6 @@ import top.niunaijun.blackboxa.util.InjectionUtil import top.niunaijun.blackboxa.util.inflate import top.niunaijun.blackboxa.view.base.BaseActivity - class ListActivity : BaseActivity() { private val viewBinding: ActivityListBinding by inflate() @@ -36,54 +35,49 @@ class ListActivity : BaseActivity() { initToolbar(viewBinding.toolbarLayout.toolbar, R.string.installed_app, true) - mAdapter = RVAdapter(this,ListAdapter()).bind(viewBinding.recyclerView).setItemClickListener { _, item, _ -> - finishWithResult(item.packageName) - } + mAdapter = + RVAdapter(this, ListAdapter()) + .bind(viewBinding.recyclerView) + .setItemClickListener { _, item, _ -> finishWithResult(item.packageName) } viewBinding.recyclerView.layoutManager = LinearLayoutManager(this) - initSearchView() initViewModel() } private fun initSearchView() { - viewBinding.searchView.setOnQueryTextListener(object : SimpleSearchView.OnQueryTextListener { - override fun onQueryTextChange(newText: String): Boolean { - filterApp(newText) - return true - } + viewBinding.searchView.setOnQueryTextListener( + object : SimpleSearchView.OnQueryTextListener { + override fun onQueryTextChange(newText: String): Boolean { + filterApp(newText) + return true + } - override fun onQueryTextCleared(): Boolean { - return true - } + override fun onQueryTextCleared(): Boolean { + return true + } - override fun onQueryTextSubmit(query: String): Boolean { - return true - } - - }) + override fun onQueryTextSubmit(query: String): Boolean { + return true + } + } + ) } private fun initViewModel() { - viewModel = ViewModelProvider(this, InjectionUtil.getListFactory()).get(ListViewModel::class.java) - val onlyShowXp = intent.getBooleanExtra("onlyShowXp", false) - val userID = intent.getIntExtra("userID",0) - - if (onlyShowXp) { - viewModel.getInstalledModules() - viewBinding.toolbarLayout.toolbar.setTitle(R.string.installed_module) - } else { - viewModel.getInstallAppList(userID) - viewBinding.toolbarLayout.toolbar.setTitle(R.string.installed_app) - } + viewModel = + ViewModelProvider(this, InjectionUtil.getListFactory()) + .get(ListViewModel::class.java) + val userID = intent.getIntExtra("userID", 0) + viewModel.getInstallAppList(userID) + viewBinding.toolbarLayout.toolbar.setTitle(R.string.installed_app) viewModel.loadingLiveData.observe(this) { if (it) { viewBinding.stateView.showLoading() } else { viewBinding.stateView.showContent() - } } @@ -103,29 +97,26 @@ class ListActivity : BaseActivity() { } private fun filterApp(newText: String) { - val newList = this.appList.filter { - it.name.contains(newText, true) or it.packageName.contains(newText, true) - } + val newList = + this.appList.filter { + it.name.contains(newText, true) or it.packageName.contains(newText, true) + } mAdapter.setItems(newList) } - private val openDocumentedResult = registerForActivityResult(ActivityResultContracts.GetContent()) { - it?.run { - finishWithResult(it.toString()) - } - } + private val openDocumentedResult = + registerForActivityResult(ActivityResultContracts.GetContent()) { + it?.run { finishWithResult(it.toString()) } + } private fun finishWithResult(source: String) { intent.putExtra("source", source) setResult(Activity.RESULT_OK, intent) val imm: InputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - window.peekDecorView()?.run { - imm.hideSoftInputFromWindow(windowToken, 0) - } + window.peekDecorView()?.run { imm.hideSoftInputFromWindow(windowToken, 0) } finish() } - override fun onBackPressed() { if (viewBinding.searchView.isSearchOpen) { viewBinding.searchView.closeSearch() @@ -157,12 +148,10 @@ class ListActivity : BaseActivity() { viewModel.appsLiveData.removeObservers(this) } - - companion object{ - fun start(context: Context,onlyShowXp:Boolean){ - val intent = Intent(context,ListActivity::class.java) - intent.putExtra("onlyShowXp",onlyShowXp) + companion object { + fun start(context: Context) { + val intent = Intent(context, ListActivity::class.java) context.startActivity(intent) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/list/ListViewModel.kt b/app/src/main/java/top/niunaijun/blackboxa/view/list/ListViewModel.kt index e21e694..b170436 100644 --- a/app/src/main/java/top/niunaijun/blackboxa/view/list/ListViewModel.kt +++ b/app/src/main/java/top/niunaijun/blackboxa/view/list/ListViewModel.kt @@ -18,21 +18,10 @@ class ListViewModel(private val repo: AppsRepository) : BaseViewModel() { val loadingLiveData = MutableLiveData() fun previewInstalledList() { - launchOnUI{ - repo.previewInstallList() - } + launchOnUI { repo.previewInstallList() } } - fun getInstallAppList(userID:Int){ - launchOnUI { - repo.getInstalledAppList(userID,loadingLiveData,appsLiveData) - } + fun getInstallAppList(userID: Int) { + launchOnUI { repo.getInstalledAppList(userID, loadingLiveData, appsLiveData) } } - - fun getInstalledModules() { - launchOnUI { - repo.getInstalledModuleList(loadingLiveData, appsLiveData) - } - } - -} \ No newline at end of file +} diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/main/BlackBoxLoader.kt b/app/src/main/java/top/niunaijun/blackboxa/view/main/BlackBoxLoader.kt index c66b4b6..b291e65 100644 --- a/app/src/main/java/top/niunaijun/blackboxa/view/main/BlackBoxLoader.kt +++ b/app/src/main/java/top/niunaijun/blackboxa/view/main/BlackBoxLoader.kt @@ -3,6 +3,7 @@ package top.niunaijun.blackboxa.view.main import android.app.Application import android.content.Context import android.util.Log +import java.io.File import top.niunaijun.blackbox.BlackBoxCore import top.niunaijun.blackbox.app.BActivityThread import top.niunaijun.blackbox.app.configuration.AppLifecycleCallback @@ -10,7 +11,6 @@ import top.niunaijun.blackbox.app.configuration.ClientConfiguration import top.niunaijun.blackboxa.app.App import top.niunaijun.blackboxa.app.rocker.RockerManager import top.niunaijun.blackboxa.biz.cache.AppSharedPreferenceDelegate -import java.io.File /** * @@ -21,7 +21,7 @@ import java.io.File class BlackBoxLoader { private var mHideRoot by AppSharedPreferenceDelegate(App.getContext(), false) - private var mHideXposed by AppSharedPreferenceDelegate(App.getContext(), false) + private var mDaemonEnable by AppSharedPreferenceDelegate(App.getContext(), false) private var mShowShortcutPermissionDialog by AppSharedPreferenceDelegate(App.getContext(), true) @@ -42,23 +42,6 @@ class BlackBoxLoader { } } - fun hideXposed(): Boolean { - return try { - mHideXposed - } catch (e: Exception) { - Log.e(TAG, "Error getting hideXposed: ${e.message}") - false - } - } - - fun invalidHideXposed(hideXposed: Boolean) { - try { - this.mHideXposed = hideXposed - } catch (e: Exception) { - Log.e(TAG, "Error setting hideXposed: ${e.message}") - } - } - fun daemonEnable(): Boolean { return try { mDaemonEnable @@ -104,70 +87,100 @@ class BlackBoxLoader { fun addLifecycleCallback() { try { - BlackBoxCore.get().addAppLifecycleCallback(object : AppLifecycleCallback() { - override fun beforeCreateApplication( - packageName: String?, - processName: String?, - context: Context?, - userId: Int - ) { - try { - Log.d( - TAG, - "beforeCreateApplication: pkg $packageName, processName $processName,userID:${BActivityThread.getUserId()}" - ) - } catch (e: Exception) { - Log.e(TAG, "Error in beforeCreateApplication: ${e.message}") - } - } + BlackBoxCore.get() + .addAppLifecycleCallback( + object : AppLifecycleCallback() { + override fun beforeCreateApplication( + packageName: String?, + processName: String?, + context: Context?, + userId: Int + ) { + try { + Log.d( + TAG, + "beforeCreateApplication: pkg $packageName, processName $processName,userID:${BActivityThread.getUserId()}" + ) + } catch (e: Exception) { + Log.e(TAG, "Error in beforeCreateApplication: ${e.message}") + } + } - override fun beforeApplicationOnCreate( - packageName: String?, - processName: String?, - application: Application?, - userId: Int - ) { - try { - Log.d(TAG, "beforeApplicationOnCreate: pkg $packageName, processName $processName") - } catch (e: Exception) { - Log.e(TAG, "Error in beforeApplicationOnCreate: ${e.message}") - } - } + override fun beforeApplicationOnCreate( + packageName: String?, + processName: String?, + application: Application?, + userId: Int + ) { + try { + Log.d( + TAG, + "beforeApplicationOnCreate: pkg $packageName, processName $processName" + ) + } catch (e: Exception) { + Log.e( + TAG, + "Error in beforeApplicationOnCreate: ${e.message}" + ) + } + } - override fun afterApplicationOnCreate( - packageName: String?, - processName: String?, - application: Application?, - userId: Int - ) { - try { - Log.d(TAG, "afterApplicationOnCreate: pkg $packageName, processName $processName") - RockerManager.init(application,userId) - } catch (e: Exception) { - Log.e(TAG, "Error in afterApplicationOnCreate: ${e.message}") - } - } - - override fun onStoragePermissionNeeded(packageName: String?, userId: Int): Boolean { - try { - Log.w(TAG, "Storage permission needed for launching: $packageName") - // Broadcast to request storage permission - // The main activity should listen for this and show permission dialog - val intent = android.content.Intent("top.niunaijun.blackboxa.REQUEST_STORAGE_PERMISSION") - intent.putExtra("package_name", packageName) - intent.putExtra("user_id", userId) - intent.setPackage(App.getContext().packageName) - App.getContext().sendBroadcast(intent) - // Return false to NOT block the launch - the app will launch anyway - // but the user will be notified to grant permission - // Change to 'true' if you want to block launch until permission is granted - return false - } catch (e: Exception) { - Log.e(TAG, "Error in onStoragePermissionNeeded: ${e.message}") - return false - } - } - }) + override fun afterApplicationOnCreate( + packageName: String?, + processName: String?, + application: Application?, + userId: Int + ) { + try { + Log.d( + TAG, + "afterApplicationOnCreate: pkg $packageName, processName $processName" + ) + RockerManager.init(application, userId) + } catch (e: Exception) { + Log.e( + TAG, + "Error in afterApplicationOnCreate: ${e.message}" + ) + } + } + + override fun onStoragePermissionNeeded( + packageName: String?, + userId: Int + ): Boolean { + try { + Log.w( + TAG, + "Storage permission needed for launching: $packageName" + ) + // Broadcast to request storage permission + // The main activity should listen for this and show + // permission dialog + val intent = + android.content.Intent( + "top.niunaijun.blackboxa.REQUEST_STORAGE_PERMISSION" + ) + intent.putExtra("package_name", packageName) + intent.putExtra("user_id", userId) + intent.setPackage(App.getContext().packageName) + App.getContext().sendBroadcast(intent) + // Return false to NOT block the launch - the app will + // launch anyway + // but the user will be notified to grant permission + // Change to 'true' if you want to block launch until + // permission is granted + return false + } catch (e: Exception) { + Log.e( + TAG, + "Error in onStoragePermissionNeeded: ${e.message}" + ) + return false + } + } + } + ) } catch (e: Exception) { Log.e(TAG, "Error adding lifecycle callback: ${e.message}") } @@ -175,58 +188,59 @@ class BlackBoxLoader { fun attachBaseContext(context: Context) { try { - BlackBoxCore.get().doAttachBaseContext(context, object : ClientConfiguration() { - override fun getHostPackageName(): String { - return try { - context.packageName - } catch (e: Exception) { - Log.e(TAG, "Error getting package name: ${e.message}") - "unknown" - } - } + BlackBoxCore.get() + .doAttachBaseContext( + context, + object : ClientConfiguration() { + override fun getHostPackageName(): String { + return try { + context.packageName + } catch (e: Exception) { + Log.e(TAG, "Error getting package name: ${e.message}") + "unknown" + } + } - override fun isHideRoot(): Boolean { - return try { - mHideRoot - } catch (e: Exception) { - Log.e(TAG, "Error checking hideRoot: ${e.message}") - false - } - } + override fun isHideRoot(): Boolean { + return try { + mHideRoot + } catch (e: Exception) { + Log.e(TAG, "Error checking hideRoot: ${e.message}") + false + } + } - override fun isHideXposed(): Boolean { - return try { - mHideXposed - } catch (e: Exception) { - Log.e(TAG, "Error checking hideXposed: ${e.message}") - false - } - } + override fun isEnableDaemonService(): Boolean { + return try { + mDaemonEnable + } catch (e: Exception) { + Log.e(TAG, "Error checking daemonEnable: ${e.message}") + false + } + } - override fun isEnableDaemonService(): Boolean { - return try { - mDaemonEnable - } catch (e: Exception) { - Log.e(TAG, "Error checking daemonEnable: ${e.message}") - false - } - } - - override fun requestInstallPackage(file: File?, userId: Int): Boolean { - return try { - if (file == null) { - Log.w(TAG, "requestInstallPackage: file is null") - return false - } - val packageInfo = - context.packageManager.getPackageArchiveInfo(file.absolutePath, 0) - false - } catch (e: Exception) { - Log.e(TAG, "Error in requestInstallPackage: ${e.message}") - false - } - } - }) + override fun requestInstallPackage( + file: File?, + userId: Int + ): Boolean { + return try { + if (file == null) { + Log.w(TAG, "requestInstallPackage: file is null") + return false + } + val packageInfo = + context.packageManager.getPackageArchiveInfo( + file.absolutePath, + 0 + ) + false + } catch (e: Exception) { + Log.e(TAG, "Error in requestInstallPackage: ${e.message}") + false + } + } + } + ) } catch (e: Exception) { Log.e(TAG, "Error in attachBaseContext: ${e.message}") } @@ -235,7 +249,7 @@ class BlackBoxLoader { fun doOnCreate(context: Context) { try { BlackBoxCore.get().doCreate() - + // Register callback to refresh app list when services become available try { BlackBoxCore.get().addServiceAvailableCallback { @@ -254,4 +268,4 @@ class BlackBoxLoader { companion object { val TAG: String = BlackBoxLoader::class.java.simpleName } -} \ No newline at end of file +} diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/setting/SettingFragment.kt b/app/src/main/java/top/niunaijun/blackboxa/view/setting/SettingFragment.kt index e144422..b850eec 100644 --- a/app/src/main/java/top/niunaijun/blackboxa/view/setting/SettingFragment.kt +++ b/app/src/main/java/top/niunaijun/blackboxa/view/setting/SettingFragment.kt @@ -1,16 +1,13 @@ package top.niunaijun.blackboxa.view.setting -import android.content.Intent import android.os.Bundle import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreferenceCompat import top.niunaijun.blackbox.BlackBoxCore import top.niunaijun.blackboxa.R import top.niunaijun.blackboxa.app.AppManager import top.niunaijun.blackboxa.util.toast import top.niunaijun.blackboxa.view.gms.GmsManagerActivity -import top.niunaijun.blackboxa.view.xp.XpActivity /** * @@ -20,37 +17,12 @@ import top.niunaijun.blackboxa.view.xp.XpActivity */ class SettingFragment : PreferenceFragmentCompat() { - private lateinit var xpEnable: SwitchPreferenceCompat - - private lateinit var xpModule: Preference - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.setting, rootKey) - xpEnable = findPreference("xp_enable")!! - xpEnable.isChecked = BlackBoxCore.get().isXPEnable - - xpEnable.setOnPreferenceChangeListener { _, newValue -> - BlackBoxCore.get().isXPEnable = (newValue == true) - true - } - //xp模块跳转 - xpModule = findPreference("xp_module")!! - xpModule.setOnPreferenceClickListener { - val intent = Intent(requireActivity(), XpActivity::class.java) - requireContext().startActivity(intent) - true - } initGms() - invalidHideState{ - val xpHidePreference: Preference = (findPreference("xp_hide")!!) - val hideXposed = AppManager.mBlackBoxLoader.hideXposed() - xpHidePreference.setDefaultValue(hideXposed) - xpHidePreference - } - - invalidHideState{ + invalidHideState { val rootHidePreference: Preference = (findPreference("root_hide")!!) val hideRoot = AppManager.mBlackBoxLoader.hideRoot() rootHidePreference.setDefaultValue(hideRoot) @@ -85,15 +57,10 @@ class SettingFragment : PreferenceFragmentCompat() { pref.setOnPreferenceChangeListener { preference, newValue -> val tmpHide = (newValue == true) when (preference.key) { - "xp_hide" -> { - AppManager.mBlackBoxLoader.invalidHideXposed(tmpHide) - } - "root_hide" -> { AppManager.mBlackBoxLoader.invalidHideRoot(tmpHide) } - "daemon_enable" -> { AppManager.mBlackBoxLoader.invalidDaemonEnable(tmpHide) } @@ -103,4 +70,4 @@ class SettingFragment : PreferenceFragmentCompat() { return@setOnPreferenceChangeListener true } } -} \ No newline at end of file +} diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpActivity.kt b/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpActivity.kt deleted file mode 100644 index b4a0683..0000000 --- a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpActivity.kt +++ /dev/null @@ -1,151 +0,0 @@ -package top.niunaijun.blackboxa.view.xp - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import android.text.TextUtils -import androidx.activity.result.contract.ActivityResultContracts -import androidx.lifecycle.ViewModelProvider -import androidx.recyclerview.widget.LinearLayoutManager -import cbfg.rvadapter.RVAdapter -import com.afollestad.materialdialogs.MaterialDialog -import top.niunaijun.blackbox.BlackBoxCore -import top.niunaijun.blackboxa.R -import top.niunaijun.blackboxa.bean.XpModuleInfo -import top.niunaijun.blackboxa.databinding.ActivityXpBinding -import top.niunaijun.blackboxa.util.InjectionUtil -import top.niunaijun.blackboxa.util.inflate -import top.niunaijun.blackboxa.util.toast -import top.niunaijun.blackboxa.view.base.LoadingActivity -import top.niunaijun.blackboxa.view.list.ListActivity - -/** - * - * @Description: xposed模块管理界面 - * @Author: wukaicheng - * @CreateDate: 2021/5/2 20:25 - */ -class XpActivity : LoadingActivity() { - - private val viewBinding: ActivityXpBinding by inflate() - - - private lateinit var viewModel: XpViewModel - - private lateinit var mAdapter: RVAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(viewBinding.root) - initToolbar(viewBinding.toolbarLayout.toolbar, R.string.xp_setting, true) - - viewModel = ViewModelProvider(this, InjectionUtil.getXpFactory()).get(XpViewModel::class.java) - - initRecyclerView() - initFab() - } - - - private fun observeLiveData() { - - viewBinding.stateView.showLoading() - viewModel.getInstalledModule() - viewModel.appsLiveData.observe(this) { - if (it.isNullOrEmpty()) { - viewBinding.stateView.showEmpty() - } else { - mAdapter.setItems(it) - viewBinding.stateView.showContent() - } - } - - viewModel.resultLiveData.observe(this) { - if (!TextUtils.isEmpty(it)) { - hideLoading() - toast(it) - viewModel.getInstalledModule() - } - } - } - - private fun initRecyclerView() { - - mAdapter = RVAdapter(this, XpAdapter()).bind(viewBinding.recyclerView) - .setItemClickListener { view, item, position -> - item.enable = !item.enable - BlackBoxCore.get().setModuleEnable(item.packageName, item.enable) - mAdapter.replaceAt(position, item) - toast(R.string.restart_module) - }.setItemLongClickListener { _, item, _ -> - unInstallModule(item.packageName) - } - - viewBinding.recyclerView.layoutManager = LinearLayoutManager(this) - viewBinding.stateView.showEmpty() - } - - private fun initFab() { - viewBinding.fab.setOnClickListener { - val intent = Intent(this, ListActivity::class.java) - intent.putExtra("onlyShowXp", true) - apkPathResult.launch(intent) - } - - } - - - override fun onStart() { - super.onStart() - observeLiveData() - } - - override fun onStop() { - super.onStop() - viewModel.appsLiveData.value = null - viewModel.appsLiveData.removeObservers(this) - viewModel.resultLiveData.value = null - viewModel.resultLiveData.removeObservers(this) - } - - - private fun unInstallModule(packageName: String) { - MaterialDialog(this).show { - title(R.string.uninstall_module) - message(R.string.uninstall_module_hint) - positiveButton(R.string.done) { - showLoading() - viewModel.unInstallModule(packageName) - } - negativeButton(R.string.cancel) - } - } - - - private fun installModule(source: String) { - showLoading() - viewModel.installModule(source) - } - - - private val apkPathResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - if (it.resultCode == RESULT_OK) { - it.data?.let { data -> - val source = data.getStringExtra("source") - if (source != null) { - installModule(source) - } - } - - } - } - - - - companion object { - fun start(context: Context) { - val intent = Intent(context, XpActivity::class.java) - context.startActivity(intent) - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpAdapter.kt b/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpAdapter.kt deleted file mode 100644 index 7f0ff2c..0000000 --- a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpAdapter.kt +++ /dev/null @@ -1,42 +0,0 @@ -package top.niunaijun.blackboxa.view.xp - -import android.view.View -import android.view.ViewGroup -import cbfg.rvadapter.RVHolder -import cbfg.rvadapter.RVHolderFactory -import top.niunaijun.blackboxa.R -import top.niunaijun.blackboxa.bean.XpModuleInfo -import top.niunaijun.blackboxa.databinding.ItemXpBinding - - -/** - * - * @Description: - * @Author: wukaicheng - * @CreateDate: 2021/5/2 21:32 - */ -class XpAdapter : RVHolderFactory() { - - override fun createViewHolder(parent: ViewGroup?, viewType: Int, item: Any): RVHolder { - return XpVH(inflate(R.layout.item_xp, parent)) - } - - class XpVH(itemView: View) : RVHolder(itemView) { - - private val binding = ItemXpBinding.bind(itemView) - - override fun setContent(item: XpModuleInfo, isSelected: Boolean, payload: Any?) { - binding.icon.setImageDrawable(item.icon) - binding.name.text = item.name - binding.desc.text = item.desc - binding.enable.isChecked = item.enable - binding.enable.setOnCheckedChangeListener { buttonView, _ -> - if (buttonView.isPressed) { - binding.root.performClick() - } - - } - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpFactory.kt b/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpFactory.kt deleted file mode 100644 index cdf8528..0000000 --- a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpFactory.kt +++ /dev/null @@ -1,18 +0,0 @@ -package top.niunaijun.blackboxa.view.xp - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider -import top.niunaijun.blackboxa.data.XpRepository - -/** - * - * @Description: - * @Author: wukaicheng - * @CreateDate: 2021/5/2 20:56 - */ -@Suppress("UNCHECKED_CAST") -class XpFactory(private val repo:XpRepository): ViewModelProvider.NewInstanceFactory() { - override fun create(modelClass: Class): T { - return XpViewModel(repo) as T - } -} \ No newline at end of file diff --git a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpViewModel.kt b/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpViewModel.kt deleted file mode 100644 index 7937b3f..0000000 --- a/app/src/main/java/top/niunaijun/blackboxa/view/xp/XpViewModel.kt +++ /dev/null @@ -1,38 +0,0 @@ -package top.niunaijun.blackboxa.view.xp - -import androidx.lifecycle.MutableLiveData -import top.niunaijun.blackboxa.bean.XpModuleInfo -import top.niunaijun.blackboxa.data.XpRepository -import top.niunaijun.blackboxa.view.base.BaseViewModel - -/** - * - * @Description: - * @Author: wukaicheng - * @CreateDate: 2021/5/2 20:55 - */ -class XpViewModel(private val repo:XpRepository):BaseViewModel() { - - val appsLiveData = MutableLiveData>() - - val resultLiveData = MutableLiveData() - - fun getInstalledModule() { - launchOnUI { - repo.getInstallModules(appsLiveData) - } - } - - fun installModule(source:String) { - launchOnUI { - repo.installModule(source,resultLiveData) - } - } - - - fun unInstallModule(packageName: String){ - launchOnUI { - repo.unInstallModule(packageName,resultLiveData) - } - } -} \ No newline at end of file diff --git a/app/src/main/res/xml/setting.xml b/app/src/main/res/xml/setting.xml index a54ead3..db703e4 100644 --- a/app/src/main/res/xml/setting.xml +++ b/app/src/main/res/xml/setting.xml @@ -2,19 +2,7 @@ - - - - - - @@ -23,9 +11,7 @@ android:title="@string/gms_manager" android:summary="@string/jump_gms"/> - +