Fix the module status in the manager after module changes (#1202)
This commit is contained in:
parent
5c27c55720
commit
67d3fe82ff
|
|
@ -38,7 +38,6 @@ import androidx.preference.PreferenceManager;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
import org.lsposed.hiddenapibypass.HiddenApiBypass;
|
||||||
import org.lsposed.manager.receivers.LSPManagerServiceHolder;
|
|
||||||
import org.lsposed.manager.repo.RepoLoader;
|
import org.lsposed.manager.repo.RepoLoader;
|
||||||
import org.lsposed.manager.ui.activity.CrashReportActivity;
|
import org.lsposed.manager.ui.activity.CrashReportActivity;
|
||||||
import org.lsposed.manager.util.DoHDNS;
|
import org.lsposed.manager.util.DoHDNS;
|
||||||
|
|
@ -168,8 +167,9 @@ public class App extends Application {
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
int userId = intent.getIntExtra(Intent.EXTRA_USER, 0);
|
int userId = intent.getIntExtra(Intent.EXTRA_USER, 0);
|
||||||
String packageName = intent.getStringExtra("android.intent.extra.PACKAGES");
|
String packageName = intent.getStringExtra("android.intent.extra.PACKAGES");
|
||||||
|
boolean packageFullyRemoved = intent.getBooleanExtra(Intent.ACTION_PACKAGE_FULLY_REMOVED, false);
|
||||||
if (packageName != null) {
|
if (packageName != null) {
|
||||||
ModuleUtil.getInstance().reloadSingleModule(packageName, userId);
|
ModuleUtil.getInstance().reloadSingleModule(packageName, userId, packageFullyRemoved);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, new IntentFilter(Intent.ACTION_PACKAGE_CHANGED));
|
}, new IntentFilter(Intent.ACTION_PACKAGE_CHANGED));
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,12 @@ public final class ModuleUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public InstalledModule reloadSingleModule(String packageName, int userId) {
|
public InstalledModule reloadSingleModule(String packageName, int userId) {
|
||||||
|
return reloadSingleModule(packageName, userId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InstalledModule reloadSingleModule(String packageName, int userId, boolean packageFullyRemoved) {
|
||||||
|
if (packageFullyRemoved && isModuleEnabled(packageName))
|
||||||
|
enabledModules.remove(packageName);
|
||||||
PackageInfo pkg;
|
PackageInfo pkg;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -115,7 +121,6 @@ public final class ModuleUtil {
|
||||||
} 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) {
|
||||||
enabledModules.remove(packageName);
|
|
||||||
for (ModuleListener listener : listeners) {
|
for (ModuleListener listener : listeners) {
|
||||||
listener.onSingleInstalledModuleReloaded();
|
listener.onSingleInstalledModuleReloaded();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -670,7 +670,10 @@ public class ConfigManager {
|
||||||
public boolean removeModule(String packageName) {
|
public boolean removeModule(String packageName) {
|
||||||
if (removeModuleWithoutCache(packageName)) {
|
if (removeModuleWithoutCache(packageName)) {
|
||||||
// called by oneway binder
|
// called by oneway binder
|
||||||
updateCaches(true);
|
// Called only when the application is completely uninstalled
|
||||||
|
// If it's a module we need to return as soon as possible to broadcast to the manager
|
||||||
|
// for updating the module status
|
||||||
|
updateCaches(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import android.graphics.Canvas;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
|
|
@ -59,7 +60,6 @@ import org.lsposed.lspd.ILSPManagerService;
|
||||||
import org.lsposed.lspd.models.Application;
|
import org.lsposed.lspd.models.Application;
|
||||||
import org.lsposed.lspd.models.UserInfo;
|
import org.lsposed.lspd.models.UserInfo;
|
||||||
import org.lsposed.lspd.util.FakeContext;
|
import org.lsposed.lspd.util.FakeContext;
|
||||||
import android.os.Handler;
|
|
||||||
import org.lsposed.lspd.util.Utils;
|
import org.lsposed.lspd.util.Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -253,12 +253,13 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void broadcastIntent(String modulePackageName, int moduleUserId) {
|
public static void broadcastIntent(String modulePackageName, int moduleUserId, boolean packageFullyRemoved) {
|
||||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
|
Intent intent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
|
||||||
intent.addFlags(0x01000000); //Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
|
intent.addFlags(0x01000000); //Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
|
||||||
intent.addFlags(0x00400000); //Intent.FLAG_RECEIVER_FROM_SHELL
|
intent.addFlags(0x00400000); //Intent.FLAG_RECEIVER_FROM_SHELL
|
||||||
intent.putExtra("android.intent.extra.PACKAGES", modulePackageName);
|
intent.putExtra("android.intent.extra.PACKAGES", modulePackageName);
|
||||||
intent.putExtra(Intent.EXTRA_USER, moduleUserId);
|
intent.putExtra(Intent.EXTRA_USER, moduleUserId);
|
||||||
|
intent.putExtra(Intent.ACTION_PACKAGE_FULLY_REMOVED, packageFullyRemoved);
|
||||||
intent.setPackage(BuildConfig.MANAGER_INJECTED_PKG_NAME);
|
intent.setPackage(BuildConfig.MANAGER_INJECTED_PKG_NAME);
|
||||||
try {
|
try {
|
||||||
ActivityManagerService.broadcastIntentWithFeature(null, intent,
|
ActivityManagerService.broadcastIntentWithFeature(null, intent,
|
||||||
|
|
@ -277,7 +278,7 @@ public class LSPManagerService extends ILSPManagerService.Stub {
|
||||||
|
|
||||||
|
|
||||||
public static void createOrUpdateShortcut(boolean force) {
|
public static void createOrUpdateShortcut(boolean force) {
|
||||||
workerHandler.post(()->createOrUpdateShortcutInternal(force));
|
workerHandler.post(() -> createOrUpdateShortcutInternal(force));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized static void createOrUpdateShortcutInternal(boolean force) {
|
private synchronized static void createOrUpdateShortcutInternal(boolean force) {
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,9 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
if (uid == AID_NOBODY || uid <= 0) return;
|
if (uid == AID_NOBODY || uid <= 0) return;
|
||||||
int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL);
|
int userId = intent.getIntExtra("android.intent.extra.user_handle", USER_NULL);
|
||||||
if (userId == USER_NULL) userId = uid % PER_USER_RANGE;
|
if (userId == USER_NULL) userId = uid % PER_USER_RANGE;
|
||||||
|
var configManager = ConfigManager.getInstance();
|
||||||
Uri uri = intent.getData();
|
Uri uri = intent.getData();
|
||||||
String moduleName = (uri != null) ? uri.getSchemeSpecificPart() : ConfigManager.getInstance().getModule(uid);
|
String moduleName = (uri != null) ? uri.getSchemeSpecificPart() : configManager.getModule(uid);
|
||||||
|
|
||||||
ApplicationInfo applicationInfo = null;
|
ApplicationInfo applicationInfo = null;
|
||||||
if (moduleName != null) {
|
if (moduleName != null) {
|
||||||
|
|
@ -94,15 +94,13 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
boolean isXposedModule = applicationInfo != null &&
|
boolean isXposedModule = applicationInfo != null &&
|
||||||
applicationInfo.metaData != null &&
|
applicationInfo.metaData != null &&
|
||||||
applicationInfo.metaData.containsKey("xposedminversion");
|
applicationInfo.metaData.containsKey("xposedminversion");
|
||||||
|
var intentAction = intent.getAction();
|
||||||
Log.d(TAG, "Package changed: uid=" + uid + " userId=" + userId + " action=" + intent.getAction() + " isXposedModule=" + isXposedModule);
|
switch (intentAction) {
|
||||||
|
|
||||||
switch (intent.getAction()) {
|
|
||||||
case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
|
case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
|
||||||
// for module, remove module
|
// for module, remove module
|
||||||
// because we only care about when the apk is gone
|
// because we only care about when the apk is gone
|
||||||
if (moduleName != null)
|
if (moduleName != null)
|
||||||
if (ConfigManager.getInstance().removeModule(moduleName))
|
if (configManager.removeModule(moduleName))
|
||||||
isXposedModule = true;
|
isXposedModule = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -116,10 +114,10 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
}
|
}
|
||||||
// when package is changed, we may need to update cache (module cache or process cache)
|
// when package is changed, we may need to update cache (module cache or process cache)
|
||||||
if (isXposedModule) {
|
if (isXposedModule) {
|
||||||
ConfigManager.getInstance().updateCache();
|
configManager.updateCache();
|
||||||
} else if (ConfigManager.getInstance().isUidHooked(uid)) {
|
} else if (configManager.isUidHooked(uid)) {
|
||||||
// it will automatically remove obsolete app from database
|
// it will automatically remove obsolete app from database
|
||||||
ConfigManager.getInstance().updateAppCache();
|
configManager.updateAppCache();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -128,33 +126,36 @@ public class LSPosedService extends ILSPosedService.Stub {
|
||||||
// (apk may still be there because of multi-user)
|
// (apk may still be there because of multi-user)
|
||||||
if (isXposedModule) {
|
if (isXposedModule) {
|
||||||
// it will automatically remove obsolete scope from database
|
// it will automatically remove obsolete scope from database
|
||||||
ConfigManager.getInstance().updateCache();
|
configManager.updateCache();
|
||||||
} else if (ConfigManager.getInstance().isUidHooked(uid)) {
|
} else if (configManager.isUidHooked(uid)) {
|
||||||
// it will automatically remove obsolete app from database
|
// it will automatically remove obsolete app from database
|
||||||
ConfigManager.getInstance().updateAppCache();
|
configManager.updateAppCache();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean removed = intent.getAction().equals(Intent.ACTION_PACKAGE_FULLY_REMOVED) ||
|
boolean removed = intentAction.equals(Intent.ACTION_PACKAGE_FULLY_REMOVED) ||
|
||||||
intent.getAction().equals(Intent.ACTION_UID_REMOVED);
|
intentAction.equals(Intent.ACTION_UID_REMOVED);
|
||||||
|
|
||||||
|
Log.d(TAG, "Package changed: uid=" + uid + " userId=" + userId + " action=" + intent.getAction() + " isXposedModule=" + isXposedModule);
|
||||||
|
|
||||||
if (isXposedModule) {
|
if (isXposedModule) {
|
||||||
Log.d(TAG, "module " + moduleName + " changed, dispatching to manager");
|
Log.d(TAG, "module " + moduleName + " changed, dispatching to manager");
|
||||||
var enabledModules = ConfigManager.getInstance().enabledModules();
|
var enabledModules = configManager.enabledModules();
|
||||||
var scope = ConfigManager.getInstance().getModuleScope(moduleName);
|
var scope = configManager.getModuleScope(moduleName);
|
||||||
boolean systemModule = scope != null &&
|
boolean systemModule = scope != null &&
|
||||||
scope.parallelStream().anyMatch(app -> app.packageName.equals("android"));
|
scope.parallelStream().anyMatch(app -> app.packageName.equals("android"));
|
||||||
boolean enabled = Arrays.asList(enabledModules).contains(moduleName);
|
boolean enabled = Arrays.asList(enabledModules).contains(moduleName);
|
||||||
if (!removed) {
|
if (!removed) {
|
||||||
LSPManagerService.showNotification(moduleName, userId, enabled, systemModule);
|
LSPManagerService.showNotification(moduleName, userId, enabled, systemModule);
|
||||||
}
|
}
|
||||||
LSPManagerService.broadcastIntent(moduleName, userId);
|
LSPManagerService.broadcastIntent(moduleName, userId, intentAction.equals(Intent.ACTION_PACKAGE_FULLY_REMOVED));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BuildConfig.DEFAULT_MANAGER_PACKAGE_NAME.equals(moduleName) && userId == 0) {
|
if (BuildConfig.DEFAULT_MANAGER_PACKAGE_NAME.equals(moduleName) && userId == 0) {
|
||||||
Log.d(TAG, "Manager updated");
|
Log.d(TAG, "Manager updated");
|
||||||
try {
|
try {
|
||||||
ConfigManager.getInstance().updateManager(removed);
|
configManager.updateManager(removed);
|
||||||
LSPManagerService.createOrUpdateShortcut(false);
|
LSPManagerService.createOrUpdateShortcut(false);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue