mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
Optimize Applications and PackageChooser
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,6 @@ import com.bintianqi.owndroid.createShortcuts
|
||||
import com.rosan.dhizuku.api.Dhizuku
|
||||
import com.rosan.dhizuku.api.DhizukuBinderWrapper
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
|
||||
@@ -127,7 +127,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.bintianqi.owndroid.ChoosePackageContract
|
||||
import com.bintianqi.owndroid.HorizontalPadding
|
||||
import com.bintianqi.owndroid.Privilege
|
||||
import com.bintianqi.owndroid.R
|
||||
@@ -153,6 +152,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.isGranted
|
||||
import com.google.accompanist.permissions.rememberPermissionState
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -886,7 +886,10 @@ fun NetworkStats.toBucketList(): List<NetworkStats.Bucket> {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@RequiresApi(23)
|
||||
@Composable
|
||||
fun NetworkStatsScreen(onNavigateUp: () -> Unit, onNavigateToViewer: (NetworkStatsViewer) -> Unit) {
|
||||
fun NetworkStatsScreen(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit,
|
||||
onNavigateUp: () -> Unit, onNavigateToViewer: (NetworkStatsViewer) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val privilege by Privilege.status.collectAsStateWithLifecycle()
|
||||
val fm = LocalFocusManager.current
|
||||
@@ -1053,16 +1056,14 @@ fun NetworkStatsScreen(onNavigateUp: () -> Unit, onNavigateToViewer: (NetworkSta
|
||||
) {
|
||||
var uidText by rememberSaveable { mutableStateOf(context.getString(NetworkStatsUID.All.strRes)) }
|
||||
var readOnly by rememberSaveable { mutableStateOf(true) }
|
||||
if(!readOnly && uidText.toIntOrNull() != null) uid = uidText.toInt()
|
||||
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) {
|
||||
it ?: return@rememberLauncherForActivityResult
|
||||
if(VERSION.SDK_INT >= 24 && readOnly) {
|
||||
try {
|
||||
uid = context.packageManager.getPackageUid(it, 0)
|
||||
uidText = "$it ($uid)"
|
||||
} catch(_: NameNotFoundException) {
|
||||
context.showOperationResultToast(false)
|
||||
}
|
||||
if (!readOnly && uidText.toIntOrNull() != null) uid = uidText.toInt()
|
||||
if (VERSION.SDK_INT >= 24) LaunchedEffect(Unit) {
|
||||
val pkg = chosenPackage.receive()
|
||||
try {
|
||||
uid = context.packageManager.getPackageUid(pkg, 0)
|
||||
uidText = "$uid ($pkg)"
|
||||
} catch(_: NameNotFoundException) {
|
||||
context.showOperationResultToast(false)
|
||||
}
|
||||
}
|
||||
OutlinedTextField(
|
||||
@@ -1093,7 +1094,7 @@ fun NetworkStatsScreen(onNavigateUp: () -> Unit, onNavigateToViewer: (NetworkSta
|
||||
onClick = {
|
||||
readOnly = true
|
||||
activeTextField = NetworkStatsActiveTextField.None
|
||||
choosePackage.launch(null)
|
||||
onChoosePackage()
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
@@ -1457,15 +1458,18 @@ fun PrivateDnsScreen(onNavigateUp: () -> Unit) {
|
||||
|
||||
@RequiresApi(24)
|
||||
@Composable
|
||||
fun AlwaysOnVpnPackageScreen(onNavigateUp: () -> Unit) {
|
||||
fun AlwaysOnVpnPackageScreen(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit, onNavigateUp: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var lockdown by rememberSaveable { mutableStateOf(false) }
|
||||
var pkgName by rememberSaveable { mutableStateOf("") }
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val refresh = { pkgName = Privilege.DPM.getAlwaysOnVpnPackage(Privilege.DAR) ?: "" }
|
||||
LaunchedEffect(Unit) { refresh() }
|
||||
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
|
||||
result?.let { pkgName = it }
|
||||
fun refresh() {
|
||||
pkgName = Privilege.DPM.getAlwaysOnVpnPackage(Privilege.DAR) ?: ""
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
refresh()
|
||||
pkgName = chosenPackage.receive()
|
||||
}
|
||||
val setAlwaysOnVpn: (String?, Boolean)->Boolean = { vpnPkg: String?, lockdownEnabled: Boolean ->
|
||||
try {
|
||||
@@ -1483,21 +1487,8 @@ fun AlwaysOnVpnPackageScreen(onNavigateUp: () -> Unit) {
|
||||
}
|
||||
}
|
||||
MyScaffold(R.string.always_on_vpn, onNavigateUp) {
|
||||
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.list_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable { choosePackage.launch(null) }
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp)
|
||||
)
|
||||
PackageNameTextField(pkgName, onChoosePackage,
|
||||
Modifier.padding(vertical = 4.dp)) { pkgName = it }
|
||||
SwitchItem(R.string.enable_lockdown, state = lockdown, onCheckedChange = { lockdown = it }, padding = false)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
Button(
|
||||
@@ -2067,7 +2058,7 @@ fun AddApnSettingScreen(origin: ApnSetting?, onNavigateUp: () -> Unit) {
|
||||
keyboardActions = KeyboardActions { fm.clearFocus() }
|
||||
)
|
||||
if(VERSION.SDK_INT >= 33) Row(Modifier.fillMaxWidth().padding(vertical = 4.dp), Arrangement.SpaceBetween) {
|
||||
val fr = FocusRequester()
|
||||
val fr = remember { FocusRequester() }
|
||||
OutlinedTextField(
|
||||
mtuV4, { mtuV4 = it }, Modifier.fillMaxWidth(0.49F),
|
||||
label = { Text("MTU (IPv4)") },
|
||||
@@ -2206,7 +2197,7 @@ fun AddApnSettingScreen(origin: ApnSetting?, onNavigateUp: () -> Unit) {
|
||||
if(dialog != 0) {
|
||||
var address by remember { mutableStateOf((if(dialog == 1) proxyAddress else mmsProxyAddress)) }
|
||||
var port by remember { mutableStateOf((if(dialog == 1) proxyPort else mmsProxyPort)) }
|
||||
val fr = FocusRequester()
|
||||
val fr = remember { FocusRequester() }
|
||||
AlertDialog(
|
||||
title = { Text(if(dialog == 1) "Proxy" else "MMS proxy") },
|
||||
text = {
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build.VERSION
|
||||
import android.os.PersistableBundle
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.annotation.Keep
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
@@ -84,10 +83,8 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.state.ToggleableState
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.bintianqi.owndroid.ChoosePackageContract
|
||||
import com.bintianqi.owndroid.DHIZUKU_CLIENTS_FILE
|
||||
import com.bintianqi.owndroid.DhizukuClientInfo
|
||||
import com.bintianqi.owndroid.DhizukuPermissions
|
||||
@@ -113,6 +110,7 @@ import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||
import com.rosan.dhizuku.api.Dhizuku
|
||||
import com.rosan.dhizuku.api.DhizukuRequestPermissionListener
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -731,30 +729,19 @@ fun DelegatedAdminsScreen(onNavigateUp: () -> Unit, onNavigate: (AddDelegatedAdm
|
||||
|
||||
@RequiresApi(26)
|
||||
@Composable
|
||||
fun AddDelegatedAdminScreen(data: AddDelegatedAdmin, onNavigateUp: () -> Unit) {
|
||||
fun AddDelegatedAdminScreen(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit,
|
||||
data: AddDelegatedAdmin, onNavigateUp: () -> Unit
|
||||
) {
|
||||
val updateMode = data.pkg.isNotEmpty()
|
||||
val fm = LocalFocusManager.current
|
||||
var input by remember { mutableStateOf(data.pkg) }
|
||||
val scopes = remember { mutableStateListOf(*data.scopes.toTypedArray()) }
|
||||
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
|
||||
result?.let { input = it }
|
||||
LaunchedEffect(Unit) {
|
||||
input = chosenPackage.receive()
|
||||
}
|
||||
MySmallTitleScaffold(if(updateMode) R.string.place_holder else R.string.add_delegated_admin, onNavigateUp, 0.dp) {
|
||||
OutlinedTextField(
|
||||
value = input, onValueChange = { input = it },
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
trailingIcon = {
|
||||
if(!updateMode) IconButton({ choosePackage.launch(null) }) {
|
||||
Icon(painterResource(R.drawable.list_fill0), null)
|
||||
}
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions { fm.clearFocus() },
|
||||
readOnly = updateMode,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 8.dp, horizontal = HorizontalPadding)
|
||||
)
|
||||
PackageNameTextField(input, onChoosePackage,
|
||||
Modifier.padding(HorizontalPadding, 8.dp)) { input = it }
|
||||
DelegatedScope.entries.filter { VERSION.SDK_INT >= it.requiresApi }.forEach { scope ->
|
||||
val checked = scope in scopes
|
||||
Row(
|
||||
|
||||
@@ -112,13 +112,11 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.bintianqi.owndroid.ChoosePackageContract
|
||||
import com.bintianqi.owndroid.HorizontalPadding
|
||||
import com.bintianqi.owndroid.NotificationUtils
|
||||
import com.bintianqi.owndroid.Privilege
|
||||
@@ -143,6 +141,7 @@ import com.bintianqi.owndroid.ui.Notes
|
||||
import com.bintianqi.owndroid.ui.SwitchItem
|
||||
import com.bintianqi.owndroid.uriToStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1134,7 +1133,9 @@ fun NearbyStreamingPolicyScreen(onNavigateUp: () -> Unit) {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@RequiresApi(28)
|
||||
@Composable
|
||||
fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
|
||||
fun LockTaskModeScreen(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit, onNavigateUp: () -> Unit
|
||||
) {
|
||||
val coroutine = rememberCoroutineScope()
|
||||
val pagerState = rememberPagerState { 3 }
|
||||
var tabIndex by remember { mutableIntStateOf(0) }
|
||||
@@ -1177,8 +1178,8 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
|
||||
.padding(horizontal = HorizontalPadding)
|
||||
.padding(bottom = 80.dp)
|
||||
) {
|
||||
if(page == 0) StartLockTaskMode()
|
||||
else LockTaskPackages()
|
||||
if(page == 0) StartLockTaskMode(chosenPackage, onChoosePackage)
|
||||
else LockTaskPackages(chosenPackage, onChoosePackage)
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
@@ -1197,33 +1198,20 @@ fun LockTaskModeScreen(onNavigateUp: () -> Unit) {
|
||||
|
||||
@RequiresApi(28)
|
||||
@Composable
|
||||
private fun ColumnScope.StartLockTaskMode() {
|
||||
private fun ColumnScope.StartLockTaskMode(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val focusMgr = LocalFocusManager.current
|
||||
var startLockTaskApp by rememberSaveable { mutableStateOf("") }
|
||||
var startLockTaskActivity by rememberSaveable { mutableStateOf("") }
|
||||
var specifyActivity by rememberSaveable { mutableStateOf(false) }
|
||||
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
|
||||
result?.let { startLockTaskApp = it }
|
||||
LaunchedEffect(Unit) {
|
||||
startLockTaskApp = chosenPackage.receive()
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
OutlinedTextField(
|
||||
value = startLockTaskApp,
|
||||
onValueChange = { startLockTaskApp = it },
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
trailingIcon = {
|
||||
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable { choosePackage.launch(null) }
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 3.dp)
|
||||
)
|
||||
PackageNameTextField(startLockTaskApp, onChoosePackage,
|
||||
Modifier.padding(vertical = 3.dp), { startLockTaskApp = it })
|
||||
CheckBoxItem(R.string.specify_activity, specifyActivity) { specifyActivity = it }
|
||||
AnimatedVisibility(specifyActivity) {
|
||||
OutlinedTextField(
|
||||
@@ -1264,37 +1252,23 @@ private fun ColumnScope.StartLockTaskMode() {
|
||||
|
||||
@RequiresApi(26)
|
||||
@Composable
|
||||
private fun ColumnScope.LockTaskPackages() {
|
||||
private fun ColumnScope.LockTaskPackages(
|
||||
chosenPackage: Channel<String>, onChoosePackage: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val lockTaskPackages = remember { mutableStateListOf<String>() }
|
||||
var input by rememberSaveable { mutableStateOf("") }
|
||||
val choosePackage = rememberLauncherForActivityResult(ChoosePackageContract()) { result ->
|
||||
result?.let { input = it }
|
||||
LaunchedEffect(Unit) {
|
||||
lockTaskPackages.addAll(Privilege.DPM.getLockTaskPackages(Privilege.DAR))
|
||||
input = chosenPackage.receive()
|
||||
}
|
||||
LaunchedEffect(Unit) { lockTaskPackages.addAll(Privilege.DPM.getLockTaskPackages(Privilege.DAR)) }
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
if(lockTaskPackages.isEmpty()) Text(text = stringResource(R.string.none))
|
||||
for(i in lockTaskPackages) {
|
||||
ListItem(i) { lockTaskPackages -= i }
|
||||
}
|
||||
OutlinedTextField(
|
||||
value = input,
|
||||
onValueChange = { input = it },
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||
trailingIcon = {
|
||||
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable { choosePackage.launch(null) }
|
||||
.padding(3.dp))
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 3.dp)
|
||||
)
|
||||
PackageNameTextField(input, onChoosePackage,
|
||||
Modifier.padding(vertical = 3.dp), { input = it })
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
|
||||
Button(
|
||||
onClick = {
|
||||
|
||||
Reference in New Issue
Block a user