From c756db870c3f4b2d6db055b6b2725ae36de3d0b2 Mon Sep 17 00:00:00 2001
From: Baidaidai_GFWD <1302064396@qq.com>
Date: Thu, 9 Apr 2026 15:25:37 +0800
Subject: [PATCH 1/2] feat(ui): Add Shizuku action icons
---
.../main/res/drawable/material_shizuku_icon.xml | 14 ++++++++++++++
.../main/res/drawable/material_symbols_check.xml | 10 ++++++++++
.../res/drawable/material_symbols_play_arrow.xml | 10 ++++++++++
3 files changed, 34 insertions(+)
create mode 100644 app/src/main/res/drawable/material_shizuku_icon.xml
create mode 100644 app/src/main/res/drawable/material_symbols_check.xml
create mode 100644 app/src/main/res/drawable/material_symbols_play_arrow.xml
diff --git a/app/src/main/res/drawable/material_shizuku_icon.xml b/app/src/main/res/drawable/material_shizuku_icon.xml
new file mode 100644
index 0000000..98c29ac
--- /dev/null
+++ b/app/src/main/res/drawable/material_shizuku_icon.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/material_symbols_check.xml b/app/src/main/res/drawable/material_symbols_check.xml
new file mode 100644
index 0000000..280f0bd
--- /dev/null
+++ b/app/src/main/res/drawable/material_symbols_check.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/material_symbols_play_arrow.xml b/app/src/main/res/drawable/material_symbols_play_arrow.xml
new file mode 100644
index 0000000..9bc6b5d
--- /dev/null
+++ b/app/src/main/res/drawable/material_symbols_play_arrow.xml
@@ -0,0 +1,10 @@
+
+
+
From 928719f4b420c9995de31556d00c9c320a22ae90 Mon Sep 17 00:00:00 2001
From: Baidaidai_GFWD <1302064396@qq.com>
Date: Thu, 9 Apr 2026 15:33:37 +0800
Subject: [PATCH 2/2] refactor!: Restructure Shizuku ADB screen components
Extract Shizuku ADB screen UI pieces into a dedicated components file.
Update the screen flow and add a simple top app bar for the Shizuku auth activity.
---
.../rootless_store/ShizukuActivity.kt | 15 +-
.../ShizukuAdbScreenNecessaryComponents.kt | 220 ++++++++++++++++++
.../ui/screens/ShizukuAdbScreen.kt | 199 +++++++---------
3 files changed, 312 insertions(+), 122 deletions(-)
create mode 100644 app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt
diff --git a/app/src/main/java/com/baidaidai/rootless_store/ShizukuActivity.kt b/app/src/main/java/com/baidaidai/rootless_store/ShizukuActivity.kt
index b2d2f46..a6824d6 100644
--- a/app/src/main/java/com/baidaidai/rootless_store/ShizukuActivity.kt
+++ b/app/src/main/java/com/baidaidai/rootless_store/ShizukuActivity.kt
@@ -4,8 +4,11 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -21,7 +24,7 @@ import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class ShizukuActivity: ComponentActivity() {
- @OptIn(ExperimentalMaterial3ExpressiveApi::class)
+ @OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
@@ -34,7 +37,15 @@ class ShizukuActivity: ComponentActivity() {
}
}
RootlessStoreTheme {
- Scaffold { contentPadding ->
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = {
+ Text("Shizuku Auth")
+ }
+ )
+ }
+ ) { contentPadding ->
if (sharedEvent is RootlessStoreError){
StartScreenErrorDialog(shizukuAdbScreenViewModel, sharedEvent)
}
diff --git a/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt b/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt
new file mode 100644
index 0000000..b04ef58
--- /dev/null
+++ b/app/src/main/java/com/baidaidai/rootless_store/components/shizukuAdbScreen/ShizukuAdbScreenNecessaryComponents.kt
@@ -0,0 +1,220 @@
+package com.baidaidai.rootless_store.components.shizukuAdbScreen
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.material3.Button
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.OutlinedCard
+import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import com.baidaidai.rootless_store.R
+
+object ShizukuAdbScreenNecessaryComponents {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ fun ShizukuAdbScreenModelSheet(
+ remainderTime: Int,
+ onDismissRequest: ()-> Unit,
+ onCloseButtonClick: ()-> Unit,
+ onReturnButtonClick: ()-> Unit
+ ){
+ ModalBottomSheet(
+ onDismissRequest = onDismissRequest,
+ sheetState = rememberModalBottomSheetState(),
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 24.dp)
+ .padding(top = 8.dp, bottom = 24.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Box(
+ modifier = Modifier
+ .size(84.dp)
+ .clip(CircleShape)
+ .background(MaterialTheme.colorScheme.primaryContainer),
+ contentAlignment = Alignment.Center
+ ) {
+ Icon(
+ painterResource(R.drawable.material_symbols_check),
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.onPrimaryContainer,
+ modifier = Modifier.size(40.dp)
+ )
+ }
+
+ Spacer(Modifier.height(16.dp))
+
+ Text(
+ text = "All done",
+ style = MaterialTheme.typography.headlineSmall,
+ color = MaterialTheme.colorScheme.onSurface,
+ textAlign = TextAlign.Center
+ )
+
+ Spacer(Modifier.height(8.dp))
+
+ Text(
+ text = "Returning to Home in $remainderTime s",
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ textAlign = TextAlign.Center
+ )
+
+ Spacer(Modifier.height(20.dp))
+
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.spacedBy(12.dp)
+ ) {
+ OutlinedButton(
+ onClick = onCloseButtonClick,
+ modifier = Modifier.weight(1f)
+ ) {
+ Text("Close")
+ }
+ Button(
+ onClick = onReturnButtonClick,
+ modifier = Modifier.weight(1f)
+ ) {
+ Text("Return now")
+ }
+ }
+ }
+ }
+ }
+
+ @OptIn(ExperimentalMaterial3ExpressiveApi::class)
+ @Composable
+ fun ShizukuAdbScreenActionCard(
+ step: String,
+ title: String,
+ description: String,
+ targetStatus: Boolean,
+ onClick: () -> Unit
+ ){
+ Card(
+ modifier = Modifier
+ .fillMaxWidth(),
+ elevation = CardDefaults.cardElevation(),
+ colors = CardDefaults.cardColors(
+ containerColor = MaterialTheme.colorScheme.surfaceContainer
+ )
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(20.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp)
+ ) {
+ Column{
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(60.dp)
+ ){
+ Column{
+ Text(
+ text = step,
+ style = MaterialTheme.typography.labelMedium,
+ color = MaterialTheme.colorScheme.primary
+ )
+ Text(
+ text = title,
+ style = MaterialTheme.typography.titleMediumEmphasized
+ )
+ }
+ Button(
+ onClick = onClick,
+ modifier = Modifier.size(48.dp),
+ contentPadding = PaddingValues(0.dp)
+ ) {
+ Icon(
+ painter = if (targetStatus){
+ painterResource(R.drawable.material_symbols_check)
+ }else{
+ painterResource(R.drawable.material_symbols_play_arrow)
+ },
+ contentDescription = "Start",
+ modifier = Modifier.size(24.dp)
+ )
+ }
+ }
+ Spacer(modifier = Modifier.height(15.dp))
+ HorizontalDivider()
+ Spacer(modifier = Modifier.height(15.dp))
+ Text(
+ text = description,
+ style = MaterialTheme.typography.bodyMediumEmphasized
+ )
+ }
+ }
+ }
+ }
+
+ @OptIn(ExperimentalMaterial3ExpressiveApi::class)
+ @Composable
+ fun ShizukuAdbScreenOverviewCard(){
+ OutlinedCard(
+ modifier = Modifier
+ .fillMaxWidth(),
+ elevation = CardDefaults.cardElevation(),
+ ) {
+ Column(
+ modifier = Modifier
+ .padding(24.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp)
+ ) {
+ Row(
+ modifier = Modifier
+ .height(50.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ){
+ Text(
+ text = "Shizuku Access",
+ style = MaterialTheme.typography.titleLargeEmphasized
+ )
+ Icon(
+ painterResource(R.drawable.material_shizuku_icon),
+ contentDescription = "Shizuku Icon",
+ tint = MaterialTheme.colorScheme.primary,
+ )
+ }
+ Text(
+ text = "Rootless Store uses Shizuku’s ADB shell for some features so please request ADB authorization.\nFirst then connect to Shizuku.",
+ style = MaterialTheme.typography.bodyMedium
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt
index 2913202..9818a89 100644
--- a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt
+++ b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/ShizukuAdbScreen.kt
@@ -4,33 +4,32 @@ import android.app.Activity
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.material3.Button
-import androidx.compose.material3.Card
-import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
-import androidx.compose.material3.HorizontalDivider
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
+import androidx.compose.material3.LinearWavyProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
-import androidx.hilt.navigation.compose.hiltViewModel
-import com.baidaidai.rootless_store.domain.error.RootlessStoreError
+import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenActionCard
+import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenModelSheet
+import com.baidaidai.rootless_store.components.shizukuAdbScreen.ShizukuAdbScreenNecessaryComponents.ShizukuAdbScreenOverviewCard
import com.baidaidai.rootless_store.ui.model.RootlessStoreShizukuAdbScreenViewModel
-import com.baidaidai.rootless_store.ui.theme.RootlessStoreTheme
+import kotlinx.coroutines.delay
+@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
fun ShizukuAdbScreen(
contentPaddingValues: PaddingValues,
@@ -42,124 +41,84 @@ fun ShizukuAdbScreen(
val context = LocalContext.current
val activity = context as? Activity
+ var sheetState by remember { mutableStateOf(false) }
+ var remainderTime by remember { mutableIntStateOf(6) }
+
LaunchedEffect(endpointActived) {
if (endpointActived) {
+ sheetState = true
+ while (remainderTime > 0){
+ delay(1000)
+ remainderTime--
+ }
activity?.finish()
}
}
- LazyColumn(
- modifier = Modifier
- .padding(contentPaddingValues)
- .padding(horizontal = 15.dp),
- verticalArrangement = Arrangement.spacedBy(12.dp),
- contentPadding = PaddingValues(vertical = 15.dp)
- ) {
- item {
- ShizukuAdbScreenOverviewCard()
- }
- item {
- ShizukuAdbScreenActionCard(
- step = "Step 1",
- title = "Request ADB Authorization",
- description = "Grant Rootless Store the ADB authorization it needs before entering the shell flow. Finish this step first so the following connection step can continue normally.",
- buttonText = if (shizukuActived) {
- "Actived ✓"
- } else {
- "Request Authorization"
- },
- onClick = {
- shizukuAdbScreenViewModel.activeShizuku()
- }
- )
- }
- item {
- ShizukuAdbScreenActionCard(
- step = "Step 2",
- title = "Connect to Shizuku UserActivity",
- description = "After ADB authorization is ready, open Shizuku's UserActivity and enter the ADB shell session used by Rootless Store. This is the final step before the user can continue with the shell-based workflow.",
- buttonText = if (endpointActived) {
- "Actived ✓"
- } else {
- "Connect to Shizuku"
- },
- onClick = {
- shizukuAdbScreenViewModel.activeShizukuEndpoint()
- }
- )
- }
- }
-}
-
-@Composable
-private fun ShizukuAdbScreenOverviewCard(){
- Card(
- modifier = Modifier
- .fillMaxWidth(),
- elevation = CardDefaults.cardElevation(),
- colors = CardDefaults.cardColors(
- containerColor = MaterialTheme.colorScheme.surfaceContainer
- )
- ) {
- Column(
- modifier = Modifier
- .padding(24.dp),
- verticalArrangement = Arrangement.spacedBy(12.dp)
- ) {
- Text(
- text = "Rootless Store ADB",
- style = MaterialTheme.typography.titleMedium
- )
- Text(
- text = "Some Rootless Store features depend on an ADB shell instead of a full root shell. This page helps the user complete the required setup in the correct order: request ADB authorization first, then connect into Shizuku's ADB shell environment.",
- style = MaterialTheme.typography.bodyMedium
- )
- }
- }
-}
-
-@Composable
-private fun ShizukuAdbScreenActionCard(
- step: String,
- title: String,
- description: String,
- buttonText: String,
- onClick: () -> Unit
-){
- Card(
- modifier = Modifier
- .fillMaxWidth(),
- elevation = CardDefaults.cardElevation(),
- colors = CardDefaults.cardColors(
- containerColor = MaterialTheme.colorScheme.surfaceContainer
+ if (sheetState){
+ ShizukuAdbScreenModelSheet(
+ remainderTime = remainderTime,
+ onDismissRequest = { sheetState = false},
+ onCloseButtonClick = { sheetState = false },
+ onReturnButtonClick = { activity?.finish() }
)
- ) {
- Column(
+ }else{
+ LazyColumn(
modifier = Modifier
- .padding(24.dp),
- verticalArrangement = Arrangement.spacedBy(12.dp)
+ .padding(contentPaddingValues)
+ .padding(horizontal = 15.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ contentPadding = PaddingValues(vertical = 15.dp)
) {
- Text(
- text = step,
- style = MaterialTheme.typography.labelMedium,
- color = MaterialTheme.colorScheme.primary
- )
- Text(
- text = title,
- style = MaterialTheme.typography.titleMedium
- )
- Text(
- text = description,
- style = MaterialTheme.typography.bodyMedium
- )
- HorizontalDivider()
- Button(
- onClick = onClick,
- modifier = Modifier
- .fillMaxWidth()
- ) {
- Text(buttonText)
+ item {
+ ShizukuAdbScreenOverviewCard()
+ }
+ item {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ Spacer(modifier = Modifier.height(10.dp))
+ LinearWavyProgressIndicator(
+ progress = {
+ if (endpointActived) {
+ 1f
+ }else if (shizukuActived){
+ 0.5f
+ }else{
+ 0.05f
+ }
+ },
+ amplitude = {1f},
+ waveSpeed = 10.dp,
+ modifier = Modifier
+ .fillMaxWidth()
+ )
+ Spacer(modifier = Modifier.height(10.dp))
+ }
+ }
+ item {
+ ShizukuAdbScreenActionCard(
+ step = "Step 1",
+ title = "Request Shizuku Auth",
+ description = "Grant ADB authorization so Rootless Store can start the shell workflow and unlock the next step",
+ targetStatus = shizukuActived,
+ onClick = {
+ shizukuAdbScreenViewModel.activeShizuku()
+ }
+ )
+ }
+ item {
+ ShizukuAdbScreenActionCard(
+ step = "Step 2",
+ title = "Connect to Shizuku",
+ description = "After authorization is ready open Shizuku and enter the ADB shell session to finish setup and continue",
+ targetStatus = endpointActived,
+ onClick = {
+ shizukuAdbScreenViewModel.activeShizukuEndpoint()
+ }
+ )
}
}
}