forked from MarcoBuster/Magisk
89 lines
2.7 KiB
Kotlin
89 lines
2.7 KiB
Kotlin
package com.topjohnwu.magisk.core.tasks
|
|
|
|
import android.content.Context
|
|
import android.net.Uri
|
|
import androidx.core.net.toFile
|
|
import com.topjohnwu.magisk.core.Const
|
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.displayName
|
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
|
|
import com.topjohnwu.magisk.core.utils.unzip
|
|
import com.topjohnwu.magisk.ktx.writeTo
|
|
import com.topjohnwu.superuser.Shell
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import org.koin.core.KoinComponent
|
|
import org.koin.core.inject
|
|
import timber.log.Timber
|
|
import java.io.File
|
|
import java.io.FileNotFoundException
|
|
import java.io.IOException
|
|
|
|
open class FlashZip(
|
|
private val mUri: Uri,
|
|
private val console: MutableList<String>,
|
|
private val logs: MutableList<String>
|
|
): KoinComponent {
|
|
|
|
private val context: Context by inject()
|
|
private val installDir = File(context.cacheDir, "flash")
|
|
private lateinit var zipFile: File
|
|
|
|
@Throws(IOException::class)
|
|
private fun flash(): Boolean {
|
|
installDir.deleteRecursively()
|
|
installDir.mkdirs()
|
|
|
|
zipFile = if (mUri.scheme == "file") {
|
|
mUri.toFile()
|
|
} else {
|
|
File(installDir, "install.zip").also {
|
|
console.add("- Copying zip to temp directory")
|
|
try {
|
|
mUri.inputStream().writeTo(it)
|
|
} catch (e: IOException) {
|
|
when (e) {
|
|
is FileNotFoundException -> console.add("! Invalid Uri")
|
|
else -> console.add("! Cannot copy to cache")
|
|
}
|
|
throw e
|
|
}
|
|
}
|
|
}
|
|
|
|
val isValid = runCatching {
|
|
zipFile.unzip(installDir, "META-INF/com/google/android", true)
|
|
val script = File(installDir, "updater-script")
|
|
script.readText().contains("#MAGISK")
|
|
}.getOrElse {
|
|
console.add("! Unzip error")
|
|
throw it
|
|
}
|
|
|
|
if (!isValid) {
|
|
console.add("! This zip is not a Magisk module!")
|
|
return false
|
|
}
|
|
|
|
console.add("- Installing ${mUri.displayName}")
|
|
|
|
return Shell.su("sh $installDir/update-binary dummy 1 $zipFile")
|
|
.to(console, logs).exec().isSuccess
|
|
}
|
|
|
|
open suspend fun exec() = withContext(Dispatchers.IO) {
|
|
try {
|
|
if (!flash()) {
|
|
console.add("! Installation failed")
|
|
false
|
|
} else {
|
|
true
|
|
}
|
|
} catch (e: IOException) {
|
|
Timber.e(e)
|
|
false
|
|
} finally {
|
|
Shell.su("cd /", "rm -rf $installDir ${Const.TMPDIR}").submit()
|
|
}
|
|
}
|
|
}
|