diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/MainActivity.kt b/app/src/main/java/com/github/capntrips/kernelflasher/MainActivity.kt index 82b668e..286ef1a 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/MainActivity.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/MainActivity.kt @@ -66,6 +66,7 @@ class MainActivity : ComponentActivity() { private var rootServiceConnected: Boolean = false private var viewModel: MainViewModel? = null + private var isAb: Boolean? = null private lateinit var mainListener: MainListener var isAwaitingResult = false @@ -140,7 +141,7 @@ class MainActivity : ComponentActivity() { content.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { - return if (viewModel?.isRefreshing == false || Shell.isAppGrantedRoot() == false) { + return if (viewModel?.isRefreshing == false || isAb == false || Shell.isAppGrantedRoot() == false) { content.viewTreeObserver.removeOnPreDrawListener(this) true } else { @@ -152,8 +153,17 @@ class MainActivity : ComponentActivity() { Shell.getShell() if (Shell.isAppGrantedRoot()!!) { - val intent = Intent(this, FilesystemService::class.java) - RootService.bind(intent, AidlConnection()) + isAb = Shell.cmd("getprop ro.build.ab_update").exec().out[0] == "true" + if (isAb!!) { + val intent = Intent(this, FilesystemService::class.java) + RootService.bind(intent, AidlConnection()) + } else { + setContent { + KernelFlasherTheme { + ErrorScreen(stringResource(R.string.non_ab_unsupported)) + } + } + } } else { setContent { KernelFlasherTheme { diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataRow.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataRow.kt index 1e8af9f..2e4a004 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataRow.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataRow.kt @@ -1,23 +1,18 @@ package com.github.capntrips.kernelflasher.ui.components -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width -import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.layout import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp @Composable @@ -54,24 +49,6 @@ fun DataRow( style = labelStyle ) Spacer(Modifier.width(8.dp)) - SelectionContainer(Modifier.alignByBaseline()) { - var clicked by remember { mutableStateOf(false)} - val modifier = if (clickable) { - Modifier - .clickable { clicked = !clicked } - .alignByBaseline() - } else { - Modifier - .alignByBaseline() - } - Text( - modifier = modifier, - text = value, - color = valueColor, - style = valueStyle, - maxLines = if (clicked) Int.MAX_VALUE else 1, - overflow = if (clicked) TextOverflow.Visible else TextOverflow.Ellipsis - ) - } + DataValue(value, valueColor, valueStyle, clickable) } } diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataValue.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataValue.kt new file mode 100644 index 0000000..792ab95 --- /dev/null +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/DataValue.kt @@ -0,0 +1,44 @@ +package com.github.capntrips.kernelflasher.ui.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow + +@Composable +fun RowScope.DataValue( + value: String, + color: Color = Color.Unspecified, + style: TextStyle = MaterialTheme.typography.titleSmall, + clickable: Boolean = false, +) { + SelectionContainer(Modifier.alignByBaseline()) { + var clicked by remember { mutableStateOf(false) } + val modifier = if (clickable) { + Modifier + .clickable { clicked = !clicked } + .alignByBaseline() + } else { + Modifier + .alignByBaseline() + } + Text( + modifier = modifier, + text = value, + color = color, + style = style, + maxLines = if (clicked) Int.MAX_VALUE else 1, + overflow = if (clicked) TextOverflow.Visible else TextOverflow.Ellipsis + ) + } +} diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/SlotCard.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/SlotCard.kt index 7dfeddf..2752a22 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/SlotCard.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/components/SlotCard.kt @@ -1,6 +1,7 @@ package com.github.capntrips.kernelflasher.ui.components import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Row import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable @@ -25,7 +26,7 @@ fun SlotCard( DataCard ( title = title, button = { - if (!isSlotScreen) { + if (!isSlotScreen && !viewModel.hasError) { AnimatedVisibility(!viewModel.isRefreshing) { ViewButton { navController.navigate("slot${viewModel.slotSuffix}") @@ -35,33 +36,44 @@ fun SlotCard( } ) { val cardWidth = remember { mutableIntStateOf(0) } - DataRow( - label = stringResource(R.string.boot_sha1), - value = viewModel.sha1.substring(0, 8), - valueStyle = MaterialTheme.typography.titleSmall.copy( - fontFamily = FontFamily.Monospace, - fontWeight = FontWeight.Medium - ), - mutableMaxWidth = cardWidth - ) - AnimatedVisibility(!viewModel.isRefreshing && viewModel.kernelVersion != null) { + if (!viewModel.hasError) { DataRow( - label = stringResource(R.string.kernel_version), - value = if (viewModel.kernelVersion != null) viewModel.kernelVersion!! else "", - mutableMaxWidth = cardWidth, - clickable = true + label = stringResource(R.string.boot_sha1), + value = viewModel.sha1.substring(0, 8), + valueStyle = MaterialTheme.typography.titleSmall.copy( + fontFamily = FontFamily.Monospace, + fontWeight = FontWeight.Medium + ), + mutableMaxWidth = cardWidth ) - } - if (showDlkm && viewModel.hasVendorDlkm) { - var vendorDlkmValue = stringResource(R.string.not_found) - if (viewModel.isVendorDlkmMapped) { - vendorDlkmValue = if (viewModel.isVendorDlkmMounted) { - String.format("%s, %s", stringResource(R.string.exists), stringResource(R.string.mounted)) - } else { - String.format("%s, %s", stringResource(R.string.exists), stringResource(R.string.unmounted)) + AnimatedVisibility(!viewModel.isRefreshing && viewModel.kernelVersion != null) { + DataRow( + label = stringResource(R.string.kernel_version), + value = if (viewModel.kernelVersion != null) viewModel.kernelVersion!! else "", + mutableMaxWidth = cardWidth, + clickable = true + ) + } + if (showDlkm && viewModel.hasVendorDlkm) { + var vendorDlkmValue = stringResource(R.string.not_found) + if (viewModel.isVendorDlkmMapped) { + vendorDlkmValue = if (viewModel.isVendorDlkmMounted) { + String.format("%s, %s", stringResource(R.string.exists), stringResource(R.string.mounted)) + } else { + String.format("%s, %s", stringResource(R.string.exists), stringResource(R.string.unmounted)) + } } + DataRow(stringResource(R.string.vendor_dlkm), vendorDlkmValue, mutableMaxWidth = cardWidth) + } + } else { + Row { + DataValue( + value = viewModel.error, + color = MaterialTheme.colorScheme.error, + style = MaterialTheme.typography.titleSmall, + clickable = true + ) } - DataRow(stringResource(R.string.vendor_dlkm), vendorDlkmValue, mutableMaxWidth = cardWidth) } } } diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/main/MainViewModel.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/main/MainViewModel.kt index 4c00a0b..20c495a 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/main/MainViewModel.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/main/MainViewModel.kt @@ -67,11 +67,11 @@ class MainViewModel( updates = UpdatesViewModel(context, fileSystemManager, navController, _isRefreshing) reboot = RebootViewModel(context, fileSystemManager, navController, _isRefreshing) slotA = SlotViewModel(context, fileSystemManager, navController, _isRefreshing, slotSuffix == "_a", "_a", bootA, initBootA, _backups) - if (slotA.hasError) { + if (slotA.hasError && slotSuffix == "_a") { _error = slotA.error } slotB = SlotViewModel(context, fileSystemManager, navController, _isRefreshing, slotSuffix == "_b", "_b", bootB, initBootB, _backups) - if (slotB.hasError) { + if (slotB.hasError && slotSuffix == "_b") { _error = slotB.error } diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt index b4de9f4..3a636cb 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt @@ -88,6 +88,10 @@ class SlotViewModel( } fun refresh(context: Context) { + if (!isActive) { + inInit = true + } + val magiskboot = File(context.filesDir, "magiskboot") Shell.cmd("$magiskboot unpack $boot").exec() if (initBoot != null) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8c9ab15..83eb694 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,6 +2,7 @@ Kernel Flasher Root is required Root service disconnected + Non-AB devices are not supported Device Model Build Number