From 5027c226263cb6691a4c53221f7a4e4168338e48 Mon Sep 17 00:00:00 2001 From: BinTianqi Date: Wed, 29 May 2024 18:58:12 +0800 Subject: [PATCH] optimize shizuku related function and wifi ssid poliicy --- .../bintianqi/owndroid/PermissionPicker.kt | 17 +- .../owndroid/dpm/ApplicationManage.kt | 27 +-- .../java/com/bintianqi/owndroid/dpm/DPM.kt | 3 +- .../com/bintianqi/owndroid/dpm/Network.kt | 187 +++++++++++------- .../bintianqi/owndroid/dpm/ShizukuActivate.kt | 92 +++++---- .../bintianqi/owndroid/dpm/ShizukuService.kt | 3 +- 6 files changed, 194 insertions(+), 135 deletions(-) diff --git a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt b/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt index b2b8012..c3e01a5 100644 --- a/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt +++ b/app/src/main/java/com/bintianqi/owndroid/PermissionPicker.kt @@ -3,17 +3,25 @@ package com.bintianqi.owndroid import android.Manifest import android.os.Build.VERSION import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.* +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import com.bintianqi.owndroid.dpm.applySelectedPermission import com.bintianqi.owndroid.dpm.selectedPermission import com.bintianqi.owndroid.ui.NavIcon @@ -37,8 +45,7 @@ fun PermissionPicker(navCtrl: NavHostController) { modifier = Modifier .fillMaxWidth() .clickable{ - selectedPermission = it.first - applySelectedPermission.value = true + selectedPermission.value = it.first navCtrl.navigateUp() } .padding(vertical = 6.dp, horizontal = 8.dp) diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt index d90e5bd..0987ca5 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ApplicationManage.kt @@ -337,17 +337,18 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) val focusMgr = LocalFocusManager.current - var inputPermission by remember{mutableStateOf(selectedPermission)} - var currentState by remember{mutableStateOf(context.getString(R.string.unknown))} + var inputPermission by remember { mutableStateOf("") } + var currentState by remember { mutableStateOf(context.getString(R.string.unknown)) } val grantState = mapOf( PERMISSION_GRANT_STATE_DEFAULT to stringResource(R.string.decide_by_user), PERMISSION_GRANT_STATE_GRANTED to stringResource(R.string.granted), PERMISSION_GRANT_STATE_DENIED to stringResource(R.string.denied) ) - LaunchedEffect(applySelectedPermission.collectAsState()) { - if(applySelectedPermission.value) { - inputPermission = selectedPermission - applySelectedPermission.value = false + val applyPermission by selectedPermission.collectAsState() + LaunchedEffect(applyPermission) { + if(applyPermission != "") { + inputPermission = applyPermission + selectedPermission.value = "" } } LaunchedEffect(pkgName) { @@ -361,7 +362,7 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController) { value = inputPermission, label = { Text(stringResource(R.string.permission)) }, onValueChange = { - inputPermission = it; selectedPermission = inputPermission + inputPermission = it currentState = grantState[dpm.getPermissionGrantState(receiver,pkgName,inputPermission)]!! }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done), @@ -577,7 +578,7 @@ private fun CredentialManagePolicy(pkgName: String) { AnimatedVisibility(policyType != -1) { Column { Text(stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { Text(text = if(credentialList.isEmpty()) stringResource(R.string.none) else credentialList.toText()) } Spacer(Modifier.padding(vertical = 10.dp)) @@ -739,7 +740,7 @@ private fun PermittedIME(pkgName: String) { } AnimatedVisibility(!allowAll) { Column { - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { if(permittedIme.isEmpty()) { Text(stringResource(R.string.only_system_ime_allowed)) } else { @@ -805,7 +806,7 @@ private fun KeepUninstalledApp(pkgName: String) { Text(text = stringResource(R.string.keep_uninstalled_packages), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) Text(text = stringResource(R.string.app_list_is)) - SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize(scrollAnim())) { + SelectionContainer(modifier = Modifier.horizontalScroll(rememberScrollState()).animateContentSize()) { Text(text = if(pkgList.isEmpty()) stringResource(R.string.none) else pkgList.toText()) } Spacer(Modifier.padding(vertical = 5.dp)) @@ -926,7 +927,7 @@ private fun InstallApp() { @SuppressLint("NewApi") @Composable -fun ClearAppDataDialog(status: MutableState, pkgName: String) { +private fun ClearAppDataDialog(status: MutableState, pkgName: String) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) @@ -972,7 +973,7 @@ fun ClearAppDataDialog(status: MutableState, pkgName: String) { @SuppressLint("NewApi") @Composable -fun DefaultDialerAppDialog(status: MutableState, pkgName: String) { +private fun DefaultDialerAppDialog(status: MutableState, pkgName: String) { val context = LocalContext.current val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager AlertDialog( @@ -1008,7 +1009,7 @@ fun DefaultDialerAppDialog(status: MutableState, pkgName: String) { } @Composable -fun AppControlDialog(status: MutableIntState) { +private fun AppControlDialog(status: MutableIntState) { val enabled = dialogGetStatus() Dialog( onDismissRequest = { status.intValue = 0 } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt index 5831fa1..d94c660 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt @@ -5,8 +5,7 @@ import android.content.Intent import androidx.activity.result.ActivityResultLauncher import kotlinx.coroutines.flow.MutableStateFlow -var selectedPermission = "" -var applySelectedPermission = MutableStateFlow(false) +var selectedPermission = MutableStateFlow("") lateinit var createManagedProfile: ActivityResultLauncher lateinit var addDeviceAdmin: ActivityResultLauncher diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt index ddcda1b..30fbde7 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/Network.kt @@ -2,7 +2,17 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint import android.app.admin.DevicePolicyManager -import android.app.admin.DevicePolicyManager.* +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_ERROR_FAILURE_SETTING +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_ERROR_HOST_NOT_SERVING +import android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR +import android.app.admin.DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_192 +import android.app.admin.DevicePolicyManager.WIFI_SECURITY_ENTERPRISE_EAP +import android.app.admin.DevicePolicyManager.WIFI_SECURITY_OPEN +import android.app.admin.DevicePolicyManager.WIFI_SECURITY_PERSONAL 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 @@ -11,21 +21,56 @@ import android.net.wifi.WifiSsid import android.os.Build.VERSION import android.telephony.TelephonyManager import android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID -import android.telephony.data.ApnSetting.* +import android.telephony.data.ApnSetting.AUTH_TYPE_CHAP +import android.telephony.data.ApnSetting.AUTH_TYPE_NONE +import android.telephony.data.ApnSetting.AUTH_TYPE_PAP +import android.telephony.data.ApnSetting.AUTH_TYPE_PAP_OR_CHAP +import android.telephony.data.ApnSetting.Builder +import android.telephony.data.ApnSetting.MVNO_TYPE_GID +import android.telephony.data.ApnSetting.MVNO_TYPE_ICCID +import android.telephony.data.ApnSetting.MVNO_TYPE_IMSI +import android.telephony.data.ApnSetting.MVNO_TYPE_SPN +import android.telephony.data.ApnSetting.PROTOCOL_IP +import android.telephony.data.ApnSetting.PROTOCOL_IPV4V6 +import android.telephony.data.ApnSetting.PROTOCOL_IPV6 +import android.telephony.data.ApnSetting.PROTOCOL_NON_IP +import android.telephony.data.ApnSetting.PROTOCOL_PPP +import android.telephony.data.ApnSetting.PROTOCOL_UNSTRUCTURED import android.util.Log import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.focusable +import androidx.compose.foundation.horizontalScroll +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.padding +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.material3.* -import androidx.compose.material3.MaterialTheme.colorScheme +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme.typography -import androidx.compose.runtime.* +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha @@ -44,9 +89,12 @@ import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.R import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.toText -import com.bintianqi.owndroid.ui.* +import com.bintianqi.owndroid.ui.Animations +import com.bintianqi.owndroid.ui.RadioButtonItem +import com.bintianqi.owndroid.ui.SubPageItem +import com.bintianqi.owndroid.ui.SwitchItem +import com.bintianqi.owndroid.ui.TopBar -var ssidSet = mutableSetOf() @Composable fun Network(navCtrl: NavHostController) { val localNavCtrl = rememberNavController() @@ -197,16 +245,15 @@ private fun WifiSsidPolicy() { val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { - var policy = dpm.wifiSsidPolicy - var selectedPolicyType by remember { mutableIntStateOf(policy?.policyType ?: -1) } - var inputSsid by remember { mutableStateOf("") } - var ssidList by remember { mutableStateOf("") } + var selectedPolicyType by remember { mutableIntStateOf(-1) } + val ssidList = remember { mutableStateListOf() } val refreshPolicy = { - policy = dpm.wifiSsidPolicy + val policy = dpm.wifiSsidPolicy + ssidList.clear() selectedPolicyType = policy?.policyType ?: -1 - ssidSet = policy?.ssids ?: mutableSetOf() + (policy?.ssids ?: mutableSetOf()).forEach { ssidList.add(it) } } - LaunchedEffect(Unit) { refreshPolicy(); ssidList= ssidSet.toText() } + LaunchedEffect(Unit) { refreshPolicy() } Spacer(Modifier.padding(vertical = 10.dp)) Text(text = stringResource(R.string.wifi_ssid_policy), style = typography.headlineLarge) Spacer(Modifier.padding(vertical = 5.dp)) @@ -225,72 +272,68 @@ private fun WifiSsidPolicy() { { selectedPolicyType == WIFI_SSID_POLICY_TYPE_DENYLIST }, { selectedPolicyType = WIFI_SSID_POLICY_TYPE_DENYLIST } ) - Column(modifier = Modifier.animateContentSize(scrollAnim()).horizontalScroll(rememberScrollState())) { - if(ssidList!="") { - Spacer(Modifier.padding(vertical = 5.dp)) - Text(stringResource(R.string.ssid_list_is)) - SelectionContainer{ - Text(text = ssidList, color = colorScheme.onPrimaryContainer) + AnimatedVisibility(selectedPolicyType != -1) { + var inputSsid by remember { mutableStateOf("") } + Column { + Column { + Spacer(Modifier.padding(vertical = 5.dp)) + Text(stringResource(R.string.ssid_list_is)) + SelectionContainer(modifier = Modifier.animateContentSize().horizontalScroll(rememberScrollState())) { + Text(if(ssidList.isEmpty()) stringResource(R.string.none) else ssidList.toText()) + } } - } - } - Spacer(Modifier.padding(vertical = 5.dp)) - OutlinedTextField( - value = inputSsid, - label = { Text("SSID") }, - onValueChange = {inputSsid = it }, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), - modifier = Modifier.focusable().fillMaxWidth() - ) - Spacer(Modifier.padding(vertical = 5.dp)) - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { - Button( - onClick = { - if(inputSsid=="") { - Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() - } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet) { - Toast.makeText(context, R.string.already_exist, Toast.LENGTH_SHORT).show() - } else { - ssidSet.add(WifiSsid.fromBytes(inputSsid.toByteArray())) - ssidList = ssidSet.toText() + Spacer(Modifier.padding(vertical = 5.dp)) + OutlinedTextField( + value = inputSsid, + label = { Text("SSID") }, + onValueChange = {inputSsid = it }, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), + modifier = Modifier.focusable().fillMaxWidth() + ) + Spacer(Modifier.padding(vertical = 5.dp)) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + Button( + onClick = { + if(inputSsid == "") { + Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() + } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidList) { + Toast.makeText(context, R.string.already_exist, Toast.LENGTH_SHORT).show() + } else { + ssidList.add(WifiSsid.fromBytes(inputSsid.toByteArray())) + } + }, + modifier = Modifier.fillMaxWidth(0.49F) + ) { + Text(stringResource(R.string.add)) } - inputSsid = "" - }, - modifier = Modifier.fillMaxWidth(0.49F) - ) { - Text(stringResource(R.string.add)) - } - Button( - onClick = { - if(inputSsid=="") { - Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() - } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidSet) { - ssidSet.remove(WifiSsid.fromBytes(inputSsid.toByteArray())) - inputSsid = "" - ssidList = ssidSet.toText() - } else { - Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() + Button( + onClick = { + if(inputSsid == "") { + Toast.makeText(context, R.string.cannot_be_empty, Toast.LENGTH_SHORT).show() + } else if (WifiSsid.fromBytes(inputSsid.toByteArray()) in ssidList) { + ssidList.remove(WifiSsid.fromBytes(inputSsid.toByteArray())) + } else { + Toast.makeText(context, R.string.not_exist, Toast.LENGTH_SHORT).show() + } + }, + modifier = Modifier.fillMaxWidth(0.96F) + ) { + Text(stringResource(R.string.remove)) } - }, - modifier = Modifier.fillMaxWidth(0.96F) - ) { - Text(stringResource(R.string.remove)) + } + Spacer(Modifier.padding(vertical = 10.dp)) } } Button( onClick = { focusMgr.clearFocus() if(selectedPolicyType == -1) { - if(policy==null && ssidSet.isNotEmpty()) { - Toast.makeText(context, R.string.please_select_a_policy, Toast.LENGTH_SHORT).show() - }else{ - dpm.wifiSsidPolicy = null - refreshPolicy() - Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - } + dpm.wifiSsidPolicy = null + refreshPolicy() + Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() }else{ - dpm.wifiSsidPolicy = if(ssidSet.size==0) { null }else{ WifiSsidPolicy(selectedPolicyType, ssidSet) } + dpm.wifiSsidPolicy = if(ssidList.isEmpty()) { null }else{ WifiSsidPolicy(selectedPolicyType, ssidList.toSet()) } refreshPolicy() Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt index 02b9847..b7d0272 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuActivate.kt @@ -11,8 +11,6 @@ import android.os.IBinder import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.SpringSpec import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -23,7 +21,14 @@ import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -45,26 +50,27 @@ fun ShizukuActivate() { val receiver = ComponentName(context, Receiver::class.java) val coScope = rememberCoroutineScope() val outputTextScrollState = rememberScrollState() - var enabled by remember{ mutableStateOf(false) } - var bindShizuku by remember{ mutableStateOf(false) } + var enabled by remember { mutableStateOf(false) } + var bindShizuku by remember { mutableStateOf(false) } var outputText by remember { mutableStateOf("") } var showDeviceAdminButton by remember { mutableStateOf(!dpm.isAdminActive(receiver)) } var showProfileOwnerButton by remember { mutableStateOf(!isProfileOwner(dpm)) } var showDeviceOwnerButton by remember { mutableStateOf(!isDeviceOwner(dpm)) } var showOrgProfileOwnerButton by remember { mutableStateOf(true) } - LaunchedEffect(Unit) { - if(service == null) { userServiceControl(context, true) } - while(true) { - if(service == null) { - enabled = false - bindShizuku = checkShizukuStatus()==1 - }else{ - enabled = true - bindShizuku = false - } - delay(200) + val service by shizukuService.collectAsState() + LaunchedEffect(service) { + if(service == null) { + enabled = false + bindShizuku = checkShizukuStatus() == 1 + } else { + enabled = true + bindShizuku = false } } + LaunchedEffect(Unit) { + shizukuService.value = null + userServiceControl(context, true) + } Column( modifier = Modifier .fillMaxSize() @@ -86,8 +92,15 @@ fun ShizukuActivate() { Button( onClick = { outputText = checkPermission(context) + if(service != null) { + enabled = true + bindShizuku = false + } else { + enabled = false + bindShizuku = checkShizukuStatus() == 1 + } coScope.launch { - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) } } ) { @@ -98,7 +111,7 @@ fun ShizukuActivate() { onClick = { coScope.launch{ outputText = service!!.execute("dpm list-owners") - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) } }, enabled = enabled @@ -112,7 +125,7 @@ fun ShizukuActivate() { onClick = { coScope.launch{ outputText = service!!.execute(context.getString(R.string.dpm_activate_da_command)) - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) delay(500) showDeviceAdminButton = !dpm.isAdminActive(receiver) } @@ -128,7 +141,7 @@ fun ShizukuActivate() { onClick = { coScope.launch{ outputText = service!!.execute(context.getString(R.string.dpm_activate_po_command)) - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) delay(500) showProfileOwnerButton = !isProfileOwner(dpm) } @@ -144,7 +157,7 @@ fun ShizukuActivate() { onClick = { coScope.launch{ outputText = service!!.execute(context.getString(R.string.dpm_activate_do_command)) - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) delay(500) showDeviceOwnerButton = !isDeviceOwner(dpm) } @@ -166,7 +179,7 @@ fun ShizukuActivate() { outputText = service!!.execute( "dpm mark-profile-owner-on-organization-owned-device --user $userID com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver" ) - outputTextScrollState.animateScrollTo(0, scrollAnim()) + outputTextScrollState.animateScrollTo(0) delay(500) showOrgProfileOwnerButton = !dpm.isOrganizationOwnedDeviceWithManagedProfile } @@ -188,16 +201,9 @@ fun ShizukuActivate() { } } -@Stable -fun scrollAnim( - dampingRatio: Float = Spring.DampingRatioNoBouncy, - stiffness: Float = Spring.StiffnessMedium, - visibilityThreshold: T? = null -): SpringSpec = SpringSpec(dampingRatio, stiffness, visibilityThreshold) - -private fun checkPermission(context: Context):String{ - if(checkShizukuStatus()==-1) { return context.getString(R.string.shizuku_not_started) } - val getUid = if(service==null) { return context.getString(R.string.shizuku_not_bind) } else { service!!.uid } +private fun checkPermission(context: Context): String { + if(checkShizukuStatus() == -1) { return context.getString(R.string.shizuku_not_started) } + val getUid = if(shizukuService.value == null) { return context.getString(R.string.shizuku_not_bind) } else { shizukuService.value!!.uid } return when(getUid) { "2000"->context.getString(R.string.shizuku_activated_shell) "0"->context.getString(R.string.shizuku_activated_root) @@ -205,12 +211,12 @@ private fun checkPermission(context: Context):String{ } } -fun checkShizukuStatus():Int{ +fun checkShizukuStatus(): Int { val status = try { if(Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) { waitGrantPermission = false; 1 } else if(Shizuku.shouldShowRequestPermissionRationale()) { 0 } else{ - if(!waitGrantPermission) {Shizuku.requestPermission(0) } + if(!waitGrantPermission) { Shizuku.requestPermission(0) } waitGrantPermission = true 0 } @@ -219,17 +225,17 @@ fun checkShizukuStatus():Int{ } fun userServiceControl(context:Context, status:Boolean) { - if(checkShizukuStatus()!=1) { return } + if(checkShizukuStatus() != 1) { return } val userServiceConnection = object : ServiceConnection { override fun onServiceConnected(componentName: ComponentName, binder: IBinder) { if (binder.pingBinder()) { - service = IUserService.Stub.asInterface(binder) + shizukuService.value = IUserService.Stub.asInterface(binder) } else { Toast.makeText(context, R.string.invalid_binder, Toast.LENGTH_SHORT).show() } } override fun onServiceDisconnected(componentName: ComponentName) { - service = null + shizukuService.value = null Toast.makeText(context, R.string.shizuku_service_disconnected, Toast.LENGTH_SHORT).show() } } @@ -242,9 +248,11 @@ fun userServiceControl(context:Context, status:Boolean) { .processNameSuffix("service") .debuggable(true) .version(26) - if(status) { - Shizuku.bindUserService(userServiceArgs, userServiceConnection) - }else{ - Shizuku.unbindUserService(userServiceArgs, userServiceConnection, false) - } + try { + if(status) { + Shizuku.bindUserService(userServiceArgs, userServiceConnection) + }else{ + Shizuku.unbindUserService(userServiceArgs, userServiceConnection, false) + } + } catch(_: Exception) { } } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt index 82ff371..2308173 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/ShizukuService.kt @@ -3,10 +3,11 @@ package com.bintianqi.owndroid.dpm import android.system.Os import androidx.annotation.Keep import com.bintianqi.owndroid.IUserService +import kotlinx.coroutines.flow.MutableStateFlow import java.io.BufferedReader import java.io.InputStreamReader -var service:IUserService? = null +val shizukuService = MutableStateFlow(null) @Keep class ShizukuService: IUserService.Stub() {