diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index 8065891..c63bf59 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -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 { - PermissionsScreen(::navigateUp) { navController.navigate(it) } - } composable { DelegatedAdminsScreen(::navigateUp, ::navigate) } composable{ AddDelegatedAdminScreen(it.toRoute(), ::navigateUp) } composable { 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) } diff --git a/app/src/main/java/com/bintianqi/owndroid/Settings.kt b/app/src/main/java/com/bintianqi/owndroid/Settings.kt index c1b2128..5693d55 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Settings.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Settings.kt @@ -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() diff --git a/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt b/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt index efafd32..89358ea 100644 --- a/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt +++ b/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt @@ -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) } diff --git a/app/src/main/java/com/bintianqi/owndroid/Utils.kt b/app/src/main/java/com/bintianqi/owndroid/Utils.kt index 68fab38..d999f10 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Utils.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Utils.kt @@ -1,6 +1,5 @@ package com.bintianqi.owndroid -import android.annotation.SuppressLint import android.content.ClipData import android.content.ClipboardManager import android.content.Context diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt index cfaaf5b..f2e673f 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt @@ -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,7 +137,14 @@ fun WorkModesScreen( dialog = 4 } ) - if(!privilege.dhizuku && VERSION.SDK_INT >= 28) DropdownMenuItem( + 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)) }, { expanded = false diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt index 2a8ad44..817284d 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt @@ -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{ - caCertByteArray = cert.data - dialog = 2 - }.animateItem().padding(vertical = 10.dp, horizontal = 8.dp) + Modifier + .fillMaxWidth() + .clickable { + caCertByteArray = cert.data + dialog = 2 + } + .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)) } diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index df8d9e6..6e2ede2 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -72,7 +72,6 @@ Таймаут - Нажмите для активации Владелец профиля Владелец устройства Делегированные администраторы @@ -327,7 +326,6 @@ Рабочий профиль - Владелец профиля (рабочий профиль) Рабочий профиль активирован Создать рабочий профиль Автономный режим @@ -632,7 +630,6 @@ - Dhizuku это инструмент позволяющий делиться правами Владельца устройства с другими приложениями. Указывает, поддерживает ли устройство проверку идентификаторов устройств в дополнение к проверке ключей. Да, если реализация StrongBox Keymaster на устройстве была обеспечена индивидуальным сертификатом аттестации и может использовать его для подписи записей аттестации (индивидуальный сертификат аттестации могут использовать только Keymaster с уровнем безопасности StrongBox). Устанавливает идентификатор предприятия (Enterprise ID). Это необходимо для создания идентификатора устройства, специфичного для регистрации. diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 4f20ba7..9449b0d 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -71,7 +71,6 @@ Zaman Aşımı - Etkinleştirmek için Tıklayın Profil Sahibi Cihaz Sahibi Yetkilendirilmiş Yöneticiler @@ -321,7 +320,6 @@ İş Profili - Profil Sahibi (İş Profili) İş Profili Etkinleştirildi İş Profili Oluştur Çevrimdışı Sağlama @@ -619,7 +617,6 @@ - Dhizuku, Cihaz Sahibi izinlerini diğer uygulamalarla paylaşabilen bir araçtır. Cihazın, anahtar doğrulamanın yanı sıra cihaz tanımlayıcılarının doğrulamasını destekleyip desteklemediğini belirtir. 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). Kurumsal Kimliği ayarlar. Bu, cihaz için kayıt özel bir kimlik oluşturmak için bir gerekliliktir. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2d0a1d0..e50beed 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -69,7 +69,6 @@ 超时 - 点击以激活 Profile owner Device owner 委托管理员 @@ -322,7 +321,6 @@ 工作资料 - Profile owner(工作资料) 工作资料已激活 创建工作资料 离线模式 @@ -560,6 +558,7 @@ 长度不得小于4 留空以保持未更改 允许生物识别 + 离开时锁定 解锁 安全性 清除存储空间 @@ -636,7 +635,6 @@ 系统更新等待中 接收时间 - Dhizuku可以分享Device owner权限给其余应用 指示设备是否除了密钥证明之外还支持设备标识符证明 如果设备上的StrongBox Keymaster可以配置单独的证明证书并且可以使用该证书签署证明记录,则返回true(只有StrongBox安全级别的Keymaster才能使用单独的证明证书进行证明) 设置组织ID后才能获取设备注册专用ID diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 93bc3c1..6a501dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,7 +74,6 @@ Timeout - Click to activate Profile owner Device owner Delegated admins @@ -353,7 +352,6 @@ Work Profile - Profile owner (Work profile) Work profile activated Create work profile Offline mode @@ -593,6 +591,7 @@ The length must not be less than 4 Leave empty to remain unchanged Allow biometrics + Lock when leaving Unlock Security Clear storage @@ -669,8 +668,7 @@ Bug report is no longer available for collection System update pending Received time - - Dhizuku is a tool that can share Device owner permissions to other application. + Indicates if the device supports attestation of device identifiers in addition to key 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). Sets the Enterprise ID. This is a requirement for generating an enrollment-specific ID for the device.