diff --git a/app/src/main/kotlin/com/aliucord/manager/patcher/steps/patch/PatchIconsStep.kt b/app/src/main/kotlin/com/aliucord/manager/patcher/steps/patch/PatchIconsStep.kt index bc2635f..0b335df 100644 --- a/app/src/main/kotlin/com/aliucord/manager/patcher/steps/patch/PatchIconsStep.kt +++ b/app/src/main/kotlin/com/aliucord/manager/patcher/steps/patch/PatchIconsStep.kt @@ -50,7 +50,7 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent override val localizedName = R.string.patch_step_patch_icon // Adaptive icons are available starting with Android 8 - private val isAdaptiveIconsAvailable = Build.VERSION.SDK_INT >= 28 + private val isAdaptiveIconsAvailable = Build.VERSION.SDK_INT >= 26 // Monochrome icons are always patched starting with Android 12 private val isMonochromeIconsAvailable = Build.VERSION.SDK_INT >= 31 @@ -90,9 +90,15 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent arsc: BinaryResourceFile, ) { container.log("Parsing AndroidManifest.xml and obtaining adaptive square/round icon file paths") - val iconRscIds = AxmlUtil.readManifestIconInfo(apk) - val squareIconFile = arsc.getMainArscChunk().getResourceFileName(iconRscIds.squareIcon, "anydpi-v26") - val roundIconFile = arsc.getMainArscChunk().getResourceFileName(iconRscIds.roundIcon, "anydpi-v26") + val iconResourceIds = AxmlUtil.readManifestIconInfo(apk) + val squareIconFile = arsc.getMainArscChunk().getResourceFileName( + resourceId = iconResourceIds.squareIcon, + configurationName = "anydpi-v26" + ) + val roundIconFile = arsc.getMainArscChunk().getResourceFileName( + resourceId = iconResourceIds.roundIcon, + configurationName = "anydpi-v26" + ) var foregroundIcon: BinaryResourceIdentifier? = null var backgroundIcon: BinaryResourceIdentifier? = null @@ -174,9 +180,15 @@ class PatchIconsStep(private val options: PatchOptions) : Step(), KoinComponent arsc: BinaryResourceFile, ) { container.log("Parsing AndroidManifest.xml and obtaining all square/round launcher icon file paths") - val iconRscIds = AxmlUtil.readManifestIconInfo(apk) - val squareIconFiles = arsc.getMainArscChunk().getResourceFileNames(iconRscIds.squareIcon) - val roundIconFiles = arsc.getMainArscChunk().getResourceFileNames(iconRscIds.roundIcon) + val iconResourceIds = AxmlUtil.readManifestIconInfo(apk) + val squareIconFiles = arsc.getMainArscChunk().getResourceFileNames( + resourceId = iconResourceIds.squareIcon, + configurations = { it.toString() != "anydpi-v26" }, + ) + val roundIconFiles = arsc.getMainArscChunk().getResourceFileNames( + resourceId = iconResourceIds.roundIcon, + configurations = { it.toString() != "anydpi-v26" }, + ) val allIconFiles = squareIconFiles + roundIconFiles val backgroundColor = when (options.iconReplacement) { diff --git a/app/src/main/kotlin/com/aliucord/manager/patcher/util/ArscUtil.kt b/app/src/main/kotlin/com/aliucord/manager/patcher/util/ArscUtil.kt index 2d9fb56..de3d63b 100644 --- a/app/src/main/kotlin/com/aliucord/manager/patcher/util/ArscUtil.kt +++ b/app/src/main/kotlin/com/aliucord/manager/patcher/util/ArscUtil.kt @@ -125,45 +125,35 @@ object ArscUtil { * * @param resourceId The target resource id. * @param configurationName The target configuration variant of the resource. (ex: `anydpi-v26`, `xxhdpi`, `ldtrl-mpi`, etc.) - * @return The string value of the resource, which should be a file path into the apk. + * @return The string value of the resource for the specified configuration. */ fun ResourceTableChunk.getResourceFileName( resourceId: BinaryResourceIdentifier, configurationName: String, ): String { - val packageChunk = this.packages.find { it.id == resourceId.packageId() } - ?: error("Unable to find target resource") - - val typeChunk = packageChunk.getTypeChunks(resourceId.typeId()) - .find { it.configuration.toString() == configurationName } - ?: error("Unable to find target resource") - - val entry = try { - typeChunk.getEntry(resourceId.entryId())!! - } catch (_: Throwable) { - error("Unable to find target resource") - } - - if (entry.isComplex || entry.value().type() != BinaryResourceValue.Type.STRING) - error("Target resource value type is not STRING") - - val valueIdx = entry.value().data() - val value = this.stringPool.getString(valueIdx) - - return value + return getResourceFileNames( + resourceId = resourceId, + configurations = { it.toString() == configurationName }, + ).single() } /** - * In an arsc file, for a specific resource in all configurations, get all values. + * In an arsc file, for a specific resource in all matching configurations, get the values. * * @param resourceId The target resource id. - * @return The string value of all configuration values of the resource, which should be file paths into the apk. + * @param configurations A predicate whether to add the value into a matching type chunk. + * @return The string values of the resources, for each configuration. */ - fun ResourceTableChunk.getResourceFileNames(resourceId: BinaryResourceIdentifier): List { + fun ResourceTableChunk.getResourceFileNames( + resourceId: BinaryResourceIdentifier, + configurations: (BinaryResourceConfiguration) -> Boolean, + ): List { val packageChunk = this.packages.find { it.id == resourceId.packageId() } ?: error("Unable to find target resource") val typeChunks = packageChunk.getTypeChunks(resourceId.typeId()) + .filter { configurations(it.configuration) } + val entries = typeChunks.map { typeChunk -> val entry = typeChunk.getEntry(resourceId.entryId()) ?: error("Unable to find target resource in type chunk " + typeChunk.configuration) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt index 8439b24..bc8ac32 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/iconopts/IconOptionsScreen.kt @@ -75,7 +75,7 @@ fun IconOptionsScreenContent( selectedImage: () -> ByteArray?, setSelectedImage: (Uri) -> Unit, ) { - val isAdaptiveIconsAvailable = Build.VERSION.SDK_INT >= 28 + val isAdaptiveIconsAvailable = Build.VERSION.SDK_INT >= 26 Scaffold( topBar = { IconOptionsAppBar() },