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 {