Add support for daemon launching without relocation
Improves RAM usage and potentially addresses #368.
Inspired by: fc42e8274e/service/src/main/java/com/topjohnwu/superuser/internal/RootServiceManager.java (L186)
This commit is contained in:
2
mobile/proguard-rules.pro
vendored
2
mobile/proguard-rules.pro
vendored
@@ -22,7 +22,7 @@
|
|||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
-if public class be.mygod.librootkotlinx.RootServer {
|
-if public class be.mygod.librootkotlinx.RootServer {
|
||||||
private void doInit(android.content.Context, java.lang.String);
|
private void doInit(android.content.Context, java.lang.String, boolean);
|
||||||
}
|
}
|
||||||
-keep class be.mygod.librootkotlinx.RootServer {
|
-keep class be.mygod.librootkotlinx.RootServer {
|
||||||
public static void main(java.lang.String[]);
|
public static void main(java.lang.String[]);
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class RootServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LaunchException(cause: Throwable) : RuntimeException("Failed to launch root daemon", cause)
|
||||||
class UnexpectedExitException : RemoteException("Root process exited unexpectedly")
|
class UnexpectedExitException : RemoteException("Root process exited unexpectedly")
|
||||||
|
|
||||||
private lateinit var process: Process
|
private lateinit var process: Process
|
||||||
@@ -130,7 +131,7 @@ class RootServer {
|
|||||||
Logger.me.w(line)
|
Logger.me.w(line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun doInit(context: Context, niceName: String) {
|
private fun doInit(context: Context, niceName: String, shouldRelocate: Boolean = false) {
|
||||||
try {
|
try {
|
||||||
val (reader, writer) = try {
|
val (reader, writer) = try {
|
||||||
process = ProcessBuilder("su").start()
|
process = ProcessBuilder("su").start()
|
||||||
@@ -147,6 +148,7 @@ class RootServer {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val token2 = UUID.randomUUID().toString()
|
val token2 = UUID.randomUUID().toString()
|
||||||
|
writer.writeBytes(if (shouldRelocate) {
|
||||||
val persistence = File(context.codeCacheDir, ".librootkotlinx-uuid")
|
val persistence = File(context.codeCacheDir, ".librootkotlinx-uuid")
|
||||||
val uuid = context.packageName + '@' + try {
|
val uuid = context.packageName + '@' + try {
|
||||||
persistence.readText()
|
persistence.readText()
|
||||||
@@ -156,11 +158,15 @@ class RootServer {
|
|||||||
val (script, relocated) = AppProcess.relocateScript(uuid)
|
val (script, relocated) = AppProcess.relocateScript(uuid)
|
||||||
script.appendLine(AppProcess.launchString(context.packageCodePath, RootServer::class.java.name,
|
script.appendLine(AppProcess.launchString(context.packageCodePath, RootServer::class.java.name,
|
||||||
relocated, niceName) + " $token2")
|
relocated, niceName) + " $token2")
|
||||||
writer.writeBytes(script.toString())
|
script.toString()
|
||||||
|
} else {
|
||||||
|
AppProcess.launchString(context.packageCodePath, RootServer::class.java.name, AppProcess.myExe,
|
||||||
|
niceName) + " $token2\n"
|
||||||
|
})
|
||||||
writer.flush()
|
writer.flush()
|
||||||
reader.lookForToken(token2) // wait for ready signal
|
reader.lookForToken(token2) // wait for ready signal
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw RuntimeException("Failed to launch root daemon", e)
|
throw LaunchException(e)
|
||||||
}
|
}
|
||||||
output = writer
|
output = writer
|
||||||
require(!active)
|
require(!active)
|
||||||
@@ -204,7 +210,19 @@ class RootServer {
|
|||||||
* @param niceName Name to call the rooted Java process.
|
* @param niceName Name to call the rooted Java process.
|
||||||
*/
|
*/
|
||||||
suspend fun init(context: Context, niceName: String = "${context.packageName}:root") {
|
suspend fun init(context: Context, niceName: String = "${context.packageName}:root") {
|
||||||
withContext(Dispatchers.IO) { doInit(context, niceName) }
|
withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
doInit(context, niceName)
|
||||||
|
} catch (e: LaunchException) {
|
||||||
|
try {
|
||||||
|
doInit(context, niceName, true)
|
||||||
|
} catch (e2: LaunchException) {
|
||||||
|
e2.addSuppressed(e)
|
||||||
|
throw e2
|
||||||
|
}
|
||||||
|
Logger.me.w("Root without relocation has failed", RuntimeException(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
callbackListenerExit = GlobalScope.async(Dispatchers.IO) {
|
callbackListenerExit = GlobalScope.async(Dispatchers.IO) {
|
||||||
val errorReader = async(Dispatchers.IO) {
|
val errorReader = async(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user