diff --git a/manager/.idea/vcs.xml b/manager/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/manager/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/manager/app/build.gradle b/manager/app/build.gradle index a55943f1..a289dca7 100644 --- a/manager/app/build.gradle +++ b/manager/app/build.gradle @@ -9,10 +9,10 @@ android { defaultConfig { applicationId "me.weishu.kernelsu" - minSdk 31 + minSdk 26 targetSdk 32 - versionCode 1 - versionName "1.0" + versionCode 10000 + versionName "0.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -27,7 +27,7 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -61,16 +61,17 @@ dependencies { implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' - implementation 'androidx.activity:activity-compose:1.6.0' + implementation 'androidx.activity:activity-compose:1.6.1' implementation "androidx.compose.ui:ui:$compose_ui_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version" - implementation 'androidx.compose.material:material:1.3.1' + + implementation "androidx.compose.material3:material3:1.0.1" + implementation "androidx.compose.material3:material3-window-size-class:1.0.1" def nav_version = "2.5.3" implementation "androidx.navigation:navigation-compose:$nav_version" implementation "com.google.accompanist:accompanist-drawablepainter:0.28.0" - implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1" diff --git a/manager/app/src/main/java/me/weishu/kernelsu/HyperlinkText.kt b/manager/app/src/main/java/me/weishu/kernelsu/HyperlinkText.kt index 789956ec..a004c2ec 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/HyperlinkText.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/HyperlinkText.kt @@ -1,73 +1,91 @@ package me.weishu.kernelsu -import androidx.compose.foundation.text.ClickableText +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.TextLayoutResult import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.unit.TextUnit +import java.util.regex.Pattern @Composable -fun HyperlinkText( - modifier: Modifier = Modifier, - fullText: String, - hyperLinks: Map, - textStyle: TextStyle = TextStyle.Default, - linkTextColor: Color = Color.Blue, - linkTextFontWeight: FontWeight = FontWeight.Normal, - linkTextDecoration: TextDecoration = TextDecoration.None, - fontSize: TextUnit = TextUnit.Unspecified -) { +fun LinkifyText(text: String, modifier: Modifier = Modifier) { + val uriHandler = LocalUriHandler.current + val layoutResult = remember { + mutableStateOf(null) + } + val linksList = extractUrls(text) val annotatedString = buildAnnotatedString { - append(fullText) - - for((key, value) in hyperLinks){ - - val startIndex = fullText.indexOf(key) - val endIndex = startIndex + key.length + append(text) + linksList.forEach { addStyle( style = SpanStyle( - color = linkTextColor, - fontSize = fontSize, - fontWeight = linkTextFontWeight, - textDecoration = linkTextDecoration + color = Color.Companion.Blue, + textDecoration = TextDecoration.Underline ), - start = startIndex, - end = endIndex + start = it.start, + end = it.end ) addStringAnnotation( tag = "URL", - annotation = value, - start = startIndex, - end = endIndex + annotation = it.url, + start = it.start, + end = it.end ) } - addStyle( - style = SpanStyle( - fontSize = fontSize - ), - start = 0, - end = fullText.length - ) } - - val uriHandler = LocalUriHandler.current - - ClickableText( - modifier = modifier, - text = annotatedString, - style = textStyle, - onClick = { - annotatedString - .getStringAnnotations("URL", it, it) - .firstOrNull()?.let { stringAnnotation -> - uriHandler.openUri(stringAnnotation.item) - } + Text(text = annotatedString, modifier = modifier.pointerInput(Unit) { + detectTapGestures { offsetPosition -> + layoutResult.value?.let { + val position = it.getOffsetForPosition(offsetPosition) + annotatedString.getStringAnnotations(position, position).firstOrNull() + ?.let { result -> + if (result.tag == "URL") { + uriHandler.openUri(result.item) + } + } + } } + }, + onTextLayout = { layoutResult.value = it } ) -} \ No newline at end of file +} + +private val urlPattern: Pattern = Pattern.compile( + "(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)" + + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*" + + "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)", + Pattern.CASE_INSENSITIVE or Pattern.MULTILINE or Pattern.DOTALL +) + +fun extractUrls(text: String): List { + val matcher = urlPattern.matcher(text) + var matchStart: Int + var matchEnd: Int + val links = arrayListOf() + + while (matcher.find()) { + matchStart = matcher.start(1) + matchEnd = matcher.end() + + var url = text.substring(matchStart, matchEnd) + if (!url.startsWith("http://") && !url.startsWith("https://")) + url = "https://$url" + + links.add(LinkInfos(url, matchStart, matchEnd)) + } + return links +} + +data class LinkInfos( + val url: String, + val start: Int, + val end: Int +) \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/MainActivity.kt b/manager/app/src/main/java/me/weishu/kernelsu/MainActivity.kt index ff6355bf..a89ff063 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/MainActivity.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/MainActivity.kt @@ -1,31 +1,29 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + package me.weishu.kernelsu import AboutDialog import Home import Module import SuperUser -import SuperUserData import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.annotation.StringRes -import androidx.compose.foundation.layout.* -import androidx.compose.material.* +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Color.Companion.Gray -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState @@ -35,14 +33,14 @@ import me.weishu.kernelsu.ui.theme.KernelSUTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setContent { KernelSUTheme { - // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colors.background + color = MaterialTheme.colorScheme.background ) { - Greeting() + MainScreen() } } } @@ -50,7 +48,68 @@ class MainActivity : ComponentActivity() { } @Composable -fun Greeting() { +fun MainTopAppBar(onMoreClick: () -> Unit) { + TopAppBar( + title = { + Text( + "KernelSU", + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + }, + actions = { + IconButton(onClick = onMoreClick) { + Icon( + imageVector = Icons.Filled.MoreVert, + contentDescription = "Localized description" + ) + } + } + ) +} + +@Composable +fun MainBottomNavigation(items: List, navController: NavHostController) { + + NavigationBar { + + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + + items.forEachIndexed { index, item -> + NavigationBarItem( + icon = { + Icon( + painter = painterResource(id = item.icon), + contentDescription = "" + ) + }, + label = { Text(text = stringResource(id = item.resourceId)) }, + selected = currentDestination?.hierarchy?.any { it.route == item.route } == true, + + onClick = { + navController.navigate(item.route) { + // Pop up to the start destination of the graph to + // avoid building up a large stack of destinations + // on the back stack as users select items + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + // Avoid multiple copies of the same destination when + // reselecting the same item + launchSingleTop = true + // Restore state when reselecting a previously selected item + restoreState = true + } + } + ) + } + } + +} + +@Composable +fun MainScreen() { val items = listOf( Screen.Home, @@ -68,68 +127,25 @@ fun Greeting() { Scaffold( topBar = { - TopAppBar( - title = { - Text(text = "KernelSU") - }, - backgroundColor = MaterialTheme.colors.primary, - contentColor = Color.White, - elevation = 12.dp, - actions = { - IconButton(onClick = { /*TODO*/ }) { - Icon(Icons.Filled.Search, contentDescription = "Search") - } - IconButton(onClick = { - showAboutDialog = true - }) { - Icon(Icons.Filled.MoreVert, contentDescription = "More") - } - } - ) + MainTopAppBar { + showAboutDialog = true + } }, bottomBar = { - BottomNavigation( - backgroundColor = MaterialTheme.colors.background, + MainBottomNavigation(items = items, navController = navController) + }, + content = { innerPadding -> + NavHost( + navController, + startDestination = Screen.Home.route, + Modifier.padding(innerPadding) ) { - val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentDestination = navBackStackEntry?.destination - items.forEach { screen -> - BottomNavigationItem( - icon = { Icon(painterResource(id = screen.icon), null) }, - label = { Text(stringResource(screen.resourceId)) }, - selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true, - selectedContentColor = MaterialTheme.colors.primary, - unselectedContentColor = MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.medium), - onClick = { - navController.navigate(screen.route) { - // Pop up to the start destination of the graph to - // avoid building up a large stack of destinations - // on the back stack as users select items - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - // Avoid multiple copies of the same destination when - // reselecting the same item - launchSingleTop = true - // Restore state when reselecting a previously selected item - restoreState = true - } - } - ) - } + composable(Screen.Home.route) { Home() } + composable(Screen.SuperUser.route) { SuperUser() } + composable(Screen.Module.route) { Module() } } } - ) { innerPadding -> - NavHost( - navController, - startDestination = Screen.Home.route, - Modifier.padding(innerPadding) - ) { - composable(Screen.Home.route) { Home() } - composable(Screen.SuperUser.route) { SuperUser() } - composable(Screen.Module.route) { Module() } - } - } + ) } @@ -137,13 +153,13 @@ fun Greeting() { @Composable fun DefaultPreview() { KernelSUTheme { - Greeting() + MainScreen() } } sealed class Screen(val route: String, @StringRes val resourceId: Int, val icon: Int) { object Home : Screen("home", R.string.home, R.drawable.ic_home) object SuperUser : Screen("superuser", R.string.superuser, R.drawable.ic_superuser) - object Module: Screen("module", R.string.module, R.drawable.ic_module) + object Module : Screen("module", R.string.module, R.drawable.ic_module) } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AboutDialog.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AboutDialog.kt index 89aecae9..ddf43e1c 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AboutDialog.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AboutDialog.kt @@ -1,86 +1,70 @@ +import android.text.method.LinkMovementMethod +import android.text.util.Linkify +import android.util.Patterns +import android.widget.TextView import androidx.compose.foundation.layout.Column -import androidx.compose.material.AlertDialog -import androidx.compose.material.Button -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign -import me.weishu.kernelsu.HyperlinkText +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.text.util.LinkifyCompat +import me.weishu.kernelsu.LinkifyText +@Composable +fun DefaultLinkifyText(modifier: Modifier = Modifier, text: String?) { + val context = LocalContext.current + val customLinkifyTextView = remember { + TextView(context) + } + AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView -> + textView.text = text ?: "" + LinkifyCompat.addLinks(textView, Linkify.ALL) + Linkify.addLinks(textView, Patterns.PHONE,"tel:", + Linkify.sPhoneNumberMatchFilter, Linkify.sPhoneNumberTransformFilter) + textView.movementMethod = LinkMovementMethod.getInstance() + } +} @Composable fun AboutDialog(openDialog: Boolean, onDismiss: () -> Unit) { - if (openDialog) { - AlertDialog( - onDismissRequest = { - onDismiss() - }, - title = { - Text(text = "About") - }, - text = { - Column { - - HyperlinkText( - fullText = "Author: weishu", - hyperLinks = mutableMapOf( - "weishu" to "https://github.com/tiann", - ), - textStyle = TextStyle( - textAlign = TextAlign.Center, - color = Color.Gray - ), - linkTextColor = MaterialTheme.colors.secondary, - ) - - HyperlinkText( - fullText = "Github: https://github.com/tiann/KernelSU", - hyperLinks = mutableMapOf( - "https://github.com/tiann/KernelSU" to "https://github.com/tiann/KernelSU", - ), - textStyle = TextStyle( - textAlign = TextAlign.Center, - color = Color.Gray - ), - linkTextColor = MaterialTheme.colors.secondary, - ) - - HyperlinkText( - fullText = "Telegram: https://t.me/KernelSU", - hyperLinks = mutableMapOf( - "https://t.me/KernelSU" to "https://t.me/KernelSU", - ), - textStyle = TextStyle( - textAlign = TextAlign.Center, - color = Color.Gray - ), - linkTextColor = MaterialTheme.colors.secondary, - ) - - HyperlinkText( - fullText = "QQ: https://pd.qq.com/s/8lipl1brp", - hyperLinks = mutableMapOf( - "https://pd.qq.com/s/8lipl1brp" to "https://pd.qq.com/s/8lipl1brp", - ), - textStyle = TextStyle( - textAlign = TextAlign.Center, - color = Color.Gray - ), - linkTextColor = MaterialTheme.colors.secondary, - ) - - } - }, - confirmButton = { - Button( - onClick = { - onDismiss() - }) { - Text("OK") - } - }, - ) + if (!openDialog) { + return } + + AlertDialog( + onDismissRequest = { + onDismiss() + }, + title = { + Text(text = "About") + }, + text = { + Column { + LinkifyText(text = "Author: weishu") + LinkifyText(text = "Github: https://github.com/tiann/KernelSU") + LinkifyText(text = "Telegram: https://t.me/KernelSU") + LinkifyText(text = "QQ: https://pd.qq.com/s/8lipl1brp") + } + }, + confirmButton = { + TextButton( + onClick = { + onDismiss() + }) { + Text("OK") + } + }, + ) + +} + +@Preview +@Composable +fun Preview_AboutDialog() { + AboutDialog(true, {}) } \ No newline at end of file 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 7e857b1a..b207769e 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 @@ -3,15 +3,13 @@ import android.system.Os import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.material.Card -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Done import androidx.compose.material.icons.filled.Warning +import androidx.compose.material3.Card +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight @@ -19,7 +17,6 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import me.weishu.kernelsu.Natives -import java.util.* @Composable fun Info(label: String, value: String) { @@ -29,7 +26,6 @@ fun Info(label: String, value: String) { withStyle( style = SpanStyle( fontWeight = FontWeight.W900, - color = MaterialTheme.colors.secondary ) ) { append(value) @@ -50,8 +46,6 @@ fun Home() { .fillMaxWidth() .padding(6.dp) .clickable { }, - elevation = 10.dp, - backgroundColor = MaterialTheme.colors.secondary ) { Row( modifier = Modifier @@ -89,8 +83,6 @@ fun Home() { modifier = Modifier .fillMaxWidth() .padding(6.dp) - .clickable { }, - elevation = 10.dp ) { Column( modifier = Modifier.padding(10.dp) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt index 373a4bf8..ae781583 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt @@ -1,29 +1,20 @@ -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material.Card -import androidx.compose.material.Text +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp +import androidx.compose.ui.tooling.preview.Preview @Composable fun Module() { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(6.dp) - .clickable { }, - elevation = 10.dp - ) { - Column( - modifier = Modifier.padding(10.dp) - ) { - - - Text("Coming Soon..") - - } + Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize()) { + Text(text = "Coming Soon..") } +} + +@Preview +@Composable +fun Preview() { + Module() } \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt index 200f3e48..0e4405e3 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt @@ -1,27 +1,29 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + import android.annotation.SuppressLint import android.content.Context -import android.content.pm.ApplicationInfo import android.graphics.drawable.Drawable +import android.os.Build import android.util.Log import android.widget.Toast import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Checkbox -import androidx.compose.material.Switch -import androidx.compose.material.Text +import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import com.google.accompanist.drawablepainter.rememberDrawablePainter import me.weishu.kernelsu.Natives import java.util.* +private const val TAG = "SuperUser" + class SuperUserData( val name: CharSequence, val description: String, @@ -39,43 +41,30 @@ fun SuperUserItem( onCheckedChange: (Boolean) -> Unit, onItemClick: () -> Unit ) { - Row(modifier = Modifier - .fillMaxWidth() - .clickable { - onItemClick() - }) { - Image( - painter = rememberDrawablePainter(drawable = superUserData.icon), - contentDescription = superUserData.name.toString(), - modifier = Modifier - .padding(4.dp) - .width(48.dp) - .height(48.dp) - ) - - Column { - Text( - superUserData.name.toString(), - modifier = Modifier.padding(4.dp), - color = Color.Black, - fontSize = 16.sp - ) - Text( - superUserData.description, - modifier = Modifier.padding(4.dp), - color = Color.Gray, - fontSize = 12.sp - ) - } - - Spacer(modifier = Modifier.weight(1f)) - - Switch( - checked = checked, - onCheckedChange = onCheckedChange, - modifier = Modifier.padding(4.dp) + Column { + ListItem( + headlineText = { Text(superUserData.name.toString()) }, + supportingText = { Text(superUserData.description) }, + leadingContent = { + Image( + painter = rememberDrawablePainter(drawable = superUserData.icon), + contentDescription = superUserData.name.toString(), + modifier = Modifier + .padding(4.dp) + .width(48.dp) + .height(48.dp) + ) + }, + trailingContent = { + Switch( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = Modifier.padding(4.dp) + ) + } ) + Divider(thickness = Dp.Hairline) } } @@ -84,8 +73,8 @@ private fun getAppList(context: Context): List { val allowList = Natives.getAllowList() val denyList = Natives.getDenyList(); - Log.i("mylog", "allowList: ${Arrays.toString(allowList)}") - Log.i("mylog", "denyList: ${Arrays.toString(denyList)}") + Log.i(TAG, "allowList: ${Arrays.toString(allowList)}") + Log.i(TAG, "denyList: ${Arrays.toString(denyList)}") val result = mutableListOf() @@ -110,8 +99,16 @@ private fun getAppList(context: Context): List { } } + val defaultDenyList = denyList.toMutableList() + + val shellUid = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) android.os.Process.SHELL_UID else 2000; + if (!allowList.contains(shellUid)) { + // shell uid is not in allow list, add it to default deny list + defaultDenyList.add(shellUid) + } + // add deny list - for (uid in denyList) { + for (uid in defaultDenyList) { val packagesForUid = pm.getPackagesForUid(uid) if (packagesForUid == null || packagesForUid.isEmpty()) { continue @@ -144,7 +141,9 @@ fun SuperUser() { val apps = remember { list.toMutableStateList() } if (apps.isEmpty()) { - Text("No apps found") + Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { + Text("No apps request superuser") + } return } @@ -171,4 +170,10 @@ fun SuperUser() { ) } } +} + +@Preview +@Composable +fun Preview_SuperUser() { + SuperUser() } \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Shape.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Shape.kt deleted file mode 100644 index 59179c69..00000000 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Shape.kt +++ /dev/null @@ -1,11 +0,0 @@ -package me.weishu.kernelsu.ui.theme - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Shapes -import androidx.compose.ui.unit.dp - -val Shapes = Shapes( - small = RoundedCornerShape(4.dp), - medium = RoundedCornerShape(4.dp), - large = RoundedCornerShape(0.dp) -) \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Theme.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Theme.kt index 8e5fda24..f5058cbe 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Theme.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Theme.kt @@ -1,36 +1,55 @@ package me.weishu.kernelsu.ui.theme +import android.app.Activity +import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material.MaterialTheme -import androidx.compose.material.darkColors -import androidx.compose.material.lightColors +import androidx.compose.material3.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.ViewCompat -private val DarkColorPalette = darkColors( +private val DarkColorScheme = darkColorScheme( primary = YELLOW, - primaryVariant = YELLOW_DARK, - secondary = SECONDARY_DARK + secondary = YELLOW_DARK, + tertiary = SECONDARY_DARK ) -private val LightColorPalette = lightColors( +private val LightColorScheme = lightColorScheme( primary = YELLOW, - primaryVariant = YELLOW_LIGHT, - secondary = SECONDARY_LIGHT + secondary = YELLOW_LIGHT, + tertiary = SECONDARY_LIGHT ) @Composable -fun KernelSUTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { - val colors = if (darkTheme) { - DarkColorPalette - } else { - LightColorPalette +fun KernelSUTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb() + ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme + } } MaterialTheme( - colors = colors, + colorScheme = colorScheme, typography = Typography, - shapes = Shapes, content = content ) } \ No newline at end of file diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Type.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Type.kt index 424f5260..e8d73313 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Type.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/theme/Type.kt @@ -1,28 +1,33 @@ package me.weishu.kernelsu.ui.theme -import androidx.compose.material.Typography import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp // Set of Material typography styles to start with -val Typography = Typography( - body1 = TextStyle( +val Typography = androidx.compose.material3.Typography( + bodyLarge = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, - fontSize = 16.sp + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp ) /* Other default text styles to override - button = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.W500, - fontSize = 14.sp - ), - caption = TextStyle( + titleLarge = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, - fontSize = 12.sp + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp ) */ ) \ No newline at end of file diff --git a/manager/app/src/main/res/values/themes.xml b/manager/app/src/main/res/values/themes.xml index 75da9ebd..bf6e252f 100644 --- a/manager/app/src/main/res/values/themes.xml +++ b/manager/app/src/main/res/values/themes.xml @@ -2,6 +2,5 @@ \ No newline at end of file diff --git a/manager/build.gradle b/manager/build.gradle index da262964..fa2ac817 100644 --- a/manager/build.gradle +++ b/manager/build.gradle @@ -1,6 +1,6 @@ buildscript { ext { - compose_ui_version = '1.1.1' + compose_ui_version = '1.3.0' } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins {