Files
OwnDroid/app/src/main/java/com/binbin/androidowner/Password.kt
2024-03-03 17:25:39 +08:00

477 lines
29 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.binbin.androidowner
import android.app.KeyguardManager
import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat.startActivity
import kotlinx.coroutines.delay
@Composable
fun Password(){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
var newPwd by remember{ mutableStateOf("") }
val focusMgr = LocalFocusManager.current
val isWear = sharedPref.getBoolean("isWear",false)
val titleColor = colorScheme.onPrimaryContainer
val bodyTextStyle = if(isWear){typography.bodyMedium}else{typography.bodyLarge}
val scrollState = rememberScrollState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize().verticalScroll(scrollState)
) {
val myByteArray by remember{ mutableStateOf(byteArrayOf(1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0,1,1,4,5,1,4,1,9,1,9,8,1,0)) }
Text(
text = stringResource(R.string.password_warning),
color = colorScheme.onErrorContainer,
modifier = sections(colorScheme.errorContainer),
style=bodyTextStyle
)
if(isWear){
Text(
text = stringResource(R.string.password_wearos_warning),
color = colorScheme.onErrorContainer,
modifier = sections(colorScheme.errorContainer),
style = typography.bodyMedium
)
}
if(myDpm.isDeviceOwnerApp("com.binbin.androidowner")){
Column(modifier = sections()) {
if(VERSION.SDK_INT>=29){
val passwordComplexity = mapOf(
PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none),
PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low),
PASSWORD_COMPLEXITY_MEDIUM to stringResource(R.string.password_complexity_medium),
PASSWORD_COMPLEXITY_HIGH to stringResource(R.string.password_complexity_high)
)
val pwdComplex = passwordComplexity[myDpm.passwordComplexity]
Text(text = stringResource(R.string.current_password_complexity_is, pwdComplex?:stringResource(R.string.unknown)),style=bodyTextStyle)
}
if(isDeviceOwner(myDpm)|| isProfileOwner(myDpm)){
Text(stringResource(R.string.is_password_sufficient, myDpm.isActivePasswordSufficient),style=bodyTextStyle)
}
val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts
Text(text = stringResource(R.string.password_failed_attempts_is, pwdFailedAttempts),style=bodyTextStyle)
if(VERSION.SDK_INT>=28&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent)
Text(stringResource(R.string.is_using_unified_password, unifiedPwd),style=bodyTextStyle)
}
}
}
if(VERSION.SDK_INT>=26){
Column(horizontalAlignment = Alignment.Start, modifier = sections()) {
Text(text = stringResource(R.string.reset_password_token), style = typography.titleLarge,color = titleColor)
Row(
modifier = if(!isWear){Modifier.fillMaxWidth()}else{Modifier.horizontalScroll(rememberScrollState())},
horizontalArrangement = Arrangement.SpaceBetween
){
Button(
onClick = {
if(myDpm.clearResetPasswordToken(myComponent)){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
},
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.32F)},
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm)
) {
Text(stringResource(R.string.clear))
}
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
Button(
onClick = {
try {
if(myDpm.setResetPasswordToken(myComponent, myByteArray)){
Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show()
}
}catch(e:SecurityException){
Toast.makeText(myContext, myContext.getString(R.string.security_exception), Toast.LENGTH_SHORT).show()
}
},
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.47F)}
) {
Text(stringResource(R.string.set))
}
if(isWear){Spacer(Modifier.padding(horizontal = 2.dp))}
Button(
onClick = {
if(!myDpm.isResetPasswordTokenActive(myComponent)){
try{ activateToken(myContext) }
catch(e:NullPointerException){ Toast.makeText(myContext, myContext.getString(R.string.please_set_a_token), Toast.LENGTH_SHORT).show() }
}else{ Toast.makeText(myContext, "已经激活", Toast.LENGTH_SHORT).show() }
},
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = if(isWear){Modifier}else{Modifier.fillMaxWidth(0.88F)}
) {
Text(stringResource(R.string.activate))
}
}
Text(stringResource(R.string.activate_token_not_required_when_no_password),style=bodyTextStyle)
}
}
Column(
modifier = sections()
) {
var confirmed by remember{ mutableStateOf(false) }
Text(text = stringResource(R.string.reset_password),style = typography.titleLarge,color = titleColor)
OutlinedTextField(
value = newPwd,
onValueChange = {newPwd=it},
enabled = !confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)||myDpm.isAdminActive(myComponent)),
label = { Text(stringResource(R.string.password))},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
modifier = Modifier.focusable().padding(vertical = if(isWear){0.dp}else{5.dp}).fillMaxWidth()
)
Text(text = stringResource(R.string.reset_pwd_desc), modifier = Modifier.padding(vertical = 3.dp),style=bodyTextStyle)
var resetPwdFlag by remember{ mutableIntStateOf(0) }
if(VERSION.SDK_INT>=23){
RadioButtonItem(
stringResource(R.string.do_not_ask_credentials_on_boot),
{resetPwdFlag==RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}, {resetPwdFlag=RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT}
)
}
RadioButtonItem(stringResource(R.string.reset_password_require_entry),{resetPwdFlag==RESET_PASSWORD_REQUIRE_ENTRY}, {resetPwdFlag=RESET_PASSWORD_REQUIRE_ENTRY})
RadioButtonItem(stringResource(R.string.none),{resetPwdFlag==0},{resetPwdFlag=0})
Button(
onClick = {
if(newPwd.length>=4||newPwd.isEmpty()){ confirmed=!confirmed
}else{ Toast.makeText(myContext, myContext.getString(R.string.require_4_digit_password), Toast.LENGTH_SHORT).show() }
},
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm) || myDpm.isAdminActive(myComponent),
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(
containerColor = if(confirmed){ colorScheme.primary }else{ colorScheme.error },
contentColor = if(confirmed){ colorScheme.onPrimary }else{ colorScheme.onError }
)
) {
Text(text = stringResource(if(confirmed){R.string.cancel}else{R.string.confirm}))
}
if(VERSION.SDK_INT>=26){
Button(
onClick = {
val resetSuccess = myDpm.resetPasswordWithToken(myComponent,newPwd,myByteArray,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show();newPwd=""}
else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
confirmed=false
},
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError),
enabled = confirmed&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm)),
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.reset_password_with_token))
}
}
Button(
onClick = {
val resetSuccess = myDpm.resetPassword(newPwd,resetPwdFlag)
if(resetSuccess){ Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show(); newPwd=""}
else{ Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show() }
confirmed=false
},
enabled = confirmed,
colors = ButtonDefaults.buttonColors(containerColor = colorScheme.error, contentColor = colorScheme.onError),
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.reset_password_deprecated))
}
}
PasswordItem(R.string.max_pwd_fail,R.string.max_pwd_fail_desc,R.string.max_pwd_fail_textfield, false,
{myDpm.getMaximumFailedPasswordsForWipe(null).toString()},{ic -> myDpm.setMaximumFailedPasswordsForWipe(myComponent, ic.toInt()) })
PasswordItem(R.string.pwd_timeout,R.string.pwd_timeout_desc,R.string.pwd_timeout_textfield,true,
{myDpm.getPasswordExpiration(null).toString()},{ic -> myDpm.setPasswordExpirationTimeout(myComponent, ic.toLong()) })
PasswordItem(R.string.pwd_history,R.string.pwd_history_desc,R.string.pwd_history_textfield,true,
{myDpm.getPasswordHistoryLength(null).toString()},{ic -> myDpm.setPasswordHistoryLength(myComponent, ic.toInt()) })
PasswordItem(R.string.max_time_to_lock,R.string.max_time_to_lock_desc,R.string.time_unit_ms,true,
{myDpm.getMaximumTimeToLock(myComponent).toString()},{ic -> myDpm.setMaximumTimeToLock(myComponent,ic.toLong())})
if(VERSION.SDK_INT>=31){
Column(modifier = sections()) {
val passwordComplexity = mapOf(
PASSWORD_COMPLEXITY_NONE to stringResource(R.string.password_complexity_none),
PASSWORD_COMPLEXITY_LOW to stringResource(R.string.password_complexity_low),
PASSWORD_COMPLEXITY_MEDIUM to stringResource(R.string.password_complexity_medium),
PASSWORD_COMPLEXITY_HIGH to stringResource(R.string.password_complexity_high)
).toList()
var selectedItem by remember{ mutableIntStateOf(passwordComplexity[0].first) }
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){
selectedItem=myDpm.requiredPasswordComplexity
}
Text(text = stringResource(R.string.required_password_complexity), style = typography.titleLarge,color = titleColor)
RadioButtonItem(passwordComplexity[0].second,{selectedItem==passwordComplexity[0].first},{selectedItem=passwordComplexity[0].first})
RadioButtonItem(passwordComplexity[1].second,{selectedItem==passwordComplexity[1].first},{selectedItem=passwordComplexity[1].first})
RadioButtonItem(passwordComplexity[2].second,{selectedItem==passwordComplexity[2].first},{selectedItem=passwordComplexity[2].first})
RadioButtonItem(passwordComplexity[3].second,{selectedItem==passwordComplexity[3].first},{selectedItem=passwordComplexity[3].first},
if(isWear){
colorScheme.error}else{
colorScheme.onBackground})
Text(text = stringResource(R.string.password_ordered_desc), modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle)
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){
Button(
onClick = {
myDpm.requiredPasswordComplexity = selectedItem
Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
},
enabled = isDeviceOwner(myDpm)|| isProfileOwner(myDpm),
modifier = if(isWear){Modifier.fillMaxWidth()}else{Modifier.fillMaxWidth(0.4F)}
) {
Text(text = stringResource(R.string.apply))
}
if(!isWear){
Button(
onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))},
modifier = Modifier.fillMaxWidth(0.95F)
){
Text(stringResource(R.string.require_set_new_password))
}
}
}
if(isWear){
Button(
onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))},
modifier = Modifier.fillMaxWidth()
){
Text(stringResource(R.string.require_set_new_password))
}
}
}
}
Column(modifier = sections()){
var state by remember{mutableIntStateOf(-1)}
var shortcuts by remember{mutableStateOf(false)}
var biometrics by remember{mutableStateOf(false)}
var iris by remember{mutableStateOf(false)}
var face by remember{mutableStateOf(false)}
var remote by remember{mutableStateOf(false)}
var fingerprint by remember{mutableStateOf(false)}
var agents by remember{mutableStateOf(false)}
var unredacted by remember{mutableStateOf(false)}
var notification by remember{mutableStateOf(false)}
var camera by remember{mutableStateOf(false)}
var widgets by remember{mutableStateOf(false)}
val calculateCustomFeature = {
var calculate = myDpm.getKeyguardDisabledFeatures(myComponent)
if(calculate==0){state=0}
else{
if(calculate-KEYGUARD_DISABLE_SHORTCUTS_ALL>=0 && VERSION.SDK_INT>=34){shortcuts=true;calculate-=KEYGUARD_DISABLE_SHORTCUTS_ALL}
if(calculate-KEYGUARD_DISABLE_BIOMETRICS>=0&&VERSION.SDK_INT>=28){biometrics=true;calculate -= KEYGUARD_DISABLE_BIOMETRICS}
if(calculate-KEYGUARD_DISABLE_IRIS>=0&&VERSION.SDK_INT>=28){iris=true;calculate -=KEYGUARD_DISABLE_IRIS }
if(calculate-KEYGUARD_DISABLE_FACE>=0&&VERSION.SDK_INT>=28){face=true;calculate -= KEYGUARD_DISABLE_FACE}
if(calculate-KEYGUARD_DISABLE_REMOTE_INPUT>=0&&VERSION.SDK_INT>=24){remote=true;calculate -= KEYGUARD_DISABLE_REMOTE_INPUT}
if(calculate-KEYGUARD_DISABLE_FINGERPRINT>=0){fingerprint=true;calculate -= KEYGUARD_DISABLE_FINGERPRINT}
if(calculate-KEYGUARD_DISABLE_TRUST_AGENTS>=0){agents=true;calculate -= KEYGUARD_DISABLE_TRUST_AGENTS}
if(calculate-KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS>=0){unredacted=true;calculate -= KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}
if(calculate-KEYGUARD_DISABLE_SECURE_NOTIFICATIONS>=0){notification=true;calculate -= KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}
if(calculate-KEYGUARD_DISABLE_SECURE_CAMERA>=0){camera=true;calculate -= KEYGUARD_DISABLE_SECURE_CAMERA}
if(calculate-KEYGUARD_DISABLE_WIDGETS_ALL>=0){widgets=true;calculate -= KEYGUARD_DISABLE_WIDGETS_ALL}
}
}
if(state==-1){
state = when(myDpm.getKeyguardDisabledFeatures(myComponent)){
KEYGUARD_DISABLE_FEATURES_NONE->0
KEYGUARD_DISABLE_FEATURES_ALL->1
else->2
}
calculateCustomFeature()
}
Text(text = stringResource(R.string.keyguard_disabled_features), style = typography.titleLarge)
RadioButtonItem(stringResource(R.string.enable_all),{state==0},{state=0})
RadioButtonItem(stringResource(R.string.disable_all),{state==1},{state=1})
RadioButtonItem(stringResource(R.string.custom),{state==2},{state=2})
AnimatedVisibility(state==2) {
Column {
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_widgets),{widgets},{widgets=!widgets})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_camera),{camera},{camera=!camera})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_notification),{notification},{notification=!notification})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_unredacted_notification),{unredacted},{unredacted=!unredacted})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_trust_agents),{agents},{agents=!agents})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_fingerprint),{fingerprint},{fingerprint=!fingerprint})
if(VERSION.SDK_INT>=24){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_remote_input),{remote}, {remote=!remote}) }
if(VERSION.SDK_INT>=28){
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_face),{face},{face=!face})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_iris),{iris},{iris=!iris})
CheckBoxItem(stringResource(R.string.keyguard_disabled_features_biometrics),{biometrics},{biometrics=!biometrics})
}
if(VERSION.SDK_INT>=34){ CheckBoxItem(stringResource(R.string.keyguard_disabled_features_shortcuts),{shortcuts},{shortcuts=!shortcuts}) }
}
}
Button(
onClick = {
var result = 0
if(state==0){ result = 0 }
else if(state==1){ result = KEYGUARD_DISABLE_FEATURES_ALL }
else{
if(shortcuts&&VERSION.SDK_INT>=34){result+=KEYGUARD_DISABLE_SHORTCUTS_ALL}
if(biometrics&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_BIOMETRICS}
if(iris&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_IRIS}
if(face&&VERSION.SDK_INT>=28){result+=KEYGUARD_DISABLE_FACE}
if(remote&&VERSION.SDK_INT>=24){result+=KEYGUARD_DISABLE_REMOTE_INPUT}
if(fingerprint){result+=KEYGUARD_DISABLE_FINGERPRINT}
if(agents){result+=KEYGUARD_DISABLE_TRUST_AGENTS}
if(unredacted){result+=KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}
if(notification){result+=KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}
if(camera){result+=KEYGUARD_DISABLE_SECURE_CAMERA}
if(widgets){result+=KEYGUARD_DISABLE_WIDGETS_ALL}
}
myDpm.setKeyguardDisabledFeatures(myComponent,result)
Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
calculateCustomFeature()
},
enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm),
modifier = Modifier.fillMaxWidth()
) {
Text(text = stringResource(R.string.apply))
}
}
var passwordQualityExpand by remember{mutableStateOf(VERSION.SDK_INT < 31)}
var launchScrollDown by remember{mutableStateOf(false)}
LaunchedEffect(launchScrollDown){
if(launchScrollDown){
delay(10)
scrollState.animateScrollTo((scrollState.value+myContext.resources.displayMetrics.heightPixels*0.4).toInt(), scrollAnim())
launchScrollDown=false
}
}
Column(modifier = sections(onClick = {passwordQualityExpand=true;launchScrollDown=true}, clickable = !passwordQualityExpand).animateContentSize(animationSpec = scrollAnim())) {
val passwordQuality = mapOf(
PASSWORD_QUALITY_UNSPECIFIED to stringResource(R.string.password_quality_unspecified),
PASSWORD_QUALITY_SOMETHING to stringResource(R.string.password_quality_something),
PASSWORD_QUALITY_ALPHABETIC to stringResource(R.string.password_quality_alphabetic),
PASSWORD_QUALITY_NUMERIC to stringResource(R.string.password_quality_numeric),
PASSWORD_QUALITY_ALPHANUMERIC to stringResource(R.string.password_quality_alphanumeric),
PASSWORD_QUALITY_BIOMETRIC_WEAK to stringResource(R.string.password_quality_biometrics_weak),
PASSWORD_QUALITY_NUMERIC_COMPLEX to stringResource(R.string.password_quality_numeric_complex),
PASSWORD_QUALITY_COMPLEX to stringResource(R.string.custom)+"${stringResource(R.string.unsupported)}",
).toList()
var selectedItem by remember{ mutableIntStateOf(passwordQuality[0].first) }
if(isDeviceOwner(myDpm) || isProfileOwner(myDpm)){ selectedItem=myDpm.getPasswordQuality(myComponent) }
Text(text = stringResource(R.string.required_password_quality), style = typography.titleLarge,color = titleColor)
if(passwordQualityExpand){
Text(text = stringResource(R.string.password_complexity_instead_password_quality), style = bodyTextStyle)
}
if(VERSION.SDK_INT>=31){ Text(text = stringResource(R.string.password_quality_deprecated_desc), color = colorScheme.error, style = bodyTextStyle) }
if(passwordQualityExpand){
RadioButtonItem(passwordQuality[0].second,{selectedItem==passwordQuality[0].first},{selectedItem=passwordQuality[0].first})
RadioButtonItem(passwordQuality[1].second,{selectedItem==passwordQuality[1].first},{selectedItem=passwordQuality[1].first})
RadioButtonItem(passwordQuality[2].second,{selectedItem==passwordQuality[2].first},{selectedItem=passwordQuality[2].first})
RadioButtonItem(passwordQuality[3].second,{selectedItem==passwordQuality[3].first},{selectedItem=passwordQuality[3].first})
RadioButtonItem(passwordQuality[4].second,{selectedItem==passwordQuality[4].first},{selectedItem=passwordQuality[4].first})
RadioButtonItem(passwordQuality[5].second,{selectedItem==passwordQuality[5].first},{selectedItem=passwordQuality[5].first})
RadioButtonItem(passwordQuality[6].second,{selectedItem==passwordQuality[6].first},{selectedItem=passwordQuality[6].first})
RadioButtonItem(passwordQuality[7].second,{selectedItem==passwordQuality[7].first},{selectedItem=passwordQuality[7].first})
Text(text = stringResource(R.string.password_ordered_desc), modifier = Modifier.padding(vertical = 3.dp), style = bodyTextStyle)
Button(
onClick = {
myDpm.setPasswordQuality(myComponent,selectedItem)
Toast.makeText(myContext, myContext.getString(R.string.success), Toast.LENGTH_SHORT).show()
},
enabled = isDeviceOwner(myDpm) || isProfileOwner(myDpm),
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.apply))
}
if(VERSION.SDK_INT<31){
Button(onClick = {myContext.startActivity(Intent(ACTION_SET_NEW_PASSWORD))}){
Text(stringResource(R.string.require_set_new_password))
}}
}
}
Spacer(Modifier.padding(vertical = 30.dp))
}
}
@Composable
private fun PasswordItem(
itemName:Int,
itemDesc:Int,
textFieldLabel:Int,
allowZero:Boolean,
getMethod:()->String,
setMethod:(ic:String)->Unit
){
val myContext = LocalContext.current
val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false)
val focusMgr = LocalFocusManager.current
Column(modifier = sections()) {
var inputContent by remember{ mutableStateOf(if(isDeviceOwner(myDpm)){getMethod()}else{""}) }
var ableToApply by remember{ mutableStateOf(inputContent!=""&&((inputContent=="0"&&allowZero)||inputContent!="0")) }
Text(text = stringResource(itemName), style = typography.titleLarge,color = colorScheme.onPrimaryContainer)
Text(text= stringResource(itemDesc),modifier=Modifier.padding(vertical = 2.dp), style = if(!isWear){typography.bodyLarge}else{typography.bodyMedium})
if(!isWear){Spacer(Modifier.padding(vertical = 2.dp))}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth()
){
OutlinedTextField(
value = inputContent,
label = { Text(stringResource(textFieldLabel))},
onValueChange = {
inputContent = it
ableToApply = inputContent!=""&&((inputContent=="0"&&allowZero)||inputContent!="0")
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus()}),
enabled = isDeviceOwner(myDpm),
modifier = Modifier.focusable().fillMaxWidth(),
trailingIcon = {
Icon(
imageVector = Icons.Outlined.Check, contentDescription = "OK",
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {focusMgr.clearFocus() ; setMethod(inputContent)}, enabled = isDeviceOwner(myDpm)&&ableToApply)
.padding(2.dp)
)
}
)
}
}
}
fun activateToken(myContext: Context){
val desc = myContext.getString(R.string.activate_reset_password_token_here)
val keyguardManager = myContext.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
val confirmIntent = keyguardManager.createConfirmDeviceCredentialIntent(myContext.getString(R.string.app_name), desc)
if (confirmIntent != null) {
startActivity(myContext,confirmIntent, null)
} else {
Toast.makeText(myContext, myContext.getString(R.string.fail), Toast.LENGTH_SHORT).show()
}
}