mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-30 13:35:27 +00:00
Added remaining methods of installation/flashing/uninstall to service
Updated parameters of patching step and fixed new ordered flashing format
This commit is contained in:
parent
b3d777bb6c
commit
5457c3803f
@ -82,6 +82,7 @@ object Const {
|
|||||||
const val INTENT_SET_NAME = "filename"
|
const val INTENT_SET_NAME = "filename"
|
||||||
const val INTENT_SET_LINK = "link"
|
const val INTENT_SET_LINK = "link"
|
||||||
const val FLASH_ACTION = "action"
|
const val FLASH_ACTION = "action"
|
||||||
|
const val FLASH_DATA = "additional_data"
|
||||||
const val BROADCAST_MANAGER_UPDATE = "manager_update"
|
const val BROADCAST_MANAGER_UPDATE = "manager_update"
|
||||||
const val BROADCAST_REBOOT = "reboot"
|
const val BROADCAST_REBOOT = "reboot"
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ val viewModelModules = module {
|
|||||||
viewModel { HideViewModel(get(), get()) }
|
viewModel { HideViewModel(get(), get()) }
|
||||||
viewModel { ModuleViewModel(get(), get(), get()) }
|
viewModel { ModuleViewModel(get(), get(), get()) }
|
||||||
viewModel { LogViewModel(get(), get()) }
|
viewModel { LogViewModel(get(), get()) }
|
||||||
viewModel { (action: String, uri: Uri?) -> FlashViewModel(action, uri, get()) }
|
viewModel { (action: String, file: Uri, additional: Uri) ->
|
||||||
|
FlashViewModel(action, file, additional, get())
|
||||||
|
}
|
||||||
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
|
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,11 @@ open class CompoundDownloadService : SubstrateDownloadService() {
|
|||||||
private fun onFinishedInternal(
|
private fun onFinishedInternal(
|
||||||
file: File,
|
file: File,
|
||||||
subject: DownloadSubject.Magisk
|
subject: DownloadSubject.Magisk
|
||||||
) = when (subject.configuration) {
|
) = when (val conf = subject.configuration) {
|
||||||
|
Configuration.Download -> moveToDownloads(file)
|
||||||
Configuration.Flash -> FlashActivity.flash(this, file)
|
Configuration.Flash -> FlashActivity.flash(this, file)
|
||||||
|
Configuration.Uninstall -> FlashActivity.uninstall(this, file)
|
||||||
|
is Configuration.Patch -> FlashActivity.patch(this, file, conf.fileUri)
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +37,7 @@ open class CompoundDownloadService : SubstrateDownloadService() {
|
|||||||
file: File,
|
file: File,
|
||||||
subject: DownloadSubject.Module
|
subject: DownloadSubject.Module
|
||||||
) = when (subject.configuration) {
|
) = when (subject.configuration) {
|
||||||
|
Configuration.Download -> moveToDownloads(file)
|
||||||
Configuration.Flash -> FlashActivity.install(this, file)
|
Configuration.Flash -> FlashActivity.install(this, file)
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
@ -51,8 +55,12 @@ open class CompoundDownloadService : SubstrateDownloadService() {
|
|||||||
private fun NotificationCompat.Builder.addActionsInternal(
|
private fun NotificationCompat.Builder.addActionsInternal(
|
||||||
file: File,
|
file: File,
|
||||||
subject: DownloadSubject.Magisk
|
subject: DownloadSubject.Magisk
|
||||||
) = when (subject.configuration) {
|
) = when (val conf = subject.configuration) {
|
||||||
|
Configuration.Download -> setContentIntent(fileIntent(subject.fileName))
|
||||||
Configuration.Flash -> setContentIntent(FlashActivity.flashIntent(context, file))
|
Configuration.Flash -> setContentIntent(FlashActivity.flashIntent(context, file))
|
||||||
|
Configuration.Uninstall -> setContentIntent(FlashActivity.uninstallIntent(context, file))
|
||||||
|
is Configuration.Patch ->
|
||||||
|
setContentIntent(FlashActivity.patchIntent(context, file, conf.fileUri))
|
||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +68,7 @@ open class CompoundDownloadService : SubstrateDownloadService() {
|
|||||||
file: File,
|
file: File,
|
||||||
subject: DownloadSubject.Module
|
subject: DownloadSubject.Module
|
||||||
) = when (subject.configuration) {
|
) = when (subject.configuration) {
|
||||||
|
Configuration.Download -> setContentIntent(fileIntent(subject.fileName))
|
||||||
Configuration.Flash -> setContentIntent(FlashActivity.installIntent(context, file))
|
Configuration.Flash -> setContentIntent(FlashActivity.installIntent(context, file))
|
||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,18 @@ import android.app.NotificationManager
|
|||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
|
import android.webkit.MimeTypeMap
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.core.net.toUri
|
||||||
import com.skoumal.teanity.extensions.subscribeK
|
import com.skoumal.teanity.extensions.subscribeK
|
||||||
import com.topjohnwu.magisk.Config
|
import com.topjohnwu.magisk.Config
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
import com.topjohnwu.magisk.R
|
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.utils.toast
|
||||||
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
|
||||||
@ -80,6 +84,27 @@ abstract class SubstrateDownloadService : Service() {
|
|||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
|
protected fun fileIntent(fileName: String): Intent {
|
||||||
|
val file = downloadsFile(fileName)
|
||||||
|
return Intent(Intent.ACTION_VIEW)
|
||||||
|
.setDataAndType(file.toUri(), file.type)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun moveToDownloads(file: File) {
|
||||||
|
val destination = downloadsFile(file.name)
|
||||||
|
file.copyTo(destination)
|
||||||
|
toast(getString(R.string.internal_storage, "/Download/${file.name}"), Toast.LENGTH_LONG)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
private val File.type
|
||||||
|
get() = MimeTypeMap.getSingleton()
|
||||||
|
.getMimeTypeFromExtension(extension)
|
||||||
|
.orEmpty()
|
||||||
|
|
||||||
|
private fun downloadsFile(name: String) = File(Const.EXTERNAL_PATH, name)
|
||||||
|
|
||||||
private fun ResponseBody.toFile(name: String): File {
|
private fun ResponseBody.toFile(name: String): File {
|
||||||
val maxRaw = contentLength()
|
val maxRaw = contentLength()
|
||||||
val max = maxRaw / 1_000_000f
|
val max = maxRaw / 1_000_000f
|
||||||
|
@ -2,6 +2,7 @@ package com.topjohnwu.magisk.ui.flash
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.topjohnwu.magisk.ClassMap
|
import com.topjohnwu.magisk.ClassMap
|
||||||
import com.topjohnwu.magisk.Const
|
import com.topjohnwu.magisk.Const
|
||||||
@ -16,9 +17,10 @@ open class FlashActivity : MagiskActivity<FlashViewModel, ActivityFlashBinding>(
|
|||||||
|
|
||||||
override val layoutRes: Int = R.layout.activity_flash
|
override val layoutRes: Int = R.layout.activity_flash
|
||||||
override val viewModel: FlashViewModel by viewModel {
|
override val viewModel: FlashViewModel by viewModel {
|
||||||
val uri = intent.data
|
val uri = intent.data ?: let { finish(); Uri.EMPTY }
|
||||||
|
val additionalUri = intent.getParcelableExtra<Uri>(Const.Key.FLASH_DATA) ?: Uri.EMPTY
|
||||||
val action = intent.getStringExtra(Const.Key.FLASH_ACTION) ?: let { finish();"" }
|
val action = intent.getStringExtra(Const.Key.FLASH_ACTION) ?: let { finish();"" }
|
||||||
parametersOf(action, uri)
|
parametersOf(action, uri, additionalUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
@ -41,11 +43,12 @@ open class FlashActivity : MagiskActivity<FlashViewModel, ActivityFlashBinding>(
|
|||||||
|
|
||||||
/* Patching is understood as injecting img files with magisk */
|
/* Patching is understood as injecting img files with magisk */
|
||||||
|
|
||||||
fun patchIntent(context: Context, file: File) = intent(context, file)
|
fun patchIntent(context: Context, file: File, uri: Uri) = intent(context, file)
|
||||||
|
.putExtra(Const.Key.FLASH_DATA, uri)
|
||||||
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_FILE)
|
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_FILE)
|
||||||
|
|
||||||
fun patch(context: Context, file: File) =
|
fun patch(context: Context, file: File, uri: Uri) =
|
||||||
context.startActivity(patchIntent(context, file))
|
context.startActivity(patchIntent(context, file, uri))
|
||||||
|
|
||||||
/* Uninstalling is understood as removing magisk entirely */
|
/* Uninstalling is understood as removing magisk entirely */
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@ import java.util.*
|
|||||||
|
|
||||||
class FlashViewModel(
|
class FlashViewModel(
|
||||||
action: String,
|
action: String,
|
||||||
uri: Uri?, // FIXME uri is now flashable file, not additional file
|
file: Uri,
|
||||||
|
uri: Uri,
|
||||||
private val resources: Resources
|
private val resources: Resources
|
||||||
) : MagiskViewModel(), FlashResultListener {
|
) : MagiskViewModel(), FlashResultListener {
|
||||||
|
|
||||||
@ -52,7 +53,6 @@ class FlashViewModel(
|
|||||||
|
|
||||||
state = State.LOADING
|
state = State.LOADING
|
||||||
|
|
||||||
val uri = uri ?: Uri.EMPTY
|
|
||||||
when (action) {
|
when (action) {
|
||||||
Const.Value.FLASH_ZIP -> Flashing
|
Const.Value.FLASH_ZIP -> Flashing
|
||||||
.Install(uri, outItems, logItems, this)
|
.Install(uri, outItems, logItems, this)
|
||||||
|
@ -9,6 +9,7 @@ import android.content.pm.PackageManager
|
|||||||
import android.content.pm.PackageManager.*
|
import android.content.pm.PackageManager.*
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
|
import android.widget.Toast
|
||||||
import com.topjohnwu.magisk.App
|
import com.topjohnwu.magisk.App
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
@ -50,21 +51,22 @@ val ApplicationInfo.packageInfo: PackageInfo?
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val Uri.fileName: String get() {
|
val Uri.fileName: String
|
||||||
var name: String? = null
|
get() {
|
||||||
App.self.contentResolver.query(this, null, null, null, null)?.use { c ->
|
var name: String? = null
|
||||||
val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
App.self.contentResolver.query(this, null, null, null, null)?.use { c ->
|
||||||
if (nameIndex != -1) {
|
val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
c.moveToFirst()
|
if (nameIndex != -1) {
|
||||||
name = c.getString(nameIndex)
|
c.moveToFirst()
|
||||||
|
name = c.getString(nameIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (name == null && path != null) {
|
||||||
|
val idx = path!!.lastIndexOf('/')
|
||||||
|
name = path!!.substring(idx + 1)
|
||||||
|
}
|
||||||
|
return name.orEmpty()
|
||||||
}
|
}
|
||||||
if (name == null && path != null) {
|
|
||||||
val idx = path!!.lastIndexOf('/')
|
|
||||||
name = path!!.substring(idx + 1)
|
|
||||||
}
|
|
||||||
return name.orEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun PackageManager.activities(packageName: String) =
|
fun PackageManager.activities(packageName: String) =
|
||||||
getPackageInfo(packageName, GET_ACTIVITIES)
|
getPackageInfo(packageName, GET_ACTIVITIES)
|
||||||
@ -80,10 +82,11 @@ fun PackageManager.providers(packageName: String) =
|
|||||||
|
|
||||||
fun Context.rawResource(id: Int) = resources.openRawResource(id)
|
fun Context.rawResource(id: Int) = resources.openRawResource(id)
|
||||||
|
|
||||||
fun Context.readUri(uri: Uri) = contentResolver.openInputStream(uri) ?: throw FileNotFoundException()
|
fun Context.readUri(uri: Uri) =
|
||||||
|
contentResolver.openInputStream(uri) ?: throw FileNotFoundException()
|
||||||
|
|
||||||
fun ApplicationInfo.findAppLabel(pm: PackageManager): String {
|
fun ApplicationInfo.findAppLabel(pm: PackageManager): String {
|
||||||
return pm.getApplicationLabel(this)?.toString().orEmpty()
|
return pm.getApplicationLabel(this).toString().orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Intent.startActivity(context: Context) = context.startActivity(this)
|
fun Intent.startActivity(context: Context) = context.startActivity(this)
|
||||||
@ -100,4 +103,10 @@ fun File.mv(destination: File) {
|
|||||||
|
|
||||||
fun String.toFile() = File(this)
|
fun String.toFile() = File(this)
|
||||||
|
|
||||||
fun Intent.chooser(title: String = "Pick an app") = Intent.createChooser(this, title)
|
fun Intent.chooser(title: String = "Pick an app") = Intent.createChooser(this, title)
|
||||||
|
|
||||||
|
fun Context.toast(message: Int, duration: Int = Toast.LENGTH_SHORT) =
|
||||||
|
toast(getString(message), duration)
|
||||||
|
|
||||||
|
fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) =
|
||||||
|
Toast.makeText(this, message, duration)
|
Loading…
Reference in New Issue
Block a user