mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
Improve UI
This commit is contained in:
@@ -38,10 +38,6 @@ android {
|
|||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
signingConfig = signingConfigs.getByName("defaultSignature")
|
signingConfig = signingConfigs.getByName("defaultSignature")
|
||||||
composeCompiler {
|
|
||||||
includeSourceInformation = false
|
|
||||||
includeTraceMarkers = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
signingConfig = signingConfigs.getByName("defaultSignature")
|
signingConfig = signingConfigs.getByName("defaultSignature")
|
||||||
@@ -64,6 +60,10 @@ android {
|
|||||||
dependenciesInfo {
|
dependenciesInfo {
|
||||||
includeInApk = false
|
includeInApk = false
|
||||||
}
|
}
|
||||||
|
composeCompiler {
|
||||||
|
includeSourceInformation = false
|
||||||
|
includeTraceMarkers = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.bintianqi.owndroid
|
package com.bintianqi.owndroid
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@@ -237,13 +236,11 @@ import com.bintianqi.owndroid.ui.Animations
|
|||||||
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
||||||
import com.rosan.dhizuku.api.Dhizuku
|
import com.rosan.dhizuku.api.Dhizuku
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
val backToHomeStateFlow = MutableStateFlow(false)
|
|
||||||
@ExperimentalMaterial3Api
|
@ExperimentalMaterial3Api
|
||||||
class MainActivity : FragmentActivity() {
|
class MainActivity : FragmentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -291,12 +288,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
val backToHome by backToHomeStateFlow.collectAsState()
|
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
LaunchedEffect(backToHome) {
|
|
||||||
if(backToHome) { navController.navigateUp(); backToHomeStateFlow.value = false }
|
|
||||||
}
|
|
||||||
val userRestrictions by vm.userRestrictions.collectAsStateWithLifecycle()
|
|
||||||
fun navigateUp() { navController.navigateUp() }
|
fun navigateUp() { navController.navigateUp() }
|
||||||
fun navigate(destination: Any) { navController.navigate(destination) }
|
fun navigate(destination: Any) { navController.navigate(destination) }
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@@ -320,7 +312,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
popEnterTransition = Animations.navHostPopEnterTransition,
|
||||||
popExitTransition = Animations.navHostPopExitTransition
|
popExitTransition = Animations.navHostPopExitTransition
|
||||||
) {
|
) {
|
||||||
composable<Home> { HomeScreen { navController.navigate(it) } }
|
composable<Home> { HomeScreen(::navigate) }
|
||||||
composable<WorkModes> {
|
composable<WorkModes> {
|
||||||
WorkModesScreen(it.toRoute(), ::navigateUp, {
|
WorkModesScreen(it.toRoute(), ::navigateUp, {
|
||||||
navController.navigate(Home) {
|
navController.navigate(Home) {
|
||||||
@@ -330,9 +322,7 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
navController.navigate(WorkModes(false)) {
|
navController.navigate(WorkModes(false)) {
|
||||||
popUpTo<Home> { inclusive = true }
|
popUpTo<Home> { inclusive = true }
|
||||||
}
|
}
|
||||||
}, {
|
}, ::navigate)
|
||||||
navController.navigate(it)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composable<DelegatedAdmins> { DelegatedAdminsScreen(::navigateUp, ::navigate) }
|
composable<DelegatedAdmins> { DelegatedAdminsScreen(::navigateUp, ::navigate) }
|
||||||
@@ -369,14 +359,14 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
composable<WipeData> { WipeDataScreen(::navigateUp) }
|
composable<WipeData> { WipeDataScreen(::navigateUp) }
|
||||||
|
|
||||||
composable<Network> { NetworkScreen(::navigateUp, ::navigate) }
|
composable<Network> { NetworkScreen(::navigateUp, ::navigate) }
|
||||||
composable<WiFi> { WifiScreen(::navigateUp, { navController.navigate(it) }) { navController.navigate(AddNetwork, it)} }
|
composable<WiFi> { WifiScreen(::navigateUp, ::navigate) { navController.navigate(AddNetwork, it)} }
|
||||||
composable<NetworkOptions> { NetworkOptionsScreen(::navigateUp) }
|
composable<NetworkOptions> { NetworkOptionsScreen(::navigateUp) }
|
||||||
composable<AddNetwork> { AddNetworkScreen(it.arguments!!, ::navigateUp) }
|
composable<AddNetwork> { AddNetworkScreen(it.arguments!!, ::navigateUp) }
|
||||||
composable<WifiSecurityLevel> { WifiSecurityLevelScreen(::navigateUp) }
|
composable<WifiSecurityLevel> { WifiSecurityLevelScreen(::navigateUp) }
|
||||||
composable<WifiSsidPolicyScreen> { WifiSsidPolicyScreen(::navigateUp) }
|
composable<WifiSsidPolicyScreen> { WifiSsidPolicyScreen(::navigateUp) }
|
||||||
composable<QueryNetworkStats> { NetworkStatsScreen(::navigateUp, ::navigate) }
|
composable<QueryNetworkStats> { NetworkStatsScreen(::navigateUp, ::navigate) }
|
||||||
composable<NetworkStatsViewer>(mapOf(serializableNavTypePair<List<NetworkStatsViewer.Data>>())) {
|
composable<NetworkStatsViewer>(mapOf(serializableNavTypePair<List<NetworkStatsViewer.Data>>())) {
|
||||||
NetworkStatsViewerScreen(it.toRoute()) { navController.navigateUp() }
|
NetworkStatsViewerScreen(it.toRoute(), ::navigateUp)
|
||||||
}
|
}
|
||||||
composable<PrivateDns> { PrivateDnsScreen(::navigateUp) }
|
composable<PrivateDns> { PrivateDnsScreen(::navigateUp) }
|
||||||
composable<AlwaysOnVpnPackage> { AlwaysOnVpnPackageScreen(::navigateUp) }
|
composable<AlwaysOnVpnPackage> { AlwaysOnVpnPackageScreen(::navigateUp) }
|
||||||
@@ -433,25 +423,12 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
|||||||
composable<SetDefaultDialer> { SetDefaultDialerScreen(::navigateUp) }
|
composable<SetDefaultDialer> { SetDefaultDialerScreen(::navigateUp) }
|
||||||
|
|
||||||
composable<UserRestriction> {
|
composable<UserRestriction> {
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
vm.userRestrictions.value = context.getDPM().getUserRestrictions(receiver)
|
|
||||||
}
|
|
||||||
UserRestrictionScreen(::navigateUp) { title, items ->
|
UserRestrictionScreen(::navigateUp) { title, items ->
|
||||||
navController.navigate(UserRestrictionOptions(title, items))
|
navigate(UserRestrictionOptions(title, items))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable<UserRestrictionOptions>(mapOf(serializableNavTypePair<List<Restriction>>())) {
|
composable<UserRestrictionOptions>(mapOf(serializableNavTypePair<List<Restriction>>())) {
|
||||||
UserRestrictionOptionsScreen(it.toRoute(), userRestrictions, ::navigateUp) { id, status ->
|
UserRestrictionOptionsScreen(it.toRoute(), ::navigateUp)
|
||||||
try {
|
|
||||||
val dpm = context.getDPM()
|
|
||||||
if(status) dpm.addUserRestriction(receiver, id)
|
|
||||||
else dpm.clearUserRestriction(receiver, id)
|
|
||||||
@SuppressLint("NewApi")
|
|
||||||
vm.userRestrictions.value = dpm.getUserRestrictions(receiver)
|
|
||||||
} catch(_: Exception) {
|
|
||||||
context.showOperationResultToast(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composable<Users> { UsersScreen(::navigateUp, ::navigate) }
|
composable<Users> { UsersScreen(::navigateUp, ::navigate) }
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.bintianqi.owndroid
|
package com.bintianqi.owndroid
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@@ -9,7 +8,6 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
class MyViewModel(application: Application): AndroidViewModel(application) {
|
class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||||
val theme = MutableStateFlow(ThemeSettings())
|
val theme = MutableStateFlow(ThemeSettings())
|
||||||
val userRestrictions = MutableStateFlow(Bundle())
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val sp = SharedPrefs(application)
|
val sp = SharedPrefs(application)
|
||||||
|
|||||||
@@ -12,20 +12,29 @@ import androidx.compose.foundation.layout.Box
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.LargeTopAppBar
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -35,6 +44,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -49,6 +59,7 @@ import androidx.core.net.toUri
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.bintianqi.owndroid.ui.FunctionItem
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.MyScaffold
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
|
import com.bintianqi.owndroid.ui.NavIcon
|
||||||
import com.bintianqi.owndroid.ui.Notes
|
import com.bintianqi.owndroid.ui.Notes
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@@ -59,6 +70,7 @@ import java.util.Locale
|
|||||||
|
|
||||||
@Serializable object Settings
|
@Serializable object Settings
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
|
fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -66,19 +78,55 @@ fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
|
|||||||
val exportLogsLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {
|
val exportLogsLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) {
|
||||||
if(it != null) exportLogs(context, it)
|
if(it != null) exportLogs(context, it)
|
||||||
}
|
}
|
||||||
MyScaffold(R.string.settings, onNavigateUp, 0.dp) {
|
val sb = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
|
||||||
FunctionItem(title = R.string.options, icon = R.drawable.tune_fill0) { onNavigate(SettingsOptions) }
|
var dropdown by remember { mutableStateOf(false) }
|
||||||
FunctionItem(title = R.string.appearance, icon = R.drawable.format_paint_fill0) { onNavigate(Appearance) }
|
Scaffold(
|
||||||
FunctionItem(R.string.app_lock, icon = R.drawable.lock_fill0) { onNavigate(AppLockSettings) }
|
Modifier.nestedScroll(sb.nestedScrollConnection),
|
||||||
if (privilege.device || privilege.profile)
|
topBar = {
|
||||||
FunctionItem(title = R.string.api, icon = R.drawable.code_fill0) { onNavigate(ApiSettings) }
|
LargeTopAppBar(
|
||||||
if (privilege.device && !privilege.dhizuku)
|
{ Text(stringResource(R.string.settings)) },
|
||||||
FunctionItem(R.string.notifications, icon = R.drawable.notifications_fill0) { onNavigate(Notifications) }
|
navigationIcon = { NavIcon(onNavigateUp) },
|
||||||
FunctionItem(title = R.string.export_logs, icon = R.drawable.description_fill0) {
|
scrollBehavior = sb,
|
||||||
val time = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(Date(System.currentTimeMillis()))
|
actions = {
|
||||||
exportLogsLauncher.launch("owndroid_log_$time")
|
Box {
|
||||||
|
IconButton({ dropdown = true }) {
|
||||||
|
Icon(Icons.Default.MoreVert, null)
|
||||||
|
}
|
||||||
|
DropdownMenu(dropdown, { dropdown = false }) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
{ Text(stringResource(R.string.export_logs)) },
|
||||||
|
{
|
||||||
|
dropdown = false
|
||||||
|
val time = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault())
|
||||||
|
.format(Date(System.currentTimeMillis()))
|
||||||
|
exportLogsLauncher.launch("owndroid_log_$time")
|
||||||
|
},
|
||||||
|
leadingIcon = {
|
||||||
|
Icon(painterResource(R.drawable.description_fill0), null)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
.padding(bottom = 80.dp)
|
||||||
|
) {
|
||||||
|
FunctionItem(title = R.string.options, icon = R.drawable.tune_fill0) { onNavigate(SettingsOptions) }
|
||||||
|
FunctionItem(title = R.string.appearance, icon = R.drawable.format_paint_fill0) { onNavigate(Appearance) }
|
||||||
|
FunctionItem(R.string.app_lock, icon = R.drawable.lock_fill0) { onNavigate(AppLockSettings) }
|
||||||
|
if (privilege.device || privilege.profile)
|
||||||
|
FunctionItem(title = R.string.api, icon = R.drawable.code_fill0) { onNavigate(ApiSettings) }
|
||||||
|
if (privilege.device && !privilege.dhizuku)
|
||||||
|
FunctionItem(R.string.notifications, icon = R.drawable.notifications_fill0) { onNavigate(Notifications) }
|
||||||
|
FunctionItem(title = R.string.about, icon = R.drawable.info_fill0) { onNavigate(About) }
|
||||||
}
|
}
|
||||||
FunctionItem(title = R.string.about, icon = R.drawable.info_fill0) { onNavigate(About) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +159,10 @@ fun SettingsOptionsScreen(onNavigateUp: () -> Unit) {
|
|||||||
fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onThemeChange: (ThemeSettings) -> Unit) {
|
fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onThemeChange: (ThemeSettings) -> Unit) {
|
||||||
var darkThemeMenu by remember { mutableStateOf(false) }
|
var darkThemeMenu by remember { mutableStateOf(false) }
|
||||||
var theme by remember { mutableStateOf(currentTheme) }
|
var theme by remember { mutableStateOf(currentTheme) }
|
||||||
|
fun update(it: ThemeSettings) {
|
||||||
|
theme = it
|
||||||
|
onThemeChange(it)
|
||||||
|
}
|
||||||
val darkThemeTextID = when(theme.darkTheme) {
|
val darkThemeTextID = when(theme.darkTheme) {
|
||||||
1 -> R.string.on
|
1 -> R.string.on
|
||||||
0 -> R.string.off
|
0 -> R.string.off
|
||||||
@@ -121,7 +173,7 @@ fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onTh
|
|||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.material_you_color,
|
R.string.material_you_color,
|
||||||
state = theme.materialYou,
|
state = theme.materialYou,
|
||||||
onCheckedChange = { theme = theme.copy(materialYou = it) }
|
onCheckedChange = { update(theme.copy(materialYou = it)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Box {
|
Box {
|
||||||
@@ -133,13 +185,14 @@ fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onTh
|
|||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.follow_system)) },
|
text = { Text(stringResource(R.string.follow_system)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
theme = theme.copy(darkTheme = -1)
|
update(theme.copy(darkTheme = -1))
|
||||||
darkThemeMenu = false
|
darkThemeMenu = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.on)) },
|
text = { Text(stringResource(R.string.on)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
|
update(theme.copy(darkTheme = 1))
|
||||||
theme = theme.copy(darkTheme = 1)
|
theme = theme.copy(darkTheme = 1)
|
||||||
darkThemeMenu = false
|
darkThemeMenu = false
|
||||||
}
|
}
|
||||||
@@ -147,19 +200,17 @@ fun AppearanceScreen(onNavigateUp: () -> Unit, currentTheme: ThemeSettings, onTh
|
|||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringResource(R.string.off)) },
|
text = { Text(stringResource(R.string.off)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
theme = theme.copy(darkTheme = 0)
|
update(theme.copy(darkTheme = 0))
|
||||||
darkThemeMenu = false
|
darkThemeMenu = false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnimatedVisibility(theme.darkTheme == 1 || (theme.darkTheme == -1 && isSystemInDarkTheme())) {
|
AnimatedVisibility(theme.darkTheme == 1 || (theme.darkTheme == -1 && isSystemInDarkTheme())) {
|
||||||
SwitchItem(R.string.black_theme, state = theme.blackTheme, onCheckedChange = { theme = theme.copy(blackTheme = it) })
|
SwitchItem(
|
||||||
}
|
R.string.black_theme, state = theme.blackTheme,
|
||||||
AnimatedVisibility(theme != currentTheme, Modifier.fillMaxWidth().padding(8.dp)) {
|
onCheckedChange = { update(theme.copy(blackTheme = it)) }
|
||||||
Button({onThemeChange(theme)}) {
|
)
|
||||||
Text(stringResource(R.string.apply))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import com.bintianqi.owndroid.backToHomeStateFlow
|
|||||||
import com.bintianqi.owndroid.createShortcuts
|
import com.bintianqi.owndroid.createShortcuts
|
||||||
import com.bintianqi.owndroid.myPrivilege
|
import com.bintianqi.owndroid.myPrivilege
|
||||||
import com.rosan.dhizuku.api.Dhizuku
|
import com.rosan.dhizuku.api.Dhizuku
|
||||||
import com.rosan.dhizuku.api.Dhizuku.binderWrapper
|
|
||||||
import com.rosan.dhizuku.api.DhizukuBinderWrapper
|
import com.rosan.dhizuku.api.DhizukuBinderWrapper
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
@@ -73,7 +72,7 @@ fun binderWrapperDevicePolicyManager(appContext: Context): DevicePolicyManager?
|
|||||||
val oldInterface = field[manager] as IDevicePolicyManager
|
val oldInterface = field[manager] as IDevicePolicyManager
|
||||||
if (oldInterface is DhizukuBinderWrapper) return manager
|
if (oldInterface is DhizukuBinderWrapper) return manager
|
||||||
val oldBinder = oldInterface.asBinder()
|
val oldBinder = oldInterface.asBinder()
|
||||||
val newBinder = binderWrapper(oldBinder)
|
val newBinder = Dhizuku.binderWrapper(oldBinder)
|
||||||
val newInterface = IDevicePolicyManager.Stub.asInterface(newBinder)
|
val newInterface = IDevicePolicyManager.Stub.asInterface(newBinder)
|
||||||
field[manager] = newInterface
|
field[manager] = newInterface
|
||||||
return manager
|
return manager
|
||||||
@@ -93,7 +92,7 @@ private fun binderWrapperPackageInstaller(appContext: Context): PackageInstaller
|
|||||||
val oldInterface = field[installer] as IPackageInstaller
|
val oldInterface = field[installer] as IPackageInstaller
|
||||||
if (oldInterface is DhizukuBinderWrapper) return installer
|
if (oldInterface is DhizukuBinderWrapper) return installer
|
||||||
val oldBinder = oldInterface.asBinder()
|
val oldBinder = oldInterface.asBinder()
|
||||||
val newBinder = binderWrapper(oldBinder)
|
val newBinder = Dhizuku.binderWrapper(oldBinder)
|
||||||
val newInterface = IPackageInstaller.Stub.asInterface(newBinder)
|
val newInterface = IPackageInstaller.Stub.asInterface(newBinder)
|
||||||
field[installer] = newInterface
|
field[installer] = newInterface
|
||||||
return installer
|
return installer
|
||||||
@@ -107,7 +106,6 @@ fun Context.getPackageInstaller(): PackageInstaller {
|
|||||||
if(SharedPrefs(this).dhizuku) {
|
if(SharedPrefs(this).dhizuku) {
|
||||||
if (!dhizukuPermissionGranted()) {
|
if (!dhizukuPermissionGranted()) {
|
||||||
dhizukuErrorStatus.value = 2
|
dhizukuErrorStatus.value = 2
|
||||||
backToHomeStateFlow.value = true
|
|
||||||
return this.packageManager.packageInstaller
|
return this.packageManager.packageInstaller
|
||||||
}
|
}
|
||||||
return binderWrapperPackageInstaller(this) ?: this.packageManager.packageInstaller
|
return binderWrapperPackageInstaller(this) ?: this.packageManager.packageInstaller
|
||||||
@@ -120,7 +118,6 @@ fun Context.getDPM(): DevicePolicyManager {
|
|||||||
if(SharedPrefs(this).dhizuku) {
|
if(SharedPrefs(this).dhizuku) {
|
||||||
if (!dhizukuPermissionGranted()) {
|
if (!dhizukuPermissionGranted()) {
|
||||||
dhizukuErrorStatus.value = 2
|
dhizukuErrorStatus.value = 2
|
||||||
backToHomeStateFlow.value = true
|
|
||||||
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
}
|
}
|
||||||
return binderWrapperDevicePolicyManager(this) ?: this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
return binderWrapperDevicePolicyManager(this) ?: this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ fun WorkModesScreen(
|
|||||||
Spacer(Modifier.padding(horizontal = 2.dp))
|
Spacer(Modifier.padding(horizontal = 2.dp))
|
||||||
Button({ dialog = 5 }) { Text(stringResource(R.string.adb_command)) }
|
Button({ dialog = 5 }) { Text(stringResource(R.string.adb_command)) }
|
||||||
Spacer(Modifier.padding(horizontal = 2.dp))
|
Spacer(Modifier.padding(horizontal = 2.dp))
|
||||||
if (VERSION.SDK_INT == 35) Button({
|
if (VERSION.SDK_INT >= 33) Button({
|
||||||
dialog = 6
|
dialog = 6
|
||||||
}) {
|
}) {
|
||||||
Text(stringResource(R.string.root_force_activate))
|
Text(stringResource(R.string.root_force_activate))
|
||||||
@@ -575,6 +575,7 @@ fun LockScreenInfoScreen(onNavigateUp: () -> Unit) {
|
|||||||
onClick = {
|
onClick = {
|
||||||
focusMgr.clearFocus()
|
focusMgr.clearFocus()
|
||||||
dpm.setDeviceOwnerLockScreenInfo(receiver, null)
|
dpm.setDeviceOwnerLockScreenInfo(receiver, null)
|
||||||
|
infoText = ""
|
||||||
context.showOperationResultToast(true)
|
context.showOperationResultToast(true)
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateMapOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@@ -73,14 +77,30 @@ data class UserRestrictionOptions(
|
|||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserRestrictionOptionsScreen(
|
fun UserRestrictionOptionsScreen(
|
||||||
data: UserRestrictionOptions, restrictions: Bundle,
|
data: UserRestrictionOptions, onNavigateUp: () -> Unit
|
||||||
onNavigateUp: () -> Unit, onRestrictionChange: (String, Boolean) -> Unit
|
|
||||||
) {
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val dpm = context.getDPM()
|
||||||
|
val receiver = context.getReceiver()
|
||||||
|
val status = remember { mutableStateMapOf<String, Boolean>() }
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
val restrictions = dpm.getUserRestrictions(receiver)
|
||||||
|
data.items.forEach {
|
||||||
|
status.put(it.id, restrictions.getBoolean(it.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
MyScaffold(data.title, onNavigateUp, 0.dp) {
|
MyScaffold(data.title, onNavigateUp, 0.dp) {
|
||||||
data.items.filter { Build.VERSION.SDK_INT >= it.requiresApi }.forEach { restriction ->
|
data.items.filter { Build.VERSION.SDK_INT >= it.requiresApi }.forEach { restriction ->
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
restriction.name, restriction.id, restriction.icon,
|
restriction.name, restriction.id, restriction.icon, status[restriction.id] == true,
|
||||||
restrictions.getBoolean(restriction.id), { onRestrictionChange(restriction.id, it) }, padding = true
|
{
|
||||||
|
if (it) {
|
||||||
|
dpm.addUserRestriction(receiver, restriction.id)
|
||||||
|
} else {
|
||||||
|
dpm.clearUserRestriction(receiver, restriction.id)
|
||||||
|
}
|
||||||
|
status[restriction.id] = dpm.getUserRestrictions(receiver).getBoolean(restriction.id)
|
||||||
|
}, padding = true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ fun OwnDroidTheme(
|
|||||||
darkTheme -> darkScheme
|
darkTheme -> darkScheme
|
||||||
else -> lightScheme
|
else -> lightScheme
|
||||||
}.let {
|
}.let {
|
||||||
if(darkTheme && theme.blackTheme) it.copy(background = Color.Black) else it
|
if(darkTheme && theme.blackTheme) it.copy(background = Color.Black, surface = Color.Black) else it
|
||||||
}
|
}
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
SideEffect {
|
SideEffect {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.9.2"
|
agp = "8.10.0"
|
||||||
kotlin = "2.1.20"
|
kotlin = "2.1.20"
|
||||||
|
|
||||||
navigation-compose = "2.9.0"
|
navigation-compose = "2.9.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user