mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-04 07:25:26 +00:00
Make stub patching 100% offline
This commit is contained in:
parent
cdc66c1ac8
commit
71b0c8b42b
@ -31,6 +31,7 @@ import java.io.IOException
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.util.zip.ZipEntry
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipFile
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
import java.util.zip.ZipOutputStream
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
@ -44,14 +45,12 @@ class DownloadService : NotificationService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun download(subject: Subject) {
|
private fun download(subject: Subject) {
|
||||||
notifyUpdate(subject.notifyId)
|
notifyUpdate(subject.notifyId)
|
||||||
val coroutineScope = CoroutineScope(job + Dispatchers.IO)
|
CoroutineScope(job + Dispatchers.IO).launch {
|
||||||
coroutineScope.launch {
|
|
||||||
try {
|
try {
|
||||||
val stream = service.fetchFile(subject.url).toProgressStream(subject)
|
val stream = service.fetchFile(subject.url).toProgressStream(subject)
|
||||||
when (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) {
|
fun writeTee(output: OutputStream) {
|
||||||
val uri = MediaStoreUtils.getFile("${subject.title}.apk").uri
|
val uri = MediaStoreUtils.getFile("${subject.title}.apk").uri
|
||||||
val external = uri.outputStream()
|
val external = uri.outputStream()
|
||||||
@ -96,9 +95,10 @@ class DownloadService : NotificationService() {
|
|||||||
.setContentText("")
|
.setContentText("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download
|
// Extract stub
|
||||||
val apk = subject.file.toFile()
|
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
|
// Patch and install
|
||||||
val session = APKInstall.startSession(this)
|
val session = APKInstall.startSession(this)
|
||||||
|
@ -22,8 +22,7 @@ data class MagiskJson(
|
|||||||
@Parcelize
|
@Parcelize
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class StubJson(
|
data class StubJson(
|
||||||
val versionCode: Int = -1,
|
val versionCode: Int = -1
|
||||||
val link: String = ""
|
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
|
@ -9,9 +9,7 @@ import com.topjohnwu.magisk.R
|
|||||||
import com.topjohnwu.magisk.StubApk
|
import com.topjohnwu.magisk.StubApk
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.Info
|
|
||||||
import com.topjohnwu.magisk.core.Provider
|
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.AXML
|
||||||
import com.topjohnwu.magisk.core.utils.Keygen
|
import com.topjohnwu.magisk.core.utils.Keygen
|
||||||
import com.topjohnwu.magisk.ktx.await
|
import com.topjohnwu.magisk.ktx.await
|
||||||
@ -40,8 +38,6 @@ object HideAPK {
|
|||||||
// Some arbitrary limit
|
// Some arbitrary limit
|
||||||
const val MAX_LABEL_LENGTH = 32
|
const val MAX_LABEL_LENGTH = 32
|
||||||
|
|
||||||
private val svc get() = ServiceLocator.networkService
|
|
||||||
|
|
||||||
private fun genPackageName(): String {
|
private fun genPackageName(): String {
|
||||||
val random = SecureRandom()
|
val random = SecureRandom()
|
||||||
val len = 5 + random.nextInt(15)
|
val len = 5 + random.nextInt(15)
|
||||||
@ -113,16 +109,12 @@ object HideAPK {
|
|||||||
activity.finish()
|
activity.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
private fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean {
|
||||||
private suspend fun patchAndHide(activity: Activity, label: String, onFailure: Runnable): Boolean {
|
|
||||||
val stub = File(activity.cacheDir, "stub.apk")
|
val stub = File(activity.cacheDir, "stub.apk")
|
||||||
try {
|
try {
|
||||||
svc.fetchFile(Info.remote.stub.link).byteStream().writeTo(stub)
|
activity.assets.open("stub.apk").writeTo(stub)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
stub.createNewFile()
|
|
||||||
val cmd = "\$MAGISKBIN/magiskinit -x manager ${stub.path}"
|
|
||||||
if (!Shell.cmd(cmd).exec().isSuccess)
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import org.gradle.api.Action
|
|||||||
import org.gradle.api.JavaVersion
|
import org.gradle.api.JavaVersion
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.ExtensionAware
|
import org.gradle.api.plugins.ExtensionAware
|
||||||
|
import org.gradle.api.tasks.Copy
|
||||||
import org.gradle.api.tasks.Delete
|
import org.gradle.api.tasks.Delete
|
||||||
import org.gradle.api.tasks.StopExecutionException
|
import org.gradle.api.tasks.StopExecutionException
|
||||||
import org.gradle.api.tasks.Sync
|
import org.gradle.api.tasks.Sync
|
||||||
@ -218,13 +219,29 @@ fun Project.setupApp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android.applicationVariants.all {
|
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 keysDir = rootProject.file("tools/keys")
|
||||||
val outSrcDir = File(buildDir, "generated/source/keydata/$name")
|
val outSrcDir = File(buildDir, "generated/source/keydata/$name")
|
||||||
val outSrc = File(outSrcDir, "com/topjohnwu/magisk/signing/KeyData.java")
|
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)
|
inputs.dir(keysDir)
|
||||||
outputs.file(outSrc)
|
outputs.file(outSrc)
|
||||||
doLast {
|
doLast {
|
||||||
|
Loading…
Reference in New Issue
Block a user