manager: refine webui (#1535)

This commit is contained in:
5ec1cff 2024-03-26 17:16:01 +08:00 committed by GitHub
parent c4d28e6256
commit 8b85e003f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 72 additions and 122 deletions

View File

@ -32,7 +32,10 @@
</activity>
<activity android:name=".ui.webui.WebUIActivity"
android:exported="false" />
android:autoRemoveFromRecents="true"
android:documentLaunchMode="intoExisting"
android:exported="false"
android:theme="@style/Theme.KernelSU.WebUI" />
<provider
android:name="androidx.core.content.FileProvider"

View File

@ -167,7 +167,6 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
.setData(Uri.parse("kernelsu://webui/$id"))
.putExtra("id", id)
.putExtra("name", name)
.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
)
}
})

View File

@ -1,76 +0,0 @@
package me.weishu.kernelsu.ui.screen
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.util.Log
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.webkit.WebViewAssetLoader
import com.google.accompanist.web.AccompanistWebViewClient
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 me.weishu.kernelsu.ui.webui.SuFilePathHandler
import me.weishu.kernelsu.ui.webui.WebViewInterface
import me.weishu.kernelsu.ui.webui.showSystemUI
import java.io.File
@SuppressLint("SetJavaScriptEnabled")
@Composable
fun WebScreen(moduleId: String, moduleName: String) {
val context = LocalContext.current
DisposableEffect(Unit) {
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
WebView.setWebContentsDebuggingEnabled(prefs.getBoolean("enable_web_debugging", false))
onDispose {
if (WebViewInterface.isHideSystemUI && context is Activity) {
showSystemUI(context.window)
}
}
}
Scaffold { innerPadding ->
val webRoot = File("/data/adb/modules/${moduleId}/webroot")
val webViewAssetLoader = WebViewAssetLoader.Builder()
.setDomain("mui.kernelsu.org")
.addPathHandler("/",
SuFilePathHandler(context, webRoot)
)
.build()
val webViewClient = object : AccompanistWebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
return webViewAssetLoader.shouldInterceptRequest(request.url)
}
}
WebView(
state = rememberWebViewState(url = "https://mui.kernelsu.org/index.html"),
Modifier
.fillMaxSize()
.padding(innerPadding),
client = webViewClient,
factory = { context ->
WebView(context).apply {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.allowFileAccess = false
addJavascriptInterface(WebViewInterface(context, this), "ksu")
}
})
}
}

View File

@ -1,49 +1,58 @@
package me.weishu.kernelsu.ui.webui
import android.annotation.SuppressLint
import android.app.ActivityManager
import android.content.Context
import android.os.Bundle
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.navigation.compose.currentBackStackEntryAsState
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
import com.ramcosta.composedestinations.DestinationsNavHost
import me.weishu.kernelsu.ui.screen.NavGraphs
import me.weishu.kernelsu.ui.screen.WebScreen
import me.weishu.kernelsu.ui.theme.KernelSUTheme
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import androidx.webkit.WebViewAssetLoader
import java.io.File
@SuppressLint("SetJavaScriptEnabled")
class WebUIActivity : ComponentActivity() {
@OptIn(ExperimentalAnimationApi::class)
private lateinit var webviewInterface: WebViewInterface
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val id = intent.getStringExtra("id")!!
val moduleId = intent.getStringExtra("id")!!
val name = intent.getStringExtra("name")!!
setTitle("KernelSU - $name")
setTaskDescription(ActivityManager.TaskDescription("KernelSU - $name"))
setContent {
KernelSUTheme {
val navController = rememberAnimatedNavController()
val snackbarHostState = remember { SnackbarHostState() }
Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) }
) { innerPadding ->
Box(modifier = Modifier
.padding(innerPadding)
.fillMaxSize()) {
WebScreen(moduleId = id, moduleName = name)
}
}
val prefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
WebView.setWebContentsDebuggingEnabled(prefs.getBoolean("enable_web_debugging", false))
val webRoot = File("/data/adb/modules/${moduleId}/webroot")
val webViewAssetLoader = WebViewAssetLoader.Builder()
.setDomain("mui.kernelsu.org")
.addPathHandler(
"/",
SuFilePathHandler(this, webRoot)
)
.build()
val webViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
return webViewAssetLoader.shouldInterceptRequest(request.url)
}
}
val webView = WebView(this).apply {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
settings.allowFileAccess = false
webviewInterface = WebViewInterface(this@WebUIActivity, this)
addJavascriptInterface(webviewInterface, "ksu")
setWebViewClient(webViewClient)
loadUrl("https://mui.kernelsu.org/index.html")
}
setContentView(webView)
}
}

View File

@ -21,10 +21,6 @@ import java.util.concurrent.CompletableFuture
class WebViewInterface(val context: Context, private val webView: WebView) {
companion object {
var isHideSystemUI: Boolean = false
}
@JavascriptInterface
fun exec(cmd: String): String {
val shell = createRootShell(true)
@ -167,7 +163,6 @@ class WebViewInterface(val context: Context, private val webView: WebView) {
} else {
showSystemUI(context.window)
}
isHideSystemUI = enable
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.KernelSU" parent="android:Theme.Material.NoActionBar">
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
</resources>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.KernelSU" parent="android:Theme.Material.NoActionBar">
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<style name="Theme.KernelSU" parent="android:Theme.Material.NoActionBar" />
<style name="Theme.KernelSU.WebUI" parent="Theme.KernelSU">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">false</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.KernelSU" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
</resources>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.KernelSU" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<style name="Theme.KernelSU" parent="android:Theme.Material.Light.NoActionBar" />
<style name="Theme.KernelSU.WebUI" parent="Theme.KernelSU">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>
</style>
</resources>