From 2f6df20085399af852b8f698aa98f7aa3ef78c99 Mon Sep 17 00:00:00 2001 From: tiann Date: Thu, 20 Apr 2023 13:52:56 +0800 Subject: [PATCH] manager: remake home page --- .../java/me/weishu/kernelsu/ui/screen/Home.kt | 113 ++++++++++++------ .../java/me/weishu/kernelsu/ui/util/KsuCli.kt | 25 +++- .../app/src/main/res/values-ja/strings.xml | 4 +- .../src/main/res/values-zh-rCN/strings.xml | 6 + manager/app/src/main/res/values/strings.xml | 7 +- 5 files changed, 114 insertions(+), 41 deletions(-) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt index d8059668..87833160 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Home.kt @@ -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})" } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt index bb17a037..4cf9bc0b 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/KsuCli.kt @@ -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() diff --git a/manager/app/src/main/res/values-ja/strings.xml b/manager/app/src/main/res/values-ja/strings.xml index bfe1c1d2..e6d0abc7 100644 --- a/manager/app/src/main/res/values-ja/strings.xml +++ b/manager/app/src/main/res/values-ja/strings.xml @@ -1,7 +1,6 @@ - KernelSU - ホーム + ホーム 未インストール タップでインストール 動作中 @@ -40,6 +39,7 @@ EDLで再起動 アプリについて KernelSU バージョン8以降が必要です + モジュール %s をアンインストールしますか? %sをアンインストールしました アンインストールに失敗: %s バージョン diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 4db2282e..c12c9de8 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -5,6 +5,7 @@ 点击安装 工作中 版本: %d + 超级用户数:%d 不支持 KernelSU 现在只支持 GKI 内核 已复制到剪贴板 @@ -53,4 +54,9 @@ 安全模式 重启生效 所有模块已被禁用,因为它与 Magisk 的模块系统有冲突! + 模块数:%d + 了解 KernelSU + 了解如何安装 KernelSU 以及如何开发模块 + 支持开发 + KernelSU 将保持免费和开源,向开发者捐赠以表示支持。 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index ac4c4f8d..3e652f4f 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -6,6 +6,8 @@ Click to install Working Version: %d + Superusers: %d + Modules: %d Unsupported KernelSU only supports GKI kernels now Copied to clipboard @@ -57,5 +59,8 @@ Safe mode Reboot to take effect Modules are disabled because it is conflict with Magisk\'s! - + Learn KernelSU + Learn how to install KernelSU and use modules + Support Us + KernelSU is, and always will be, free, and open source. You can however show us that you care by making a donation.