Skip to content

Commit 16faf6c

Browse files
lightsummer233backslashxx
authored andcommitted
manager: Insets stuffs for Android 15 (tiann#2100)
Fix insets on Android 15 Bump dependencies Migrate Compose Destination to v2 Ready for review now
1 parent 856f295 commit 16faf6c

27 files changed

+406
-313
lines changed

manager/app/build.gradle.kts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ android {
6161
val output = it as BaseVariantOutputImpl
6262
output.outputFileName = "KernelSU_${managerVersionName}_${managerVersionCode}-$name.apk"
6363
}
64-
6564
kotlin.sourceSets {
6665
getByName(name) {
6766
kotlin.srcDir("build/generated/ksp/$name/kotlin")
@@ -90,10 +89,9 @@ dependencies {
9089

9190
implementation(libs.com.google.accompanist.drawablepainter)
9291
implementation(libs.com.google.accompanist.navigation.animation)
93-
implementation(libs.com.google.accompanist.systemuicontroller)
9492
implementation(libs.com.google.accompanist.webview)
9593

96-
implementation(libs.compose.destinations.animations.core)
94+
implementation(libs.compose.destinations.core)
9795
ksp(libs.compose.destinations.ksp)
9896

9997
implementation(libs.com.github.topjohnwu.libsu.core)

manager/app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
android:theme="@style/Theme.KernelSU">
2323
<intent-filter>
2424
<action android:name="android.intent.action.MAIN" />
25-
2625
<category android:name="android.intent.category.LAUNCHER" />
2726
</intent-filter>
2827

manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package me.weishu.kernelsu.ui
22

3+
import android.os.Build
34
import android.os.Bundle
45
import androidx.activity.ComponentActivity
56
import androidx.activity.compose.setContent
7+
import androidx.activity.enableEdgeToEdge
8+
import androidx.compose.foundation.layout.WindowInsets
9+
import androidx.compose.foundation.layout.WindowInsetsSides
10+
import androidx.compose.foundation.layout.only
611
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.layout.safeDrawing
713
import androidx.compose.material3.Icon
814
import androidx.compose.material3.NavigationBar
915
import androidx.compose.material3.NavigationBarItem
@@ -21,19 +27,26 @@ import androidx.compose.ui.unit.dp
2127
import androidx.navigation.NavHostController
2228
import androidx.navigation.compose.rememberNavController
2329
import com.ramcosta.composedestinations.DestinationsNavHost
24-
import com.ramcosta.composedestinations.navigation.popBackStack
30+
import com.ramcosta.composedestinations.generated.NavGraphs
2531
import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState
32+
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
2633
import me.weishu.kernelsu.Natives
2734
import me.weishu.kernelsu.ksuApp
2835
import me.weishu.kernelsu.ui.screen.BottomBarDestination
29-
import me.weishu.kernelsu.ui.screen.NavGraphs
3036
import me.weishu.kernelsu.ui.theme.KernelSUTheme
3137
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
3238
import me.weishu.kernelsu.ui.util.rootAvailable
3339

3440
class MainActivity : ComponentActivity() {
3541

3642
override fun onCreate(savedInstanceState: Bundle?) {
43+
44+
// Enable edge to edge
45+
enableEdgeToEdge()
46+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
47+
window.isNavigationBarContrastEnforced = false
48+
}
49+
3750
super.onCreate(savedInstanceState)
3851

3952
setContent {
@@ -42,7 +55,8 @@ class MainActivity : ComponentActivity() {
4255
val snackbarHostState = remember { SnackbarHostState() }
4356
Scaffold(
4457
bottomBar = { BottomBar(navController) },
45-
snackbarHost = { SnackbarHost(snackbarHostState) }
58+
snackbarHost = { SnackbarHost(snackbarHostState) },
59+
contentWindowInsets = WindowInsets(0, 0, 0, 0)
4660
) { innerPadding ->
4761
CompositionLocalProvider(
4862
LocalSnackbarHost provides snackbarHostState,
@@ -61,21 +75,24 @@ class MainActivity : ComponentActivity() {
6175

6276
@Composable
6377
private fun BottomBar(navController: NavHostController) {
78+
val navigator = navController.rememberDestinationsNavigator()
6479
val isManager = Natives.becomeManager(ksuApp.packageName)
6580
val fullFeatured = isManager && !Natives.requireNewKernel() && rootAvailable()
66-
NavigationBar(tonalElevation = 8.dp) {
81+
NavigationBar(
82+
tonalElevation = 8.dp,
83+
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal)
84+
) {
6785
BottomBarDestination.entries.forEach { destination ->
6886
if (!fullFeatured && destination.rootRequired) return@forEach
6987
val isCurrentDestOnBackStack by navController.isRouteOnBackStackAsState(destination.direction)
7088
NavigationBarItem(
7189
selected = isCurrentDestOnBackStack,
7290
onClick = {
7391
if (isCurrentDestOnBackStack) {
74-
navController.popBackStack(destination.direction, false)
92+
navigator.popBackStack(destination.direction, false)
7593
}
76-
77-
navController.navigate(destination.direction.route) {
78-
popUpTo(NavGraphs.root.route) {
94+
navigator.navigate(destination.direction) {
95+
popUpTo(NavGraphs.root) {
7996
saveState = true
8097
}
8198
launchSingleTop = true

manager/app/src/main/java/me/weishu/kernelsu/ui/component/Dialog.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package me.weishu.kernelsu.ui.component
22

33
import android.graphics.text.LineBreaker
4+
import android.os.Build
45
import android.os.Parcelable
56
import android.text.Layout
67
import android.text.method.LinkMovementMethod
@@ -96,8 +97,8 @@ interface ConfirmDialogHandle : DialogHandle {
9697
}
9798

9899
private abstract class DialogHandleBase(
99-
protected val visible: MutableState<Boolean>,
100-
protected val coroutineScope: CoroutineScope
100+
val visible: MutableState<Boolean>,
101+
val coroutineScope: CoroutineScope
101102
) : DialogHandle {
102103
override val isShown: Boolean
103104
get() = visible.value
@@ -432,7 +433,9 @@ private fun MarkdownContent(content: String) {
432433
TextView(context).apply {
433434
movementMethod = LinkMovementMethod.getInstance()
434435
setSpannableFactory(NoCopySpannableFactory.getInstance())
435-
breakStrategy = LineBreaker.BREAK_STRATEGY_SIMPLE
436+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
437+
breakStrategy = LineBreaker.BREAK_STRATEGY_SIMPLE
438+
}
436439
hyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE
437440
layoutParams = ViewGroup.LayoutParams(
438441
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT

manager/app/src/main/java/me/weishu/kernelsu/ui/component/SearchBar.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ import androidx.compose.animation.AnimatedVisibility
55
import androidx.compose.animation.fadeIn
66
import androidx.compose.animation.fadeOut
77
import androidx.compose.foundation.layout.Box
8+
import androidx.compose.foundation.layout.WindowInsets
9+
import androidx.compose.foundation.layout.WindowInsetsSides
810
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.only
912
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.layout.safeDrawing
1014
import androidx.compose.foundation.text.KeyboardActions
1115
import androidx.compose.foundation.text.KeyboardOptions
1216
import androidx.compose.material.icons.Icons
@@ -132,7 +136,8 @@ fun SearchAppBar(
132136
dropdownContent()
133137
}
134138

135-
}
139+
},
140+
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
136141
)
137142
}
138143

manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/RootProfileConfig.kt

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
@file:OptIn(ExperimentalMaterial3Api::class)
2-
31
package me.weishu.kernelsu.ui.component.profile
42

53
import androidx.compose.foundation.clickable
64
import androidx.compose.foundation.layout.Column
75
import androidx.compose.foundation.layout.ExperimentalLayoutApi
86
import androidx.compose.foundation.layout.FlowRow
7+
import androidx.compose.foundation.layout.fillMaxSize
98
import androidx.compose.foundation.layout.fillMaxWidth
109
import androidx.compose.foundation.layout.padding
1110
import androidx.compose.foundation.text.KeyboardActions
@@ -20,12 +19,14 @@ import androidx.compose.material3.ExposedDropdownMenuBox
2019
import androidx.compose.material3.Icon
2120
import androidx.compose.material3.ListItem
2221
import androidx.compose.material3.MaterialTheme
22+
import androidx.compose.material3.MenuAnchorType
2323
import androidx.compose.material3.OutlinedCard
2424
import androidx.compose.material3.OutlinedTextField
2525
import androidx.compose.material3.OutlinedTextFieldDefaults
2626
import androidx.compose.material3.Text
2727
import androidx.compose.runtime.Composable
2828
import androidx.compose.runtime.getValue
29+
import androidx.compose.runtime.mutableIntStateOf
2930
import androidx.compose.runtime.mutableStateOf
3031
import androidx.compose.runtime.remember
3132
import androidx.compose.runtime.setValue
@@ -86,7 +87,7 @@ fun RootProfileConfig(
8687
) {
8788
OutlinedTextField(
8889
modifier = Modifier
89-
.menuAnchor()
90+
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
9091
.fillMaxWidth(),
9192
readOnly = true,
9293
label = { Text(stringResource(R.string.profile_namespace)) },
@@ -184,7 +185,7 @@ fun RootProfileConfig(
184185
}
185186
}
186187

187-
@OptIn(ExperimentalLayoutApi::class)
188+
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
188189
@Composable
189190
fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>) -> Unit) {
190191
val selectGroupsDialog = rememberCustomDialog { dismiss: () -> Unit ->
@@ -234,14 +235,20 @@ fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>)
234235
)
235236
}
236237

237-
OutlinedCard(modifier = Modifier
238-
.fillMaxWidth()
239-
.padding(16.dp)
240-
.clickable {
241-
selectGroupsDialog.show()
242-
}) {
238+
OutlinedCard(
239+
modifier = Modifier
240+
.fillMaxWidth()
241+
.padding(16.dp)
242+
) {
243243

244-
Column(modifier = Modifier.padding(16.dp)) {
244+
Column(
245+
modifier = Modifier
246+
.fillMaxSize()
247+
.clickable {
248+
selectGroupsDialog.show()
249+
}
250+
.padding(16.dp)
251+
) {
245252
Text(stringResource(R.string.profile_groups))
246253
FlowRow {
247254
selected.forEach { group ->
@@ -256,7 +263,7 @@ fun GroupsPanel(selected: List<Groups>, closeSelection: (selection: Set<Groups>)
256263
}
257264
}
258265

259-
@OptIn(ExperimentalLayoutApi::class)
266+
@OptIn(ExperimentalLayoutApi::class, ExperimentalMaterial3Api::class)
260267
@Composable
261268
fun CapsPanel(
262269
selected: Collection<Capabilities>,
@@ -299,14 +306,20 @@ fun CapsPanel(
299306
)
300307
}
301308

302-
OutlinedCard(modifier = Modifier
303-
.fillMaxWidth()
304-
.padding(16.dp)
305-
.clickable {
306-
selectCapabilitiesDialog.show()
307-
}) {
309+
OutlinedCard(
310+
modifier = Modifier
311+
.fillMaxWidth()
312+
.padding(16.dp)
313+
) {
308314

309-
Column(modifier = Modifier.padding(16.dp)) {
315+
Column(
316+
modifier = Modifier
317+
.fillMaxSize()
318+
.clickable {
319+
selectCapabilitiesDialog.show()
320+
}
321+
.padding(16.dp)
322+
) {
310323
Text(stringResource(R.string.profile_capabilities))
311324
FlowRow {
312325
selected.forEach { group ->
@@ -329,10 +342,10 @@ private fun UidPanel(uid: Int, label: String, onUidChange: (Int) -> Unit) {
329342
mutableStateOf(false)
330343
}
331344
var lastValidUid by remember {
332-
mutableStateOf(uid)
345+
mutableIntStateOf(uid)
333346
}
334-
335347
val keyboardController = LocalSoftwareKeyboardController.current
348+
336349
OutlinedTextField(
337350
modifier = Modifier.fillMaxWidth(),
338351
label = { Text(label) },
@@ -365,6 +378,7 @@ private fun UidPanel(uid: Int, label: String, onUidChange: (Int) -> Unit) {
365378
})
366379
}
367380

381+
@OptIn(ExperimentalMaterial3Api::class)
368382
@Composable
369383
private fun SELinuxPanel(
370384
profile: Natives.Profile,
@@ -452,7 +466,7 @@ private fun SELinuxPanel(
452466
),
453467
label = { Text(text = stringResource(R.string.profile_selinux_context)) },
454468
value = profile.context,
455-
onValueChange = { },
469+
onValueChange = { }
456470
)
457471
})
458472
}

manager/app/src/main/java/me/weishu/kernelsu/ui/component/profile/TemplateConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.material3.ExposedDropdownMenuBox
1212
import androidx.compose.material3.Icon
1313
import androidx.compose.material3.IconButton
1414
import androidx.compose.material3.ListItem
15+
import androidx.compose.material3.MenuAnchorType
1516
import androidx.compose.material3.OutlinedTextField
1617
import androidx.compose.material3.Text
1718
import androidx.compose.runtime.Composable
@@ -54,7 +55,7 @@ fun TemplateConfig(
5455
) {
5556
OutlinedTextField(
5657
modifier = Modifier
57-
.menuAnchor()
58+
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
5859
.fillMaxWidth(),
5960
readOnly = true,
6061
label = { Text(stringResource(R.string.profile_template)) },

manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ import androidx.compose.foundation.layout.Arrangement
77
import androidx.compose.foundation.layout.BoxWithConstraints
88
import androidx.compose.foundation.layout.Column
99
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.WindowInsets
11+
import androidx.compose.foundation.layout.WindowInsetsSides
1012
import androidx.compose.foundation.layout.fillMaxSize
1113
import androidx.compose.foundation.layout.fillMaxWidth
1214
import androidx.compose.foundation.layout.height
15+
import androidx.compose.foundation.layout.only
1316
import androidx.compose.foundation.layout.padding
17+
import androidx.compose.foundation.layout.safeDrawing
1418
import androidx.compose.foundation.layout.width
1519
import androidx.compose.foundation.rememberScrollState
1620
import androidx.compose.foundation.verticalScroll
@@ -50,6 +54,9 @@ import androidx.compose.ui.unit.dp
5054
import coil.compose.AsyncImage
5155
import coil.request.ImageRequest
5256
import com.ramcosta.composedestinations.annotation.Destination
57+
import com.ramcosta.composedestinations.annotation.RootGraph
58+
import com.ramcosta.composedestinations.generated.destinations.AppProfileTemplateScreenDestination
59+
import com.ramcosta.composedestinations.generated.destinations.TemplateEditorScreenDestination
5360
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
5461
import kotlinx.coroutines.launch
5562
import me.weishu.kernelsu.Natives
@@ -58,8 +65,6 @@ import me.weishu.kernelsu.ui.component.SwitchItem
5865
import me.weishu.kernelsu.ui.component.profile.AppProfileConfig
5966
import me.weishu.kernelsu.ui.component.profile.RootProfileConfig
6067
import me.weishu.kernelsu.ui.component.profile.TemplateConfig
61-
import me.weishu.kernelsu.ui.screen.destinations.AppProfileTemplateScreenDestination
62-
import me.weishu.kernelsu.ui.screen.destinations.TemplateEditorScreenDestination
6368
import me.weishu.kernelsu.ui.util.LocalSnackbarHost
6469
import me.weishu.kernelsu.ui.util.forceStopApp
6570
import me.weishu.kernelsu.ui.util.getSepolicy
@@ -73,7 +78,7 @@ import me.weishu.kernelsu.ui.viewmodel.getTemplateInfoById
7378
* @author weishu
7479
* @date 2023/5/16.
7580
*/
76-
@Destination
81+
@Destination<RootGraph>
7782
@Composable
7883
fun AppProfileScreen(
7984
navigator: DestinationsNavigator,
@@ -82,10 +87,8 @@ fun AppProfileScreen(
8287
val context = LocalContext.current
8388
val snackbarHost = LocalSnackbarHost.current
8489
val scope = rememberCoroutineScope()
85-
val failToUpdateAppProfile =
86-
stringResource(R.string.failed_to_update_app_profile).format(appInfo.label)
87-
val failToUpdateSepolicy =
88-
stringResource(R.string.failed_to_update_sepolicy).format(appInfo.label)
90+
val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label)
91+
val failToUpdateSepolicy = stringResource(R.string.failed_to_update_sepolicy).format(appInfo.label)
8992

9093
val packageName = appInfo.packageName
9194
val initialProfile = Natives.getAppProfile(packageName, appInfo.uid)
@@ -98,6 +101,7 @@ fun AppProfileScreen(
98101

99102
Scaffold(
100103
topBar = { TopBar { navigator.popBackStack() } },
104+
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
101105
) { paddingValues ->
102106
AppProfileInner(
103107
modifier = Modifier
@@ -248,6 +252,7 @@ private fun TopBar(onBack: () -> Unit) {
248252
onClick = onBack
249253
) { Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = null) }
250254
},
255+
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
251256
)
252257
}
253258

0 commit comments

Comments
 (0)