You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Added appending installers to modules
This commit is contained in:
committed by
John Wu
parent
967bdeae7b
commit
0785945635
@@ -43,6 +43,7 @@ open class DownloadService : RemoteFileService() {
|
||||
override fun onFinished(file: File, subject: DownloadSubject) = when (subject) {
|
||||
is Magisk -> onFinishedInternal(file, subject)
|
||||
is Module -> onFinishedInternal(file, subject)
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
private fun onFinishedInternal(
|
||||
@@ -73,6 +74,7 @@ open class DownloadService : RemoteFileService() {
|
||||
) = when (subject) {
|
||||
is Magisk -> addActionsInternal(file, subject)
|
||||
is Module -> addActionsInternal(file, subject)
|
||||
else -> this
|
||||
}
|
||||
|
||||
private fun NotificationCompat.Builder.addActionsInternal(
|
||||
|
||||
@@ -8,14 +8,21 @@ import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.data.repository.FileRepository
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
|
||||
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
|
||||
import com.topjohnwu.magisk.utils.cachedFile
|
||||
import com.topjohnwu.magisk.utils.withStreams
|
||||
import com.topjohnwu.magisk.utils.writeToCachedFile
|
||||
import com.topjohnwu.magisk.view.Notifications
|
||||
import com.topjohnwu.superuser.ShellUtils
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import okhttp3.ResponseBody
|
||||
import org.koin.android.ext.android.inject
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
abstract class RemoteFileService : NotificationService() {
|
||||
|
||||
@@ -33,14 +40,17 @@ abstract class RemoteFileService : NotificationService() {
|
||||
|
||||
// ---
|
||||
|
||||
private fun start(subject: DownloadSubject) = search(subject)
|
||||
private fun startInternal(subject: DownloadSubject) = search(subject)
|
||||
.onErrorResumeNext(download(subject))
|
||||
.doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.fileName) } }
|
||||
.subscribeK {
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.doOnSuccess {
|
||||
runCatching { onFinished(it, subject) }.onFailure { Timber.e(it) }
|
||||
finish(it, subject)
|
||||
}
|
||||
|
||||
private fun start(subject: DownloadSubject) = startInternal(subject).subscribeK()
|
||||
|
||||
private fun search(subject: DownloadSubject) = Single.fromCallable {
|
||||
if (!Config.isDownloadCacheEnabled) {
|
||||
throw IllegalStateException("The download cache is disabled")
|
||||
@@ -56,7 +66,7 @@ abstract class RemoteFileService : NotificationService() {
|
||||
.let { File(Const.EXTERNAL_PATH, it) }
|
||||
}
|
||||
|
||||
if (subject is DownloadSubject.Magisk) {
|
||||
if (subject is Magisk) {
|
||||
if (!ShellUtils.checkSum("MD5", file, subject.magisk.hash)) {
|
||||
throw IllegalStateException("The given file doesn't match the hash")
|
||||
}
|
||||
@@ -66,8 +76,57 @@ abstract class RemoteFileService : NotificationService() {
|
||||
}
|
||||
|
||||
private fun download(subject: DownloadSubject) = repo.downloadFile(subject.url)
|
||||
.map { it.toFile(subject.hashCode(), subject.fileName) }
|
||||
.map { map(subject, it) }
|
||||
.map {
|
||||
when (subject) {
|
||||
is Module -> appendInstaller(it, subject)
|
||||
else -> it.toFile(subject.hashCode(), subject.fileName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendInstaller(body: ResponseBody, subject: DownloadSubject): File {
|
||||
update(subject.hashCode()) {
|
||||
it.setContentText(getString(R.string.download_module))
|
||||
}
|
||||
|
||||
val installer = startInternal(Installer).blockingGet()
|
||||
val target = cachedFile(subject.fileName)
|
||||
|
||||
val input = ZipInputStream(body.byteStream())
|
||||
val output = ZipOutputStream(target.outputStream())
|
||||
|
||||
withStreams(input, output) { zin, zout ->
|
||||
zout.putNextEntry(ZipEntry("META-INF/"))
|
||||
zout.putNextEntry(ZipEntry("META-INF/com/"))
|
||||
zout.putNextEntry(ZipEntry("META-INF/com/google/"))
|
||||
zout.putNextEntry(ZipEntry("META-INF/com/google/android/"))
|
||||
zout.putNextEntry(ZipEntry("META-INF/com/google/android/update-binary"))
|
||||
installer.inputStream().copyTo(zout).also { zout.flush() }
|
||||
|
||||
zout.putNextEntry(ZipEntry("META-INF/com/google/android/updater-script"))
|
||||
zout.write("#MAGISK\n".toByteArray(charset("UTF-8")))
|
||||
|
||||
var off = -1
|
||||
var entry: ZipEntry? = zin.nextEntry
|
||||
while (entry != null) {
|
||||
Timber.i("Let's gooo (${entry.name})")
|
||||
if (off < 0) {
|
||||
off = entry.name.indexOf('/') + 1
|
||||
}
|
||||
|
||||
val path = entry.name.substring(off)
|
||||
if (path.isNotEmpty() && !path.startsWith("META-INF")) {
|
||||
zout.putNextEntry(ZipEntry(path))
|
||||
if (!entry.isDirectory) {
|
||||
zin.copyTo(zout).also { zout.flush() }
|
||||
}
|
||||
}
|
||||
|
||||
entry = zin.nextEntry
|
||||
}
|
||||
}
|
||||
|
||||
return target
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
@@ -87,6 +146,8 @@ abstract class RemoteFileService : NotificationService() {
|
||||
}
|
||||
|
||||
private fun finish(file: File, subject: DownloadSubject) = finishWork(subject.hashCode()) {
|
||||
if (subject is Installer) return@finishWork null
|
||||
|
||||
it.addActions(file, subject)
|
||||
.setContentText(getString(R.string.download_complete))
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.topjohnwu.magisk.model.entity.internal
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.Info
|
||||
import com.topjohnwu.magisk.model.entity.MagiskJson
|
||||
import com.topjohnwu.magisk.model.entity.Repo
|
||||
@@ -33,4 +35,10 @@ sealed class DownloadSubject : Parcelable {
|
||||
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
object Installer : DownloadSubject() {
|
||||
override val fileName: String get() = "module_installer(${BuildConfig.VERSION_CODE}).sh"
|
||||
override val url: String get() = Const.Url.MODULE_INSTALLER
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user