mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
Manage delegated admins
Upgrade AGP and gradle wrapper version Fix navigation bug of Shizuku Fix Action build
This commit is contained in:
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -61,9 +61,9 @@ jobs:
|
||||
|
||||
upload-telegram:
|
||||
name: Upload Builds
|
||||
if: github.ref_name == 'dev'
|
||||
runs-on: ubuntu-latest
|
||||
needs: ["build"]
|
||||
needs: build
|
||||
if: github.ref == 'refs/heads/dev'
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
@@ -6,4 +6,5 @@ interface IUserService {
|
||||
String execute(String command) = 1;
|
||||
int getUid() = 2;
|
||||
Account[] listAccounts() = 3;
|
||||
void destroy() = 16777114;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import com.bintianqi.owndroid.dpm.ChangeUsername
|
||||
import com.bintianqi.owndroid.dpm.CreateUser
|
||||
import com.bintianqi.owndroid.dpm.CreateWorkProfile
|
||||
import com.bintianqi.owndroid.dpm.CurrentUserInfo
|
||||
import com.bintianqi.owndroid.dpm.DelegatedAdmins
|
||||
import com.bintianqi.owndroid.dpm.DeleteWorkProfile
|
||||
import com.bintianqi.owndroid.dpm.DeviceAdmin
|
||||
import com.bintianqi.owndroid.dpm.DeviceInfo
|
||||
@@ -219,6 +220,7 @@ fun Home(activity: FragmentActivity, vm: MyViewModel) {
|
||||
composable(route = "DeviceAdmin") { DeviceAdmin(navCtrl) }
|
||||
composable(route = "ProfileOwner") { ProfileOwner(navCtrl) }
|
||||
composable(route = "DeviceOwner") { DeviceOwner(navCtrl) }
|
||||
composable(route = "DelegatedAdmins") { DelegatedAdmins(navCtrl, vm) }
|
||||
composable(route = "DeviceInfo") { DeviceInfo(navCtrl) }
|
||||
composable(route = "LockScreenInfo") { LockScreenInfo(navCtrl) }
|
||||
composable(route = "SupportMessages") { SupportMessages(navCtrl) }
|
||||
|
||||
@@ -9,29 +9,42 @@ import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Binder
|
||||
import android.os.Build.VERSION
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.os.RemoteException
|
||||
import android.os.UserManager
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
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.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
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.compose.ui.window.Dialog
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptions
|
||||
import com.bintianqi.owndroid.MyViewModel
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.backToHomeStateFlow
|
||||
import com.bintianqi.owndroid.showOperationResultToast
|
||||
@@ -87,39 +100,38 @@ fun Permissions(navCtrl: NavHostController) {
|
||||
try {
|
||||
if(Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
|
||||
bindingShizuku = true
|
||||
val destination = navCtrl.graph.findNode("Shizuku")!!.id
|
||||
bindShizukuService(context, { binder ->
|
||||
val args = Bundle()
|
||||
args.putBinder("binder", binder)
|
||||
fun onBind(binder: IBinder) {
|
||||
val destinationId = navCtrl.graph.findNode("Shizuku")!!.id
|
||||
bindingShizuku = false
|
||||
navCtrl.navigate(destination, args)
|
||||
}, {
|
||||
Toast.makeText(context, R.string.shizuku_service_disconnected, Toast.LENGTH_SHORT).show()
|
||||
navCtrl.navigate(destinationId, bundleOf("binder" to binder), NavOptions.Builder().setLaunchSingleTop(true).build())
|
||||
}
|
||||
try {
|
||||
controlShizukuService(context, ::onBind, { bindingShizuku = false }, true)
|
||||
} catch(e: Exception) {
|
||||
e.printStackTrace()
|
||||
bindingShizuku = false
|
||||
})
|
||||
}
|
||||
} else if(Shizuku.shouldShowRequestPermissionRationale()) {
|
||||
Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Sui.init(context.packageName)
|
||||
val listener = object: Shizuku.OnRequestPermissionResultListener {
|
||||
override fun onRequestPermissionResult(requestCode: Int, grantResult: Int) {
|
||||
if(grantResult == PackageManager.PERMISSION_GRANTED) {
|
||||
navCtrl.navigate("Shizuku")
|
||||
} else {
|
||||
Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
Shizuku.removeRequestPermissionResultListener(this)
|
||||
fun requestPermissionResultListener(requestCode: Int, grantResult: Int) {
|
||||
if(grantResult != PackageManager.PERMISSION_GRANTED) {
|
||||
Toast.makeText(context, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
Shizuku.removeRequestPermissionResultListener(::requestPermissionResultListener)
|
||||
}
|
||||
Shizuku.addRequestPermissionResultListener(listener)
|
||||
Shizuku.addRequestPermissionResultListener(::requestPermissionResultListener)
|
||||
Shizuku.requestPermission(0)
|
||||
}
|
||||
} catch(_: IllegalStateException) {
|
||||
Toast.makeText(context, R.string.shizuku_not_started, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner))
|
||||
FunctionItem(R.string.delegated_admins) { navCtrl.navigate("DelegatedAdmins") }
|
||||
FunctionItem(R.string.device_info, icon = R.drawable.perm_device_information_fill0) { navCtrl.navigate("DeviceInfo") }
|
||||
if((VERSION.SDK_INT >= 26 && deviceOwner) || (VERSION.SDK_INT>=24 && profileOwner)) {
|
||||
if((VERSION.SDK_INT >= 26 && deviceOwner) || (VERSION.SDK_INT >= 24 && profileOwner)) {
|
||||
FunctionItem(R.string.org_name, icon = R.drawable.corporate_fare_fill0) { dialog = 2 }
|
||||
}
|
||||
if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) {
|
||||
@@ -476,6 +488,133 @@ fun DeviceOwner(navCtrl: NavHostController) {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("InlinedApi")
|
||||
private enum class DelegatedScope(val id: String, @StringRes val string: Int, val requiresApi: Int = 0) {
|
||||
AppRestrictions(DevicePolicyManager.DELEGATION_APP_RESTRICTIONS, R.string.manage_application_restrictions),
|
||||
BlockUninstall(DevicePolicyManager.DELEGATION_BLOCK_UNINSTALL, R.string.block_uninstall),
|
||||
CertInstall(DevicePolicyManager.DELEGATION_CERT_INSTALL, R.string.manage_certificates),
|
||||
CertSelection(DevicePolicyManager.DELEGATION_CERT_SELECTION, R.string.select_keychain_certificates, 29),
|
||||
EnableSystemApp(DevicePolicyManager.DELEGATION_ENABLE_SYSTEM_APP, R.string.enable_system_app),
|
||||
InstallExistingPackage(DevicePolicyManager.DELEGATION_INSTALL_EXISTING_PACKAGE, R.string.install_existing_packages, 28),
|
||||
KeepUninstalledPackages(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES, R.string.manage_uninstalled_packages, 28),
|
||||
NetworkLogging(DevicePolicyManager.DELEGATION_NETWORK_LOGGING, R.string.network_logging, 29),
|
||||
PackageAccess(DevicePolicyManager.DELEGATION_PACKAGE_ACCESS, R.string.change_package_state),
|
||||
PermissionGrant(DevicePolicyManager.DELEGATION_PERMISSION_GRANT, R.string.grant_permissions),
|
||||
SecurityLogging(DevicePolicyManager.DELEGATION_SECURITY_LOGGING, R.string.security_logging, 31)
|
||||
}
|
||||
|
||||
@RequiresApi(26)
|
||||
@Composable
|
||||
fun DelegatedAdmins(navCtrl: NavHostController, vm: MyViewModel) {
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
var dialog by rememberSaveable { mutableIntStateOf(0) } // 0:None, 1:Edit, 2:Add
|
||||
var inputPackageName by rememberSaveable { mutableStateOf("") }
|
||||
var selectedScopes by rememberSaveable { mutableStateOf(listOf<String>()) }
|
||||
val packages = remember { mutableStateMapOf<String, MutableList<DelegatedScope>>() }
|
||||
fun refresh() {
|
||||
val list = mutableMapOf<String, MutableList<DelegatedScope>>()
|
||||
DelegatedScope.entries.forEach { ds ->
|
||||
if(VERSION.SDK_INT >= ds.requiresApi) {
|
||||
dpm.getDelegatePackages(receiver, ds.id)?.forEach { pkg ->
|
||||
if(list[pkg] != null) {
|
||||
list[pkg]!!.add(ds)
|
||||
} else {
|
||||
list[pkg] = mutableListOf(ds)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
packages.clear()
|
||||
packages.putAll(list)
|
||||
}
|
||||
LaunchedEffect(Unit) { refresh() }
|
||||
MyScaffold(R.string.delegated_admins, 0.dp, navCtrl) {
|
||||
packages.forEach { (pkg, scopes) ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { inputPackageName = pkg; selectedScopes = scopes.map { it.id }; dialog = 1 }
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
) {
|
||||
Text(pkg, style = typography.titleLarge)
|
||||
Text(scopes.size.toString() + " " + stringResource(R.string.delegated_scope))
|
||||
}
|
||||
}
|
||||
if(packages.isEmpty())
|
||||
Text(
|
||||
stringResource(R.string.none),
|
||||
color = colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally).padding(vertical = 4.dp)
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { inputPackageName = ""; selectedScopes = emptyList(); dialog = 2 }
|
||||
.padding(vertical = 10.dp, horizontal = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(Icons.Default.Add, null, modifier = Modifier.padding(end = 12.dp))
|
||||
Text(stringResource(R.string.add_delegated_admin), style = typography.titleLarge)
|
||||
}
|
||||
if(dialog != 0) {
|
||||
val selectedPackage by vm.selectedPackage.collectAsStateWithLifecycle()
|
||||
LaunchedEffect(selectedPackage) {
|
||||
if(selectedPackage != "") {
|
||||
inputPackageName = selectedPackage
|
||||
vm.selectedPackage.value = ""
|
||||
}
|
||||
}
|
||||
AlertDialog(
|
||||
text = {
|
||||
val fm = LocalFocusManager.current
|
||||
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
|
||||
OutlinedTextField(
|
||||
value = inputPackageName, onValueChange = { inputPackageName = it },
|
||||
label = { Text(stringResource(R.string.package_name)) },
|
||||
trailingIcon = {
|
||||
if(dialog == 2) IconButton({ navCtrl.navigate("PackageSelector") }) {
|
||||
Icon(painterResource(R.drawable.list_fill0), null)
|
||||
}
|
||||
},
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions { fm.clearFocus() },
|
||||
readOnly = dialog == 1,
|
||||
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
|
||||
)
|
||||
DelegatedScope.entries.forEach { scope ->
|
||||
if(VERSION.SDK_INT >= scope.requiresApi) {
|
||||
CheckBoxItem(scope.string, scope.id in selectedScopes) {
|
||||
if(it) selectedScopes += scope.id else selectedScopes -= scope.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
dpm.setDelegatedScopes(receiver, inputPackageName, selectedScopes)
|
||||
refresh()
|
||||
dialog = 0
|
||||
},
|
||||
enabled = inputPackageName.isNotBlank()
|
||||
) {
|
||||
Text(stringResource(if(dialog == 1) R.string.apply else R.string.add))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton({ dialog = 0 }) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
},
|
||||
onDismissRequest = { dialog = 0 }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DeviceInfo(navCtrl: NavHostController) {
|
||||
val context = LocalContext.current
|
||||
|
||||
@@ -151,10 +151,11 @@ fun Shizuku(navCtrl: NavHostController, navArgs: Bundle) {
|
||||
}
|
||||
}
|
||||
|
||||
fun bindShizukuService(
|
||||
fun controlShizukuService(
|
||||
context: Context,
|
||||
onServiceConnected: (IBinder) -> Unit,
|
||||
onServiceDisconnected: () -> Unit
|
||||
onServiceDisconnected: () -> Unit,
|
||||
state: Boolean
|
||||
) {
|
||||
val userServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(componentName: ComponentName, binder: IBinder) {
|
||||
@@ -169,11 +170,8 @@ fun bindShizukuService(
|
||||
.processNameSuffix("shizuku-service")
|
||||
.debuggable(false)
|
||||
.version(26)
|
||||
try {
|
||||
Shizuku.bindUserService(userServiceArgs, userServiceConnection)
|
||||
} catch(e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if(state) Shizuku.bindUserService(userServiceArgs, userServiceConnection)
|
||||
else Shizuku.unbindUserService(userServiceArgs, userServiceConnection, true)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -4,15 +4,11 @@ import android.accounts.Account
|
||||
import android.accounts.AccountManager
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.os.Parcelable
|
||||
import android.os.UserManager
|
||||
import android.system.Os
|
||||
import androidx.annotation.Keep
|
||||
import com.bintianqi.owndroid.IUserService
|
||||
import com.bintianqi.owndroid.getContext
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.lang.Class
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
@Keep
|
||||
class ShizukuService: IUserService.Stub() {
|
||||
@@ -28,10 +24,10 @@ class ShizukuService: IUserService.Stub() {
|
||||
return e.toString()
|
||||
}
|
||||
try {
|
||||
val outputReader = BufferedReader(InputStreamReader(process.inputStream))
|
||||
val outputReader = process.inputStream.bufferedReader()
|
||||
var outputLine: String
|
||||
while(outputReader.readLine().also {outputLine = it} != null) { result += "$outputLine\n" }
|
||||
val errorReader = BufferedReader(InputStreamReader(process.errorStream))
|
||||
val errorReader = process.errorStream.bufferedReader()
|
||||
var errorLine: String
|
||||
while(errorReader.readLine().also {errorLine = it} != null) { result += "$errorLine\n" }
|
||||
} catch(e: NullPointerException) {
|
||||
@@ -47,4 +43,8 @@ class ShizukuService: IUserService.Stub() {
|
||||
val am = getContext().getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
|
||||
return am.accounts
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="overview">Overview</string>
|
||||
<string name="features">Features</string>
|
||||
<string name="default_str">Default</string>
|
||||
|
||||
|
||||
<!--Разрешения-->
|
||||
@@ -76,6 +77,17 @@
|
||||
<string name="activate_jump" tools:ignore="TypographyEllipsis">Активировать...</string>
|
||||
<string name="profile_owner">Владелец профиля</string>
|
||||
<string name="device_owner">Владелец устройства</string>
|
||||
<!--TODO: translate the following 10 strings-->
|
||||
<string name="delegated_admins">Delegated admins</string>
|
||||
<string name="delegated_scope">delegated scope</string>
|
||||
<string name="manage_application_restrictions">Manage application restrictions</string>
|
||||
<string name="manage_certificates">Manage certificates</string>
|
||||
<string name="select_keychain_certificates">Select KeyChain certificate</string>
|
||||
<string name="install_existing_packages">Install existing packages</string>
|
||||
<string name="manage_uninstalled_packages">Manage uninstalled packages</string>
|
||||
<string name="change_package_state">Change package state</string>
|
||||
<string name="grant_permissions">Grant permissions</string>
|
||||
<string name="add_delegated_admin">Add delegated admin</string>
|
||||
<string name="dhizuku_will_be_deactivated">Dhizuku будет деактивирован</string>
|
||||
<string name="reset_device_policy">Сбросить политику устройства</string>
|
||||
<string name="activate_device_admin">Активировать администратора устройства</string>
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
<string name="edit">Edit</string>
|
||||
<string name="overview">Overview</string>
|
||||
<string name="features">Features</string>
|
||||
<string name="default_str">Default</string>
|
||||
|
||||
<!--Permissions-->
|
||||
<string name="click_to_activate">Etkinleştirmek İçin Tıklayın</string>
|
||||
@@ -76,6 +77,17 @@
|
||||
<string name="activate_jump" tools:ignore="TypographyEllipsis">Etkinleştir...</string>
|
||||
<string name="profile_owner">Profil Sahibi</string>
|
||||
<string name="device_owner">Cihaz Sahibi</string>
|
||||
<!--TODO: translate the following 10 strings-->
|
||||
<string name="delegated_admins">Delegated admins</string>
|
||||
<string name="delegated_scope">delegated scope</string>
|
||||
<string name="manage_application_restrictions">Manage application restrictions</string>
|
||||
<string name="manage_certificates">Manage certificates</string>
|
||||
<string name="select_keychain_certificates">Select KeyChain certificate</string>
|
||||
<string name="install_existing_packages">Install existing packages</string>
|
||||
<string name="manage_uninstalled_packages">Manage uninstalled packages</string>
|
||||
<string name="change_package_state">Change package state</string>
|
||||
<string name="grant_permissions">Grant permissions</string>
|
||||
<string name="add_delegated_admin">Add delegated admin</string>
|
||||
<string name="dhizuku_will_be_deactivated">Dhizuku will be deactivated</string> <!--TODO-->
|
||||
<string name="reset_device_policy">Reset device policy</string> <!--TODO-->
|
||||
<string name="activate_device_admin">Cihaz Yöneticisini Etkinleştir</string>
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
<string name="edit">编辑</string>
|
||||
<string name="overview">概览</string>
|
||||
<string name="features">功能</string>
|
||||
<string name="default_str">默认</string>
|
||||
|
||||
<!--Permissions-->
|
||||
<string name="click_to_activate">点击以激活</string>
|
||||
@@ -72,6 +73,16 @@
|
||||
<string name="activate_jump" tools:ignore="TypographyEllipsis">激活...</string>
|
||||
<string name="profile_owner">Profile owner</string>
|
||||
<string name="device_owner">Device owner</string>
|
||||
<string name="delegated_admins">委托管理员</string>
|
||||
<string name="delegated_scope">委托作用域</string>
|
||||
<string name="manage_application_restrictions">管理应用限制</string>
|
||||
<string name="manage_certificates">管理证书</string>
|
||||
<string name="select_keychain_certificates">选择密钥链证书</string>
|
||||
<string name="install_existing_packages">安装存在的软件包</string>
|
||||
<string name="manage_uninstalled_packages">管理已被卸载的软件包</string>
|
||||
<string name="change_package_state">修改软件包状态</string>
|
||||
<string name="grant_permissions">授予权限</string>
|
||||
<string name="add_delegated_admin">添加委托管理员</string>
|
||||
<string name="reset_device_policy">重置设备策略</string>
|
||||
<string name="dhizuku_will_be_deactivated">Dhizuku将被停用</string>
|
||||
<string name="activate_device_admin">激活Device admin</string>
|
||||
@@ -365,7 +376,7 @@
|
||||
<string name="scope_is_work_profile">作用域: 工作资料</string>
|
||||
<string name="app_info">应用详情</string>
|
||||
<string name="not_installed">未安装</string>
|
||||
<string name="block_uninstall">防卸载</string>
|
||||
<string name="block_uninstall">阻止</string>
|
||||
<string name="ucd">禁止用户控制</string>
|
||||
<string name="ucd_desc">用户将无法清除这些应用的存储空间或强制停止这些应用</string>
|
||||
<string name="app_list_is">应用列表:</string>
|
||||
|
||||
@@ -78,6 +78,16 @@
|
||||
<string name="activate_jump" tools:ignore="TypographyEllipsis">Activate...</string>
|
||||
<string name="profile_owner">Profile owner</string>
|
||||
<string name="device_owner">Device owner</string>
|
||||
<string name="delegated_admins">Delegated admins</string>
|
||||
<string name="delegated_scope">delegated scope</string>
|
||||
<string name="manage_application_restrictions">Manage application restrictions</string>
|
||||
<string name="manage_certificates">Manage certificates</string>
|
||||
<string name="select_keychain_certificates">Select KeyChain certificate</string>
|
||||
<string name="install_existing_packages">Install existing packages</string>
|
||||
<string name="manage_uninstalled_packages">Manage uninstalled packages</string>
|
||||
<string name="change_package_state">Change package state</string>
|
||||
<string name="grant_permissions">Grant permissions</string>
|
||||
<string name="add_delegated_admin">Add delegated admin</string>
|
||||
<string name="dhizuku_will_be_deactivated">Dhizuku will be deactivated</string>
|
||||
<string name="reset_device_policy">Reset device policy</string>
|
||||
<string name="activate_device_admin">Activate Device admin</string>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.7.3"
|
||||
agp = "8.8.0"
|
||||
kotlin = "2.0.21"
|
||||
|
||||
navigation-compose = "2.8.5"
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Fri Jan 12 20:22:20 CST 2024
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
Reference in New Issue
Block a user