Directly download to target location

This commit is contained in:
topjohnwu 2019-07-23 01:31:59 -07:00
parent a8932706d8
commit 55aaa421e8
3 changed files with 34 additions and 46 deletions

View File

@ -6,13 +6,10 @@ import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Environment
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast
import androidx.annotation.RequiresPermission import androidx.annotation.RequiresPermission
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.topjohnwu.magisk.ClassMap import com.topjohnwu.magisk.ClassMap
import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.model.entity.internal.Configuration.* import com.topjohnwu.magisk.model.entity.internal.Configuration.*
import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary
@ -20,7 +17,6 @@ import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module
import com.topjohnwu.magisk.ui.flash.FlashActivity import com.topjohnwu.magisk.ui.flash.FlashActivity
import com.topjohnwu.magisk.utils.Utils
import com.topjohnwu.magisk.utils.chooser import com.topjohnwu.magisk.utils.chooser
import com.topjohnwu.magisk.utils.provide import com.topjohnwu.magisk.utils.provide
import java.io.File import java.io.File
@ -31,7 +27,6 @@ import kotlin.random.Random.Default.nextInt
open class DownloadService : RemoteFileService() { open class DownloadService : RemoteFileService() {
private val context get() = this private val context get() = this
private val String.downloadsFile get() = File(Config.downloadDirectory, this)
private val File.type private val File.type
get() = MimeTypeMap.getSingleton() get() = MimeTypeMap.getSingleton()
.getMimeTypeFromExtension(extension) .getMimeTypeFromExtension(extension)
@ -46,17 +41,16 @@ open class DownloadService : RemoteFileService() {
file: File, file: File,
subject: Magisk subject: Magisk
) = when (val conf = subject.configuration) { ) = when (val conf = subject.configuration) {
Download -> moveToDownloads(file)
Uninstall -> FlashActivity.uninstall(this, file) Uninstall -> FlashActivity.uninstall(this, file)
is Patch -> FlashActivity.patch(this, file, conf.fileUri) is Patch -> FlashActivity.patch(this, file, conf.fileUri)
is Flash -> FlashActivity.flash(this, file, conf is Secondary) is Flash -> FlashActivity.flash(this, file, conf is Secondary)
else -> Unit
} }
private fun onFinishedInternal( private fun onFinishedInternal(
file: File, file: File,
subject: Module subject: Module
) = when (subject.configuration) { ) = when (subject.configuration) {
Download -> moveToDownloads(file)
is Flash -> FlashActivity.install(this, file) is Flash -> FlashActivity.install(this, file)
else -> Unit else -> Unit
} }
@ -75,8 +69,8 @@ open class DownloadService : RemoteFileService() {
file: File, file: File,
subject: Magisk subject: Magisk
) = when (val conf = subject.configuration) { ) = when (val conf = subject.configuration) {
Download -> addAction(0, R.string.download_open_parent, fileParentIntent(subject.fileName)) Download -> addAction(0, R.string.download_open_parent, fileIntent(subject.file.parentFile!!))
.addAction(0, R.string.download_open_self, fileIntent(subject.fileName)) .addAction(0, R.string.download_open_self, fileIntent(subject.file))
Uninstall -> setContentIntent(FlashActivity.uninstallIntent(context, file)) Uninstall -> setContentIntent(FlashActivity.uninstallIntent(context, file))
is Flash -> setContentIntent(FlashActivity.flashIntent(context, file, conf is Secondary)) is Flash -> setContentIntent(FlashActivity.flashIntent(context, file, conf is Secondary))
is Patch -> setContentIntent(FlashActivity.patchIntent(context, file, conf.fileUri)) is Patch -> setContentIntent(FlashActivity.patchIntent(context, file, conf.fileUri))
@ -87,8 +81,8 @@ open class DownloadService : RemoteFileService() {
file: File, file: File,
subject: Module subject: Module
) = when (subject.configuration) { ) = when (subject.configuration) {
Download -> addAction(0, R.string.download_open_parent, fileParentIntent(subject.fileName)) Download -> addAction(0, R.string.download_open_parent, fileIntent(subject.file.parentFile!!))
.addAction(0, R.string.download_open_self, fileIntent(subject.fileName)) .addAction(0, R.string.download_open_self, fileIntent(subject.file))
is Flash -> setContentIntent(FlashActivity.installIntent(context, file)) is Flash -> setContentIntent(FlashActivity.installIntent(context, file))
else -> this else -> this
} }
@ -105,31 +99,6 @@ open class DownloadService : RemoteFileService() {
// --- // ---
private fun moveToDownloads(file: File) {
val destination = file.name.downloadsFile
if (file != destination) {
destination.deleteRecursively()
file.copyTo(destination)
}
Utils.toast(
getString(
R.string.internal_storage,
"/" + destination.toRelativeString(Environment.getExternalStorageDirectory())
),
Toast.LENGTH_LONG
)
}
private fun fileIntent(fileName: String): Intent {
return fileIntent(fileName.downloadsFile)
}
private fun fileParentIntent(fileName: String): Intent {
return fileIntent(fileName.downloadsFile.parentFile!!)
}
private fun fileIntent(file: File): Intent { private fun fileIntent(file: File): Intent {
return Intent(Intent.ACTION_VIEW) return Intent(Intent.ACTION_VIEW)
.setDataAndType(file.provide(this), file.type) .setDataAndType(file.provide(this), file.type)

View File

@ -11,7 +11,6 @@ import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module
import com.topjohnwu.magisk.utils.ProgInputStream import com.topjohnwu.magisk.utils.ProgInputStream
import com.topjohnwu.magisk.utils.cachedFile
import com.topjohnwu.magisk.utils.firstMap import com.topjohnwu.magisk.utils.firstMap
import com.topjohnwu.magisk.utils.writeTo import com.topjohnwu.magisk.utils.writeTo
import com.topjohnwu.magisk.view.Notifications import com.topjohnwu.magisk.view.Notifications
@ -48,7 +47,7 @@ abstract class RemoteFileService : NotificationService() {
private fun start(subject: DownloadSubject) = search(subject) private fun start(subject: DownloadSubject) = search(subject)
.onErrorResumeNext(download(subject)) .onErrorResumeNext(download(subject))
.doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.fileName) } } .doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.title) } }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnSuccess { .doOnSuccess {
runCatching { onFinished(it, subject) }.onFailure { Timber.e(it) } runCatching { onFinished(it, subject) }.onFailure { Timber.e(it) }
@ -60,7 +59,7 @@ abstract class RemoteFileService : NotificationService() {
throw IllegalStateException("The download cache is disabled") throw IllegalStateException("The download cache is disabled")
} }
supportedFolders.firstMap { it.find(subject.fileName) }.also { supportedFolders.firstMap { it.find(subject.file.name) }.also {
if (subject is Magisk) { if (subject is Magisk) {
if (!ShellUtils.checkSum("MD5", it, subject.magisk.hash)) { if (!ShellUtils.checkSum("MD5", it, subject.magisk.hash)) {
throw IllegalStateException("The given file doesn't match the hash") throw IllegalStateException("The given file doesn't match the hash")
@ -72,7 +71,7 @@ abstract class RemoteFileService : NotificationService() {
private fun download(subject: DownloadSubject) = repo.downloadFile(subject.url) private fun download(subject: DownloadSubject) = repo.downloadFile(subject.url)
.map { it.toStream(subject.hashCode()) } .map { it.toStream(subject.hashCode()) }
.map { .map {
cachedFile(subject.fileName).apply { subject.file.apply {
when (subject) { when (subject) {
is Module -> it.toModule(this, is Module -> it.toModule(this,
repo.downloadFile(Const.Url.MODULE_INSTALLER).blockingGet().byteStream()) repo.downloadFile(Const.Url.MODULE_INSTALLER).blockingGet().byteStream())

View File

@ -1,15 +1,22 @@
package com.topjohnwu.magisk.model.entity.internal package com.topjohnwu.magisk.model.entity.internal
import android.content.Context
import android.os.Parcelable import android.os.Parcelable
import com.topjohnwu.magisk.Config
import com.topjohnwu.magisk.Info import com.topjohnwu.magisk.Info
import com.topjohnwu.magisk.model.entity.MagiskJson import com.topjohnwu.magisk.model.entity.MagiskJson
import com.topjohnwu.magisk.model.entity.Repo import com.topjohnwu.magisk.model.entity.Repo
import com.topjohnwu.magisk.utils.cachedFile
import com.topjohnwu.magisk.utils.get
import kotlinx.android.parcel.IgnoredOnParcel
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import java.io.File
sealed class DownloadSubject : Parcelable { sealed class DownloadSubject : Parcelable {
abstract val fileName: String
abstract val url: String abstract val url: String
abstract val file: File
open val title: String get() = file.name
@Parcelize @Parcelize
data class Module( data class Module(
@ -17,7 +24,11 @@ sealed class DownloadSubject : Parcelable {
val configuration: Configuration val configuration: Configuration
) : DownloadSubject() { ) : DownloadSubject() {
override val url: String get() = module.zipUrl override val url: String get() = module.zipUrl
override val fileName: String get() = "${module.name}-v${module.version}(${module.versionCode}).zip"
@IgnoredOnParcel
override val file by lazy {
File(Config.downloadDirectory, "${module.name}-v${module.version}(${module.versionCode}).zip")
}
} }
sealed class Magisk : DownloadSubject() { sealed class Magisk : DownloadSubject() {
@ -30,19 +41,28 @@ sealed class DownloadSubject : Parcelable {
override val configuration: Configuration override val configuration: Configuration
) : Magisk() { ) : Magisk() {
override val url: String get() = magisk.link override val url: String get() = magisk.link
override val fileName get() = "magisk.zip" override val title: String get() = "Magisk-v${magisk.version}(${magisk.versionCode})"
@IgnoredOnParcel
override val file by lazy {
get<Context>().cachedFile("magisk.zip")
}
} }
@Parcelize @Parcelize
protected object Download : Magisk() { protected class Download : Magisk() {
override val configuration: Configuration get() = Configuration.Download override val configuration: Configuration get() = Configuration.Download
override val url: String get() = magisk.link override val url: String get() = magisk.link
override val fileName get() = "Magisk-v${magisk.version}(${magisk.versionCode}).zip"
@IgnoredOnParcel
override val file by lazy {
File(Config.downloadDirectory, "Magisk-v${magisk.version}(${magisk.versionCode}).zip")
}
} }
companion object { companion object {
operator fun invoke(configuration: Configuration) = when (configuration) { operator fun invoke(configuration: Configuration) = when (configuration) {
Configuration.Download -> Download Configuration.Download -> Download()
else -> Flash(configuration) else -> Flash(configuration)
} }
} }