mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-25 22:27:24 +00:00
parent
7dfe3e53d5
commit
0ad0ef485c
@ -25,10 +25,9 @@ object Const {
|
|||||||
val APP_IS_CANARY get() = Version.isCanary(BuildConfig.VERSION_CODE)
|
val APP_IS_CANARY get() = Version.isCanary(BuildConfig.VERSION_CODE)
|
||||||
|
|
||||||
object Version {
|
object Version {
|
||||||
const val MIN_VERSION = "v20.4"
|
const val MIN_VERSION = "v21.0"
|
||||||
const val MIN_VERCODE = 20400
|
const val MIN_VERCODE = 21000
|
||||||
|
|
||||||
fun atLeast_21_0() = Info.env.versionCode >= 21000 || isCanary()
|
|
||||||
fun atLeast_21_2() = Info.env.versionCode >= 21200 || isCanary()
|
fun atLeast_21_2() = Info.env.versionCode >= 21200 || isCanary()
|
||||||
fun isCanary() = isCanary(Info.env.versionCode)
|
fun isCanary() = isCanary(Info.env.versionCode)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class Provider : ContentProvider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
|
override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
|
||||||
SuCallbackHandler(context!!, method, extras)
|
SuCallbackHandler.run(context!!, method, extras)
|
||||||
return Bundle.EMPTY
|
return Bundle.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,24 +1,17 @@
|
|||||||
package com.topjohnwu.magisk.core.su
|
package com.topjohnwu.magisk.core.su
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Process
|
import android.os.Process
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.topjohnwu.magisk.BuildConfig
|
import com.topjohnwu.magisk.BuildConfig
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.core.Config
|
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.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.model.su.toLog
|
import com.topjohnwu.magisk.core.model.su.toLog
|
||||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||||
import com.topjohnwu.magisk.di.ServiceLocator
|
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.magisk.utils.Utils
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -28,9 +21,8 @@ object SuCallbackHandler {
|
|||||||
const val REQUEST = "request"
|
const val REQUEST = "request"
|
||||||
const val LOG = "log"
|
const val LOG = "log"
|
||||||
const val NOTIFY = "notify"
|
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
|
data ?: return
|
||||||
|
|
||||||
// Debug messages
|
// Debug messages
|
||||||
@ -44,16 +36,8 @@ object SuCallbackHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (action) {
|
when (action) {
|
||||||
REQUEST -> handleRequest(context, data)
|
|
||||||
LOG -> handleLogging(context, data)
|
LOG -> handleLogging(context, data)
|
||||||
NOTIFY -> handleNotify(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) {
|
private fun handleLogging(context: Context, data: Bundle) {
|
||||||
val fromUid = data["from.uid"].toInt() ?: return
|
val fromUid = data["from.uid"].toInt() ?: return
|
||||||
if (fromUid == Process.myUid())
|
if (fromUid == Process.myUid())
|
||||||
|
@ -2,9 +2,6 @@ package com.topjohnwu.magisk.core.su
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
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.BuildConfig
|
||||||
import com.topjohnwu.magisk.core.Config
|
import com.topjohnwu.magisk.core.Config
|
||||||
import com.topjohnwu.magisk.core.Const
|
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.SuPolicy
|
||||||
import com.topjohnwu.magisk.core.model.su.toPolicy
|
import com.topjohnwu.magisk.core.model.su.toPolicy
|
||||||
import com.topjohnwu.magisk.ktx.now
|
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 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
|
||||||
import java.util.concurrent.TimeUnit.SECONDS
|
|
||||||
|
|
||||||
class SuRequestHandler(
|
class SuRequestHandler(
|
||||||
private val pm: PackageManager,
|
private val pm: PackageManager,
|
||||||
@ -50,12 +52,6 @@ class SuRequestHandler(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun <T> Deferred<T>.timedAwait() : T? {
|
|
||||||
return withTimeoutOrNull(SECONDS.toMillis(1)) {
|
|
||||||
await()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
override fun close() {
|
override fun close() {
|
||||||
if (::output.isInitialized)
|
if (::output.isInitialized)
|
||||||
@ -66,20 +62,9 @@ class SuRequestHandler(
|
|||||||
|
|
||||||
private suspend fun init(intent: Intent) = withContext(Dispatchers.IO) {
|
private suspend fun init(intent: Intent) = withContext(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val uid: Int
|
|
||||||
if (Const.Version.atLeast_21_0()) {
|
|
||||||
val name = intent.getStringExtra("fifo") ?: throw SuRequestError()
|
val name = intent.getStringExtra("fifo") ?: throw SuRequestError()
|
||||||
uid = intent.getIntExtra("uid", -1).also { if (it < 0) throw SuRequestError() }
|
val uid = intent.getIntExtra("uid", -1).also { if (it < 0) throw SuRequestError() }
|
||||||
output = DataOutputStream(FileOutputStream(name).buffered())
|
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()
|
|
||||||
}
|
|
||||||
policy = uid.toPolicy(pm)
|
policy = uid.toPolicy(pm)
|
||||||
true
|
true
|
||||||
} catch (e: Exception) {
|
} 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)
|
setTheme(Theme.selected.themeRes)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
fun showRequest() {
|
|
||||||
viewModel.handleRequest(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun runHandler(action: String?) {
|
|
||||||
SuCallbackHandler(this, action, intent.extras)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intent.action == Intent.ACTION_VIEW) {
|
if (intent.action == Intent.ACTION_VIEW) {
|
||||||
val action = intent.getStringExtra("action")
|
val action = intent.getStringExtra("action")
|
||||||
if (action == REQUEST) {
|
if (action == REQUEST) {
|
||||||
showRequest()
|
viewModel.handleRequest(intent)
|
||||||
} else {
|
} else {
|
||||||
runHandler(action)
|
SuCallbackHandler.run(this, action, intent.extras)
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
} else if (intent.action == REQUEST) {
|
|
||||||
showRequest()
|
|
||||||
} else {
|
} else {
|
||||||
runHandler(intent.action)
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user