manager: remake home page

This commit is contained in:
tiann
2023-04-20 13:52:56 +08:00
parent 609ea40d1c
commit 2f6df20085
5 changed files with 114 additions and 41 deletions

View File

@@ -1,7 +1,5 @@
package me.weishu.kernelsu.ui.screen
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Build
import android.os.PowerManager
@@ -30,14 +28,10 @@ import androidx.compose.ui.unit.dp
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.launch
import me.weishu.kernelsu.*
import me.weishu.kernelsu.R
import me.weishu.kernelsu.ui.screen.destinations.SettingScreenDestination
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
import me.weishu.kernelsu.ui.util.reboot
import me.weishu.kernelsu.ui.util.getSELinuxStatus
import me.weishu.kernelsu.ui.util.install
import me.weishu.kernelsu.ui.util.*
@OptIn(ExperimentalMaterial3Api::class)
@RootNavGraph(start = true)
@@ -67,6 +61,8 @@ fun HomeScreen(navigator: DestinationsNavigator) {
StatusCard(kernelVersion, ksuVersion)
InfoCard()
DonateCard()
AboutCard()
Spacer(Modifier)
}
}
@@ -102,7 +98,8 @@ private fun TopBar(onSettingsClick: () -> Unit) {
RebootDropdownItem(id = R.string.reboot)
val pm = LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager?
val pm =
LocalContext.current.getSystemService(Context.POWER_SERVICE) as PowerManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && pm?.isRebootingUserspaceSupported == true) {
RebootDropdownItem(id = R.string.reboot_userspace, reason = "userspace")
}
@@ -161,6 +158,16 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) {
text = stringResource(R.string.home_working_version, ksuVersion),
style = MaterialTheme.typography.bodyMedium
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.home_superuser_count, getSuperuserCount()),
style = MaterialTheme.typography.bodyMedium
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.home_module_count, getModuleCount()),
style = MaterialTheme.typography.bodyMedium
)
}
}
kernelVersion.isGKI() -> {
@@ -197,11 +204,69 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?) {
}
}
@Composable
fun AboutCard() {
val uriHandler = LocalUriHandler.current
ElevatedCard {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
uriHandler.openUri("https://kernelsu.org/guide/what-is-kernelsu.html")
}
.padding(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column() {
Text(
text = stringResource(R.string.home_learn_kernelsu),
style = MaterialTheme.typography.titleSmall
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.home_click_to_learn_kernelsu),
style = MaterialTheme.typography.bodyMedium
)
}
}
}
}
@Composable
fun DonateCard() {
val uriHandler = LocalUriHandler.current
ElevatedCard {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
uriHandler.openUri("https://patreon.com/weishu")
}
.padding(24.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column() {
Text(
text = stringResource(R.string.home_support_title),
style = MaterialTheme.typography.titleSmall
)
Spacer(Modifier.height(4.dp))
Text(
text = stringResource(R.string.home_support_content),
style = MaterialTheme.typography.bodyMedium
)
}
}
}
}
@Composable
private fun InfoCard() {
val context = LocalContext.current
val snackbarHost = LocalSnackbarHost.current
val scope = rememberCoroutineScope()
ElevatedCard {
Column(
@@ -221,39 +286,19 @@ private fun InfoCard() {
InfoCardItem(stringResource(R.string.home_kernel), uname.release)
Spacer(Modifier.height(24.dp))
Spacer(Modifier.height(16.dp))
InfoCardItem(stringResource(R.string.home_manager_version), getManagerVersion(context))
Spacer(Modifier.height(24.dp))
InfoCardItem(stringResource(R.string.home_api), Build.VERSION.SDK_INT.toString())
Spacer(Modifier.height(24.dp))
InfoCardItem(stringResource(R.string.home_abi), Build.SUPPORTED_ABIS.joinToString(", "))
Spacer(Modifier.height(24.dp))
Spacer(Modifier.height(16.dp))
InfoCardItem(stringResource(R.string.home_fingerprint), Build.FINGERPRINT)
Spacer(Modifier.height(24.dp))
InfoCardItem(stringResource(R.string.home_securitypatch), Build.VERSION.SECURITY_PATCH)
Spacer(Modifier.height(24.dp))
Spacer(Modifier.height(16.dp))
InfoCardItem(stringResource(R.string.home_selinux_status), getSELinuxStatus())
val copiedMessage = stringResource(R.string.home_copied_to_clipboard)
TextButton(
modifier = Modifier.align(Alignment.End),
onClick = {
val cm = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
cm.setPrimaryClip(ClipData.newPlainText("KernelSU", contents.toString()))
scope.launch { snackbarHost.showSnackbar(copiedMessage) }
},
content = { Text(stringResource(android.R.string.copy)) }
)
}
}
}
fun getManagerVersion(context: Context) : String {
fun getManagerVersion(context: Context): String {
val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
return "${packageInfo.versionName} (${packageInfo.versionCode})"
}

View File

@@ -7,7 +7,10 @@ import com.topjohnwu.superuser.CallbackList
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ShellUtils
import me.weishu.kernelsu.BuildConfig
import me.weishu.kernelsu.Natives
import me.weishu.kernelsu.ksuApp
import me.weishu.kernelsu.ui.viewmodel.ModuleViewModel
import org.json.JSONArray
import java.io.File
@@ -54,10 +57,23 @@ fun install() {
fun listModules(): String {
val shell = getRootShell()
val out = shell.newJob().add("${getKsuDaemonPath()} module list").to(ArrayList(), null).exec().out
val out =
shell.newJob().add("${getKsuDaemonPath()} module list").to(ArrayList(), null).exec().out
return out.joinToString("\n").ifBlank { "[]" }
}
fun getModuleCount(): Int {
val result = listModules()
runCatching {
val array = JSONArray(result)
return array.length()
}.getOrElse { return 0 }
}
fun getSuperuserCount(): Int {
return Natives.getAllowList().size
}
fun toggleModule(id: String, enable: Boolean): Boolean {
val cmd = if (enable) {
"module enable $id"
@@ -69,14 +85,14 @@ fun toggleModule(id: String, enable: Boolean): Boolean {
return result
}
fun uninstallModule(id: String) : Boolean {
fun uninstallModule(id: String): Boolean {
val cmd = "module uninstall $id"
val result = execKsud(cmd)
Log.i(TAG, "uninstall module $id result: $result")
return result
}
fun installModule(uri: Uri, onFinish: (Boolean)->Unit, onOutput: (String) -> Unit) : Boolean {
fun installModule(uri: Uri, onFinish: (Boolean) -> Unit, onOutput: (String) -> Unit): Boolean {
val resolver = ksuApp.contentResolver
with(resolver.openInputStream(uri)) {
val file = File(ksuApp.cacheDir, "module.zip")
@@ -93,7 +109,8 @@ fun installModule(uri: Uri, onFinish: (Boolean)->Unit, onOutput: (String) -> Uni
}
}
val result = shell.newJob().add("${getKsuDaemonPath()} $cmd").to(callbackList, callbackList).exec()
val result =
shell.newJob().add("${getKsuDaemonPath()} $cmd").to(callbackList, callbackList).exec()
Log.i("KernelSU", "install module $uri result: $result")
file.delete()

View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name" translatable="false">KernelSU</string>
<string name="home">ホーム</string>
<string name="home">ホーム</string>
<string name="home_not_installed">未インストール</string>
<string name="home_click_to_install">タップでインストール</string>
<string name="home_working">動作中</string>
@@ -40,6 +39,7 @@
<string name="reboot_edl">EDLで再起動</string>
<string name="about">アプリについて</string>
<string name="require_kernel_version_8">KernelSU バージョン8以降が必要です</string>
<string name="module_uninstall_confirm">モジュール %s をアンインストールしますか?</string>
<string name="module_uninstall_success">%sをアンインストールしました</string>
<string name="module_uninstall_failed">アンインストールに失敗: %s</string>
<string name="module_version">バージョン</string>

View File

@@ -5,6 +5,7 @@
<string name="home_click_to_install">点击安装</string>
<string name="home_working">工作中</string>
<string name="home_working_version">版本: %d</string>
<string name="home_superuser_count">超级用户数:%d</string>
<string name="home_unsupported">不支持</string>
<string name="home_unsupported_reason">KernelSU 现在只支持 GKI 内核</string>
<string name="home_copied_to_clipboard">已复制到剪贴板</string>
@@ -53,4 +54,9 @@
<string name="safe_mode">安全模式</string>
<string name="reboot_to_apply">重启生效</string>
<string name="module_magisk_conflict">所有模块已被禁用,因为它与 Magisk 的模块系统有冲突!</string>
<string name="home_module_count">模块数:%d</string>
<string name="home_learn_kernelsu">了解 KernelSU</string>
<string name="home_click_to_learn_kernelsu">了解如何安装 KernelSU 以及如何开发模块</string>
<string name="home_support_title">支持开发</string>
<string name="home_support_content">KernelSU 将保持免费和开源,向开发者捐赠以表示支持。</string>
</resources>

View File

@@ -6,6 +6,8 @@
<string name="home_click_to_install">Click to install</string>
<string name="home_working">Working</string>
<string name="home_working_version">Version: %d</string>
<string name="home_superuser_count">Superusers: %d</string>
<string name="home_module_count">Modules: %d</string>
<string name="home_unsupported">Unsupported</string>
<string name="home_unsupported_reason">KernelSU only supports GKI kernels now</string>
<string name="home_copied_to_clipboard">Copied to clipboard</string>
@@ -57,5 +59,8 @@
<string name="safe_mode">Safe mode</string>
<string name="reboot_to_apply">Reboot to take effect</string>
<string name="module_magisk_conflict">Modules are disabled because it is conflict with Magisk\'s!</string>
<string name="home_learn_kernelsu">Learn KernelSU</string>
<string name="home_click_to_learn_kernelsu">Learn how to install KernelSU and use modules</string>
<string name="home_support_title">Support Us</string>
<string name="home_support_content">KernelSU is, and always will be, free, and open source. You can however show us that you care by making a donation.</string>
</resources>