build: bump patcher to v14.1.0 (#1153)

Co-authored-by: aAbed <aabedhkhan@gmail.com>
This commit is contained in:
Ushie 2023-08-27 02:21:16 +03:00 committed by GitHub
parent d9953b1473
commit b456512bbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 161 additions and 151 deletions

View File

@ -52,6 +52,8 @@ android {
buildTypes { buildTypes {
release { release {
shrinkResources false
minifyEnabled false
resValue "string", "app_name", "ReVanced Manager" resValue "string", "app_name", "ReVanced Manager"
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
ndk { ndk {
@ -83,10 +85,9 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// ReVanced // ReVanced
implementation "app.revanced:revanced-patcher:11.0.4" implementation "app.revanced:revanced-patcher:14.1.0"
// Signing & aligning // Signing & aligning
implementation("org.bouncycastle:bcpkix-jdk15on:1.70") implementation("org.bouncycastle:bcpkix-jdk15on:1.70")
implementation("com.android.tools.build:apksig:7.2.2") implementation("com.android.tools.build:apksig:7.2.2")
} }

View File

@ -1,25 +1,30 @@
package app.revanced.manager.flutter package app.revanced.manager.flutter
import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.annotation.NonNull
import app.revanced.manager.flutter.utils.Aapt import app.revanced.manager.flutter.utils.Aapt
import app.revanced.manager.flutter.utils.aligning.ZipAligner import app.revanced.manager.flutter.utils.aligning.ZipAligner
import app.revanced.manager.flutter.utils.signing.Signer import app.revanced.manager.flutter.utils.signing.Signer
import app.revanced.manager.flutter.utils.zip.ZipFile import app.revanced.manager.flutter.utils.zip.ZipFile
import app.revanced.manager.flutter.utils.zip.structures.ZipEntry import app.revanced.manager.flutter.utils.zip.structures.ZipEntry
import app.revanced.patcher.PatchBundleLoader
import app.revanced.patcher.Patcher import app.revanced.patcher.Patcher
import app.revanced.patcher.PatcherOptions import app.revanced.patcher.PatcherOptions
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
import app.revanced.patcher.extensions.PatchExtensions.patchName import app.revanced.patcher.extensions.PatchExtensions.patchName
import app.revanced.patcher.logging.Logger import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.util.patch.PatchBundle
import dalvik.system.DexClassLoader
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
import java.io.File import java.io.File
import java.io.PrintWriter
import java.io.StringWriter
import java.util.logging.Level
import java.util.logging.LogRecord
import java.util.logging.Logger
import java.util.logging.SimpleFormatter
private const val PATCHER_CHANNEL = "app.revanced.manager.flutter/patcher" private const val PATCHER_CHANNEL = "app.revanced.manager.flutter/patcher"
private const val INSTALLER_CHANNEL = "app.revanced.manager.flutter/installer" private const val INSTALLER_CHANNEL = "app.revanced.manager.flutter/installer"
@ -30,10 +35,11 @@ class MainActivity : FlutterActivity() {
private var cancel: Boolean = false private var cancel: Boolean = false
private var stopResult: MethodChannel.Result? = null private var stopResult: MethodChannel.Result? = null
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
val mainChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, PATCHER_CHANNEL) val mainChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, PATCHER_CHANNEL)
installerChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, INSTALLER_CHANNEL) installerChannel =
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, INSTALLER_CHANNEL)
mainChannel.setMethodCallHandler { call, result -> mainChannel.setMethodCallHandler { call, result ->
when (call.method) { when (call.method) {
"runPatcher" -> { "runPatcher" -> {
@ -77,10 +83,12 @@ class MainActivity : FlutterActivity() {
result.notImplemented() result.notImplemented()
} }
} }
"stopPatcher" -> { "stopPatcher" -> {
cancel = true cancel = true
stopResult = result stopResult = result
} }
else -> result.notImplemented() else -> result.notImplemented()
} }
} }
@ -105,55 +113,79 @@ class MainActivity : FlutterActivity() {
val outFile = File(outFilePath) val outFile = File(outFilePath)
val integrations = File(integrationsPath) val integrations = File(integrationsPath)
val keyStoreFile = File(keyStoreFilePath) val keyStoreFile = File(keyStoreFilePath)
val cacheDir = File(cacheDirPath)
Thread { Thread {
try { try {
Logger.getLogger("").apply {
handlers.forEach {
it.close()
removeHandler(it)
}
object : java.util.logging.Handler() {
override fun publish(record: LogRecord) = formatter.format(record).toByteArray().let {
if (record.level.intValue() > Level.INFO.intValue())
System.err.write(it)
else
System.out.write(it)
}
override fun flush() {
System.out.flush()
System.err.flush()
}
override fun close() = flush()
}.also {
it.level = Level.ALL
it.formatter = SimpleFormatter()
}.let(::addHandler)
}
handler.post { handler.post {
installerChannel.invokeMethod( installerChannel.invokeMethod(
"update", "update",
mapOf( mapOf(
"progress" to 0.1, "progress" to 0.1,
"header" to "", "header" to "",
"log" to "Copying original apk" "log" to "Copying original APK"
) )
) )
} }
if(cancel) { if (cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
originalFile.copyTo(inputFile, true) originalFile.copyTo(inputFile, true)
if (cancel) {
handler.post { stopResult!!.success(null) }
return@Thread
}
handler.post { handler.post {
installerChannel.invokeMethod( installerChannel.invokeMethod(
"update", "update",
mapOf( mapOf(
"progress" to 0.2, "progress" to 0.2,
"header" to "Unpacking apk...", "header" to "Reading APK...",
"log" to "Unpacking input apk" "log" to "Reading input APK"
) )
) )
} }
if(cancel) {
handler.post { stopResult!!.success(null) }
return@Thread
}
val patcher = val patcher =
Patcher( Patcher(
PatcherOptions( PatcherOptions(
inputFile, inputFile,
cacheDirPath, cacheDir,
Aapt.binary(applicationContext).absolutePath, Aapt.binary(applicationContext).absolutePath,
cacheDirPath, cacheDir.path,
logger = ManagerLogger()
) )
) )
if(cancel) { if (cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
@ -161,28 +193,19 @@ class MainActivity : FlutterActivity() {
handler.post { handler.post {
installerChannel.invokeMethod( installerChannel.invokeMethod(
"update", "update",
mapOf("progress" to 0.3, "header" to "", "log" to "") mapOf("progress" to 0.3, "header" to "Loading patches...", "log" to "Loading patches")
)
}
handler.post {
installerChannel.invokeMethod(
"update",
mapOf(
"progress" to 0.4,
"header" to "Merging integrations...",
"log" to "Merging integrations"
)
) )
} }
if(cancel) { val patches =
handler.post { stopResult!!.success(null) } PatchBundleLoader.Dex(
return@Thread File(patchBundleFilePath)
} ).filter { patch ->
(patch.compatiblePackages?.any { it.name == patcher.context.packageMetadata.packageName } == true || patch.compatiblePackages.isNullOrEmpty()) &&
selectedPatches.any { it == patch.patchName }
}
patcher.addIntegrations(listOf(integrations)) {} if (cancel) {
if(cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
@ -192,91 +215,75 @@ class MainActivity : FlutterActivity() {
"update", "update",
mapOf( mapOf(
"progress" to 0.5, "progress" to 0.5,
"header" to "Applying patches...", "header" to "Executing patches...",
"log" to "" "log" to ""
) )
) )
} }
if(cancel) { patcher.apply {
acceptIntegrations(listOf(integrations))
acceptPatches(patches)
runBlocking {
apply(false).collect { patchResult: PatchResult ->
patchResult.exception?.let {
if (cancel) {
handler.post { stopResult!!.success(null) }
this.cancel()
return@collect
}
StringWriter().use { writer ->
it.printStackTrace(PrintWriter(writer))
handler.post {
installerChannel.invokeMethod(
"update",
mapOf("progress" to 0.5, "header" to "", "log" to "${patchResult.patchName} failed: $writer")
)
}
}
} ?: run {
if (cancel) {
handler.post { stopResult!!.success(null) }
this.cancel()
return@collect
}
val msg = "${patchResult.patchName} succeeded"
handler.post {
installerChannel.invokeMethod(
"update",
mapOf(
"progress" to 0.5,
"header" to "",
"log" to msg
)
)
}
}
}
}
}
if (cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
val patches = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
PatchBundle.Dex(
patchBundleFilePath,
DexClassLoader(
patchBundleFilePath,
cacheDirPath,
null,
javaClass.classLoader
)
).loadPatches().filter { patch ->
(patch.compatiblePackages?.any { it.name == patcher.context.packageMetadata.packageName } == true || patch.compatiblePackages.isNullOrEmpty()) &&
selectedPatches.any { it == patch.patchName }
}
} else {
TODO("VERSION.SDK_INT < CUPCAKE")
}
if(cancel) {
handler.post { stopResult!!.success(null) }
return@Thread
}
patcher.addPatches(patches)
patcher.executePatches().forEach { (patch, res) ->
if (res.isSuccess) {
val msg = "Applied $patch"
handler.post {
installerChannel.invokeMethod(
"update",
mapOf(
"progress" to 0.5,
"header" to "",
"log" to msg
)
)
}
if(cancel) {
handler.post { stopResult!!.success(null) }
return@Thread
}
return@forEach
}
val msg =
"Failed to apply $patch: " + "${res.exceptionOrNull()!!.message ?: res.exceptionOrNull()!!.cause!!::class.simpleName}"
handler.post {
installerChannel.invokeMethod(
"update",
mapOf("progress" to 0.5, "header" to "", "log" to msg)
)
}
if(cancel) {
handler.post { stopResult!!.success(null) }
return@Thread
}
}
handler.post { handler.post {
installerChannel.invokeMethod( installerChannel.invokeMethod(
"update", "update",
mapOf( mapOf(
"progress" to 0.7, "progress" to 0.7,
"header" to "Repacking apk...", "header" to "Repacking APK...",
"log" to "Repacking patched apk" "log" to ""
) )
) )
} }
if(cancel) { val res = patcher.get()
handler.post { stopResult!!.success(null) } patcher.close()
return@Thread
}
val res = patcher.save()
ZipFile(patchedFile).use { file -> ZipFile(patchedFile).use { file ->
res.dexFiles.forEach { res.dexFiles.forEach {
if(cancel) { if (cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
@ -296,7 +303,7 @@ class MainActivity : FlutterActivity() {
ZipAligner::getEntryAlignment ZipAligner::getEntryAlignment
) )
} }
if(cancel) { if (cancel) {
handler.post { stopResult!!.success(null) } handler.post { stopResult!!.success(null) }
return@Thread return@Thread
} }
@ -305,7 +312,7 @@ class MainActivity : FlutterActivity() {
"update", "update",
mapOf( mapOf(
"progress" to 0.9, "progress" to 0.9,
"header" to "Signing apk...", "header" to "Signing APK...",
"log" to "" "log" to ""
) )
) )
@ -319,7 +326,7 @@ class MainActivity : FlutterActivity() {
) )
} catch (e: Exception) { } catch (e: Exception) {
//log to console //log to console
print("Error signing apk: ${e.message}") print("Error signing APK: ${e.message}")
e.printStackTrace() e.printStackTrace()
} }
@ -334,52 +341,54 @@ class MainActivity : FlutterActivity() {
) )
} }
} catch (ex: Throwable) { } catch (ex: Throwable) {
val stack = ex.stackTraceToString() if (!cancel) {
handler.post { val stack = ex.stackTraceToString()
installerChannel.invokeMethod( handler.post {
"update", installerChannel.invokeMethod(
mapOf( "update",
"progress" to -100.0, mapOf(
"header" to "Aborted...", "progress" to -100.0,
"log" to "An error occurred! Aborted\nError:\n$stack" "header" to "Aborted...",
"log" to "An error occurred! Aborted\nError:\n$stack"
)
) )
) }
} }
} }
handler.post { result.success(null) } handler.post { result.success(null) }
}.start() }.start()
} }
inner class ManagerLogger : Logger { // inner class ManagerLogger : Logger {
override fun error(msg: String) { // override fun error(msg: String) {
handler.post { // handler.post {
installerChannel // installerChannel
.invokeMethod( // .invokeMethod(
"update", // "update",
mapOf("progress" to -1.0, "header" to "", "log" to msg) // mapOf("progress" to -1.0, "header" to "", "log" to msg)
) // )
} // }
} // }
//
override fun warn(msg: String) { // override fun warn(msg: String) {
handler.post { // handler.post {
installerChannel.invokeMethod( // installerChannel.invokeMethod(
"update", // "update",
mapOf("progress" to -1.0, "header" to "", "log" to msg) // mapOf("progress" to -1.0, "header" to "", "log" to msg)
) // )
} // }
} // }
//
override fun info(msg: String) { // override fun info(msg: String) {
handler.post { // handler.post {
installerChannel.invokeMethod( // installerChannel.invokeMethod(
"update", // "update",
mapOf("progress" to -1.0, "header" to "", "log" to msg) // mapOf("progress" to -1.0, "header" to "", "log" to msg)
) // )
} // }
} // }
//
override fun trace(_msg: String) { /* unused */ // override fun trace(_msg: String) { /* unused */
} // }
} // }
} }

View File

@ -1,5 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.7.10' ext.kotlin_version = '1.9.0'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()