From 3d5b9efd965e55b0452aae345587f37eeddabe13 Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Sat, 7 Sep 2024 10:44:59 +0800 Subject: [PATCH] Hide some functions when unavailable --- .../com/bintianqi/owndroid/MainActivity.kt | 6 +- .../com/bintianqi/owndroid/dpm/Network.kt | 17 ++++- .../com/bintianqi/owndroid/dpm/Password.kt | 5 +- .../com/bintianqi/owndroid/dpm/Permissions.kt | 66 +++++++++++-------- app/src/main/res/values-tr/strings.xml | 5 -- app/src/main/res/values-zh-rCN/strings.xml | 5 -- app/src/main/res/values/strings.xml | 5 -- 7 files changed, 58 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt index 6996d8f..4c65381 100644 --- a/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/MainActivity.kt @@ -183,12 +183,14 @@ private fun HomePage(navCtrl:NavHostController) { val dpm = context.getDPM() val receiver = context.getReceiver() val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE) + var activated by remember { mutableStateOf(false) } var activateType by remember { mutableStateOf("") } val deviceAdmin = context.isDeviceAdmin val deviceOwner = context.isDeviceOwner val profileOwner = context.isProfileOwner val refreshStatus by dhizukuErrorStatus.collectAsState() LaunchedEffect(refreshStatus) { + activated = context.isDeviceAdmin activateType = if(sharedPref.getBoolean("dhizuku", false)) context.getString(R.string.dhizuku) + " - " else "" activateType += context.getString( if(deviceOwner) { R.string.device_owner } @@ -217,14 +219,14 @@ private fun HomePage(navCtrl:NavHostController) { ) { Spacer(modifier = Modifier.padding(start = 22.dp)) Icon( - painter = painterResource(if(deviceAdmin) R.drawable.check_circle_fill1 else R.drawable.block_fill0), + painter = painterResource(if(activated) R.drawable.check_circle_fill1 else R.drawable.block_fill0), contentDescription = null, tint = colorScheme.onPrimary ) Spacer(modifier = Modifier.padding(start = 10.dp)) Column { Text( - text = stringResource(if(deviceAdmin) R.string.activated else R.string.deactivated), + text = stringResource(if(activated) R.string.activated else R.string.deactivated), style = typography.headlineSmall, color = colorScheme.onPrimary, modifier = Modifier.padding(bottom = 2.dp) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt index c4b6972..94fab02 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt @@ -62,6 +62,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme.typography import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold @@ -110,6 +111,7 @@ import com.bintianqi.owndroid.ui.RadioButtonItem import com.bintianqi.owndroid.ui.SubPageItem import com.bintianqi.owndroid.ui.SwitchItem import com.bintianqi.owndroid.ui.TopBar +import com.bintianqi.owndroid.writeClipBoard @Composable fun Network(navCtrl: NavHostController) { @@ -157,7 +159,18 @@ fun Network(navCtrl: NavHostController) { onDismissRequest = { wifiMacDialog.value = false }, confirmButton = { TextButton(onClick = { wifiMacDialog.value = false }) { Text(stringResource(R.string.confirm)) } }, title = { Text(stringResource(R.string.wifi_mac_addr)) }, - text = { SelectionContainer { Text(dpm.getWifiMacAddress(receiver)?: stringResource(R.string.none)) } }, + text = { + val mac = dpm.getWifiMacAddress(receiver) + OutlinedTextField( + value = mac ?: stringResource(R.string.none), + onValueChange = {}, readOnly = true, modifier = Modifier.fillMaxWidth(), textStyle = typography.titleMedium, + trailingIcon = { + if(mac != null) IconButton(onClick = { writeClipBoard(context, mac) }) { + Icon(painter = painterResource(R.drawable.content_copy_fill0), contentDescription = stringResource(R.string.copy)) + } + } + ) + }, modifier = Modifier.fillMaxWidth() ) } @@ -222,7 +235,7 @@ private fun Switches() { Spacer(Modifier.padding(vertical = 5.dp)) if(VERSION.SDK_INT >= 33 && deviceOwner) { SwitchItem( - R.string.preferential_network_service, stringResource(R.string.developing), R.drawable.globe_fill0, + R.string.preferential_network_service, "", R.drawable.globe_fill0, { dpm.isPreferentialNetworkServiceEnabled }, { dpm.isPreferentialNetworkServiceEnabled = it }, padding = false ) } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt index 2e0af07..ae509e2 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Password.kt @@ -167,7 +167,7 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState) { if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) { SubPageItem(R.string.required_strong_auth_timeout, "", R.drawable.fingerprint_off_fill0) { navCtrl.navigate("RequiredStrongAuthTimeout") } } - if(deviceOwner || profileOwner) { + if(VERSION.SDK_INT < 31 && (deviceOwner || profileOwner)) { SubPageItem(R.string.required_password_quality, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordQuality") } } Spacer(Modifier.padding(vertical = 30.dp)) @@ -736,9 +736,6 @@ private fun PasswordQuality() { Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.required_password_quality), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) - Text(text = stringResource(R.string.password_complexity_instead_password_quality)) - if(VERSION.SDK_INT >= 31) { Text(text = stringResource(R.string.password_quality_deprecated_desc), color = colorScheme.error) } - Spacer(Modifier.padding(vertical = 5.dp)) for(index in 1..6) { RadioButtonItem(passwordQuality[index].second, selectedItem == passwordQuality[index].first, { selectedItem = passwordQuality[index].first }) } 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 4a5aa1a..c33da36 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Permissions.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType @@ -38,6 +39,7 @@ import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.R import com.bintianqi.owndroid.backToHomeStateFlow import com.bintianqi.owndroid.ui.* +import com.bintianqi.owndroid.writeClipBoard import com.rosan.dhizuku.api.Dhizuku import com.rosan.dhizuku.api.DhizukuRequestPermissionListener import kotlinx.coroutines.launch @@ -74,7 +76,6 @@ fun DpmPermissions(navCtrl:NavHostController) { composable(route = "DeviceOwner") { DeviceOwner() } composable(route = "DeviceInfo") { DeviceInfo() } composable(route = "OrgID") { OrgID() } - composable(route = "SpecificID") { SpecificID() } composable(route = "OrgName") { OrgName() } composable(route = "DisableAccountManagement") { DisableAccountManagement() } composable(route = "LockScreenInfo") { LockScreenInfo() } @@ -84,6 +85,7 @@ fun DpmPermissions(navCtrl:NavHostController) { } } +@SuppressLint("NewApi") @Composable private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { val context = LocalContext.current @@ -93,6 +95,8 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { val deviceAdmin = context.isDeviceAdmin val deviceOwner = context.isDeviceOwner val profileOwner = context.isProfileOwner + var enrollmentIdDialog by remember { mutableStateOf(false) } + val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) dpm.enrollmentSpecificId else "" Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) { Text( text = stringResource(R.string.permission), @@ -112,9 +116,9 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { R.string.device_admin, stringResource(if(deviceAdmin) R.string.activated else R.string.deactivated), operation = { localNavCtrl.navigate("DeviceAdmin") } ) - if(!deviceOwner) { + if(profileOwner) { SubPageItem( - R.string.profile_owner, stringResource(if(profileOwner) R.string.activated else R.string.deactivated), + R.string.profile_owner, stringResource(R.string.activated), operation = { localNavCtrl.navigate("ProfileOwner") } ) } @@ -131,7 +135,9 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { } if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) { SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgID") } - SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { localNavCtrl.navigate("SpecificID") } + } + if(enrollmentSpecificId != "") { + SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { enrollmentIdDialog = true } } if(deviceOwner || profileOwner) { SubPageItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { localNavCtrl.navigate("DisableAccountManagement") } @@ -147,6 +153,27 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) { } Spacer(Modifier.padding(vertical = 30.dp)) } + if(enrollmentIdDialog) AlertDialog( + title = { Text(stringResource(R.string.enrollment_specific_id)) }, + text = { + val esid = dpm.enrollmentSpecificId + OutlinedTextField( + value = esid, + onValueChange = {}, readOnly = true, modifier = Modifier.fillMaxWidth(), + trailingIcon = { + IconButton(onClick = { writeClipBoard(context, esid) }) { + Icon(painter = painterResource(R.drawable.content_copy_fill0), contentDescription = stringResource(R.string.copy)) + } + } + ) + }, + onDismissRequest = { enrollmentIdDialog = false }, + confirmButton = { + TextButton(onClick = { enrollmentIdDialog = false }) { + Text(stringResource(R.string.confirm)) + } + } + ) } private fun toggleDhizukuMode(status: Boolean, context: Context) { @@ -466,7 +493,7 @@ private fun OrgID() { Text(text = stringResource(R.string.org_id), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) OutlinedTextField( - value = orgId, onValueChange = {orgId=it}, + value = orgId, onValueChange = { orgId=it }, label = { Text(stringResource(R.string.org_id)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }), @@ -479,35 +506,18 @@ private fun OrgID() { Spacer(Modifier.padding(vertical = 5.dp)) Button( onClick = { - dpm.setOrganizationId(orgId) - Toast.makeText(context, R.string.success,Toast.LENGTH_SHORT).show() + try { + dpm.setOrganizationId(orgId) + Toast.makeText(context, R.string.success,Toast.LENGTH_SHORT).show() + } catch(e: IllegalStateException) { + Toast.makeText(context, R.string.failed,Toast.LENGTH_SHORT).show() + } }, enabled = orgId.length in 6..64, modifier = Modifier.fillMaxWidth() ) { Text(stringResource(R.string.apply)) } - Spacer(Modifier.padding(vertical = 5.dp)) - Information{ Text(text = stringResource(R.string.get_specific_id_after_set_org_id)) } - } -} - -@SuppressLint("NewApi") -@Composable -private fun SpecificID() { - val context = LocalContext.current - val dpm = context.getDPM() - Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) { - val specificId = dpm.enrollmentSpecificId - Spacer(Modifier.padding(vertical = 10.dp)) - Text(text = stringResource(R.string.enrollment_specific_id), style = typography.headlineLarge) - Spacer(Modifier.padding(vertical = 5.dp)) - if(specificId != "") { - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState())) { Text(specificId) } - CopyTextButton(R.string.copy, specificId) - }else{ - Text(stringResource(R.string.require_set_org_id)) - } } } diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 74b5324..c406269 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -79,7 +79,6 @@ Aktif(Kullanıcı Başına) Aktif Cihaz Yöneticileri: %1$s Kayıt Özel Kimliği - Organizasyon Kimliği Gerekli Organizasyon Adı Hesap Yönetimini Devre Dışı Bırak Hesap Türleri: @@ -244,7 +243,6 @@ Log file size: %1$s Delete logs Export logs - Geri al WiFi anahtar çifti Anahtar çifti APN ayarlarını geçersiz kıl @@ -290,7 +288,6 @@ Tüm filtreleri temizle Kuruluş Kimliği Uzunluk 6 ile 64 karakter arasında olmalıdır - Bunu ayarladıktan sonra cihaz spesifik Kimlik alabilirsiniz. Delete work profile @@ -532,8 +529,6 @@ Biyometrik (Zayıf) Sayısal karmaşık (Tekrar eden karakter yok) Gereken şifre kalitesi - Şifre karmaşıklığı ayarlamak şifre kalitesi ayarlarını devre dışı bırakacaktır. - Kullanım dışı. Bunun yerine "Gereken şifre karmaşıklığı" kullanın. Şifre sıfırlama jetonunu burada etkinleştirin. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a85e0e4..b769131 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -74,7 +74,6 @@ 每个用户分别加密 激活的Device admin: %1$s 设备注册专用ID - 需要设置组织ID 组织名称 禁用账号管理 账号类型: @@ -239,7 +238,6 @@ 日志文件大小:%1$s 删除日志 导出日志 - 收集 WiFi密钥对 密钥对 APN设置 @@ -285,7 +283,6 @@ 清除所有过滤器 组织ID 长度应在6~64个字符之间 - 设置组织ID后才能获取设备唯一标识码 删除工作资料 @@ -524,8 +521,6 @@ 生物识别(弱) 复杂数字(无连续性) 密码质量要求 - 设置密码复杂度将会取代密码质量 - 已弃用,请使用上面的”密码复杂度要求“ 在这里激活密码重置令牌 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5db16d3..3be6e3f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -80,7 +80,6 @@ Active(per-user) Active device admins: %1$s Enrollment specific ID - Require organization ID Organization name Disable account management Account types: @@ -248,7 +247,6 @@ Log file size: %1$s Delete logs Export logs - Retrieve WiFi keypair Keypair APN settings @@ -297,7 +295,6 @@ Clear all filters Organization ID The length should be between 6~64 characters - You can get device specific ID after set this. Delete work profile @@ -537,8 +534,6 @@ Biometrics (Weak) Numeric complex (No repeating characters) Required password quality - Set password complexity will disable password quality settings. - Deprecated. Use "Required password complexity" instead. Activate reset password token here.