From 8afc509368adfbcac26f205f73a511dbbd514e0e Mon Sep 17 00:00:00 2001 From: vvb2060 Date: Tue, 17 Aug 2021 04:35:12 +0800 Subject: [PATCH] [app] Update module updated notification message (#922) --- app/src/main/AndroidManifest.xml | 18 ++---- .../main/java/org/lsposed/manager/App.java | 61 ++++++++++--------- .../org/lsposed/manager/ConfigManager.java | 4 +- .../manager/receivers/ServiceReceiver.java | 8 +-- .../org/lsposed/manager/util/ModuleUtil.java | 3 - .../manager/util/NotificationUtil.java | 17 +++++- app/src/main/res/values-zh-rCN/strings.xml | 6 +- app/src/main/res/values/strings.xml | 6 +- .../lsposed/lspd/service/ConfigManager.java | 9 +-- .../lsposed/lspd/service/LSPosedService.java | 18 ++++-- 10 files changed, 83 insertions(+), 67 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8067627e..a6079baa 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,18 +33,18 @@ + android:launchMode="singleInstance"> @@ -59,17 +59,7 @@ android:name=".ui.activity.CrashReportActivity" android:process=":error_activity" /> - - - - - - - - + { + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + throwable.printStackTrace(pw); + String stackTraceString = sw.toString(); + + //Reduce data to 128KB so we don't get a TransactionTooLargeException when sending the intent. + //The limit is 1MB on Android but some devices seem to have it lower. + //See: http://developer.android.com/reference/android/os/TransactionTooLargeException.html + //And: http://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception#comment46697371_12809171 + if (stackTraceString.length() > 131071) { + String disclaimer = " [stack trace too large]"; + stackTraceString = stackTraceString.substring(0, 131071 - disclaimer.length()) + disclaimer; + } + Intent intent = new Intent(App.this, CrashReportActivity.class); + intent.putExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE", stackTraceString); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + App.this.startActivity(intent); + System.exit(10); + Process.killProcess(Os.getpid()); + }); + } + + @Override public void onCreate() { super.onCreate(); if (!BuildConfig.DEBUG) { - try { - Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { - - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - throwable.printStackTrace(pw); - String stackTraceString = sw.toString(); - - //Reduce data to 128KB so we don't get a TransactionTooLargeException when sending the intent. - //The limit is 1MB on Android but some devices seem to have it lower. - //See: http://developer.android.com/reference/android/os/TransactionTooLargeException.html - //And: http://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception#comment46697371_12809171 - if (stackTraceString.length() > 131071) { - String disclaimer = " [stack trace too large]"; - stackTraceString = stackTraceString.substring(0, 131071 - disclaimer.length()) + disclaimer; - } - Intent intent = new Intent(App.this, CrashReportActivity.class); - intent.putExtra(BuildConfig.APPLICATION_ID + ".EXTRA_STACK_TRACE", stackTraceString); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - App.this.startActivity(intent); - android.os.Process.killProcess(android.os.Process.myPid()); - System.exit(10); - }); - } catch (Throwable t) { - t.printStackTrace(); - } + setCrashReport(); } instance = this; @@ -121,8 +124,9 @@ public class App extends Application { } DayNightDelegate.setApplicationContext(this); DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme()); - RepoLoader.getInstance().loadRemoteData(); + loadRemoteVersion(); + RepoLoader.getInstance().loadRemoteData(); } @NonNull @@ -134,8 +138,7 @@ public class App extends Application { request.header("User-Agent", TAG); return chain.proceed(request.build()); }); - HttpLoggingInterceptor.Logger logger = s -> Log.v(TAG, s); - HttpLoggingInterceptor log = new HttpLoggingInterceptor(logger); + HttpLoggingInterceptor log = new HttpLoggingInterceptor(); log.setLevel(HttpLoggingInterceptor.Level.HEADERS); if (BuildConfig.DEBUG) builder.addInterceptor(log); okHttpClient = builder.dns(new DoHDNS(builder.build())).build(); diff --git a/app/src/main/java/org/lsposed/manager/ConfigManager.java b/app/src/main/java/org/lsposed/manager/ConfigManager.java index 2d62c816..df37a516 100644 --- a/app/src/main/java/org/lsposed/manager/ConfigManager.java +++ b/app/src/main/java/org/lsposed/manager/ConfigManager.java @@ -193,7 +193,9 @@ public class ConfigManager { public static PackageInfo getPackageInfo(String packageName, int flags, int userId) throws PackageManager.NameNotFoundException { try { - return LSPManagerServiceHolder.getService().getPackageInfo(packageName, flags, userId); + var info = LSPManagerServiceHolder.getService().getPackageInfo(packageName, flags, userId); + if (info == null) throw new PackageManager.NameNotFoundException(); + return info; } catch (RemoteException e) { Log.e(App.TAG, Log.getStackTraceString(e)); throw new PackageManager.NameNotFoundException(); diff --git a/app/src/main/java/org/lsposed/manager/receivers/ServiceReceiver.java b/app/src/main/java/org/lsposed/manager/receivers/ServiceReceiver.java index 65a9c716..4f2177e1 100644 --- a/app/src/main/java/org/lsposed/manager/receivers/ServiceReceiver.java +++ b/app/src/main/java/org/lsposed/manager/receivers/ServiceReceiver.java @@ -48,10 +48,8 @@ public class ServiceReceiver extends BroadcastReceiver { return; } - if (intent.getAction().equals("org.lsposed.action.MODULE_NOT_ACTIVATAED")) { - NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, false); - } else if (intent.getAction().equals("org.lsposed.action.MODULE_UPDATED")) { - NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, true); - } + var enabled = "org.lsposed.action.MODULE_UPDATED".equals(intent.getAction()); + var systemModule = intent.getBooleanExtra("systemModule", false); + NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, enabled, systemModule); } } diff --git a/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java b/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java index 37c2d0fe..9bd4b46a 100644 --- a/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java +++ b/app/src/main/java/org/lsposed/manager/util/ModuleUtil.java @@ -106,9 +106,6 @@ public final class ModuleUtil { try { pkg = ConfigManager.getPackageInfo(packageName, PackageManager.GET_META_DATA, userId); - if (pkg == null) { - throw new NameNotFoundException(); - } } catch (NameNotFoundException e) { InstalledModule old = installedModules.remove(Pair.create(packageName, userId)); if (old != null) { diff --git a/app/src/main/java/org/lsposed/manager/util/NotificationUtil.java b/app/src/main/java/org/lsposed/manager/util/NotificationUtil.java index f0b1cb1c..151a5c4d 100644 --- a/app/src/main/java/org/lsposed/manager/util/NotificationUtil.java +++ b/app/src/main/java/org/lsposed/manager/util/NotificationUtil.java @@ -38,7 +38,12 @@ public final class NotificationUtil { private static final int PENDING_INTENT_OPEN_APP_LIST = 0; private static final String NOTIFICATION_MODULES_CHANNEL = "modules_channel_2"; - public static void showNotification(Context context, String modulePackageName, String moduleName, int moduleUserId, boolean enabled) { + public static void showNotification(Context context, + String modulePackageName, + String moduleName, + int moduleUserId, + boolean enabled, + boolean systemModule) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel(NOTIFICATION_MODULES_CHANNEL, @@ -48,8 +53,14 @@ public final class NotificationUtil { channel.setVibrationPattern(null); notificationManager.createNotificationChannel(channel); - String title = context.getString(enabled ? R.string.xposed_module_updated_notification_title : R.string.module_is_not_activated_yet); - String content = context.getString(enabled ? R.string.xposed_module_updated_notification_content : R.string.module_is_not_activated_yet_detailed, moduleName); + String title = context.getString(enabled ? systemModule ? + R.string.xposed_module_updated_notification_title_system : + R.string.xposed_module_updated_notification_title : + R.string.module_is_not_activated_yet); + String content = context.getString(enabled ? systemModule ? + R.string.xposed_module_updated_notification_content_system : + R.string.xposed_module_updated_notification_content : + R.string.module_is_not_activated_yet_detailed, moduleName); Intent intent = new Intent(context, MainActivity.class) .putExtra("modulePackageName", modulePackageName) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 242660ed..dd714db2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -77,12 +77,14 @@ Xposed 模块尚未激活 %s 已安装, 但尚未激活 - %s 已更新 + Xposed 模块已更新 + %s 已更新,请强行停止并重新打开其作用域内的应用 + Xposed 模块已更新,需要重新启动 + %s 已更新,由于作用域包含系统框架,需要重启设备以应用更改 (未提供介绍) 该模块未提供用户界面 - Xposed 模块已更新 该模块需要更新版本的 Xposed(%d), 因此无法被激活 该模块未指定所需的 Xposed 版本 该模块针对 Xposed %1$d 版本构建 , 由于不兼容 %2$d 版本中的变更, 现已被停用 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1f97094e..799a16cc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -77,12 +77,14 @@ Xposed module is not activated yet %s has been installed, but is not activated yet - %s has been updated + Xposed module updated + %s has been updated, please force stop and restart apps in its scope + Xposed module updated, system reboot required + %s has been updated, since the scope contains System Framework, required reboot to apply changes (no description provided) This module does not provide a user interface - Xposed module updated This module requires a newer Xposed version (%d) and thus cannot be activated This module does not specify the Xposed version it needs. This module was created for Xposed version %1$d, but due to incompatible changes in version %2$d, it has been disabled diff --git a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java index 8908bc3e..acdd3972 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java @@ -654,14 +654,16 @@ public class ConfigManager { // This is called when a new process created, use the cached result public boolean shouldSkipProcess(ProcessScope scope) { - return !cachedScope.containsKey(scope) && !isManager(scope.uid); + return !cachedScope.containsKey(scope) && + !isManager(scope.uid) && + !shouldBlock(scope.processName); } public boolean isUidHooked(int uid) { return cachedScope.keySet().stream().reduce(false, (p, scope) -> p || scope.uid == uid, Boolean::logicalOr); } - // This should only be called by manager, so we don't need to cache it + @Nullable public List getModuleScope(String packageName) { int mid = getModuleId(packageName); if (mid == -1) return null; @@ -690,8 +692,7 @@ public class ConfigManager { apks = Arrays.copyOf(info.splitSourceDirs, info.splitSourceDirs.length + 1); apks[info.splitSourceDirs.length] = info.sourceDir; } else apks = new String[]{info.sourceDir}; - var apkPath = Arrays.stream(apks).parallel() - .filter(apk -> { + var apkPath = Arrays.stream(apks).parallel().filter(apk -> { if (apk == null) { Log.w(TAG, info.packageName + " has null apk path???"); return false; diff --git a/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java b/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java index 271dfbfd..55815d62 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java @@ -136,16 +136,26 @@ public class LSPosedService extends ILSPosedService.Stub { } if (isXposedModule) { Log.d(TAG, "module " + moduleName + " changed, dispatching to manager"); - boolean enabled = Arrays.asList(ConfigManager.getInstance().enabledModules()).contains(moduleName); - boolean removed = intent.getAction().equals(Intent.ACTION_PACKAGE_FULLY_REMOVED) || intent.getAction().equals(Intent.ACTION_UID_REMOVED); - Intent broadcastIntent = new Intent(enabled || removed ? "org.lsposed.action.MODULE_UPDATED" : "org.lsposed.action.MODULE_NOT_ACTIVATAED"); + var enabledModules = ConfigManager.getInstance().enabledModules(); + var scope = ConfigManager.getInstance().getModuleScope(moduleName); + boolean systemModule = scope != null && + scope.parallelStream().anyMatch(app -> app.packageName.equals("android")); + boolean enabled = Arrays.asList(enabledModules).contains(moduleName); + boolean removed = intent.getAction().equals(Intent.ACTION_PACKAGE_FULLY_REMOVED) || + intent.getAction().equals(Intent.ACTION_UID_REMOVED); + var action = enabled || removed ? "org.lsposed.action.MODULE_UPDATED" : + "org.lsposed.action.MODULE_NOT_ACTIVATAED"; + Intent broadcastIntent = new Intent(action); broadcastIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); broadcastIntent.addFlags(0x01000000); broadcastIntent.addFlags(0x00400000); broadcastIntent.setData(intent.getData()); broadcastIntent.putExtras(intent.getExtras()); broadcastIntent.putExtra(Intent.EXTRA_USER, userId); - broadcastIntent.setComponent(ComponentName.unflattenFromString(ConfigManager.getInstance().getManagerPackageName() + "/.receivers.ServiceReceiver")); + broadcastIntent.putExtra("systemModule", systemModule); + var manager = ConfigManager.getInstance().getManagerPackageName(); + var component = ComponentName.createRelative(manager, ".receivers.ServiceReceiver"); + broadcastIntent.setComponent(component); try { ActivityManagerService.broadcastIntentWithFeature(null, broadcastIntent,