Improve performance

This commit is contained in:
Mygod
2020-06-28 04:20:23 +08:00
parent fd3783b95f
commit e6f72df814
2 changed files with 31 additions and 35 deletions

View File

@@ -77,7 +77,6 @@ class RootServer @JvmOverloads constructor(private val warnLogger: (String) -> U
} }
private lateinit var process: Process private lateinit var process: Process
private lateinit var worker: Thread
/** /**
* Thread safety: needs to be protected by mutex. * Thread safety: needs to be protected by mutex.
*/ */
@@ -86,7 +85,7 @@ class RootServer @JvmOverloads constructor(private val warnLogger: (String) -> U
@Volatile @Volatile
var active = false var active = false
private var counter = 0L private var counter = 0L
private val callbackListenerExit = CompletableDeferred<Unit>() private lateinit var callbackListenerExit: Deferred<Unit>
private val callbackLookup = LongSparseArray<Callback>() private val callbackLookup = LongSparseArray<Callback>()
private val mutex = Mutex() private val mutex = Mutex()
@@ -120,9 +119,11 @@ class RootServer @JvmOverloads constructor(private val warnLogger: (String) -> U
warnLogger(line) warnLogger(line)
} }
} }
private suspend fun doInit(context: Context, niceName: String) = coroutineScope {
@Suppress("BlockingMethodInNonBlockingContext") @Suppress("BlockingMethodInNonBlockingContext")
val init = async { private suspend fun doInit(context: Context, niceName: String) {
val token2 = UUID.randomUUID().toString()
val list = coroutineScope {
val init = async(start = CoroutineStart.LAZY) {
try { try {
process = ProcessBuilder("su").start() process = ProcessBuilder("su").start()
val token1 = UUID.randomUUID().toString() val token1 = UUID.randomUUID().toString()
@@ -137,14 +138,14 @@ class RootServer @JvmOverloads constructor(private val warnLogger: (String) -> U
throw NoShellException(e) throw NoShellException(e)
} }
} }
val token2 = UUID.randomUUID().toString() val launchString = async(start = CoroutineStart.LAZY) {
val launchString = async(Dispatchers.IO) {
val appProcess = AppProcess.getAppProcess() val appProcess = AppProcess.getAppProcess()
RootJava.getLaunchString(context.packageCodePath + " exec", // hack: plugging in exec RootJava.getLaunchString(context.packageCodePath + " exec", // hack: plugging in exec
RootServer::class.java.name, appProcess, AppProcess.guessIfAppProcessIs64Bits(appProcess), RootServer::class.java.name, appProcess, AppProcess.guessIfAppProcessIs64Bits(appProcess),
arrayOf("$token2\n"), niceName) arrayOf("$token2\n"), niceName)
} }
val list = awaitAll(init, launchString) awaitAll(init, launchString)
}
val (reader, writer) = list[0] as Pair<BufferedReader, DataOutputStream> val (reader, writer) = list[0] as Pair<BufferedReader, DataOutputStream>
writer.writeBytes(list[1] as String) writer.writeBytes(list[1] as String)
writer.flush() writer.flush()
@@ -180,29 +181,23 @@ class RootServer @JvmOverloads constructor(private val warnLogger: (String) -> U
*/ */
suspend fun init(context: Context, niceName: String = "${context.packageName}:root") { suspend fun init(context: Context, niceName: String = "${context.packageName}:root") {
val future = CompletableDeferred<Unit>() val future = CompletableDeferred<Unit>()
worker = Thread { callbackListenerExit = GlobalScope.async(Dispatchers.IO) {
try { try {
runBlocking { doInit(context, niceName) } doInit(context, niceName)
future.complete(Unit) future.complete(Unit)
} catch (e: Throwable) { } catch (e: Throwable) {
future.completeExceptionally(e) future.completeExceptionally(e)
callbackListenerExit.complete(Unit) return@async
return@Thread
} }
try { try {
callbackSpin() callbackSpin()
} catch (e: Throwable) {
callbackListenerExit.completeExceptionally(e)
return@Thread
} finally { } finally {
if (DEBUG) Log.d(TAG, "Waiting for exit") if (DEBUG) Log.d(TAG, "Waiting for exit")
process.waitFor() process.waitFor()
runBlocking { closeInternal(true) } closeInternal(true)
} }
check(process.errorStream.available() == 0) // stderr should not be used check(process.errorStream.available() == 0) // stderr should not be used
callbackListenerExit.complete(Unit)
} }
worker.start()
future.await() future.await()
} }
/** /**

View File

@@ -15,6 +15,7 @@ object RootManager : RootSession() {
@Parcelize @Parcelize
class RootInit : RootCommandNoResult { class RootInit : RootCommandNoResult {
override suspend fun execute(): Parcelable? { override suspend fun execute(): Parcelable? {
RootServer.DEBUG = BuildConfig.DEBUG
Services.init(RootJava.getSystemContext()) Services.init(RootJava.getSystemContext())
return null return null
} }