diff --git a/manager/app/src/main/cpp/jni.cc b/manager/app/src/main/cpp/jni.cc index 4abcc8cc..b0d28698 100644 --- a/manager/app/src/main/cpp/jni.cc +++ b/manager/app/src/main/cpp/jni.cc @@ -46,6 +46,12 @@ Java_me_weishu_kernelsu_Natives_isSafeMode(JNIEnv *env, jclass clazz) { return is_safe_mode(); } +extern "C" +JNIEXPORT jboolean JNICALL +Java_me_weishu_kernelsu_Natives_isLkmMode(JNIEnv *env, jclass clazz) { + return is_lkm_mode(); +} + static void fillIntArray(JNIEnv *env, jobject list, int *data, int count) { auto cls = env->GetObjectClass(list); auto add = env->GetMethodID(cls, "add", "(Ljava/lang/Object;)Z"); diff --git a/manager/app/src/main/cpp/ksu.cc b/manager/app/src/main/cpp/ksu.cc index 1ad43763..1e798189 100644 --- a/manager/app/src/main/cpp/ksu.cc +++ b/manager/app/src/main/cpp/ksu.cc @@ -47,10 +47,14 @@ bool become_manager(const char* pkg) { return ksuctl(CMD_BECOME_MANAGER, param, nullptr); } +// cache the result to avoid unnecessary syscall +static bool is_lkm; int get_version() { int32_t version = -1; - if (ksuctl(CMD_GET_VERSION, &version, nullptr)) { - return version; + int32_t lkm = 0; + ksuctl(CMD_GET_VERSION, &version, &lkm); + if (!is_lkm && lkm != 0) { + is_lkm = true; } return version; } @@ -63,6 +67,11 @@ bool is_safe_mode() { return ksuctl(CMD_CHECK_SAFEMODE, nullptr, nullptr); } +bool is_lkm_mode() { + // you should call get_version first! + return is_lkm; +} + bool uid_should_umount(int uid) { bool should; return ksuctl(CMD_IS_UID_SHOULD_UMOUNT, reinterpret_cast(uid), &should) && should; diff --git a/manager/app/src/main/cpp/ksu.h b/manager/app/src/main/cpp/ksu.h index 8f9c4c0b..160a9d6f 100644 --- a/manager/app/src/main/cpp/ksu.h +++ b/manager/app/src/main/cpp/ksu.h @@ -17,6 +17,8 @@ bool uid_should_umount(int uid); bool is_safe_mode(); +bool is_lkm_mode(); + #define KSU_APP_PROFILE_VER 2 #define KSU_MAX_PACKAGE_NAME 256 // NGROUPS_MAX for Linux is 65535 generally, but we only supports 32 groups. diff --git a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt index 1ca552c6..6360d558 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/Natives.kt @@ -18,6 +18,9 @@ object Natives { // 11071: Fix the issue of failing to set a custom SELinux type. const val MINIMAL_SUPPORTED_KERNEL = 11071 + // 11640: Support query working mode, LKM or GKI + // when MINIMAL_SUPPORTED_KERNEL > 11640, we can remove this constant. + const val MINIMAL_SUPPORTED_KERNEL_LKM = 11640 const val KERNEL_SU_DOMAIN = "u:r:su:s0" const val ROOT_UID = 0 @@ -39,6 +42,9 @@ object Natives { val isSafeMode: Boolean external get + val isLkmMode: Boolean + external get + external fun uidShouldUmount(uid: Int): Boolean /** 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 fafed693..9caeb0a1 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 @@ -64,8 +64,12 @@ fun HomeScreen(navigator: DestinationsNavigator) { if (isManager) install() } val ksuVersion = if (isManager) Natives.version else null + val lkmMode = + ksuVersion?.let { + if (it >= Natives.MINIMAL_SUPPORTED_KERNEL_LKM) Natives.isLkmMode else null + } - StatusCard(kernelVersion, ksuVersion) { + StatusCard(kernelVersion, ksuVersion, lkmMode) { navigator.navigate(InstallScreenDestination) } if (isManager && Natives.requireNewKernel()) { @@ -142,7 +146,11 @@ fun RebootDropdownItem(@StringRes id: Int, reason: String = "") { @OptIn(ExperimentalMaterial3Api::class) @Composable -private fun TopBar(kernelVersion: KernelVersion, onInstallClick: () -> Unit, onSettingsClick: () -> Unit) { +private fun TopBar( + kernelVersion: KernelVersion, + onInstallClick: () -> Unit, + onSettingsClick: () -> Unit +) { TopAppBar(title = { Text(stringResource(R.string.app_name)) }, actions = { if (kernelVersion.isGKI()) { IconButton(onClick = onInstallClick) { @@ -190,14 +198,18 @@ private fun TopBar(kernelVersion: KernelVersion, onInstallClick: () -> Unit, onS } @Composable -private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?, onClickInstall: () -> Unit = {}) { +private fun StatusCard( + kernelVersion: KernelVersion, + ksuVersion: Int?, + lkmMode: Boolean?, + onClickInstall: () -> Unit = {} +) { ElevatedCard( colors = CardDefaults.elevatedCardColors(containerColor = run { if (ksuVersion != null) MaterialTheme.colorScheme.secondaryContainer else MaterialTheme.colorScheme.errorContainer }) ) { - val uriHandler = LocalUriHandler.current Row(modifier = Modifier .fillMaxWidth() .clickable { @@ -208,15 +220,24 @@ private fun StatusCard(kernelVersion: KernelVersion, ksuVersion: Int?, onClickIn .padding(24.dp), verticalAlignment = Alignment.CenterVertically) { when { ksuVersion != null -> { - val appendText = if (Natives.isSafeMode) { - " [${stringResource(id = R.string.safe_mode)}]" - } else { - "" + val safeMode = when { + Natives.isSafeMode -> " [${stringResource(id = R.string.safe_mode)}]" + else -> "" } + + val workingMode = when (lkmMode) { + null -> "" + true -> " " + else -> " " + } + + val workingText = + "${stringResource(id = R.string.home_working)}$workingMode$safeMode" + Icon(Icons.Outlined.CheckCircle, stringResource(R.string.home_working)) Column(Modifier.padding(start = 20.dp)) { Text( - text = stringResource(R.string.home_working) + appendText, + text = workingText, style = MaterialTheme.typography.titleMedium ) Spacer(Modifier.height(4.dp)) @@ -396,9 +417,10 @@ fun getManagerVersion(context: Context): Pair { @Composable private fun StatusCardPreview() { Column { - StatusCard(KernelVersion(5, 10, 101), 1) - StatusCard(KernelVersion(5, 10, 101), null) - StatusCard(KernelVersion(4, 10, 101), null) + StatusCard(KernelVersion(5, 10, 101), 1, null) + StatusCard(KernelVersion(5, 10, 101), 20000, true) + StatusCard(KernelVersion(5, 10, 101), null, true) + StatusCard(KernelVersion(4, 10, 101), null, false) } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/LogEvent.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/LogEvent.kt index 4aa9ff6e..913b7062 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/util/LogEvent.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/util/LogEvent.kt @@ -86,6 +86,8 @@ fun getBugreportFile(context: Context): File { pw.println("KernelSU: $ksuKernel") val safeMode = Natives.isSafeMode pw.println("SafeMode: $safeMode") + val lkmMode = Natives.isLkmMode + pw.println("LKM: $lkmMode") } // modules