mirror of
https://github.com/tiann/KernelSU.git
synced 2025-02-20 11:43:32 +08:00
manager: mount modules webui resources to manager directly.
This commit is contained in:
parent
9c4d20c0f2
commit
329010a694
@ -5,6 +5,7 @@ import coil.Coil
|
||||
import coil.ImageLoader
|
||||
import me.zhanghai.android.appiconloader.coil.AppIconFetcher
|
||||
import me.zhanghai.android.appiconloader.coil.AppIconKeyer
|
||||
import java.io.File
|
||||
|
||||
lateinit var ksuApp: KernelSUApplication
|
||||
|
||||
@ -24,6 +25,11 @@ class KernelSUApplication : Application() {
|
||||
}
|
||||
.build()
|
||||
)
|
||||
|
||||
val webroot = File(dataDir, "webroot")
|
||||
if (!webroot.exists()) {
|
||||
webroot.mkdir()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,34 +15,26 @@ import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.accompanist.web.WebView
|
||||
import com.google.accompanist.web.rememberWebViewState
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.topjohnwu.superuser.ShellUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.weishu.kernelsu.ui.util.createRootShell
|
||||
import me.weishu.kernelsu.ui.util.serveModule
|
||||
import java.net.ServerSocket
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Destination
|
||||
@Composable
|
||||
fun WebScreen(navigator: DestinationsNavigator, moduleId: String, moduleName: String) {
|
||||
|
||||
val port = 8080
|
||||
LaunchedEffect(Unit) {
|
||||
serveModule(moduleId, port)
|
||||
serveModule(moduleId)
|
||||
}
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
val context = LocalContext.current
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
@ -50,15 +42,12 @@ fun WebScreen(navigator: DestinationsNavigator, moduleId: String, moduleName: St
|
||||
if (WebViewInterface.isHideSystemUI && context is Activity) {
|
||||
showSystemUI(context.window)
|
||||
}
|
||||
lifecycleOwner.lifecycleScope.launch {
|
||||
stopServer(port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold { innerPadding ->
|
||||
WebView(
|
||||
state = rememberWebViewState(url = "http://localhost:$port"),
|
||||
state = rememberWebViewState(url = "file:///data/data/me.weishu.kernelsu/webroot/index.html"),
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding),
|
||||
@ -66,6 +55,7 @@ fun WebScreen(navigator: DestinationsNavigator, moduleId: String, moduleName: St
|
||||
android.webkit.WebView(context).apply {
|
||||
settings.javaScriptEnabled = true
|
||||
settings.domStorageEnabled = true
|
||||
settings.allowFileAccess = true
|
||||
addJavascriptInterface(WebViewInterface(context), "ksu")
|
||||
}
|
||||
})
|
||||
@ -100,22 +90,6 @@ class WebViewInterface(val context: Context) {
|
||||
|
||||
}
|
||||
|
||||
private suspend fun getFreePort(): Int {
|
||||
return withContext(Dispatchers.IO) {
|
||||
ServerSocket(0).use { socket -> socket.localPort }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun stopServer(port: Int) {
|
||||
withContext(Dispatchers.IO) {
|
||||
runCatching {
|
||||
okhttp3.OkHttpClient()
|
||||
.newCall(okhttp3.Request.Builder().url("http://localhost:$port/stop").build())
|
||||
.execute()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideSystemUI(window: Window) {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||
|
@ -131,13 +131,13 @@ fun installModule(
|
||||
}
|
||||
}
|
||||
|
||||
fun serveModule(id: String, port: Int): Process {
|
||||
fun serveModule(id: String): Boolean {
|
||||
// we should use a new root shell to avoid blocking the global shell
|
||||
val process = Runtime.getRuntime().exec("${getKsuDaemonPath()} debug su")
|
||||
val builder = Shell.Builder.create()
|
||||
val shell = builder.build(process)
|
||||
shell.newJob().add("${getKsuDaemonPath()} module serve $id $port").submit()
|
||||
return process
|
||||
val shell = createRootShell()
|
||||
return ShellUtils.fastCmdResult(
|
||||
shell,
|
||||
"${getKsuDaemonPath()} module link-manager $id ${android.os.Process.myPid()} ${BuildConfig.APPLICATION_ID}"
|
||||
)
|
||||
}
|
||||
|
||||
fun reboot(reason: String = "") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user