diff --git a/manager/src/main/java/org/lsposed/lspatch/Patcher.kt b/manager/src/main/java/org/lsposed/lspatch/Patcher.kt index 28ddda4..953f884 100644 --- a/manager/src/main/java/org/lsposed/lspatch/Patcher.kt +++ b/manager/src/main/java/org/lsposed/lspatch/Patcher.kt @@ -25,8 +25,6 @@ object Patcher { add("-o"); add(lspApp.tmpApkDir.absolutePath) if (config.debuggable) add("-d") add("-l"); add(config.sigBypassLevel.toString()) - add("--v1"); add(config.v1.toString()) - add("--v2"); add(config.v2.toString()) if (config.useManager) add("--manager") if (config.overrideVersionCode) add("-r") if (Configs.detailPatchLogs) add("-v") diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/NewPatchScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/NewPatchScreen.kt index b2f4513..f43af63 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/NewPatchScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/NewPatchScreen.kt @@ -176,7 +176,6 @@ private fun sigBypassLvStr(level: Int) = when (level) { else -> throw IllegalArgumentException("Invalid sigBypassLv: $level") } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun PatchOptionsBody(modifier: Modifier, onAddEmbed: () -> Unit) { val viewModel = viewModel() @@ -236,34 +235,6 @@ private fun PatchOptionsBody(modifier: Modifier, onAddEmbed: () -> Unit) { title = stringResource(R.string.patch_override_version_code), desc = stringResource(R.string.patch_override_version_code_desc) ) - var signExpanded by remember { mutableStateOf(false) } - AnywhereDropdown( - expanded = signExpanded, - onDismissRequest = { signExpanded = false }, - onClick = { signExpanded = true }, - surface = { - SettingsItem( - icon = Icons.Outlined.Edit, - title = stringResource(R.string.patch_sign), - desc = viewModel.sign - .mapIndexedNotNull { index, on -> if (on) "V" + (index + 1) else null } - .joinToString(" + ") - .ifEmpty { "None" } - ) - } - ) { - repeat(2) { index -> - DropdownMenuItem( - text = { - Row(verticalAlignment = Alignment.CenterVertically) { - Checkbox(checked = viewModel.sign[index], onCheckedChange = { viewModel.sign[index] = !viewModel.sign[index] }) - Text("V" + (index + 1)) - } - }, - onClick = { viewModel.sign[index] = !viewModel.sign[index] } - ) - } - } var bypassExpanded by remember { mutableStateOf(false) } AnywhereDropdown( expanded = bypassExpanded, diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt index 295d46b..656ae62 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/viewmodel/NewPatchViewModel.kt @@ -37,7 +37,6 @@ class NewPatchViewModel : ViewModel() { var useManager by mutableStateOf(true) var debuggable by mutableStateOf(false) var overrideVersionCode by mutableStateOf(false) - val sign = mutableStateListOf(false, true) var sigBypassLevel by mutableStateOf(2) var embeddedModules = emptyList() @@ -89,7 +88,7 @@ class NewPatchViewModel : ViewModel() { Log.d(TAG, "Submit patch") if (useManager) embeddedModules = emptyList() patchOptions = Patcher.Options( - config = PatchConfig(useManager, debuggable, overrideVersionCode, sign[0], sign[1], sigBypassLevel, null, null), + config = PatchConfig(useManager, debuggable, overrideVersionCode, sigBypassLevel, null, null), apkPaths = listOf(patchApp.app.sourceDir) + (patchApp.app.splitSourceDirs ?: emptyArray()), embeddedModules = embeddedModules.flatMap { listOf(it.app.sourceDir) + (it.app.splitSourceDirs ?: emptyArray()) } ) diff --git a/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt b/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt index f92dde6..c66bc2d 100644 --- a/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt +++ b/manager/src/main/java/org/lsposed/lspatch/util/LSPPackageManager.kt @@ -21,12 +21,10 @@ import org.lsposed.lspatch.Constants.PATCH_FILE_SUFFIX import org.lsposed.lspatch.config.ConfigManager import org.lsposed.lspatch.config.Configs import org.lsposed.lspatch.lspApp -import org.lsposed.patch.util.ManifestParser import java.io.File import java.io.IOException import java.text.Collator import java.util.* -import java.util.zip.ZipFile import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -150,9 +148,8 @@ object LSPPackageManager { suspend fun getAppInfoFromApks(apks: List): Result { return withContext(Dispatchers.IO) { runCatching { - val app = ApplicationInfo() - if (apks.size > 1) app.splitSourceDirs = Array(apks.size - 1) { null } - apks.forEachIndexed { index, uri -> + var primary: ApplicationInfo? = null + val splits = apks.mapNotNull { uri -> val src = DocumentFile.fromSingleUri(lspApp, uri) ?: throw IOException("DocumentFile is null") val dst = lspApp.tmpApkDir.resolve(src.name!!) @@ -163,21 +160,18 @@ object LSPPackageManager { input.copyTo(output) } } - ZipFile(dst).use { zip -> - val entry = zip.getEntry("AndroidManifest.xml") - ?: throw IOException("AndroidManifest.xml is not found") - zip.getInputStream(entry).use { - val info = ManifestParser.parseManifestFile(it) - if (app.packageName != null && app.packageName != info.packageName) { - throw IOException("Selected apks are not of the same app") - } - app.packageName = info.packageName - } + if (primary == null) { + primary = lspApp.packageManager.getPackageArchiveInfo(dst.absolutePath, 0)?.applicationInfo + if (primary != null) return@mapNotNull null } - if (index == 0) app.sourceDir = dst.absolutePath - else app.splitSourceDirs[index - 1] = dst.absolutePath + dst.absolutePath } - AppInfo(app, app.packageName) + + // TODO: Check selected apks are from the same app + if (primary == null) throw IllegalArgumentException("No primary apk") + val label = lspApp.packageManager.getApplicationLabel(primary!!).toString() + if (splits.isNotEmpty()) primary!!.splitSourceDirs = splits.toTypedArray() + AppInfo(primary!!, label) }.recoverCatching { t -> cleanTmpApkDir() Log.e(TAG, "Failed to load apks", t) diff --git a/manager/src/main/res/values/strings.xml b/manager/src/main/res/values/strings.xml index 51e0db3..caac48b 100644 --- a/manager/src/main/res/values/strings.xml +++ b/manager/src/main/res/values/strings.xml @@ -53,7 +53,6 @@ Patch an app with modules embedded.\nThe patched app can run without the manager, but cannot be managed dynamically.\nPortable patched apps can be used on devices that do not have LSPatch Manager installed. Embed modules Debuggable - Sign Signature bypass lv0: Off lv1: Bypass PM diff --git a/patch/src/main/java/org/lsposed/patch/LSPatch.java b/patch/src/main/java/org/lsposed/patch/LSPatch.java index 234bff6..df37857 100644 --- a/patch/src/main/java/org/lsposed/patch/LSPatch.java +++ b/patch/src/main/java/org/lsposed/patch/LSPatch.java @@ -79,12 +79,6 @@ public class LSPatch { @Parameter(names = {"-k", "--keystore"}, arity = 4, description = "Set custom signature keystore. Followed by 4 arguments: keystore path, keystore password, keystore alias, keystore alias password") private List keystoreArgs = Arrays.asList(null, "123456", "key0", "123456"); - @Parameter(names = {"--v1"}, arity = 1, description = "Sign with v1 signature") - private boolean v1 = false; - - @Parameter(names = {"--v2"}, arity = 1, description = "Sign with v2 signature") - private boolean v2 = true; - @Parameter(names = {"--manager"}, description = "Use manager (Cannot work with embedding modules)") private boolean useManager = false; @@ -207,8 +201,7 @@ public class LSPatch { var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(keystoreArgs.get(2), new KeyStore.PasswordProtection(keystoreArgs.get(3).toCharArray())); new SigningExtension(SigningOptions.builder() .setMinSdkVersion(28) - .setV1SigningEnabled(v1) - .setV2SigningEnabled(v2) + .setV2SigningEnabled(true) .setCertificates((X509Certificate[]) entry.getCertificateChain()) .setKey(entry.getPrivateKey()) .build()).register(dstZFile); @@ -239,7 +232,7 @@ public class LSPatch { logger.i("Patching apk..."); // modify manifest - final var config = new PatchConfig(useManager, debuggableFlag, overrideVersionCode, v1, v2, sigbypassLevel, originalSignature, appComponentFactory); + final var config = new PatchConfig(useManager, debuggableFlag, overrideVersionCode, sigbypassLevel, originalSignature, appComponentFactory); final var configBytes = new Gson().toJson(config).getBytes(StandardCharsets.UTF_8); final var metadata = Base64.getEncoder().encodeToString(configBytes); try (var is = new ByteArrayInputStream(modifyManifestFile(manifestEntry.open(), metadata))) { diff --git a/share/java/src/main/java/org/lsposed/lspatch/share/PatchConfig.java b/share/java/src/main/java/org/lsposed/lspatch/share/PatchConfig.java index 3119f68..2cf9dc0 100644 --- a/share/java/src/main/java/org/lsposed/lspatch/share/PatchConfig.java +++ b/share/java/src/main/java/org/lsposed/lspatch/share/PatchConfig.java @@ -5,8 +5,6 @@ public class PatchConfig { public final boolean useManager; public final boolean debuggable; public final boolean overrideVersionCode; - public final boolean v1; - public final boolean v2; public final int sigBypassLevel; public final String originalSignature; public final String appComponentFactory; @@ -16,8 +14,6 @@ public class PatchConfig { boolean useManager, boolean debuggable, boolean overrideVersionCode, - boolean v1, - boolean v2, int sigBypassLevel, String originalSignature, String appComponentFactory @@ -25,8 +21,6 @@ public class PatchConfig { this.useManager = useManager; this.debuggable = debuggable; this.overrideVersionCode = overrideVersionCode; - this.v1 = v1; - this.v2 = v2; this.sigBypassLevel = sigBypassLevel; this.originalSignature = originalSignature; this.appComponentFactory = appComponentFactory;