mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +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) {
|
||||
|
||||
@@ -109,6 +109,8 @@
|
||||
<!--Shizuku-->
|
||||
<string name="check_shizuku">İzni Kontrol Et</string>
|
||||
<string name="list_owners">Sahipleri Listele</string>
|
||||
<string name="list_users">List users</string> <!--TODO-->
|
||||
<string name="list_accounts">List accounts</string> <!--TODO-->
|
||||
<string name="shizuku_not_started">Shizuku Başlatılmadı. </string>
|
||||
<string name="shizuku_activated_shell">İzin Verildi (Kabuk)</string>
|
||||
<string name="shizuku_activated_root">İzin Verildi (Root)</string>
|
||||
@@ -160,8 +162,9 @@
|
||||
<string name="lock_task_mode">Lock task mode</string> <!--TODO-->
|
||||
<string name="lock_task_feature">Görev kilitleme özelliği</string>
|
||||
<string name="lock_task_packages">Lock task packages</string> <!--TODO-->
|
||||
<string name="specify_activity">Specify Activity</string> <!--TODO-->
|
||||
<string name="start_lock_task_mode">Start lock task mode</string> <!--TODO-->
|
||||
<string name="app_not_allowed">App not allowed</string> <!--TODO-->
|
||||
<string name="app_not_allowed">App is not allowed</string> <!--TODO-->
|
||||
<string name="disable_all">Hepsini devre dışı bırak</string>
|
||||
|
||||
<!--ltf: lock task feature-->
|
||||
|
||||
@@ -104,6 +104,8 @@
|
||||
<!--Shizuku-->
|
||||
<string name="check_shizuku">检查Shizuku</string>
|
||||
<string name="list_owners">列出Owners</string>
|
||||
<string name="list_users">列出用户</string>
|
||||
<string name="list_accounts">列出账号</string>
|
||||
<string name="shizuku_not_started">服务未启动</string>
|
||||
<string name="shizuku_activated_shell">已授权(Shell)</string>
|
||||
<string name="shizuku_activated_root">已授权(Root)</string>
|
||||
@@ -155,6 +157,7 @@
|
||||
<string name="lock_task_mode">锁定任务模式</string>
|
||||
<string name="lock_task_feature">锁定任务功能</string>
|
||||
<string name="lock_task_packages">锁定任务应用</string>
|
||||
<string name="specify_activity">指定Activity</string>
|
||||
<string name="start_lock_task_mode">启动锁定任务模式</string>
|
||||
<string name="app_not_allowed">应用未被允许</string>
|
||||
<string name="disable_all">禁用全部</string>
|
||||
|
||||
@@ -111,6 +111,8 @@
|
||||
<string name="shizuku" translatable="false">Shizuku</string>
|
||||
<string name="check_shizuku">Check permission</string>
|
||||
<string name="list_owners">List owners</string>
|
||||
<string name="list_users">List users</string>
|
||||
<string name="list_accounts">List accounts</string>
|
||||
<string name="shizuku_not_started">Shizuku not started. </string>
|
||||
<string name="dpm_activate_do_command" translatable="false">dpm set-device-owner com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
|
||||
<string name="dpm_activate_da_command" translatable="false">dpm set-active-admin com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver</string>
|
||||
@@ -164,8 +166,9 @@
|
||||
<string name="lock_task_mode">Lock task mode</string>
|
||||
<string name="lock_task_feature">Lock task feature</string>
|
||||
<string name="lock_task_packages">Lock task packages</string>
|
||||
<string name="specify_activity">Specify Activity</string>
|
||||
<string name="start_lock_task_mode">Start lock task mode</string>
|
||||
<string name="app_not_allowed">App not allowed</string>
|
||||
<string name="app_not_allowed">App is not allowed</string>
|
||||
<string name="disable_all">Disable all</string>
|
||||
<!--ltf: lock task feature-->
|
||||
<string name="ltf_sys_info">Allow system info</string>
|
||||
|
||||
Reference in New Issue
Block a user