[app] Update module updated notification message (#922)

This commit is contained in:
vvb2060 2021-08-17 04:35:12 +08:00 committed by GitHub
parent 1779706cbf
commit 8afc509368
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 83 additions and 67 deletions

View File

@ -33,18 +33,18 @@
<application <application
android:name=".App" android:name=".App"
android:allowBackup="true" android:allowBackup="true"
android:hasFragileUserData="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:hasFragileUserData="true"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning" tools:ignore="AllowBackup,GoogleAppIndexingWarning"
tools:targetApi="q"> tools:targetApi="q">
<activity <activity
android:name=".ui.activity.MainActivity" android:name=".ui.activity.MainActivity"
android:exported="true"
android:label="@string/app_name" android:label="@string/app_name"
android:launchMode="singleInstance" android:launchMode="singleInstance">
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.APPLICATION_PREFERENCES" /> <action android:name="android.intent.action.APPLICATION_PREFERENCES" />
@ -59,17 +59,7 @@
android:name=".ui.activity.CrashReportActivity" android:name=".ui.activity.CrashReportActivity"
android:process=":error_activity" /> android:process=":error_activity" />
<receiver <receiver android:name=".receivers.ServiceReceiver" />
android:name=".receivers.ServiceReceiver"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL">
<intent-filter>
<action android:name="org.lsposed.action.MODULE_UPDATED" />
<action android:name="org.lsposed.action.MODULE_NOT_ACTIVATAED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"

View File

@ -25,6 +25,8 @@ import android.app.Application;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Build; import android.os.Build;
import android.os.Process;
import android.system.Os;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -80,35 +82,36 @@ public class App extends Application {
return instance.pref; return instance.pref;
} }
private void setCrashReport() {
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);
System.exit(10);
Process.killProcess(Os.getpid());
});
}
@Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
if (!BuildConfig.DEBUG) { if (!BuildConfig.DEBUG) {
try { setCrashReport();
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();
}
} }
instance = this; instance = this;
@ -121,8 +124,9 @@ public class App extends Application {
} }
DayNightDelegate.setApplicationContext(this); DayNightDelegate.setApplicationContext(this);
DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme()); DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme());
RepoLoader.getInstance().loadRemoteData();
loadRemoteVersion(); loadRemoteVersion();
RepoLoader.getInstance().loadRemoteData();
} }
@NonNull @NonNull
@ -134,8 +138,7 @@ public class App extends Application {
request.header("User-Agent", TAG); request.header("User-Agent", TAG);
return chain.proceed(request.build()); return chain.proceed(request.build());
}); });
HttpLoggingInterceptor.Logger logger = s -> Log.v(TAG, s); HttpLoggingInterceptor log = new HttpLoggingInterceptor();
HttpLoggingInterceptor log = new HttpLoggingInterceptor(logger);
log.setLevel(HttpLoggingInterceptor.Level.HEADERS); log.setLevel(HttpLoggingInterceptor.Level.HEADERS);
if (BuildConfig.DEBUG) builder.addInterceptor(log); if (BuildConfig.DEBUG) builder.addInterceptor(log);
okHttpClient = builder.dns(new DoHDNS(builder.build())).build(); okHttpClient = builder.dns(new DoHDNS(builder.build())).build();

View File

@ -193,7 +193,9 @@ public class ConfigManager {
public static PackageInfo getPackageInfo(String packageName, int flags, int userId) throws PackageManager.NameNotFoundException { public static PackageInfo getPackageInfo(String packageName, int flags, int userId) throws PackageManager.NameNotFoundException {
try { 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) { } catch (RemoteException e) {
Log.e(App.TAG, Log.getStackTraceString(e)); Log.e(App.TAG, Log.getStackTraceString(e));
throw new PackageManager.NameNotFoundException(); throw new PackageManager.NameNotFoundException();

View File

@ -48,10 +48,8 @@ public class ServiceReceiver extends BroadcastReceiver {
return; return;
} }
if (intent.getAction().equals("org.lsposed.action.MODULE_NOT_ACTIVATAED")) { var enabled = "org.lsposed.action.MODULE_UPDATED".equals(intent.getAction());
NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, false); var systemModule = intent.getBooleanExtra("systemModule", false);
} else if (intent.getAction().equals("org.lsposed.action.MODULE_UPDATED")) { NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, enabled, systemModule);
NotificationUtil.showNotification(context, packageName, module.getAppName(), userId, true);
}
} }
} }

