mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-24 03:16:00 +00:00
Move AlwaysOnVpn from App manager to Network
Use Shizuku to list users and list accounts Add package selector for Lock task mode Specify an Activity before start lock task mode Improve UI design
This commit is contained in:
@@ -67,11 +67,11 @@ private fun Home(navCtrl: NavHostController) {
|
||||
@Composable
|
||||
private fun Options() {
|
||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
||||
SwitchItem(
|
||||
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
|
||||
{ sharedPref.getBoolean("dangerous_features", false) },
|
||||
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }
|
||||
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }, padding = false
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -79,15 +79,15 @@ private fun Options() {
|
||||
@Composable
|
||||
private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
|
||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
||||
if(VERSION.SDK_INT>=31) {
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
||||
if(VERSION.SDK_INT >= 31) {
|
||||
SwitchItem(
|
||||
R.string.material_you_color, stringResource(R.string.dynamic_color_desc), null,
|
||||
{ sharedPref.getBoolean("material_you",true) },
|
||||
{
|
||||
sharedPref.edit().putBoolean("material_you", it).apply()
|
||||
materialYou.value = it
|
||||
}
|
||||
}, padding = false
|
||||
)
|
||||
}
|
||||
if(isSystemInDarkTheme()) {
|
||||
@@ -97,7 +97,7 @@ private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableS
|
||||
{
|
||||
sharedPref.edit().putBoolean("black_theme", it).apply()
|
||||
blackTheme.value = it
|
||||
}
|
||||
}, padding = false
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -107,30 +107,30 @@ private fun ThemeSettings(materialYou:MutableState<Boolean>, blackTheme:MutableS
|
||||
private fun AuthSettings() {
|
||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||
var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) }
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
||||
SwitchItem(
|
||||
R.string.lock_owndroid, "", null, auth,
|
||||
{
|
||||
sharedPref.edit().putBoolean("auth", it).apply()
|
||||
auth = sharedPref.getBoolean("auth", false)
|
||||
}
|
||||
}, padding = false
|
||||
)
|
||||
if(auth) {
|
||||
SwitchItem(
|
||||
R.string.enable_bio_auth, "", null,
|
||||
{ sharedPref.getBoolean("bio_auth", false) },
|
||||
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }
|
||||
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }, padding = false
|
||||
)
|
||||
SwitchItem(
|
||||
R.string.lock_in_background, stringResource(R.string.developing), null,
|
||||
{ sharedPref.getBoolean("lock_in_background", false) },
|
||||
{ sharedPref.edit().putBoolean("lock_in_background", it).apply() }
|
||||
{ sharedPref.edit().putBoolean("lock_in_background", it).apply() }, padding = false
|
||||
)
|
||||
}
|
||||
SwitchItem(
|
||||
R.string.protect_storage, "", null,
|
||||
{ sharedPref.getBoolean("protect_storage", false) },
|
||||
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }
|
||||
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }, padding = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,6 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
|
||||
composable(route = "Home") {
|
||||
Home(localNavCtrl, pkgName, dialogStatus)
|
||||
}
|
||||
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(pkgName) }
|
||||
composable(route = "UserControlDisabled") { UserCtrlDisabledPkg(pkgName) }
|
||||
composable(route = "PermissionManage") { PermissionManage(pkgName) }
|
||||
composable(route = "CrossProfilePackage") { CrossProfilePkg(pkgName) }
|
||||
@@ -245,9 +244,6 @@ private fun Home(
|
||||
onClickBlank = { appControlAction = 3; appControlDialog = true }
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 24 && (deviceOwner || profileOwner)) {
|
||||
SubPageItem(R.string.always_on_vpn, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("AlwaysOnVpn") }
|
||||
}
|
||||
if((VERSION.SDK_INT >= 33 && profileOwner) || (VERSION.SDK_INT >= 30 && deviceOwner)) {
|
||||
SubPageItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") }
|
||||
}
|
||||
@@ -349,48 +345,6 @@ private fun Home(
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Composable
|
||||
fun AlwaysOnVPNPackage(pkgName: String) {
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
var lockdown by remember { mutableStateOf(false) }
|
||||
var pkg by remember { mutableStateOf<String?>("") }
|
||||
val refresh = { pkg = dpm.getAlwaysOnVpnPackage(receiver) }
|
||||
LaunchedEffect(Unit) { refresh() }
|
||||
val setAlwaysOnVpn: (String?, Boolean)->Unit = { vpnPkg: String?, lockdownEnabled: Boolean ->
|
||||
try {
|
||||
dpm.setAlwaysOnVpnPackage(receiver, vpnPkg, lockdownEnabled)
|
||||
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
|
||||
} catch(e: UnsupportedOperationException) {
|
||||
Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show()
|
||||
} catch(e: NameNotFoundException) {
|
||||
Toast.makeText(context, R.string.not_installed, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.always_on_vpn), style = typography.headlineLarge, modifier = Modifier.padding(vertical = 8.dp))
|
||||
Text(text = stringResource(R.string.current_app_is) + pkg, modifier = Modifier.padding(vertical = 8.dp))
|
||||
SwitchItem(R.string.enable_lockdown, "", null, lockdown, { lockdown = it }, padding = false)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
Button(
|
||||
onClick = { setAlwaysOnVpn(pkgName, lockdown); refresh() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
Button(
|
||||
onClick = { setAlwaysOnVpn(null, false); refresh() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(R.string.clear_current_config))
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Composable
|
||||
|
||||
@@ -16,6 +16,7 @@ import android.app.admin.WifiSsidPolicy
|
||||
import android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST
|
||||
import android.app.admin.WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
import android.net.ProxyInfo
|
||||
import android.net.Uri
|
||||
import android.net.wifi.WifiSsid
|
||||
@@ -42,6 +43,7 @@ import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -50,15 +52,16 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
@@ -69,17 +72,21 @@ import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
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
|
||||
@@ -91,6 +98,7 @@ import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.selectedPackage
|
||||
import com.bintianqi.owndroid.toText
|
||||
import com.bintianqi.owndroid.ui.Animations
|
||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||
@@ -130,6 +138,7 @@ fun Network(navCtrl: NavHostController) {
|
||||
composable(route = "MinWifiSecurityLevel") { WifiSecLevel() }
|
||||
composable(route = "WifiSsidPolicy") { WifiSsidPolicy() }
|
||||
composable(route = "PrivateDNS") { PrivateDNS() }
|
||||
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(navCtrl) }
|
||||
composable(route = "RecommendedGlobalProxy") { RecommendedGlobalProxy() }
|
||||
composable(route = "NetworkLog") { NetworkLog() }
|
||||
composable(route = "WifiAuthKeypair") { WifiAuthKeypair() }
|
||||
@@ -178,6 +187,9 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState, wifiMacDia
|
||||
if(VERSION.SDK_INT >= 29 && deviceOwner) {
|
||||
SubPageItem(R.string.private_dns, "", R.drawable.dns_fill0) { navCtrl.navigate("PrivateDNS") }
|
||||
}
|
||||
if(VERSION.SDK_INT >= 24 && (deviceOwner || profileOwner)) {
|
||||
SubPageItem(R.string.always_on_vpn, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("AlwaysOnVpn") }
|
||||
}
|
||||
if(deviceOwner) {
|
||||
SubPageItem(R.string.recommended_global_proxy, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("RecommendedGlobalProxy") }
|
||||
}
|
||||
@@ -200,17 +212,17 @@ private fun Switches() {
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val deviceOwner = context.isDeviceOwner
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
Column(modifier = Modifier.fillMaxSize().padding(start = 20.dp, end = 16.dp)) {
|
||||
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,
|
||||
{ dpm.isPreferentialNetworkServiceEnabled }, { dpm.isPreferentialNetworkServiceEnabled = it }
|
||||
{ dpm.isPreferentialNetworkServiceEnabled }, { dpm.isPreferentialNetworkServiceEnabled = it }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT>=30 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||
SwitchItem(R.string.lockdown_admin_configured_network, "", R.drawable.wifi_password_fill0,
|
||||
{ dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) }
|
||||
{ dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -438,6 +450,77 @@ private fun PrivateDNS() {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Composable
|
||||
fun AlwaysOnVPNPackage(navCtrl: NavHostController) {
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
var lockdown by rememberSaveable { mutableStateOf(false) }
|
||||
var pkgName by rememberSaveable { mutableStateOf("") }
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val refresh = { pkgName = dpm.getAlwaysOnVpnPackage(receiver) ?: "" }
|
||||
LaunchedEffect(Unit) { refresh() }
|
||||
val updatePackage by selectedPackage.collectAsState()
|
||||
LaunchedEffect(updatePackage) {
|
||||
if(selectedPackage.value != "") {
|
||||
pkgName = selectedPackage.value
|
||||
selectedPackage.value = ""
|
||||
}
|
||||
}
|
||||
val setAlwaysOnVpn: (String?, Boolean)->Boolean = { vpnPkg: String?, lockdownEnabled: Boolean ->
|
||||
try {
|
||||
dpm.setAlwaysOnVpnPackage(receiver, vpnPkg, lockdownEnabled)
|
||||
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
|
||||
true
|
||||
} catch(e: UnsupportedOperationException) {
|
||||
Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show()
|
||||
false
|
||||
} catch(e: NameNotFoundException) {
|
||||
Toast.makeText(context, R.string.not_installed, Toast.LENGTH_SHORT).show()
|
||||
false
|
||||
}
|
||||
}
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.always_on_vpn), style = typography.headlineLarge, modifier = Modifier.padding(vertical = 8.dp))
|
||||
OutlinedTextField(
|
||||
value = pkgName,
|
||||
onValueChange = { pkgName = it },
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
trailingIcon = {
|
||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable(onClick = {
|
||||
focusMgr.clearFocus()
|
||||
navCtrl.navigate("PackageSelector")
|
||||
})
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
|
||||
)
|
||||
SwitchItem(R.string.enable_lockdown, "", null, lockdown, { lockdown = it }, padding = false)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
Button(
|
||||
onClick = { if(setAlwaysOnVpn(pkgName, lockdown)) refresh() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
Button(
|
||||
onClick = { if(setAlwaysOnVpn(null, false)) refresh() },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(R.string.clear_current_config))
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RecommendedGlobalProxy() {
|
||||
val context = LocalContext.current
|
||||
|
||||
@@ -114,6 +114,28 @@ fun ShizukuActivate() {
|
||||
) {
|
||||
Text(text = stringResource(R.string.list_owners))
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
coScope.launch{
|
||||
outputText = service!!.execute("pm list users")
|
||||
outputTextScrollState.animateScrollTo(0)
|
||||
}
|
||||
},
|
||||
enabled = enabled
|
||||
) {
|
||||
Text(text = stringResource(R.string.list_users))
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
coScope.launch{
|
||||
outputText = service!!.execute("dumpsys account")
|
||||
outputTextScrollState.animateScrollTo(0)
|
||||
}
|
||||
},
|
||||
enabled = enabled
|
||||
) {
|
||||
Text(text = stringResource(R.string.list_accounts))
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
|
||||
AnimatedVisibility(showDeviceAdminButton && showDeviceOwnerButton) {
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.app.admin.SystemUpdatePolicy
|
||||
import android.app.admin.SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC
|
||||
import android.app.admin.SystemUpdatePolicy.TYPE_INSTALL_WINDOWED
|
||||
import android.app.admin.SystemUpdatePolicy.TYPE_POSTPONE
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
@@ -45,16 +46,17 @@ import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
@@ -62,6 +64,7 @@ import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
@@ -79,12 +82,15 @@ import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
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
|
||||
@@ -100,6 +106,7 @@ import com.bintianqi.owndroid.StopLockTaskModeReceiver
|
||||
import com.bintianqi.owndroid.fileUriFlow
|
||||
import com.bintianqi.owndroid.getFile
|
||||
import com.bintianqi.owndroid.prepareForNotification
|
||||
import com.bintianqi.owndroid.selectedPackage
|
||||
import com.bintianqi.owndroid.toText
|
||||
import com.bintianqi.owndroid.toggle
|
||||
import com.bintianqi.owndroid.ui.Animations
|
||||
@@ -117,7 +124,7 @@ import java.util.concurrent.Executors
|
||||
import kotlin.math.pow
|
||||
|
||||
@Composable
|
||||
fun SystemManage(navCtrl:NavHostController) {
|
||||
fun SystemManage(navCtrl: NavHostController) {
|
||||
val localNavCtrl = rememberNavController()
|
||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
||||
val scrollState = rememberScrollState()
|
||||
@@ -151,7 +158,7 @@ fun SystemManage(navCtrl:NavHostController) {
|
||||
composable(route = "PermissionPolicy") { PermissionPolicy() }
|
||||
composable(route = "MTEPolicy") { MTEPolicy() }
|
||||
composable(route = "NearbyStreamingPolicy") { NearbyStreamingPolicy() }
|
||||
composable(route = "LockTaskMode") { LockTaskMode() }
|
||||
composable(route = "LockTaskMode") { LockTaskMode(navCtrl) }
|
||||
composable(route = "CaCert") { CaCert() }
|
||||
composable(route = "SecurityLogs") { SecurityLogs() }
|
||||
composable(route = "SystemUpdatePolicy") { SysUpdatePolicy() }
|
||||
@@ -239,53 +246,53 @@ private fun Switches() {
|
||||
val receiver = context.getReceiver()
|
||||
val deviceOwner = context.isDeviceOwner
|
||||
val profileOwner = context.isProfileOwner
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
if(deviceOwner || profileOwner) {
|
||||
SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0,
|
||||
{ dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) }
|
||||
{ dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(deviceOwner || profileOwner) {
|
||||
SwitchItem(R.string.disable_screen_capture, "", R.drawable.screenshot_fill0,
|
||||
{ dpm.getScreenCaptureDisabled(null) }, { dpm.setScreenCaptureDisabled(receiver,it) }
|
||||
{ dpm.getScreenCaptureDisabled(null) }, { dpm.setScreenCaptureDisabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 34 && (deviceOwner || (profileOwner && dpm.isAffiliatedUser))) {
|
||||
SwitchItem(R.string.disable_status_bar, "", R.drawable.notifications_fill0,
|
||||
{ dpm.isStatusBarDisabled}, { dpm.setStatusBarDisabled(receiver,it) }
|
||||
{ dpm.isStatusBarDisabled}, { dpm.setStatusBarDisabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(deviceOwner || dpm.isOrgProfile(receiver)) {
|
||||
if(VERSION.SDK_INT >= 30) {
|
||||
SwitchItem(R.string.auto_time, "", R.drawable.schedule_fill0,
|
||||
{ dpm.getAutoTimeEnabled(receiver) }, { dpm.setAutoTimeEnabled(receiver,it) }
|
||||
{ dpm.getAutoTimeEnabled(receiver) }, { dpm.setAutoTimeEnabled(receiver,it) }, padding = false
|
||||
)
|
||||
SwitchItem(R.string.auto_timezone, "", R.drawable.globe_fill0,
|
||||
{ dpm.getAutoTimeZoneEnabled(receiver) }, { dpm.setAutoTimeZoneEnabled(receiver,it) }
|
||||
{ dpm.getAutoTimeZoneEnabled(receiver) }, { dpm.setAutoTimeZoneEnabled(receiver,it) }, padding = false
|
||||
)
|
||||
}else{
|
||||
SwitchItem(R.string.require_auto_time, "", R.drawable.schedule_fill0, { dpm.autoTimeRequired}, { dpm.setAutoTimeRequired(receiver,it) })
|
||||
SwitchItem(R.string.require_auto_time, "", R.drawable.schedule_fill0, { dpm.autoTimeRequired}, { dpm.setAutoTimeRequired(receiver,it) }, padding = false)
|
||||
}
|
||||
}
|
||||
if(deviceOwner || profileOwner) {
|
||||
SwitchItem(R.string.master_mute, "", R.drawable.volume_up_fill0,
|
||||
{ dpm.isMasterVolumeMuted(receiver) }, { dpm.setMasterVolumeMuted(receiver,it) }
|
||||
{ dpm.isMasterVolumeMuted(receiver) }, { dpm.setMasterVolumeMuted(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
||||
SwitchItem(R.string.backup_service, "", R.drawable.backup_fill0,
|
||||
{ dpm.isBackupServiceEnabled(receiver) }, { dpm.setBackupServiceEnabled(receiver,it) }
|
||||
{ dpm.isBackupServiceEnabled(receiver) }, { dpm.setBackupServiceEnabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
|
||||
SwitchItem(R.string.disable_bt_contact_share, "", R.drawable.account_circle_fill0,
|
||||
{ dpm.getBluetoothContactSharingDisabled(receiver) }, { dpm.setBluetoothContactSharingDisabled(receiver,it) }
|
||||
{ dpm.getBluetoothContactSharingDisabled(receiver) }, { dpm.setBluetoothContactSharingDisabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 30 && deviceOwner) {
|
||||
SwitchItem(R.string.common_criteria_mode , "",R.drawable.security_fill0,
|
||||
{ dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) }
|
||||
{ dpm.isCommonCriteriaModeEnabled(receiver) }, { dpm.setCommonCriteriaModeEnabled(receiver,it) }, padding = false
|
||||
)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 31 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||
@@ -297,7 +304,7 @@ private fun Switches() {
|
||||
} else {
|
||||
Toast.makeText(context, R.string.unsupported, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}, padding = false
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
@@ -657,15 +664,16 @@ private fun NearbyStreamingPolicy() {
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Composable
|
||||
private fun LockTaskMode() {
|
||||
private fun LockTaskMode(navCtrl: NavHostController) {
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val coroutine = rememberCoroutineScope()
|
||||
var appSelectorRequest by rememberSaveable { mutableIntStateOf(0) }
|
||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
||||
val lockTaskFeatures = remember { mutableStateListOf<Int>() }
|
||||
var custom by remember { mutableStateOf(false) }
|
||||
var custom by rememberSaveable { mutableStateOf(false) }
|
||||
val refreshFeature = {
|
||||
var calculate = dpm.getLockTaskFeatures(receiver)
|
||||
lockTaskFeatures.clear()
|
||||
@@ -756,7 +764,7 @@ private fun LockTaskMode() {
|
||||
}
|
||||
|
||||
val lockTaskPackages = remember { mutableStateListOf<String>() }
|
||||
var inputLockTaskPkg by remember { mutableStateOf("") }
|
||||
var inputLockTaskPkg by rememberSaveable { mutableStateOf("") }
|
||||
LaunchedEffect(Unit) { lockTaskPackages.addAll(dpm.getLockTaskPackages(receiver)) }
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.lock_task_packages), style = typography.headlineLarge)
|
||||
@@ -772,6 +780,17 @@ private fun LockTaskMode() {
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
trailingIcon = {
|
||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable(onClick = {
|
||||
focusMgr.clearFocus()
|
||||
appSelectorRequest = 1
|
||||
navCtrl.navigate("PackageSelector")
|
||||
})
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
|
||||
)
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
@@ -797,7 +816,16 @@ private fun LockTaskMode() {
|
||||
) {
|
||||
Text(stringResource(R.string.apply))
|
||||
}
|
||||
var startLockTaskApp by remember { mutableStateOf("") }
|
||||
var startLockTaskApp by rememberSaveable { mutableStateOf("") }
|
||||
var startLockTaskActivity by rememberSaveable { mutableStateOf("") }
|
||||
var specifyActivity by rememberSaveable { mutableStateOf(false) }
|
||||
val updatePackage by selectedPackage.collectAsState()
|
||||
LaunchedEffect(updatePackage) {
|
||||
if(updatePackage != "") {
|
||||
if(appSelectorRequest == 1) inputLockTaskPkg = updatePackage else startLockTaskApp = updatePackage
|
||||
selectedPackage.value = ""
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.start_lock_task_mode), style = typography.headlineLarge)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
@@ -807,8 +835,30 @@ private fun LockTaskMode() {
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
trailingIcon = {
|
||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable(onClick = {
|
||||
focusMgr.clearFocus()
|
||||
appSelectorRequest = 2
|
||||
navCtrl.navigate("PackageSelector")
|
||||
})
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
|
||||
)
|
||||
CheckBoxItem(R.string.specify_activity, specifyActivity, { specifyActivity = it })
|
||||
AnimatedVisibility(specifyActivity) {
|
||||
OutlinedTextField(
|
||||
value = startLockTaskActivity,
|
||||
onValueChange = { startLockTaskActivity = it },
|
||||
label = { Text("Activity") },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp)
|
||||
)
|
||||
}
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {
|
||||
@@ -818,7 +868,8 @@ private fun LockTaskMode() {
|
||||
}
|
||||
val options = ActivityOptions.makeBasic().setLockTaskEnabled(true)
|
||||
val packageManager = context.packageManager
|
||||
val launchIntent = packageManager.getLaunchIntentForPackage(startLockTaskApp)
|
||||
val launchIntent = if(specifyActivity) Intent().setComponent(ComponentName(startLockTaskApp, startLockTaskActivity))
|
||||
else packageManager.getLaunchIntentForPackage(startLockTaskApp)
|
||||
if (launchIntent != null) {
|
||||
coroutine.launch {
|
||||
prepareForNotification(context) {
|
||||
|
||||
Reference in New Issue
Block a user