mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-01 15:14:34 +02:00
feat(YouTube Music): Support patching on Android 5-7 (#140)
* feat(YouTube Music): Support patching on Android 5-7 * Improve comments
This commit is contained in:
parent
325b43e394
commit
967776a484
@ -11,6 +11,7 @@ import app.revanced.patches.music.utils.playservice.versionCheckPatch
|
|||||||
import app.revanced.patches.music.utils.settings.ResourceUtils.setIconType
|
import app.revanced.patches.music.utils.settings.ResourceUtils.setIconType
|
||||||
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
|
import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus
|
||||||
import app.revanced.patches.music.utils.settings.settingsPatch
|
import app.revanced.patches.music.utils.settings.settingsPatch
|
||||||
|
import app.revanced.util.FilesCompat
|
||||||
import app.revanced.util.ResourceGroup
|
import app.revanced.util.ResourceGroup
|
||||||
import app.revanced.util.Utils.trimIndentMultiline
|
import app.revanced.util.Utils.trimIndentMultiline
|
||||||
import app.revanced.util.copyAdaptiveIcon
|
import app.revanced.util.copyAdaptiveIcon
|
||||||
@ -20,7 +21,6 @@ import app.revanced.util.underBarOrThrow
|
|||||||
import app.revanced.util.valueOrThrow
|
import app.revanced.util.valueOrThrow
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME =
|
private const val ADAPTIVE_ICON_BACKGROUND_FILE_NAME =
|
||||||
"adaptiveproduct_youtube_music_background_color_108"
|
"adaptiveproduct_youtube_music_background_color_108"
|
||||||
@ -155,9 +155,9 @@ val customBrandingIconPatch = resourcePatch(
|
|||||||
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
||||||
|
|
||||||
group.resources.forEach { iconFileName ->
|
group.resources.forEach { iconFileName ->
|
||||||
Files.write(
|
FilesCompat.copy(
|
||||||
toDirectory.resolve(iconFileName).toPath(),
|
fromDirectory.resolve(iconFileName),
|
||||||
fromDirectory.resolve(iconFileName).readBytes()
|
toDirectory.resolve(iconFileName)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package app.revanced.patches.shared.materialyou
|
package app.revanced.patches.shared.materialyou
|
||||||
|
|
||||||
import app.revanced.patcher.patch.ResourcePatchContext
|
import app.revanced.patcher.patch.ResourcePatchContext
|
||||||
|
import app.revanced.util.FilesCompat
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import java.nio.file.Files
|
|
||||||
|
|
||||||
private fun ResourcePatchContext.patchXmlFile(
|
private fun ResourcePatchContext.patchXmlFile(
|
||||||
fromDir: String,
|
fromDir: String,
|
||||||
@ -17,7 +17,7 @@ private fun ResourcePatchContext.patchXmlFile(
|
|||||||
val fromDirectory = resourceDirectory.resolve(fromDir)
|
val fromDirectory = resourceDirectory.resolve(fromDir)
|
||||||
val toDirectory = resourceDirectory.resolve(toDir)
|
val toDirectory = resourceDirectory.resolve(toDir)
|
||||||
|
|
||||||
if (!toDirectory.isDirectory) Files.createDirectories(toDirectory.toPath())
|
if (!toDirectory.isDirectory) toDirectory.mkdirs()
|
||||||
|
|
||||||
val fromXmlFile = fromDirectory.resolve(xmlFileName)
|
val fromXmlFile = fromDirectory.resolve(xmlFileName)
|
||||||
val toXmlFile = toDirectory.resolve(xmlFileName)
|
val toXmlFile = toDirectory.resolve(xmlFileName)
|
||||||
@ -27,9 +27,9 @@ private fun ResourcePatchContext.patchXmlFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!toXmlFile.exists()) {
|
if (!toXmlFile.exists()) {
|
||||||
Files.copy(
|
FilesCompat.copy(
|
||||||
fromXmlFile.toPath(),
|
fromXmlFile,
|
||||||
toXmlFile.toPath()
|
toXmlFile
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,12 @@ package app.revanced.patches.shared.translations
|
|||||||
|
|
||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.ResourcePatchContext
|
import app.revanced.patcher.patch.ResourcePatchContext
|
||||||
|
import app.revanced.util.FilesCompat
|
||||||
import app.revanced.util.doRecursively
|
import app.revanced.util.doRecursively
|
||||||
import app.revanced.util.inputStreamFromBundledResource
|
import app.revanced.util.inputStreamFromBundledResource
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.StandardCopyOption
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory
|
import javax.xml.parsers.DocumentBuilderFactory
|
||||||
import javax.xml.transform.OutputKeys
|
import javax.xml.transform.OutputKeys
|
||||||
import javax.xml.transform.TransformerFactory
|
import javax.xml.transform.TransformerFactory
|
||||||
@ -173,12 +172,11 @@ private fun ResourcePatchContext.copyStringsXml(
|
|||||||
)?.let { inputStream ->
|
)?.let { inputStream ->
|
||||||
val directory = "values-$language-v21"
|
val directory = "values-$language-v21"
|
||||||
val valuesV21Directory = resourceDirectory.resolve(directory)
|
val valuesV21Directory = resourceDirectory.resolve(directory)
|
||||||
if (!valuesV21Directory.isDirectory) Files.createDirectories(valuesV21Directory.toPath())
|
if (!valuesV21Directory.isDirectory) valuesV21Directory.mkdirs()
|
||||||
|
|
||||||
Files.copy(
|
FilesCompat.copy(
|
||||||
inputStream,
|
inputStream,
|
||||||
resourceDirectory.resolve("$directory/strings.xml").toPath(),
|
resourceDirectory.resolve("$directory/strings.xml")
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
patches/src/main/kotlin/app/revanced/util/FilesCompat.kt
Normal file
53
patches/src/main/kotlin/app/revanced/util/FilesCompat.kt
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package app.revanced.util
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides java.nio.file.Files compatible functions.
|
||||||
|
*
|
||||||
|
* This is needed for the ReVanced Manager running on Android 5.0-7.1
|
||||||
|
* because Android 7.1 and below does not support the Java NIO2 Files API.
|
||||||
|
*/
|
||||||
|
internal object FilesCompat {
|
||||||
|
private val useCompat = try {
|
||||||
|
// Check for the existence of java.nio.file.Files class
|
||||||
|
Class.forName("java.nio.file.Files")
|
||||||
|
false
|
||||||
|
} catch (_ : ClassNotFoundException) {
|
||||||
|
// Under Android 8.0
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy a file to a target file.
|
||||||
|
*
|
||||||
|
* If the `target` file already exists, replace an existing file.
|
||||||
|
*/
|
||||||
|
fun copy(source: File, target: File) {
|
||||||
|
if (useCompat) {
|
||||||
|
source.copyTo(target, overwrite = true)
|
||||||
|
} else {
|
||||||
|
Files.copy(source.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies all bytes from an input stream to a file.
|
||||||
|
*
|
||||||
|
* If the `target` file already exists, replace an existing file.
|
||||||
|
*/
|
||||||
|
fun copy(source: InputStream, target: File) {
|
||||||
|
if (useCompat) {
|
||||||
|
source.use { inputStream ->
|
||||||
|
target.outputStream().use { outputStream ->
|
||||||
|
inputStream.copyTo(outputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Files.copy(source, target.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,8 +11,6 @@ import org.w3c.dom.Node
|
|||||||
import org.w3c.dom.NodeList
|
import org.w3c.dom.NodeList
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.StandardCopyOption
|
|
||||||
|
|
||||||
private val classLoader = object {}.javaClass.classLoader
|
private val classLoader = object {}.javaClass.classLoader
|
||||||
|
|
||||||
@ -115,14 +113,9 @@ fun ResourcePatchContext.copyAdaptiveIcon(
|
|||||||
if (oldIconResourceFile != newIconResourceFile) {
|
if (oldIconResourceFile != newIconResourceFile) {
|
||||||
mipmapDirectories.forEach {
|
mipmapDirectories.forEach {
|
||||||
val mipmapDirectory = get("res").resolve(it)
|
val mipmapDirectory = get("res").resolve(it)
|
||||||
Files.copy(
|
FilesCompat.copy(
|
||||||
mipmapDirectory
|
mipmapDirectory.resolve("$oldIconResourceFile.png"),
|
||||||
.resolve("$oldIconResourceFile.png")
|
mipmapDirectory.resolve("$newIconResourceFile.png")
|
||||||
.toPath(),
|
|
||||||
mipmapDirectory
|
|
||||||
.resolve("$newIconResourceFile.png")
|
|
||||||
.toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,14 +125,9 @@ fun ResourcePatchContext.copyAdaptiveIcon(
|
|||||||
adaptiveIconMonoChromeFileName != getAdaptiveIconMonoChromeResourceFile()
|
adaptiveIconMonoChromeFileName != getAdaptiveIconMonoChromeResourceFile()
|
||||||
) {
|
) {
|
||||||
val drawableDirectory = get("res").resolve("drawable")
|
val drawableDirectory = get("res").resolve("drawable")
|
||||||
Files.copy(
|
FilesCompat.copy(
|
||||||
drawableDirectory
|
drawableDirectory.resolve("$adaptiveIconMonoChromeFileName.xml"),
|
||||||
.resolve("$adaptiveIconMonoChromeFileName.xml")
|
drawableDirectory.resolve("${getAdaptiveIconMonoChromeResourceFile()}.xml")
|
||||||
.toPath(),
|
|
||||||
drawableDirectory
|
|
||||||
.resolve("${getAdaptiveIconMonoChromeResourceFile()}.xml")
|
|
||||||
.toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,9 +189,9 @@ fun ResourcePatchContext.copyFile(
|
|||||||
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
val toDirectory = resourceDirectory.resolve(group.resourceDirectoryName)
|
||||||
|
|
||||||
group.resources.forEach { iconFileName ->
|
group.resources.forEach { iconFileName ->
|
||||||
Files.write(
|
FilesCompat.copy(
|
||||||
toDirectory.resolve(iconFileName).toPath(),
|
fromDirectory.resolve(iconFileName),
|
||||||
fromDirectory.resolve(iconFileName).readBytes()
|
toDirectory.resolve(iconFileName)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,16 +295,15 @@ fun ResourcePatchContext.copyResources(
|
|||||||
resourceGroup.resources.forEach { resource ->
|
resourceGroup.resources.forEach { resource ->
|
||||||
val resourceDirectoryName = resourceGroup.resourceDirectoryName
|
val resourceDirectoryName = resourceGroup.resourceDirectoryName
|
||||||
val targetDirectory = resourceDirectory.resolve(resourceDirectoryName)
|
val targetDirectory = resourceDirectory.resolve(resourceDirectoryName)
|
||||||
if (!targetDirectory.isDirectory) Files.createDirectories(targetDirectory.toPath())
|
if (!targetDirectory.isDirectory) targetDirectory.mkdirs()
|
||||||
val resourceFile = "$resourceDirectoryName/$resource"
|
val resourceFile = "$resourceDirectoryName/$resource"
|
||||||
inputStreamFromBundledResource(
|
inputStreamFromBundledResource(
|
||||||
sourceResourceDirectory,
|
sourceResourceDirectory,
|
||||||
resourceFile
|
resourceFile
|
||||||
)?.let { inputStream ->
|
)?.let { inputStream ->
|
||||||
Files.copy(
|
FilesCompat.copy(
|
||||||
inputStream,
|
inputStream,
|
||||||
resourceDirectory.resolve(resourceFile).toPath(),
|
resourceDirectory.resolve(resourceFile),
|
||||||
StandardCopyOption.REPLACE_EXISTING,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user