Make stub patching 100% offline

This commit is contained in:
topjohnwu 2022-08-26 03:43:31 -07:00
parent cdc66c1ac8
commit 71b0c8b42b
4 changed files with 29 additions and 21 deletions

View File

@ -31,6 +31,7 @@ import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
@ -44,14 +45,12 @@ class DownloadService : NotificationService() {
}
override fun onDestroy() {
super.onDestroy()
job.cancel()
}
private fun download(subject: Subject) {
notifyUpdate(subject.notifyId)
val coroutineScope = CoroutineScope(job + Dispatchers.IO)
coroutineScope.launch {
CoroutineScope(job + Dispatchers.IO).launch {
try {
val stream = service.fetchFile(subject.url).toProgressStream(subject)
when (subject) {
@ -75,7 +74,7 @@ class DownloadService : NotificationService() {
}
}
private suspend fun handleApp(stream: InputStream, subject: Subject.App) {
private fun handleApp(stream: InputStream, subject: Subject.App) {
fun writeTee(output: OutputStream) {
val uri = MediaStoreUtils.getFile("${subject.title}.apk").uri
val external = uri.outputStream()
@ -96,9 +95,10 @@ class DownloadService : NotificationService() {
.setContentText("")
}
// Download
// Extract stub
val apk = subject.file.toFile()
service.fetchFile(subject.stub.link).byteStream().writeTo(apk)
val zf = ZipFile(updateApk)
zf.getInputStream(zf.getEntry("assets/stub.apk")).writeTo(apk)
// Patch and install
val session = APKInstall.startSession(this)

View File

@ -22,8 +22,7 @@ data class MagiskJson(
@Parcelize
@JsonClass(generateAdapter = true)
data class StubJson(
val versionCode: Int = -1,
val link: String = ""
val versionCode: Int = -1
) : Parcelable
@JsonClass(generateAdapter = true)

View File

@ -9,9 +9,7 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.StubApk
import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.Provider
import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.utils.AXML
import com.topjohnwu.magisk.core.utils.Keygen
import com.topjohnwu.magisk.ktx.await
@ -40,8 +38,6 @@ object HideAPK {
// Some arbitrary limit
const val MAX_LABEL_LENGTH = 32
private val svc get() = ServiceLocator.networkService
private fun genPackageName(): String {
val random = SecureRandom()
val len = 5 + random.nextInt(15)
@ -113,16 +109,12 @@ object HideAPK {
activity.finish()
}
@Suppress("BlockingMethodInNonBlockingContext")
private suspend fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean {
private fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean {
val stub = File(activity.cacheDir, "stub.apk")
try {
svc.fetchFile(Info.remote.stub.link).byteStream().writeTo(stub)
activity.assets.open("stub.apk").writeTo(stub)
} catch (e: IOException) {
Timber.e(e)
stub.createNewFile()
val cmd = "\$MAGISKBIN/magiskinit -x manager ${stub.path}"
if (!Shell.cmd(cmd).exec().isSuccess)
return false
}

View File

@ -11,6 +11,7 @@ import org.gradle.api.Action
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.StopExecutionException
import org.gradle.api.tasks.Sync
@ -218,13 +219,29 @@ fun Project.setupApp() {
}
android.applicationVariants.all {
preBuildProvider.get().dependsOn(syncResources)
val variantCapped = name.capitalize(Locale.ROOT)
val variantLowered = name.toLowerCase(Locale.ROOT)
val copyStub = tasks.register("copy${variantCapped}StubApk", Copy::class.java) {
dependsOn(syncResources)
into("src/main/assets")
from(rootProject.file("out/stub-${variantLowered}.apk")) {
rename { "stub.apk" }
}
onlyIf {
if (inputs.sourceFiles.files.size != 1)
throw StopExecutionException("Please build stub first! (./build.py stub)")
true
}
}
preBuildProvider.get().dependsOn(copyStub)
val keysDir = rootProject.file("tools/keys")
val outSrcDir = File(buildDir, "generated/source/keydata/$name")
val outSrc = File(outSrcDir, "com/topjohnwu/magisk/signing/KeyData.java")
val genSrcTask = tasks.register("generate${name.capitalize(Locale.ROOT)}KeyData") {
val genSrcTask = tasks.register("generate${variantCapped}KeyData") {
inputs.dir(keysDir)
outputs.file(outSrc)
doLast {