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 fdcc9c3d..b6822de3 100644 --- a/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/org/lsposed/lspd/service/ConfigManager.java @@ -22,6 +22,7 @@ package org.lsposed.lspd.service; import static org.lsposed.lspd.service.ServiceManager.TAG; import android.content.ContentValues; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; @@ -64,6 +65,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.zip.ZipFile; // This config manager assume uid won't change when our service is off. // Otherwise, user should maintain it manually. @@ -499,14 +501,27 @@ public class ConfigManager { } } - public boolean updateModuleApkPath(String packageName, String apkPath) { + public boolean updateModuleApkPath(String packageName, ApplicationInfo info) { + String[] apks; + if (info.splitSourceDirs != null) { + 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).filter(apk -> { + try (var zip = new ZipFile(apk)) { + return zip.getEntry("assets/xposed_init") != null; + } catch (IOException e) { + return false; + } + }).findFirst(); + if (!apkPath.isPresent()) return false; if (db.inTransaction()) { Log.w(TAG, "update module apk path should not be called inside transaction"); return false; } ContentValues values = new ContentValues(); values.put("module_pkg_name", packageName); - values.put("apk_path", apkPath); + values.put("apk_path", apkPath.get()); int count = (int) db.insertWithOnConflict("modules", null, values, SQLiteDatabase.CONFLICT_IGNORE); if (count < 0) { count = db.updateWithOnConflict("modules", values, "module_pkg_name=?", new String[]{packageName}, SQLiteDatabase.CONFLICT_IGNORE); @@ -627,8 +642,8 @@ public class ConfigManager { return true; } - public boolean enableModule(String packageName, String apkPath) { - if (!updateModuleApkPath(packageName, apkPath)) return false; + public boolean enableModule(String packageName, ApplicationInfo info) { + if (!updateModuleApkPath(packageName, info)) return false; int mid = getModuleId(packageName); if (mid == -1) return false; try { diff --git a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java index 4d8880db..acb0aff2 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPManagerService.java @@ -124,7 +124,7 @@ public class LSPManagerService extends ILSPManagerService.Stub { public boolean enableModule(String packageName) throws RemoteException { PackageInfo pkgInfo = PackageService.getPackageInfo(packageName, PackageService.MATCH_ALL_FLAGS, 0); if (pkgInfo == null) return false; - return ConfigManager.getInstance().enableModule(packageName, pkgInfo.applicationInfo.sourceDir); + return ConfigManager.getInstance().enableModule(packageName, pkgInfo.applicationInfo); } @Override 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 044ad9d1..d89ebb42 100644 --- a/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java +++ b/core/src/main/java/org/lsposed/lspd/service/LSPosedService.java @@ -113,8 +113,8 @@ public class LSPosedService extends ILSPosedService.Stub { } // when package is changed, we may need to update cache (module cache or process cache) if (isXposedModule) { - ConfigManager.getInstance().updateModuleApkPath(moduleName, applicationInfo.sourceDir); - Log.d(TAG, "Updated module apk path: " + moduleName); + var ret = ConfigManager.getInstance().updateModuleApkPath(moduleName, applicationInfo); + if (ret) Log.i(TAG, "Updated module apk path: " + moduleName); } else if (ConfigManager.getInstance().isUidHooked(uid)) { // it will automatically remove obsolete app from database ConfigManager.getInstance().updateAppCache();