mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
Fix CA certs manager and User restrictions manager
Add authentication to app installer Change version to 6.4 (36)
This commit is contained in:
@@ -15,7 +15,7 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
namespace = "com.bintianqi.owndroid"
|
namespace = "com.bintianqi.owndroid"
|
||||||
compileSdk = 34
|
compileSdk = 35
|
||||||
|
|
||||||
lint.checkReleaseBuilds = false
|
lint.checkReleaseBuilds = false
|
||||||
lint.disable += "All"
|
lint.disable += "All"
|
||||||
@@ -24,9 +24,8 @@ android {
|
|||||||
applicationId = "com.bintianqi.owndroid"
|
applicationId = "com.bintianqi.owndroid"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
compileSdk = 35
|
versionCode = 36
|
||||||
versionCode = 35
|
versionName = "6.4"
|
||||||
versionName = "6.3"
|
|
||||||
multiDexEnabled = false
|
multiDexEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import android.content.pm.PackageInstaller
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import android.widget.Toast
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -49,6 +50,7 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
@@ -63,7 +65,7 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
|
|
||||||
class AppInstallerActivity:ComponentActivity() {
|
class AppInstallerActivity:FragmentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -82,7 +84,7 @@ class AppInstallerActivity:ComponentActivity() {
|
|||||||
installing, sessionMode, { vm.sessionMode.value = it },
|
installing, sessionMode, { vm.sessionMode.value = it },
|
||||||
packages, { uri -> vm.packages.update { it.minus(uri) } },
|
packages, { uri -> vm.packages.update { it.minus(uri) } },
|
||||||
{ uris -> vm.packages.update { it.plus(uris) } },
|
{ uris -> vm.packages.update { it.plus(uris) } },
|
||||||
vm::startInstallationProcess, writtenPackages, writingPackage,
|
{ vm.startInstallationProcess(this) }, writtenPackages, writingPackage,
|
||||||
result, { vm.result.value = null }
|
result, { vm.result.value = null }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -237,7 +239,19 @@ class AppInstallerViewModel(application: Application): AndroidViewModel(applicat
|
|||||||
|
|
||||||
val writtenPackages = MutableStateFlow(setOf<Uri>())
|
val writtenPackages = MutableStateFlow(setOf<Uri>())
|
||||||
val writingPackage = MutableStateFlow<Uri?>(null)
|
val writingPackage = MutableStateFlow<Uri?>(null)
|
||||||
fun startInstallationProcess() {
|
fun startInstallationProcess(activity: FragmentActivity) {
|
||||||
|
startAuth(activity, object : BiometricPrompt.AuthenticationCallback() {
|
||||||
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
|
||||||
|
super.onAuthenticationSucceeded(result)
|
||||||
|
startInstall()
|
||||||
|
}
|
||||||
|
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
|
||||||
|
super.onAuthenticationError(errorCode, errString)
|
||||||
|
Toast.makeText(activity, R.string.failed_to_authenticate, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
private fun startInstall() {
|
||||||
if(installing.value) return
|
if(installing.value) return
|
||||||
installing.value = true
|
installing.value = true
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.bintianqi.owndroid
|
package com.bintianqi.owndroid
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.admin.DevicePolicyManager
|
import android.app.admin.DevicePolicyManager
|
||||||
import android.os.Build.VERSION
|
import android.os.Build.VERSION
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -53,6 +54,7 @@ import androidx.fragment.app.FragmentActivity
|
|||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
@@ -119,7 +121,7 @@ import com.bintianqi.owndroid.dpm.UpdateNetwork
|
|||||||
import com.bintianqi.owndroid.dpm.UserOperation
|
import com.bintianqi.owndroid.dpm.UserOperation
|
||||||
import com.bintianqi.owndroid.dpm.UserOptions
|
import com.bintianqi.owndroid.dpm.UserOptions
|
||||||
import com.bintianqi.owndroid.dpm.UserRestriction
|
import com.bintianqi.owndroid.dpm.UserRestriction
|
||||||
import com.bintianqi.owndroid.dpm.UserRestrictionItem
|
import com.bintianqi.owndroid.dpm.UserRestrictionScreen
|
||||||
import com.bintianqi.owndroid.dpm.UserSessionMessage
|
import com.bintianqi.owndroid.dpm.UserSessionMessage
|
||||||
import com.bintianqi.owndroid.dpm.Users
|
import com.bintianqi.owndroid.dpm.Users
|
||||||
import com.bintianqi.owndroid.dpm.Wifi
|
import com.bintianqi.owndroid.dpm.Wifi
|
||||||
@@ -137,7 +139,6 @@ import com.bintianqi.owndroid.dpm.isDeviceOwner
|
|||||||
import com.bintianqi.owndroid.dpm.isProfileOwner
|
import com.bintianqi.owndroid.dpm.isProfileOwner
|
||||||
import com.bintianqi.owndroid.dpm.setDefaultAffiliationID
|
import com.bintianqi.owndroid.dpm.setDefaultAffiliationID
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
import com.bintianqi.owndroid.ui.Animations
|
||||||
import com.bintianqi.owndroid.ui.MyScaffold
|
|
||||||
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
||||||
import com.rosan.dhizuku.api.Dhizuku
|
import com.rosan.dhizuku.api.Dhizuku
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -196,6 +197,17 @@ fun Home(activity: FragmentActivity, vm: MyViewModel) {
|
|||||||
LaunchedEffect(backToHome) {
|
LaunchedEffect(backToHome) {
|
||||||
if(backToHome) { navCtrl.navigateUp(); backToHomeStateFlow.value = false }
|
if(backToHome) { navCtrl.navigateUp(); backToHomeStateFlow.value = false }
|
||||||
}
|
}
|
||||||
|
val userRestrictions by vm.userRestrictions.collectAsStateWithLifecycle()
|
||||||
|
fun onUserRestrictionsChange(id: String, status: Boolean) {
|
||||||
|
try {
|
||||||
|
if(status) dpm.addUserRestriction(receiver, id)
|
||||||
|
else dpm.clearUserRestriction(receiver, id)
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
vm.userRestrictions.value = dpm.getUserRestrictions(receiver)
|
||||||
|
} catch(_: Exception) {
|
||||||
|
context.showOperationResultToast(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
@Suppress("NewApi") NavHost(
|
@Suppress("NewApi") NavHost(
|
||||||
navController = navCtrl,
|
navController = navCtrl,
|
||||||
startDestination = "HomePage",
|
startDestination = "HomePage",
|
||||||
@@ -268,24 +280,36 @@ fun Home(activity: FragmentActivity, vm: MyViewModel) {
|
|||||||
|
|
||||||
composable(route = "Applications") { ApplicationManage(navCtrl, vm) }
|
composable(route = "Applications") { ApplicationManage(navCtrl, vm) }
|
||||||
|
|
||||||
composable(route = "UserRestriction") { UserRestriction(navCtrl) }
|
composable(route = "UserRestriction") { UserRestriction(navCtrl, vm) }
|
||||||
composable(route = "UR-Internet") {
|
composable(route = "UR-Internet") {
|
||||||
MyScaffold(R.string.network_and_internet, 0.dp, navCtrl) { RestrictionData.internet.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.network_and_internet, RestrictionData.internet, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
composable(route = "UR-Connectivity") {
|
composable(route = "UR-Connectivity") {
|
||||||
MyScaffold(R.string.connectivity, 0.dp, navCtrl) { RestrictionData.connectivity.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.connectivity, RestrictionData.connectivity, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
composable(route = "UR-Applications") {
|
composable(route = "UR-Applications") {
|
||||||
MyScaffold(R.string.applications, 0.dp, navCtrl) { RestrictionData.applications.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.applications, RestrictionData.applications, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
composable(route = "UR-Users") {
|
composable(route = "UR-Users") {
|
||||||
MyScaffold(R.string.users, 0.dp, navCtrl) { RestrictionData.users.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.users, RestrictionData.users, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
composable(route = "UR-Media") {
|
composable(route = "UR-Media") {
|
||||||
MyScaffold(R.string.media, 0.dp, navCtrl) { RestrictionData.media.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.media, RestrictionData.media, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
composable(route = "UR-Other") {
|
composable(route = "UR-Other") {
|
||||||
MyScaffold(R.string.other, 0.dp, navCtrl) { RestrictionData.other.forEach { UserRestrictionItem(it, vm) } }
|
UserRestrictionScreen(R.string.other, RestrictionData.other, userRestrictions, ::onUserRestrictionsChange) {
|
||||||
|
navCtrl.navigateUp()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(route = "Users") { Users(navCtrl) }
|
composable(route = "Users") { Users(navCtrl) }
|
||||||
|
|||||||
@@ -137,7 +137,6 @@ import com.bintianqi.owndroid.ui.NavIcon
|
|||||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.uriToStream
|
import com.bintianqi.owndroid.uriToStream
|
||||||
import com.bintianqi.owndroid.yesOrNo
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
@@ -1227,63 +1226,24 @@ fun CACert(navCtrl: NavHostController) {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var exist by remember { mutableStateOf(false) }
|
var dialog by remember { mutableStateOf(false) }
|
||||||
var fileUri by remember { mutableStateOf<Uri?>(null) }
|
var caCertByteArray = remember { byteArrayOf() }
|
||||||
var caCertByteArray by remember { mutableStateOf(ByteArray(100000)) }
|
val getFileLauncher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
|
||||||
val getFileLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
uri ?: return@rememberLauncherForActivityResult
|
||||||
result.data?.data?.let { uri ->
|
uriToStream(context, uri) {
|
||||||
uriToStream(context, uri) {
|
caCertByteArray = it.readBytes()
|
||||||
val array = it.readBytes()
|
|
||||||
caCertByteArray = if(array.size < 10000) {
|
|
||||||
array
|
|
||||||
} else {
|
|
||||||
byteArrayOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dialog = true
|
||||||
}
|
}
|
||||||
MyScaffold(R.string.ca_cert, 8.dp, navCtrl) {
|
MyScaffold(R.string.ca_cert, 8.dp, navCtrl) {
|
||||||
Text(
|
|
||||||
text = if(fileUri == null) { stringResource(R.string.please_select_ca_cert) }
|
|
||||||
else { stringResource(R.string.cert_installed, stringResource(exist.yesOrNo)) },
|
|
||||||
modifier = Modifier.animateContentSize()
|
|
||||||
)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
val caCertIntent = Intent(Intent.ACTION_GET_CONTENT)
|
getFileLauncher.launch("*/*")
|
||||||
caCertIntent.setType("*/*")
|
|
||||||
caCertIntent.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
getFileLauncher.launch(caCertIntent)
|
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.select_ca_cert))
|
Text(stringResource(R.string.select_ca_cert))
|
||||||
}
|
}
|
||||||
AnimatedVisibility(fileUri != null) {
|
|
||||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
context.showOperationResultToast(dpm.installCaCert(receiver, caCertByteArray))
|
|
||||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxWidth(0.49F)
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.install))
|
|
||||||
}
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
dpm.uninstallCaCert(receiver, caCertByteArray)
|
|
||||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
|
||||||
context.showOperationResultToast(true)
|
|
||||||
},
|
|
||||||
enabled = exist,
|
|
||||||
modifier = Modifier.fillMaxWidth(0.96F)
|
|
||||||
) {
|
|
||||||
Text(stringResource(R.string.uninstall))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
dpm.uninstallAllUserCaCerts(receiver)
|
dpm.uninstallAllUserCaCerts(receiver)
|
||||||
@@ -1293,6 +1253,28 @@ fun CACert(navCtrl: NavHostController) {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.uninstall_all_user_ca_cert))
|
Text(stringResource(R.string.uninstall_all_user_ca_cert))
|
||||||
}
|
}
|
||||||
|
if(dialog) {
|
||||||
|
val exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
||||||
|
AlertDialog(
|
||||||
|
confirmButton = {
|
||||||
|
TextButton({
|
||||||
|
if(exist) {
|
||||||
|
dpm.uninstallCaCert(receiver, caCertByteArray)
|
||||||
|
} else {
|
||||||
|
val result = dpm.installCaCert(receiver, caCertByteArray)
|
||||||
|
context.showOperationResultToast(result)
|
||||||
|
}
|
||||||
|
dialog = false
|
||||||
|
}) {
|
||||||
|
Text(stringResource(if(exist) R.string.uninstall else R.string.install))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton({ dialog = false }) { Text(stringResource(R.string.cancel)) }
|
||||||
|
},
|
||||||
|
onDismissRequest = { dialog = false }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
package com.bintianqi.owndroid.dpm
|
package com.bintianqi.owndroid.dpm
|
||||||
|
|
||||||
import android.os.Build.VERSION
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import com.bintianqi.owndroid.MyViewModel
|
import com.bintianqi.owndroid.MyViewModel
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
@@ -31,15 +29,19 @@ data class Restriction(
|
|||||||
val requiresApi: Int = 0
|
val requiresApi: Int = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@RequiresApi(24)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserRestriction(navCtrl:NavHostController) {
|
fun UserRestriction(navCtrl:NavHostController, vm: MyViewModel) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
vm.userRestrictions.value = dpm.getUserRestrictions(receiver)
|
||||||
|
}
|
||||||
MyScaffold(R.string.user_restriction, 0.dp, navCtrl) {
|
MyScaffold(R.string.user_restriction, 0.dp, navCtrl) {
|
||||||
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
|
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
|
||||||
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
|
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
|
||||||
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || dpm.isManagedProfile(receiver))) {
|
if(context.isProfileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
|
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 2.dp))
|
Spacer(Modifier.padding(vertical = 2.dp))
|
||||||
@@ -54,30 +56,19 @@ fun UserRestriction(navCtrl:NavHostController) {
|
|||||||
|
|
||||||
@RequiresApi(24)
|
@RequiresApi(24)
|
||||||
@Composable
|
@Composable
|
||||||
fun UserRestrictionItem(restriction: Restriction, vm: MyViewModel) {
|
fun UserRestrictionScreen(
|
||||||
val context = LocalContext.current
|
title: Int, items: List<Restriction>, restrictions: Bundle,
|
||||||
val userRestrictions by vm.userRestrictions.collectAsStateWithLifecycle()
|
onRestrictionChange: (String, Boolean) -> Unit, onNavigateUp: () -> Unit
|
||||||
Box(modifier = Modifier.padding(start = 22.dp, end = 16.dp)) {
|
) {
|
||||||
SwitchItem(
|
MyScaffold(title, 0.dp, onNavigateUp, false) {
|
||||||
restriction.name, restriction.id, restriction.icon,
|
items.filter { Build.VERSION.SDK_INT >= it.requiresApi }.forEach { restriction ->
|
||||||
userRestrictions.getBoolean(restriction.id),
|
SwitchItem(
|
||||||
{
|
restriction.name, restriction.id, restriction.icon,
|
||||||
val dpm = context.getDPM()
|
restrictions.getBoolean(restriction.id), { onRestrictionChange(restriction.id, it) }, padding = true
|
||||||
val receiver = context.getReceiver()
|
)
|
||||||
try {
|
/*Box(modifier = Modifier.padding(start = 22.dp, end = 16.dp)) {
|
||||||
if(it) {
|
}*/
|
||||||
dpm.addUserRestriction(receiver, restriction.id)
|
}
|
||||||
} else {
|
|
||||||
dpm.clearUserRestriction(receiver, restriction.id)
|
|
||||||
}
|
|
||||||
vm.userRestrictions.value = dpm.getUserRestrictions(receiver)
|
|
||||||
} catch(_: SecurityException) {
|
|
||||||
if(context.isProfileOwner) {
|
|
||||||
Toast.makeText(context, R.string.require_device_owner, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, padding = false
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<string name="disable">Отключить</string>
|
<string name="disable">Отключить</string>
|
||||||
<string name="enable">Включить</string>
|
<string name="enable">Включить</string>
|
||||||
<string name="success">Успешно</string>
|
<string name="success">Успешно</string>
|
||||||
|
<string name="failure">Failure</string> <!--TODO-->
|
||||||
<string name="failed">Ошибка</string>
|
<string name="failed">Ошибка</string>
|
||||||
<string name="add">Добавить</string>
|
<string name="add">Добавить</string>
|
||||||
<string name="remove">Удалить</string>
|
<string name="remove">Удалить</string>
|
||||||
@@ -69,7 +70,7 @@
|
|||||||
<string name="overview">Обзор</string>
|
<string name="overview">Обзор</string>
|
||||||
<string name="features">Особенности</string>
|
<string name="features">Особенности</string>
|
||||||
<string name="default_str">По умолчанию</string>
|
<string name="default_str">По умолчанию</string>
|
||||||
|
<string name="timeout">Timeout</string> <!--TODO-->
|
||||||
|
|
||||||
<!--Разрешения-->
|
<!--Разрешения-->
|
||||||
<string name="click_to_activate">Нажмите для активации</string>
|
<string name="click_to_activate">Нажмите для активации</string>
|
||||||
@@ -194,8 +195,6 @@
|
|||||||
<string name="ltf_keyguard">Разрешить блокировку экрана</string>
|
<string name="ltf_keyguard">Разрешить блокировку экрана</string>
|
||||||
<string name="ltf_block_activity_start_in_task">Блокировать запуск активности в задаче</string>
|
<string name="ltf_block_activity_start_in_task">Блокировать запуск активности в задаче</string>
|
||||||
<string name="ca_cert">CA-сертификат</string>
|
<string name="ca_cert">CA-сертификат</string>
|
||||||
<string name="please_select_ca_cert">Выберите сертификат</string>
|
|
||||||
<string name="cert_installed">Сертификат установлен: %1$s</string>
|
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Выберите сертификат...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Выберите сертификат...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">Удалить все пользовательские CA-сертификаты</string>
|
<string name="uninstall_all_user_ca_cert">Удалить все пользовательские CA-сертификаты</string>
|
||||||
<string name="security_logging">Журнал безопасности</string>
|
<string name="security_logging">Журнал безопасности</string>
|
||||||
@@ -413,6 +412,7 @@
|
|||||||
<string name="silent_uninstall">Тихое удаление</string>
|
<string name="silent_uninstall">Тихое удаление</string>
|
||||||
<string name="request_uninstall">Запросить удаление</string>
|
<string name="request_uninstall">Запросить удаление</string>
|
||||||
<string name="install_app">Установить приложение</string>
|
<string name="install_app">Установить приложение</string>
|
||||||
|
<string name="search">Search</string> <!--TODO-->
|
||||||
|
|
||||||
<!--Ограничения пользователя-->
|
<!--Ограничения пользователя-->
|
||||||
<string name="user_restriction">Ограничения пользователя</string>
|
<string name="user_restriction">Ограничения пользователя</string>
|
||||||
@@ -423,7 +423,6 @@
|
|||||||
<string name="connectivity">Другие подключения</string>
|
<string name="connectivity">Другие подключения</string>
|
||||||
<string name="media">Медиа</string>
|
<string name="media">Медиа</string>
|
||||||
<string name="other">Другое</string>
|
<string name="other">Другое</string>
|
||||||
<string name="require_device_owner">Требуется владелец устройства</string>
|
|
||||||
<string name="config_mobile_network">Настроить мобильную сеть</string>
|
<string name="config_mobile_network">Настроить мобильную сеть</string>
|
||||||
<string name="config_wifi">Настроить Wi-Fi</string>
|
<string name="config_wifi">Настроить Wi-Fi</string>
|
||||||
<string name="data_roaming">Роуминг данных</string>
|
<string name="data_roaming">Роуминг данных</string>
|
||||||
@@ -609,7 +608,7 @@
|
|||||||
<string name="lock_in_background">Блокировать при переключении в фоновый режим</string>
|
<string name="lock_in_background">Блокировать при переключении в фоновый режим</string>
|
||||||
<string name="clear_storage">Очистить хранилище</string>
|
<string name="clear_storage">Очистить хранилище</string>
|
||||||
<string name="skipped_authentication">Авторизация пропущена, поскольку она недоступна.</string>
|
<string name="skipped_authentication">Авторизация пропущена, поскольку она недоступна.</string>
|
||||||
|
<string name="failed_to_authenticate">Failed to authenticate</string> <!--TODO-->
|
||||||
|
|
||||||
<string name="api_key">API ключ</string>
|
<string name="api_key">API ключ</string>
|
||||||
<string name="api_key_exist">API ключ уже сущетвует, установка нового перезапишет текущий</string>
|
<string name="api_key_exist">API ключ уже сущетвует, установка нового перезапишет текущий</string>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<string name="disable">Devre Dışı Bırak</string>
|
<string name="disable">Devre Dışı Bırak</string>
|
||||||
<string name="enable">Etkinleştir</string>
|
<string name="enable">Etkinleştir</string>
|
||||||
<string name="success">Başarılı</string>
|
<string name="success">Başarılı</string>
|
||||||
|
<string name="failure">Failure</string> <!--TODO-->
|
||||||
<string name="failed">Başarısız</string>
|
<string name="failed">Başarısız</string>
|
||||||
<string name="add">Ekle</string>
|
<string name="add">Ekle</string>
|
||||||
<string name="remove">Kaldır</string>
|
<string name="remove">Kaldır</string>
|
||||||
@@ -70,6 +71,7 @@
|
|||||||
<string name="overview">Overview</string>
|
<string name="overview">Overview</string>
|
||||||
<string name="features">Features</string>
|
<string name="features">Features</string>
|
||||||
<string name="default_str">Default</string>
|
<string name="default_str">Default</string>
|
||||||
|
<string name="timeout">Timeout</string>
|
||||||
|
|
||||||
<!--Permissions-->
|
<!--Permissions-->
|
||||||
<string name="click_to_activate">Etkinleştirmek İçin Tıklayın</string>
|
<string name="click_to_activate">Etkinleştirmek İçin Tıklayın</string>
|
||||||
@@ -200,8 +202,6 @@
|
|||||||
<string name="ltf_keyguard">Ekran kilidine izin ver</string>
|
<string name="ltf_keyguard">Ekran kilidine izin ver</string>
|
||||||
<string name="ltf_block_activity_start_in_task">Görevde etkinlik başlatmayı engelle</string>
|
<string name="ltf_block_activity_start_in_task">Görevde etkinlik başlatmayı engelle</string>
|
||||||
<string name="ca_cert">CA sertifikası</string> <!--TODO-->
|
<string name="ca_cert">CA sertifikası</string> <!--TODO-->
|
||||||
<string name="please_select_ca_cert">Lütfen bir sertifika seçin</string> <!--TODO-->
|
|
||||||
<string name="cert_installed">Yüklenen sertifika: %1$s</string> <!--TODO-->
|
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Sertifika seç...</string> <!--TODO-->
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Sertifika seç...</string> <!--TODO-->
|
||||||
<string name="uninstall_all_user_ca_cert">Tüm kullanıcı sertifikalarını kaldır</string> <!--TODO-->
|
<string name="uninstall_all_user_ca_cert">Tüm kullanıcı sertifikalarını kaldır</string> <!--TODO-->
|
||||||
<string name="security_logging">Security logging</string> <!--TODO-->
|
<string name="security_logging">Security logging</string> <!--TODO-->
|
||||||
@@ -428,7 +428,6 @@
|
|||||||
<string name="connectivity">Diğer bağlantı</string>
|
<string name="connectivity">Diğer bağlantı</string>
|
||||||
<string name="media">Medya</string>
|
<string name="media">Medya</string>
|
||||||
<string name="other">Diğer</string>
|
<string name="other">Diğer</string>
|
||||||
<string name="require_device_owner">Cihaz sahibi gerektirir</string>
|
|
||||||
<string name="config_mobile_network">Mobil ağı yapılandır</string>
|
<string name="config_mobile_network">Mobil ağı yapılandır</string>
|
||||||
<string name="config_wifi">Wi-Fi\'yi yapılandır</string>
|
<string name="config_wifi">Wi-Fi\'yi yapılandır</string>
|
||||||
<string name="data_roaming">Veri dolaşımı</string>
|
<string name="data_roaming">Veri dolaşımı</string>
|
||||||
@@ -610,6 +609,7 @@
|
|||||||
<string name="lock_in_background">Arka plana geçince kilitle</string>
|
<string name="lock_in_background">Arka plana geçince kilitle</string>
|
||||||
<string name="clear_storage">Depolamayı temizle</string>
|
<string name="clear_storage">Depolamayı temizle</string>
|
||||||
<string name="skipped_authentication">Skipped authentication because it is unavailable.</string> <!--TODO-->
|
<string name="skipped_authentication">Skipped authentication because it is unavailable.</string> <!--TODO-->
|
||||||
|
<string name="failed_to_authenticate">Failed to authenticate</string> <!--TODO-->
|
||||||
|
|
||||||
<!--TODO-->
|
<!--TODO-->
|
||||||
<string name="api_key">API key</string>
|
<string name="api_key">API key</string>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<string name="disable">禁用</string>
|
<string name="disable">禁用</string>
|
||||||
<string name="enable">启用</string>
|
<string name="enable">启用</string>
|
||||||
<string name="success">成功</string>
|
<string name="success">成功</string>
|
||||||
|
<string name="failure">失败</string>
|
||||||
<string name="failed">失败</string>
|
<string name="failed">失败</string>
|
||||||
<string name="add">添加</string>
|
<string name="add">添加</string>
|
||||||
<string name="remove">移除</string>
|
<string name="remove">移除</string>
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
<string name="overview">概览</string>
|
<string name="overview">概览</string>
|
||||||
<string name="features">功能</string>
|
<string name="features">功能</string>
|
||||||
<string name="default_str">默认</string>
|
<string name="default_str">默认</string>
|
||||||
|
<string name="timeout">超时</string>
|
||||||
|
|
||||||
<!--Permissions-->
|
<!--Permissions-->
|
||||||
<string name="click_to_activate">点击以激活</string>
|
<string name="click_to_activate">点击以激活</string>
|
||||||
@@ -191,8 +193,6 @@
|
|||||||
<string name="package_name">包名</string>
|
<string name="package_name">包名</string>
|
||||||
<string name="not_exist">不存在</string>
|
<string name="not_exist">不存在</string>
|
||||||
<string name="ca_cert">CA证书</string>
|
<string name="ca_cert">CA证书</string>
|
||||||
<string name="please_select_ca_cert">请选择CA证书</string>
|
|
||||||
<string name="cert_installed">证书已安装:%1$s</string>
|
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">选择证书...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">选择证书...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">卸载所有用户证书</string>
|
<string name="uninstall_all_user_ca_cert">卸载所有用户证书</string>
|
||||||
<string name="security_logging">安全日志</string>
|
<string name="security_logging">安全日志</string>
|
||||||
@@ -415,7 +415,6 @@
|
|||||||
<string name="connectivity">更多连接</string>
|
<string name="connectivity">更多连接</string>
|
||||||
<string name="media">媒体</string>
|
<string name="media">媒体</string>
|
||||||
<string name="other">其他</string>
|
<string name="other">其他</string>
|
||||||
<string name="require_device_owner">需要DeviceOwner</string>
|
|
||||||
<string name="config_mobile_network">配置移动数据</string>
|
<string name="config_mobile_network">配置移动数据</string>
|
||||||
<string name="config_wifi">配置Wi-Fi</string>
|
<string name="config_wifi">配置Wi-Fi</string>
|
||||||
<string name="data_roaming">数据漫游</string>
|
<string name="data_roaming">数据漫游</string>
|
||||||
@@ -597,6 +596,7 @@
|
|||||||
<string name="lock_in_background">处于后台时锁定</string>
|
<string name="lock_in_background">处于后台时锁定</string>
|
||||||
<string name="clear_storage">清除存储空间</string>
|
<string name="clear_storage">清除存储空间</string>
|
||||||
<string name="skipped_authentication">验证已跳过,因为不可用</string>
|
<string name="skipped_authentication">验证已跳过,因为不可用</string>
|
||||||
|
<string name="failed_to_authenticate">验证失败</string>
|
||||||
|
|
||||||
<string name="api_key">API密钥</string>
|
<string name="api_key">API密钥</string>
|
||||||
<string name="api_key_exist">API密钥已存在,设置新的密钥将会覆盖当前密钥</string>
|
<string name="api_key_exist">API密钥已存在,设置新的密钥将会覆盖当前密钥</string>
|
||||||
|
|||||||
@@ -222,8 +222,6 @@
|
|||||||
<string name="ltf_keyguard">Allow keyguard</string>
|
<string name="ltf_keyguard">Allow keyguard</string>
|
||||||
<string name="ltf_block_activity_start_in_task">Block activity start in task</string>
|
<string name="ltf_block_activity_start_in_task">Block activity start in task</string>
|
||||||
<string name="ca_cert">CA certificate</string>
|
<string name="ca_cert">CA certificate</string>
|
||||||
<string name="please_select_ca_cert">Please select a certificate</string>
|
|
||||||
<string name="cert_installed">Certificate installed: %1$s</string>
|
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Select certificate...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Select certificate...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">Uninstall all user CA certificate</string>
|
<string name="uninstall_all_user_ca_cert">Uninstall all user CA certificate</string>
|
||||||
<string name="security_logging">Security logging</string>
|
<string name="security_logging">Security logging</string>
|
||||||
@@ -454,7 +452,6 @@
|
|||||||
<string name="connectivity">Other connection</string>
|
<string name="connectivity">Other connection</string>
|
||||||
<string name="media">Media</string>
|
<string name="media">Media</string>
|
||||||
<string name="other">Other</string>
|
<string name="other">Other</string>
|
||||||
<string name="require_device_owner">Require device owner</string>
|
|
||||||
<string name="config_mobile_network">Configure mobile network</string>
|
<string name="config_mobile_network">Configure mobile network</string>
|
||||||
<string name="config_wifi">Configure Wi-Fi</string>
|
<string name="config_wifi">Configure Wi-Fi</string>
|
||||||
<string name="data_roaming">Data roaming</string>
|
<string name="data_roaming">Data roaming</string>
|
||||||
@@ -637,6 +634,7 @@
|
|||||||
<string name="lock_in_background">Lock when switch to background</string>
|
<string name="lock_in_background">Lock when switch to background</string>
|
||||||
<string name="clear_storage">Clear storage</string>
|
<string name="clear_storage">Clear storage</string>
|
||||||
<string name="skipped_authentication">Skipped authentication because it is unavailable.</string>
|
<string name="skipped_authentication">Skipped authentication because it is unavailable.</string>
|
||||||
|
<string name="failed_to_authenticate">Failed to authenticate</string>
|
||||||
|
|
||||||
<string name="api_key">API key</string>
|
<string name="api_key">API key</string>
|
||||||
<string name="api_key_exist">The API key already exists, setting a new key will overwrite the current key.</string>
|
<string name="api_key_exist">The API key already exists, setting a new key will overwrite the current key.</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user