Commit 7cd814d9 authored by Viktor De Pasquale's avatar Viktor De Pasquale Committed by John Wu

Updated service to use extra transformer so the service itself is not plagued by unnecessary code

parent 78282c1a
...@@ -4,6 +4,8 @@ import android.content.Context ...@@ -4,6 +4,8 @@ import android.content.Context
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.skoumal.teanity.rxbus.RxBus import com.skoumal.teanity.rxbus.RxBus
import com.topjohnwu.magisk.App import com.topjohnwu.magisk.App
import com.topjohnwu.magisk.model.download.ModuleTransformer
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import org.koin.dsl.module import org.koin.dsl.module
...@@ -15,4 +17,6 @@ val applicationModule = module { ...@@ -15,4 +17,6 @@ val applicationModule = module {
factory(Protected) { get<App>().protectedContext } factory(Protected) { get<App>().protectedContext }
single(SUTimeout) { get<Context>(Protected).getSharedPreferences("su_timeout", 0) } single(SUTimeout) { get<Context>(Protected).getSharedPreferences("su_timeout", 0) }
single { PreferenceManager.getDefaultSharedPreferences(get<Context>(Protected)) } single { PreferenceManager.getDefaultSharedPreferences(get<Context>(Protected)) }
factory { (subject: DownloadSubject) -> ModuleTransformer(get(), subject) }
} }
\ No newline at end of file
package com.topjohnwu.magisk.model.download
import android.content.Context
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.utils.cachedFile
import com.topjohnwu.magisk.utils.withStreams
import java.io.File
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
class ModuleTransformer(
private val context: Context,
subject: DownloadSubject
) {
private val destination = context.cachedFile(subject.fileName)
fun inject(file: File, installer: File): File {
return injectInternal(move(file), installer)
}
// ---
private fun injectInternal(file: File, installer: File): File {
val input = ZipInputStream(file.inputStream())
val output = ZipOutputStream(destination.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) {
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
}
}
file.delete()
return destination
}
private fun move(file: File) = context.cachedFile("temp").apply {
file.renameTo(this)
}
}
\ No newline at end of file
...@@ -9,20 +9,17 @@ import com.topjohnwu.magisk.R ...@@ -9,20 +9,17 @@ import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.data.repository.FileRepository 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.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.utils.writeToCachedFile
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koin.core.parameter.parametersOf
import timber.log.Timber import timber.log.Timber
import java.io.File import java.io.File
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
abstract class RemoteFileService : NotificationService() { abstract class RemoteFileService : NotificationService() {
...@@ -40,7 +37,7 @@ abstract class RemoteFileService : NotificationService() { ...@@ -40,7 +37,7 @@ abstract class RemoteFileService : NotificationService() {
// --- // ---
private fun startInternal(subject: DownloadSubject) = search(subject) private fun startInternal(subject: DownloadSubject): Single<File> = search(subject)
.onErrorResumeNext(download(subject)) .onErrorResumeNext(download(subject))
.doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.fileName) } } .doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.fileName) } }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
...@@ -76,57 +73,22 @@ abstract class RemoteFileService : NotificationService() { ...@@ -76,57 +73,22 @@ abstract class RemoteFileService : NotificationService() {
} }
private fun download(subject: DownloadSubject) = repo.downloadFile(subject.url) private fun download(subject: DownloadSubject) = repo.downloadFile(subject.url)
.map { it.toFile(subject.hashCode(), subject.fileName) }
.map { .map {
when (subject) { when (subject) {
is Module -> appendInstaller(it, subject) is Module -> {
else -> it.toFile(subject.hashCode(), subject.fileName) update(subject.hashCode()) {
} it.setContentText(getString(R.string.download_module))
} .setProgress(0, 0, true)
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) {
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 get<ModuleTransformer> { parametersOf(subject) }
.inject(it, startInternal(Installer).blockingGet())
}
else -> it
} }
} }
return target
}
// --- // ---
private fun ResponseBody.toFile(id: Int, name: String): File { private fun ResponseBody.toFile(id: Int, name: String): File {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment