Remove PermissionsScreen

Lock app when leaving, close #118
This commit is contained in:
BinTianqi
2025-04-20 12:14:16 +08:00
parent 19acf94e7b
commit 16a57206ea
10 changed files with 210 additions and 217 deletions

View File

@@ -19,7 +19,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
@@ -27,12 +26,13 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -40,7 +40,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
@@ -159,10 +159,8 @@ import com.bintianqi.owndroid.dpm.PasswordInfoScreen
import com.bintianqi.owndroid.dpm.PasswordScreen
import com.bintianqi.owndroid.dpm.PermissionPolicy
import com.bintianqi.owndroid.dpm.PermissionPolicyScreen
import com.bintianqi.owndroid.dpm.Permissions
import com.bintianqi.owndroid.dpm.PermissionsManager
import com.bintianqi.owndroid.dpm.PermissionsManagerScreen
import com.bintianqi.owndroid.dpm.PermissionsScreen
import com.bintianqi.owndroid.dpm.PermittedAccessibilityServices
import com.bintianqi.owndroid.dpm.PermittedAccessibilityServicesScreen
import com.bintianqi.owndroid.dpm.PermittedInputMethods
@@ -333,9 +331,6 @@ fun Home(vm: MyViewModel) {
})
}
composable<Permissions> {
PermissionsScreen(::navigateUp) { navController.navigate(it) }
}
composable<DelegatedAdmins> { DelegatedAdminsScreen(::navigateUp, ::navigate) }
composable<AddDelegatedAdmin>{ AddDelegatedAdminScreen(it.toRoute(), ::navigateUp) }
composable<DeviceInfo> { DeviceInfoScreen(::navigateUp) }
@@ -488,9 +483,15 @@ fun Home(vm: MyViewModel) {
}
}
DisposableEffect(lifecycleOwner) {
val sp = SharedPrefs(context)
val observer = LifecycleEventObserver { _, event ->
if(event == Lifecycle.Event.ON_CREATE && !SharedPrefs(context).lockPasswordHash.isNullOrEmpty()) {
navController.navigate(AppLock)
if (
(event == Lifecycle.Event.ON_CREATE && !sp.lockPasswordHash.isNullOrEmpty()) ||
(event == Lifecycle.Event.ON_RESUME && sp.lockWhenLeaving)
) {
navController.navigate(AppLock) {
launchSingleTop = true
}
}
}
lifecycleOwner.lifecycle.addObserver(observer)
@@ -518,55 +519,22 @@ fun Home(vm: MyViewModel) {
private fun HomeScreen(onNavigate: (Any) -> Unit) {
val context = LocalContext.current
val privilege by myPrivilege.collectAsStateWithLifecycle()
val activateType = (if(privilege.dhizuku) context.getString(R.string.dhizuku) + " - " else "") +
context.getString(
if(privilege.device) R.string.device_owner
else if(privilege.work) R.string.work_profile_owner
else if(privilege.profile) R.string.profile_owner
else R.string.click_to_activate
)
val sb = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
Modifier.nestedScroll(sb.nestedScrollConnection),
topBar = {
TopAppBar(
{}, actions = {
LargeTopAppBar(
{ Text(stringResource(R.string.app_name)) },
actions = {
IconButton({ onNavigate(WorkModes(true)) }) { Icon(painterResource(R.drawable.security_fill0), null) }
IconButton({ onNavigate(Settings) }) { Icon(Icons.Default.Settings, null) }
}
},
scrollBehavior = sb
)
}
) {
Column(modifier = Modifier.padding(it).verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 8.dp))
Text(
text = stringResource(R.string.app_name), style = typography.headlineLarge,
modifier = Modifier.padding(start = HorizontalPadding)
)
Spacer(Modifier.padding(vertical = 8.dp))
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp, horizontal = HorizontalPadding)
.clip(RoundedCornerShape(15))
.background(color = colorScheme.primary)
.clickable(onClick = { onNavigate(Permissions) })
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
val activated = privilege.device || privilege.profile
Icon(
painterResource(if(activated) R.drawable.check_circle_fill1 else R.drawable.block_fill0), null,
Modifier.padding(start = 14.dp), colorScheme.onPrimary
)
Column(Modifier.padding(start = 12.dp)) {
Text(
text = stringResource(if(activated) R.string.activated else R.string.deactivated),
style = typography.headlineSmall,
color = colorScheme.onPrimary,
modifier = Modifier.padding(bottom = 2.dp)
)
if(activateType != "") { Text(text = activateType, color = colorScheme.onPrimary) }
}
}
Column(Modifier.fillMaxSize().padding(it).verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 6.dp))
if(privilege.device || privilege.profile) {
HomePageItem(R.string.system, R.drawable.android_fill0) { onNavigate(SystemManager) }
HomePageItem(R.string.network, R.drawable.wifi_fill0) { onNavigate(Network) }

View File

@@ -173,6 +173,7 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
var password by remember { mutableStateOf("") }
var confirmPassword by remember { mutableStateOf("") }
var allowBiometrics by remember { mutableStateOf(sp.biometricsUnlock) }
var lockWhenLeaving by remember { mutableStateOf(sp.lockWhenLeaving) }
val fr = FocusRequester()
val alreadySet = !sp.lockPasswordHash.isNullOrEmpty()
val isInputLegal = password.length !in 1..3 && (alreadySet || (password.isNotEmpty() && password.isNotBlank()))
@@ -194,11 +195,16 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
Text(stringResource(R.string.allow_biometrics))
Switch(allowBiometrics, { allowBiometrics = it })
}
Row(Modifier.fillMaxWidth().padding(bottom = 6.dp), Arrangement.SpaceBetween, Alignment.CenterVertically) {
Text(stringResource(R.string.lock_when_leaving))
Switch(lockWhenLeaving, { lockWhenLeaving = it })
}
Button(
onClick = {
fm.clearFocus()
if(password.isNotEmpty()) sp.lockPasswordHash = password.hash()
sp.biometricsUnlock = allowBiometrics
sp.lockWhenLeaving = lockWhenLeaving
onNavigateUp()
},
modifier = Modifier.fillMaxWidth(),
@@ -211,6 +217,7 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
fm.clearFocus()
sp.lockPasswordHash = ""
sp.biometricsUnlock = false
sp.lockWhenLeaving = false
onNavigateUp()
},
modifier = Modifier.fillMaxWidth()

View File

@@ -21,6 +21,7 @@ class SharedPrefs(context: Context) {
var blackTheme by BooleanSharedPref("theme.black")
var lockPasswordHash by StringSharedPref("lock.password.sha256")
var biometricsUnlock by BooleanSharedPref("lock.biometrics")
var lockWhenLeaving by BooleanSharedPref("lock.onleave")
var applicationsListView by BooleanSharedPref("applications.list_view", true)
var shortcuts by BooleanSharedPref("shortcuts", true)
}

View File

@@ -1,6 +1,5 @@
package com.bintianqi.owndroid
import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context

View File

@@ -6,7 +6,6 @@ import android.content.Context
import android.content.pm.PackageManager
import android.os.Build.VERSION
import android.os.PersistableBundle
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.annotation.Keep
import androidx.annotation.RequiresApi
@@ -83,7 +82,6 @@ import com.bintianqi.owndroid.Settings
import com.bintianqi.owndroid.SharedPrefs
import com.bintianqi.owndroid.myPrivilege
import com.bintianqi.owndroid.showOperationResultToast
import com.bintianqi.owndroid.ui.FunctionItem
import com.bintianqi.owndroid.ui.InfoItem
import com.bintianqi.owndroid.ui.MyScaffold
import com.bintianqi.owndroid.ui.MySmallTitleScaffold
@@ -91,7 +89,6 @@ import com.bintianqi.owndroid.ui.NavIcon
import com.bintianqi.owndroid.ui.Notes
import com.bintianqi.owndroid.updatePrivilege
import com.bintianqi.owndroid.useShizuku
import com.bintianqi.owndroid.writeClipBoard
import com.bintianqi.owndroid.yesOrNo
import com.rosan.dhizuku.api.Dhizuku
import com.rosan.dhizuku.api.DhizukuRequestPermissionListener
@@ -99,120 +96,6 @@ import com.topjohnwu.superuser.Shell
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
@Serializable object Permissions
@Composable
fun PermissionsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val privilege by myPrivilege.collectAsStateWithLifecycle()
var dialog by remember { mutableIntStateOf(0) }
var bindingShizuku by remember { mutableStateOf(false) }
val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (privilege.device || privilege.profile)) dpm.enrollmentSpecificId else ""
MyScaffold(R.string.permissions, onNavigateUp, 0.dp) {
if(VERSION.SDK_INT >= 26) FunctionItem(R.string.delegated_admins) { onNavigate(DelegatedAdmins) }
FunctionItem(R.string.device_info, icon = R.drawable.perm_device_information_fill0) { onNavigate(DeviceInfo) }
if(VERSION.SDK_INT >= 24 && (privilege.profile || (VERSION.SDK_INT >= 26 && privilege.device))) {
FunctionItem(R.string.org_name, icon = R.drawable.corporate_fare_fill0) { dialog = 2 }
}
if(VERSION.SDK_INT >= 31) {
FunctionItem(R.string.org_id, icon = R.drawable.corporate_fare_fill0) { dialog = 3 }
}
if(enrollmentSpecificId != "") {
FunctionItem(R.string.enrollment_specific_id, icon = R.drawable.id_card_fill0) { dialog = 1 }
}
if(VERSION.SDK_INT >= 24 && (privilege.device || privilege.org)) {
FunctionItem(R.string.lock_screen_info, icon = R.drawable.screen_lock_portrait_fill0) { onNavigate(LockScreenInfo) }
}
if(VERSION.SDK_INT >= 24) {
FunctionItem(R.string.support_messages, icon = R.drawable.chat_fill0) { onNavigate(SupportMessage) }
}
}
if(bindingShizuku) {
Dialog(onDismissRequest = { bindingShizuku = false }) {
CircularProgressIndicator()
}
}
if(dialog != 0) {
var input by remember { mutableStateOf("") }
AlertDialog(
title = {
Text(stringResource(
when(dialog){
1 -> R.string.enrollment_specific_id
2 -> R.string.org_name
3 -> R.string.org_id
4 -> R.string.dhizuku
else -> R.string.permissions
}
))
},
text = {
val focusMgr = LocalFocusManager.current
LaunchedEffect(Unit) {
if(dialog == 1 && VERSION.SDK_INT >= 31) input = dpm.enrollmentSpecificId
}
Column {
if(dialog != 4) OutlinedTextField(
value = input,
onValueChange = { input = it }, readOnly = dialog == 1,
label = {
Text(stringResource(
when(dialog){
1 -> R.string.enrollment_specific_id
2 -> R.string.org_name
3 -> R.string.org_id
else -> R.string.permissions
}
))
},
trailingIcon = {
if(dialog == 1) IconButton(onClick = { writeClipBoard(context, input) }) {
Icon(painter = painterResource(R.drawable.content_copy_fill0), contentDescription = stringResource(R.string.copy))
}
},
supportingText = {
if(dialog == 3) Text(stringResource(R.string.length_6_to_64))
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
textStyle = typography.bodyLarge,
modifier = Modifier.fillMaxWidth().padding(bottom = if(dialog == 2) 0.dp else 10.dp)
)
if(dialog == 1) Text(stringResource(R.string.info_enrollment_specific_id))
if(dialog == 3) Text(stringResource(R.string.info_org_id))
if(dialog == 4) Text(stringResource(R.string.info_dhizuku))
}
},
onDismissRequest = { dialog = 0 },
dismissButton = {
if(dialog != 4) TextButton(
onClick = { dialog = 0 }
) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try {
if(dialog == 2 && VERSION.SDK_INT >= 24) dpm.setOrganizationName(receiver, input)
if(dialog == 3 && VERSION.SDK_INT >= 31) dpm.setOrganizationId(input)
dialog = 0
} catch(_: IllegalStateException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
},
enabled = (dialog == 3 && input.length in 6..64) || dialog != 3
) {
Text(stringResource(R.string.confirm))
}
}
)
}
}
@Serializable data class WorkModes(val canNavigateUp: Boolean)
@OptIn(ExperimentalMaterial3Api::class)
@@ -254,6 +137,13 @@ fun WorkModesScreen(
dialog = 4
}
)
if (VERSION.SDK_INT >= 26) DropdownMenuItem(
{ Text(stringResource(R.string.delegated_admins)) },
{
expanded = false
onNavigate(DelegatedAdmins)
}
)
if (!privilege.dhizuku && VERSION.SDK_INT >= 28) DropdownMenuItem(
{ Text(stringResource(R.string.transfer_ownership)) },
{

View File

@@ -152,7 +152,6 @@ import java.security.cert.X509Certificate
import java.util.Date
import java.util.TimeZone
import java.util.concurrent.Executors
import kotlin.collections.addAll
import kotlin.math.roundToLong
@Serializable object SystemManager
@@ -164,7 +163,11 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
val receiver = context.getReceiver()
val sp = SharedPrefs(context)
val privilege by myPrivilege.collectAsStateWithLifecycle()
/** 1: reboot, 2: bug report, 3: org name, 4: org id, 5: enrollment specific id*/
var dialog by remember { mutableIntStateOf(0) }
var enrollmentSpecificId by remember {
mutableStateOf(if (VERSION.SDK_INT >= 31 && (privilege.device || privilege.profile)) dpm.enrollmentSpecificId else "")
}
MyScaffold(R.string.system, onNavigateUp, 0.dp) {
FunctionItem(R.string.options, icon = R.drawable.tune_fill0) { onNavigate(SystemOptions) }
FunctionItem(R.string.keyguard, icon = R.drawable.screen_lock_portrait_fill0) { onNavigate(Keyguard) }
@@ -200,6 +203,22 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
if(VERSION.SDK_INT >= 26 && !privilege.dhizuku && (privilege.device || privilege.org)) {
FunctionItem(R.string.security_logging, icon = R.drawable.description_fill0) { onNavigate(SecurityLogging) }
}
FunctionItem(R.string.device_info, icon = R.drawable.perm_device_information_fill0) { onNavigate(DeviceInfo) }
if(VERSION.SDK_INT >= 24 && (privilege.profile || (VERSION.SDK_INT >= 26 && privilege.device))) {
FunctionItem(R.string.org_name, icon = R.drawable.corporate_fare_fill0) { dialog = 3 }
}
if(VERSION.SDK_INT >= 31) {
FunctionItem(R.string.org_id, icon = R.drawable.corporate_fare_fill0) { dialog = 4 }
}
if(enrollmentSpecificId != "") {
FunctionItem(R.string.enrollment_specific_id, icon = R.drawable.id_card_fill0) { dialog = 5 }
}
if(VERSION.SDK_INT >= 24 && (privilege.device || privilege.org)) {
FunctionItem(R.string.lock_screen_info, icon = R.drawable.screen_lock_portrait_fill0) { onNavigate(LockScreenInfo) }
}
if(VERSION.SDK_INT >= 24) {
FunctionItem(R.string.support_messages, icon = R.drawable.chat_fill0) { onNavigate(SupportMessage) }
}
FunctionItem(R.string.disable_account_management, icon = R.drawable.account_circle_fill0) { onNavigate(DisableAccountManagement) }
if(VERSION.SDK_INT >= 23 && (privilege.device || privilege.org)) {
FunctionItem(R.string.system_update_policy, icon = R.drawable.system_update_fill0) { onNavigate(SetSystemUpdatePolicy) }
@@ -214,7 +233,7 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
FunctionItem(R.string.wipe_data, icon = R.drawable.device_reset_fill0) { onNavigate(WipeData) }
}
}
if(dialog != 0 &&VERSION.SDK_INT >= 24) AlertDialog(
if((dialog == 1 || dialog == 2) && VERSION.SDK_INT >= 24) AlertDialog(
onDismissRequest = { dialog = 0 },
title = { Text(stringResource(if(dialog == 1) R.string.reboot else R.string.bug_report)) },
text = { Text(stringResource(if(dialog == 1) R.string.info_reboot else R.string.confirm_bug_report)) },
@@ -239,6 +258,65 @@ fun SystemManagerScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) {
},
modifier = Modifier.fillMaxWidth()
)
if(dialog in 3..5) {
var input by remember { mutableStateOf("") }
AlertDialog(
text = {
val focusMgr = LocalFocusManager.current
LaunchedEffect(Unit) {
if(dialog == 5 && VERSION.SDK_INT >= 31) input = dpm.enrollmentSpecificId
}
Column {
OutlinedTextField(
input, { input = it },
Modifier.fillMaxWidth().padding(bottom = if (dialog != 3) 8.dp else 0.dp),
readOnly = dialog == 5,
label = {
Text(stringResource(
when(dialog){
3 -> R.string.org_name
4 -> R.string.org_id
5 -> R.string.enrollment_specific_id
else -> R.string.place_holder
}
))
},
supportingText = {
if(dialog == 4) Text(stringResource(R.string.length_6_to_64))
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
textStyle = typography.bodyLarge
)
if(dialog == 5) Text(stringResource(R.string.info_enrollment_specific_id))
if(dialog == 4) Text(stringResource(R.string.info_org_id))
}
},
onDismissRequest = { dialog = 0 },
dismissButton = {
if (dialog != 5) TextButton({ dialog = 0 }) { Text(stringResource(R.string.cancel)) }
},
confirmButton = {
TextButton(
onClick = {
try {
if (dialog == 3 && VERSION.SDK_INT >= 24) dpm.setOrganizationName(receiver, input)
if (dialog == 4 && VERSION.SDK_INT >= 31) {
dpm.setOrganizationId(input)
enrollmentSpecificId = dpm.enrollmentSpecificId
}
dialog = 0
} catch(_: IllegalStateException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
},
enabled = dialog != 4 || input.length in 6..64
) {
Text(stringResource(R.string.confirm))
}
}
)
}
}
@Serializable object SystemOptions
@@ -482,7 +560,9 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
if(timeInteractionSource.collectIsPressedAsState().value) picker = 2
MyScaffold(R.string.change_time, onNavigateUp) {
SingleChoiceSegmentedButtonRow(
modifier = Modifier.fillMaxWidth().padding(top = 4.dp)
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp)
) {
val coroutine = rememberCoroutineScope()
SegmentedButton(
@@ -524,7 +604,9 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
onValueChange = {}, readOnly = true,
label = { Text(stringResource(R.string.time)) },
interactionSource = timeInteractionSource,
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
)
Button(
onClick = {
@@ -551,7 +633,9 @@ fun ChangeTimeScreen(onNavigateUp: () -> Unit) {
val timeMillis = inputTime.toLong()
context.showOperationResultToast(dpm.setTime(receiver, timeMillis))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
enabled = inputTime.toLongOrNull() != null
) {
Text(stringResource(R.string.apply))
@@ -851,7 +935,9 @@ fun ContentProtectionPolicyScreen(onNavigateUp: () -> Unit) {
refresh()
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -884,7 +970,9 @@ fun PermissionPolicyScreen(onNavigateUp: () -> Unit) {
dpm.setPermissionPolicy(receiver,selectedPolicy)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -916,7 +1004,9 @@ fun MtePolicyScreen(onNavigateUp: () -> Unit) {
}
selectedMtePolicy = dpm.mtePolicy
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -953,7 +1043,9 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
appPolicy = dpm.nearbyAppStreamingPolicy
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -985,7 +1077,9 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
notificationPolicy = dpm.nearbyNotificationStreamingPolicy
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -1013,7 +1107,9 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
}
) { paddingValues ->
Column(
modifier = Modifier.fillMaxSize().padding(paddingValues)
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
) {
TabRow(tabIndex) {
Tab(
@@ -1032,14 +1128,21 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
HorizontalPager(pagerState, verticalAlignment = Alignment.Top) { page ->
if(page == 0 || page == 1) {
Column(
Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = HorizontalPadding).padding(bottom = 80.dp)
Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(horizontal = HorizontalPadding)
.padding(bottom = 80.dp)
) {
if(page == 0) StartLockTaskMode()
else LockTaskPackages()
}
} else {
Column(
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(bottom = 80.dp)
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(bottom = 80.dp)
) {
LockTaskFeatures()
}
@@ -1075,7 +1178,9 @@ private fun ColumnScope.StartLockTaskMode() {
.clickable { choosePackage.launch(null) }
.padding(3.dp))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 3.dp)
)
CheckBoxItem(R.string.specify_activity, specifyActivity) { specifyActivity = it }
AnimatedVisibility(specifyActivity) {
@@ -1085,7 +1190,9 @@ private fun ColumnScope.StartLockTaskMode() {
label = { Text("Activity") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp)
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 5.dp)
)
}
Button(
@@ -1144,7 +1251,9 @@ private fun ColumnScope.LockTaskPackages() {
.clickable { choosePackage.launch(null) }
.padding(3.dp))
},
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 3.dp)
)
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Button(
@@ -1214,7 +1323,9 @@ private fun ColumnScope.LockTaskFeatures() {
}
}
Button(
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding),
onClick = {
try {
dpm.setLockTaskFeatures(receiver, flags)
@@ -1297,15 +1408,21 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
}
) { paddingValues ->
LazyColumn(
Modifier.fillMaxSize().padding(paddingValues),
Modifier
.fillMaxSize()
.padding(paddingValues),
horizontalAlignment = Alignment.CenterHorizontally
) {
items(caCerts, { it.hash }) { cert ->
Column(
Modifier.fillMaxWidth().clickable{
Modifier
.fillMaxWidth()
.clickable {
caCertByteArray = cert.data
dialog = 2
}.animateItem().padding(vertical = 10.dp, horizontal = 8.dp)
}
.animateItem()
.padding(vertical = 10.dp, horizontal = 8.dp)
) {
Text(cert.hash.substring(0..7))
}
@@ -1339,7 +1456,9 @@ fun CaCertScreen(onNavigateUp: () -> Unit) {
SelectionContainer {
Text(text)
}
if(dialog == 2) Row(Modifier.fillMaxWidth().padding(top = 4.dp), Arrangement.SpaceBetween) {
if(dialog == 2) Row(Modifier
.fillMaxWidth()
.padding(top = 4.dp), Arrangement.SpaceBetween) {
TextButton(
onClick = {
dpm.uninstallCaCert(receiver, caCertByteArray)
@@ -1511,7 +1630,9 @@ fun DisableAccountManagementScreen(onNavigateUp: () -> Unit) {
Icon(imageVector = Icons.Default.Add, contentDescription = stringResource(R.string.add))
}
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() })
)
@@ -1553,15 +1674,20 @@ fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
MyScaffold(R.string.frp_policy, onNavigateUp) {
if(unsupported) {
Column(
Modifier.fillMaxWidth().padding(vertical = 8.dp)
.clip(RoundedCornerShape(8.dp)).background(colorScheme.primaryContainer)
Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clip(RoundedCornerShape(8.dp))
.background(colorScheme.primaryContainer)
) {
Text(stringResource(R.string.frp_not_supported), Modifier.padding(8.dp), color = colorScheme.onPrimaryContainer)
}
} else {
Row(
horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().padding(horizontal = 6.dp, vertical = 8.dp)
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 6.dp, vertical = 8.dp)
) {
Text(stringResource(R.string.use_policy), style = typography.titleLarge)
Switch(checked = usePolicy, onCheckedChange = { usePolicy = it })
@@ -1607,7 +1733,9 @@ fun FrpPolicyScreen(onNavigateUp: () -> Unit) {
.build()
dpm.setFactoryResetProtectionPolicy(receiver, policy)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
) {
Text(stringResource(R.string.apply))
}
@@ -1639,7 +1767,9 @@ fun WipeDataScreen(onNavigateUp: () -> Unit) {
OutlinedTextField(
value = reason, onValueChange = { reason = it },
label = { Text(stringResource(R.string.reason)) },
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 3.dp)
)
}
Spacer(Modifier.padding(vertical = 5.dp))
@@ -1752,7 +1882,9 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
var windowedPolicyEnd by remember { mutableStateOf("") }
AnimatedVisibility(selectedPolicy == 2) {
Column(Modifier.padding(horizontal = HorizontalPadding)) {
Row(Modifier.fillMaxWidth().padding(vertical = 4.dp), Arrangement.SpaceBetween) {
Row(Modifier
.fillMaxWidth()
.padding(vertical = 4.dp), Arrangement.SpaceBetween) {
OutlinedTextField(
value = windowedPolicyStart,
label = { Text(stringResource(R.string.start_time)) },
@@ -1767,7 +1899,9 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
label = { Text(stringResource(R.string.end_time)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth(0.96F).padding(bottom = 2.dp)
modifier = Modifier
.fillMaxWidth(0.96F)
.padding(bottom = 2.dp)
)
}
Text(stringResource(R.string.minutes_in_one_day), color = colorScheme.onSurfaceVariant, style = typography.bodyMedium)
@@ -1785,7 +1919,9 @@ fun SystemUpdatePolicyScreen(onNavigateUp: () -> Unit) {
dpm.setSystemUpdatePolicy(receiver,policy)
context.showOperationResultToast(true)
},
modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp, horizontal = HorizontalPadding)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp, horizontal = HorizontalPadding)
) {
Text(stringResource(R.string.apply))
}
@@ -1838,7 +1974,9 @@ fun InstallSystemUpdateScreen(onNavigateUp: () -> Unit) {
onClick = {
getFileLauncher.launch("application/zip")
},
modifier = Modifier.fillMaxWidth().padding(top = 8.dp)
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
) {
Text(stringResource(R.string.select_ota_package))
}

View File

@@ -72,7 +72,6 @@
<string name="timeout">Таймаут</string>
<!--Разрешения-->
<string name="click_to_activate">Нажмите для активации</string>
<string name="profile_owner">Владелец профиля</string>
<string name="device_owner">Владелец устройства</string>
<string name="delegated_admins">Делегированные администраторы</string>
@@ -327,7 +326,6 @@
<!--Рабочий профиль-->
<string name="work_profile">Рабочий профиль</string>
<string name="work_profile_owner">Владелец профиля (рабочий профиль)</string>
<string name="work_profile_activated">Рабочий профиль активирован</string>
<string name="create_work_profile">Создать рабочий профиль</string>
<string name="offline_provisioning">Автономный режим</string>
@@ -632,7 +630,6 @@
<!--TODO: events notification-->
<string name="info_dhizuku">Dhizuku это инструмент позволяющий делиться правами Владельца устройства с другими приложениями.</string>
<string name="info_device_id_attestation">Указывает, поддерживает ли устройство проверку идентификаторов устройств в дополнение к проверке ключей.</string>
<string name="info_unique_device_attestation">Да, если реализация StrongBox Keymaster на устройстве была обеспечена индивидуальным сертификатом аттестации и может использовать его для подписи записей аттестации (индивидуальный сертификат аттестации могут использовать только Keymaster с уровнем безопасности StrongBox).</string>
<string name="info_org_id">Устанавливает идентификатор предприятия (Enterprise ID). Это необходимо для создания идентификатора устройства, специфичного для регистрации.</string>

View File

@@ -71,7 +71,6 @@
<string name="timeout">Zaman Aşımı</string>
<!--Permissions-->
<string name="click_to_activate">Etkinleştirmek için Tıklayın</string>
<string name="profile_owner">Profil Sahibi</string>
<string name="device_owner">Cihaz Sahibi</string>
<string name="delegated_admins">Yetkilendirilmiş Yöneticiler</string>
@@ -321,7 +320,6 @@
<!--WorkProfile-->
<string name="work_profile">İş Profili</string>
<string name="work_profile_owner">Profil Sahibi (İş Profili)</string>
<string name="work_profile_activated">İş Profili Etkinleştirildi</string>
<string name="create_work_profile">İş Profili Oluştur</string>
<string name="offline_provisioning">Çevrimdışı Sağlama</string>
@@ -619,7 +617,6 @@
<!--TODO: events notification-->
<string name="info_dhizuku">Dhizuku, Cihaz Sahibi izinlerini diğer uygulamalarla paylaşabilen bir araçtır.</string>
<string name="info_device_id_attestation">Cihazın, anahtar doğrulamanın yanı sıra cihaz tanımlayıcılarının doğrulamasını destekleyip desteklemediğini belirtir.</string>
<string name="info_unique_device_attestation">Evet, eğer cihaz üzerindeki StrongBox Keymaster uygulaması bireysel bir doğrulama sertifikası ile sağlanmışsa ve bunu kullanarak doğrulama kayıtlarını imzalayabiliyorsa (yalnızca StrongBox güvenlik seviyesine sahip Keymaster bireysel doğrulama sertifikası kullanabilir).</string>
<string name="info_org_id">Kurumsal Kimliği ayarlar. Bu, cihaz için kayıt özel bir kimlik oluşturmak için bir gerekliliktir.</string>

View File

@@ -69,7 +69,6 @@
<string name="timeout">超时</string>
<!--Permissions-->
<string name="click_to_activate">点击以激活</string>
<string name="profile_owner">Profile owner</string>
<string name="device_owner">Device owner</string>
<string name="delegated_admins">委托管理员</string>
@@ -322,7 +321,6 @@
<!--WorkProfile-->
<string name="work_profile">工作资料</string>
<string name="work_profile_owner">Profile owner工作资料</string>
<string name="work_profile_activated">工作资料已激活</string>
<string name="create_work_profile">创建工作资料</string>
<string name="offline_provisioning">离线模式</string>
@@ -560,6 +558,7 @@
<string name="minimum_length_4">长度不得小于4</string>
<string name="leave_empty_to_remain_unchanged">留空以保持未更改</string>
<string name="allow_biometrics">允许生物识别</string>
<string name="lock_when_leaving">离开时锁定</string>
<string name="unlock">解锁</string>
<string name="security">安全性</string>
<string name="clear_storage">清除存储空间</string>
@@ -636,7 +635,6 @@
<string name="system_update_pending">系统更新等待中</string>
<string name="received_time">接收时间</string>
<string name="info_dhizuku">Dhizuku可以分享Device owner权限给其余应用</string>
<string name="info_device_id_attestation">指示设备是否除了密钥证明之外还支持设备标识符证明</string>
<string name="info_unique_device_attestation">如果设备上的StrongBox Keymaster可以配置单独的证明证书并且可以使用该证书签署证明记录则返回true只有StrongBox安全级别的Keymaster才能使用单独的证明证书进行证明</string>
<string name="info_org_id">设置组织ID后才能获取设备注册专用ID</string>

View File

@@ -74,7 +74,6 @@
<string name="timeout">Timeout</string>
<!--Permissions-->
<string name="click_to_activate">Click to activate</string>
<string name="profile_owner">Profile owner</string>
<string name="device_owner">Device owner</string>
<string name="delegated_admins">Delegated admins</string>
@@ -353,7 +352,6 @@
<!--WorkProfile-->
<string name="work_profile">Work Profile</string>
<string name="work_profile_owner">Profile owner (Work profile)</string>
<string name="work_profile_activated">Work profile activated</string>
<string name="create_work_profile">Create work profile</string>
<string name="offline_provisioning">Offline mode</string>
@@ -593,6 +591,7 @@
<string name="minimum_length_4">The length must not be less than 4</string>
<string name="leave_empty_to_remain_unchanged">Leave empty to remain unchanged</string>
<string name="allow_biometrics">Allow biometrics</string>
<string name="lock_when_leaving">Lock when leaving</string>
<string name="unlock">Unlock</string>
<string name="security">Security</string>
<string name="clear_storage">Clear storage</string>
@@ -670,7 +669,6 @@
<string name="system_update_pending">System update pending</string>
<string name="received_time">Received time</string>
<string name="info_dhizuku">Dhizuku is a tool that can share Device owner permissions to other application.</string>
<string name="info_device_id_attestation">Indicates if the device supports attestation of device identifiers in addition to key attestation.</string>
<string name="info_unique_device_attestation">Yes if the StrongBox Keymaster implementation on the device was provisioned with an individual attestation certificate and can sign attestation records using it (only Keymaster with StrongBox security level can use an individual attestation certificate).</string>
<string name="info_org_id">Sets the Enterprise ID. This is a requirement for generating an enrollment-specific ID for the device.</string>