mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-27 20:15:29 +00:00
parent
7dfe3e53d5
commit
0ad0ef485c
@ -25,10 +25,9 @@ object Const {
|
||||
val APP_IS_CANARY get() = Version.isCanary(BuildConfig.VERSION_CODE)
|
||||
|
||||
object Version {
|
||||
const val MIN_VERSION = "v20.4"
|
||||
const val MIN_VERCODE = 20400
|
||||
const val MIN_VERSION = "v21.0"
|
||||
const val MIN_VERCODE = 21000
|
||||
|
||||
fun atLeast_21_0() = Info.env.versionCode >= 21000 || isCanary()
|
||||
fun atLeast_21_2() = Info.env.versionCode >= 21200 || isCanary()
|
||||
fun isCanary() = isCanary(Info.env.versionCode)
|
||||
|
||||
|
@ -19,7 +19,7 @@ class Provider : ContentProvider() {
|
||||
}
|
||||
|
||||
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
|
||||
SuCallbackHandler(context!!, method, extras)
|
||||
SuCallbackHandler.run(context!!, method, extras)
|
||||
return Bundle.EMPTY
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,17 @@
|
||||
package com.topjohnwu.magisk.core.su
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Process
|
||||
import android.widget.Toast
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.intent
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.toLog
|
||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||
import com.topjohnwu.magisk.di.ServiceLocator
|
||||
import com.topjohnwu.magisk.ktx.startActivity
|
||||
import com.topjohnwu.magisk.ktx.startActivityWithRoot
|
||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
@ -28,9 +21,8 @@ object SuCallbackHandler {
|
||||
const val REQUEST = "request"
|
||||
const val LOG = "log"
|
||||
const val NOTIFY = "notify"
|
||||
const val TEST = "test"
|
||||
|
||||
operator fun invoke(context: Context, action: String?, data: Bundle?) {
|
||||
fun run(context: Context, action: String?, data: Bundle?) {
|
||||
data ?: return
|
||||
|
||||
// Debug messages
|
||||
@ -44,16 +36,8 @@ object SuCallbackHandler {
|
||||
}
|
||||
|
||||
when (action) {
|
||||
REQUEST -> handleRequest(context, data)
|
||||
LOG -> handleLogging(context, data)
|
||||
NOTIFY -> handleNotify(context, data)
|
||||
TEST -> {
|
||||
val mode = data.getInt("mode", 2)
|
||||
Shell.su(
|
||||
"magisk --connect-mode $mode",
|
||||
"magisk --use-broadcast"
|
||||
).submit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,20 +48,6 @@ object SuCallbackHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleRequest(context: Context, data: Bundle) {
|
||||
val intent = context.intent<SuRequestActivity>()
|
||||
.setAction(REQUEST)
|
||||
.putExtras(data)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
// Android Q does not allow starting activity from background
|
||||
intent.startActivityWithRoot()
|
||||
} else {
|
||||
intent.startActivity(context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLogging(context: Context, data: Bundle) {
|
||||
val fromUid = data["from.uid"].toInt() ?: return
|
||||
if (fromUid == Process.myUid())
|
||||
|
@ -2,9 +2,6 @@ package com.topjohnwu.magisk.core.su
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import androidx.collection.ArrayMap
|
||||
import com.topjohnwu.magisk.BuildConfig
|
||||
import com.topjohnwu.magisk.core.Config
|
||||
import com.topjohnwu.magisk.core.Const
|
||||
@ -12,11 +9,16 @@ import com.topjohnwu.magisk.core.magiskdb.PolicyDao
|
||||
import com.topjohnwu.magisk.core.model.su.SuPolicy
|
||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||
import com.topjohnwu.magisk.ktx.now
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import java.io.*
|
||||
import java.io.Closeable
|
||||
import java.io.DataOutputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeUnit.SECONDS
|
||||
|
||||
class SuRequestHandler(
|
||||
private val pm: PackageManager,
|
||||
@ -50,12 +52,6 @@ class SuRequestHandler(
|
||||
return true
|
||||
}
|
||||
|
||||
private suspend fun <T> Deferred<T>.timedAwait() : T? {
|
||||
return withTimeoutOrNull(SECONDS.toMillis(1)) {
|
||||
await()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun close() {
|
||||
if (::output.isInitialized)
|
||||
@ -66,20 +62,9 @@ class SuRequestHandler(
|
||||
|
||||
private suspend fun init(intent: Intent) = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
val uid: Int
|
||||
if (Const.Version.atLeast_21_0()) {
|
||||
val name = intent.getStringExtra("fifo") ?: throw SuRequestError()
|
||||
uid = intent.getIntExtra("uid", -1).also { if (it < 0) throw SuRequestError() }
|
||||
output = DataOutputStream(FileOutputStream(name).buffered())
|
||||
} else {
|
||||
val name = intent.getStringExtra("socket") ?: throw SuRequestError()
|
||||
val socket = LocalSocket()
|
||||
socket.connect(LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT))
|
||||
output = DataOutputStream(BufferedOutputStream(socket.outputStream))
|
||||
val input = DataInputStream(BufferedInputStream(socket.inputStream))
|
||||
val map = async { input.readRequest() }.timedAwait() ?: throw SuRequestError()
|
||||
uid = map["uid"]?.toIntOrNull() ?: throw SuRequestError()
|
||||
}
|
||||
val name = intent.getStringExtra("fifo") ?: throw SuRequestError()
|
||||
val uid = intent.getIntExtra("uid", -1).also { if (it < 0) throw SuRequestError() }
|
||||
output = DataOutputStream(FileOutputStream(name).buffered())
|
||||
policy = uid.toPolicy(pm)
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
@ -117,23 +102,4 @@ class SuRequestHandler(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun DataInputStream.readRequest(): Map<String, String> {
|
||||
fun readString(): String {
|
||||
val len = readInt()
|
||||
val buf = ByteArray(len)
|
||||
readFully(buf)
|
||||
return String(buf, Charsets.UTF_8)
|
||||
}
|
||||
val ret = ArrayMap<String, String>()
|
||||
while (true) {
|
||||
val name = readString()
|
||||
if (name == "eof")
|
||||
break
|
||||
ret[name] = readString()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,26 +37,16 @@ open class SuRequestActivity : BaseUIActivity<SuRequestViewModel, ActivityReques
|
||||
setTheme(Theme.selected.themeRes)
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
fun showRequest() {
|
||||
viewModel.handleRequest(intent)
|
||||
}
|
||||
|
||||
fun runHandler(action: String?) {
|
||||
SuCallbackHandler(this, action, intent.extras)
|
||||
finish()
|
||||
}
|
||||
|
||||
if (intent.action == Intent.ACTION_VIEW) {
|
||||
val action = intent.getStringExtra("action")
|
||||
if (action == REQUEST) {
|
||||
showRequest()
|
||||
viewModel.handleRequest(intent)
|
||||
} else {
|
||||
runHandler(action)
|
||||
SuCallbackHandler.run(this, action, intent.extras)
|
||||
finish()
|
||||
}
|
||||
} else if (intent.action == REQUEST) {
|
||||
showRequest()
|
||||
} else {
|
||||
runHandler(intent.action)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user