View File

@ -106,9 +106,6 @@ public final class ModuleUtil {
try { try {
pkg = ConfigManager.getPackageInfo(packageName, PackageManager.GET_META_DATA, userId); pkg = ConfigManager.getPackageInfo(packageName, PackageManager.GET_META_DATA, userId);
if (pkg == null) {
throw new NameNotFoundException();
}
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
InstalledModule old = installedModules.remove(Pair.create(packageName, userId)); InstalledModule old = installedModules.remove(Pair.create(packageName, userId));
if (old != null) { if (old != null) {

View File

@ -38,7 +38,12 @@ public final class NotificationUtil {
private static final int PENDING_INTENT_OPEN_APP_LIST = 0; private static final int PENDING_INTENT_OPEN_APP_LIST = 0;
private static final String NOTIFICATION_MODULES_CHANNEL = "modules_channel_2"; 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); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(NOTIFICATION_MODULES_CHANNEL, NotificationChannel channel = new NotificationChannel(NOTIFICATION_MODULES_CHANNEL,
@ -48,8 +53,14 @@ public final class NotificationUtil {
channel.setVibrationPattern(null); channel.setVibrationPattern(null);
notificationManager.createNotificationChannel(channel); notificationManager.createNotificationChannel(channel);
String title = context.getString(enabled ? R.string.xposed_module_updated_notification_title : R.string.module_is_not_activated_yet); String title = context.getString(enabled ? systemModule ?
String content = context.getString(enabled ? R.string.xposed_module_updated_notification_content : R.string.module_is_not_activated_yet_detailed, moduleName); 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) Intent intent = new Intent(context, MainActivity.class)
.putExtra("modulePackageName", modulePackageName) .putExtra("modulePackageName", modulePackageName)

View File

@ -77,12 +77,14 @@
<!-- Notification --> <!-- Notification -->
<string name="module_is_not_activated_yet">Xposed 模块尚未激活</string> <string name="module_is_not_activated_yet">Xposed 模块尚未激活</string>
<string name="module_is_not_activated_yet_detailed">%s 已安装, 但尚未激活</string> <string name="module_is_not_activated_yet_detailed">%s 已安装, 但尚未激活</string>
<string name="xposed_module_updated_notification_content">%s 已更新</string> <string name="xposed_module_updated_notification_title">Xposed 模块已更新</string>
<string name="xposed_module_updated_notification_content">%s 已更新,请强行停止并重新打开其作用域内的应用</string>
<string name="xposed_module_updated_notification_title_system">Xposed 模块已更新,需要重新启动</string>
<string name="xposed_module_updated_notification_content_system">%s 已更新,由于作用域包含系统框架,需要重启设备以应用更改</string>
<!-- ModulesActivity --> <!-- ModulesActivity -->
<string name="module_empty_description">(未提供介绍)</string> <string name="module_empty_description">(未提供介绍)</string>
<string name="module_no_ui">该模块未提供用户界面</string> <string name="module_no_ui">该模块未提供用户界面</string>
<string name="xposed_module_updated_notification_title">Xposed 模块已更新</string>
<string name="warning_xposed_min_version">该模块需要更新版本的 Xposed(%d), 因此无法被激活</string> <string name="warning_xposed_min_version">该模块需要更新版本的 Xposed(%d), 因此无法被激活</string>
<string name="no_min_version_specified">该模块未指定所需的 Xposed 版本</string> <string name="no_min_version_specified">该模块未指定所需的 Xposed 版本</string>
<string name="warning_min_version_too_low">该模块针对 Xposed %1$d 版本构建 , 由于不兼容 %2$d 版本中的变更, 现已被停用</string> <string name="warning_min_version_too_low">该模块针对 Xposed %1$d 版本构建 , 由于不兼容 %2$d 版本中的变更, 现已被停用</string>

View File

@ -77,12 +77,14 @@
<!-- Notification --> <!-- Notification -->
<string name="module_is_not_activated_yet">Xposed module is not activated yet</string> <string name="module_is_not_activated_yet">Xposed module is not activated yet</string>
<string name="module_is_not_activated_yet_detailed">%s has been installed, but is not activated yet</string> <string name="module_is_not_activated_yet_detailed">%s has been installed, but is not activated yet</string>
<string name="xposed_module_updated_notification_content">%s has been updated</string> <string name="xposed_module_updated_notification_title">Xposed module updated</string>
<string name="xposed_module_updated_notification_content">%s has been updated, please force stop and restart apps in its scope</string>
<string name="xposed_module_updated_notification_title_system">Xposed module updated, system reboot required</string>
<string name="xposed_module_updated_notification_content_system">%s has been updated, since the scope contains System Framework, required reboot to apply changes</string>
<!-- ModulesActivity --> <!-- ModulesActivity -->
<string name="module_empty_description">(no description provided)</string> <string name="module_empty_description">(no description provided)</string>
<string name="module_no_ui">This module does not provide a user interface</string> <string name="module_no_ui">This module does not provide a user interface</string>
<string name="xposed_module_updated_notification_title">Xposed module updated</string>
<string name="warning_xposed_min_version">This module requires a newer Xposed version (%d) and thus cannot be activated</string> <string name="warning_xposed_min_version">This module requires a newer Xposed version (%d) and thus cannot be activated</string>
<string name="no_min_version_specified">This module does not specify the Xposed version it needs.</string> <string name="no_min_version_specified">This module does not specify the Xposed version it needs.</string>
<string name="warning_min_version_too_low">This module was created for Xposed version %1$d, but due to incompatible changes in version %2$d, it has been disabled</string> <string name="warning_min_version_too_low">This module was created for Xposed version %1$d, but due to incompatible changes in version %2$d, it has been disabled</string>

View File

@ -654,14 +654,16 @@ public class ConfigManager {
// This is called when a new process created, use the cached result // This is called when a new process created, use the cached result
public boolean shouldSkipProcess(ProcessScope scope) { 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) { public boolean isUidHooked(int uid) {
return cachedScope.keySet().stream().reduce(false, (p, scope) -> p || scope.uid == uid, Boolean::logicalOr); 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<Application> getModuleScope(String packageName) { public List<Application> getModuleScope(String packageName) {
int mid = getModuleId(packageName); int mid = getModuleId(packageName);
if (mid == -1) return null; if (mid == -1) return null;
@ -690,8 +692,7 @@ public class ConfigManager {
apks = Arrays.copyOf(info.splitSourceDirs, info.splitSourceDirs.length + 1); apks = Arrays.copyOf(info.splitSourceDirs, info.splitSourceDirs.length + 1);
apks[info.splitSourceDirs.length] = info.sourceDir; apks[info.splitSourceDirs.length] = info.sourceDir;
} else apks = new String[]{info.sourceDir}; } else apks = new String[]{info.sourceDir};
var apkPath = Arrays.stream(apks).parallel() var apkPath = Arrays.stream(apks).parallel().filter(apk -> {
.filter(apk -> {
if (apk == null) { if (apk == null) {
Log.w(TAG, info.packageName + " has null apk path???"); Log.w(TAG, info.packageName + " has null apk path???");
return false; return false;

View File

@ -136,16 +136,26 @@ public class LSPosedService extends ILSPosedService.Stub {
} }
if (isXposedModule) { if (isXposedModule) {
Log.d(TAG, "module " + moduleName + " changed, dispatching to manager"); Log.d(TAG, "module " + moduleName + " changed, dispatching to manager");
boolean enabled = Arrays.asList(ConfigManager.getInstance().enabledModules()).contains(moduleName); var enabledModules = ConfigManager.getInstance().enabledModules();
boolean removed = intent.getAction().equals(Intent.ACTION_PACKAGE_FULLY_REMOVED) || intent.getAction().equals(Intent.ACTION_UID_REMOVED); var scope = ConfigManager.getInstance().getModuleScope(moduleName);
Intent broadcastIntent = new Intent(enabled || removed ? "org.lsposed.action.MODULE_UPDATED" : "org.lsposed.action.MODULE_NOT_ACTIVATAED"); 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(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
broadcastIntent.addFlags(0x01000000); broadcastIntent.addFlags(0x01000000);
broadcastIntent.addFlags(0x00400000); broadcastIntent.addFlags(0x00400000);
broadcastIntent.setData(intent.getData()); broadcastIntent.setData(intent.getData());
broadcastIntent.putExtras(intent.getExtras()); broadcastIntent.putExtras(intent.getExtras());
broadcastIntent.putExtra(Intent.EXTRA_USER, userId); 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 { try {
ActivityManagerService.broadcastIntentWithFeature(null, broadcastIntent, ActivityManagerService.broadcastIntentWithFeature(null, broadcastIntent,