mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
@@ -316,29 +316,64 @@ fun Home(vm: MyViewModel, onLock: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
composable<SystemManager> { SystemManagerScreen(::navigateUp, ::navigate) }
|
||||
composable<SystemOptions> { SystemOptionsScreen(::navigateUp) }
|
||||
composable<Keyguard> { KeyguardScreen(::navigateUp) }
|
||||
composable<HardwareMonitor> { HardwareMonitorScreen(::navigateUp) }
|
||||
composable<ChangeTime> { ChangeTimeScreen(::navigateUp) }
|
||||
composable<ChangeTimeZone> { ChangeTimeZoneScreen(::navigateUp) }
|
||||
composable<AutoTimePolicy> { AutoTimePolicyScreen(::navigateUp) }
|
||||
composable<AutoTimeZonePolicy> { AutoTimeZonePolicyScreen(::navigateUp) }
|
||||
//composable<> { KeyPairs(::navigateUp) }
|
||||
composable<ContentProtectionPolicy> { ContentProtectionPolicyScreen(::navigateUp) }
|
||||
composable<PermissionPolicy> { PermissionPolicyScreen(::navigateUp) }
|
||||
composable<MtePolicy> { MtePolicyScreen(::navigateUp) }
|
||||
composable<NearbyStreamingPolicy> { NearbyStreamingPolicyScreen(::navigateUp) }
|
||||
composable<LockTaskMode> {
|
||||
LockTaskModeScreen(vm.chosenPackage, ::choosePackage, ::navigateUp)
|
||||
composable<SystemManager> { SystemManagerScreen(vm, ::navigateUp, ::navigate) }
|
||||
composable<SystemOptions> { SystemOptionsScreen(vm, ::navigateUp) }
|
||||
composable<Keyguard> {
|
||||
KeyguardScreen(vm::setKeyguardDisabled, vm::lockScreen, ::navigateUp)
|
||||
}
|
||||
composable<HardwareMonitor> {
|
||||
HardwareMonitorScreen(vm.hardwareProperties, vm::getHardwareProperties,
|
||||
vm::setHpRefreshInterval, ::navigateUp)
|
||||
}
|
||||
composable<ChangeTime> { ChangeTimeScreen(vm::setTime, ::navigateUp) }
|
||||
composable<ChangeTimeZone> { ChangeTimeZoneScreen(vm::setTimeZone, ::navigateUp) }
|
||||
composable<AutoTimePolicy> {
|
||||
AutoTimePolicyScreen(vm::getAutoTimePolicy, vm::setAutoTimePolicy, ::navigateUp)
|
||||
}
|
||||
composable<AutoTimeZonePolicy> {
|
||||
AutoTimeZonePolicyScreen(vm::getAutoTimeZonePolicy, vm::setAutoTimeZonePolicy,
|
||||
::navigateUp)
|
||||
}
|
||||
//composable<> { KeyPairs(::navigateUp) }
|
||||
composable<ContentProtectionPolicy> {
|
||||
ContentProtectionPolicyScreen(vm::getContentProtectionPolicy,
|
||||
vm::setContentProtectionPolicy, ::navigateUp)
|
||||
}
|
||||
composable<PermissionPolicy> {
|
||||
PermissionPolicyScreen(vm::getPermissionPolicy, vm::setPermissionPolicy, ::navigateUp)
|
||||
}
|
||||
composable<MtePolicy> {
|
||||
MtePolicyScreen(vm::getMtePolicy, vm::setMtePolicy, ::navigateUp)
|
||||
}
|
||||
composable<NearbyStreamingPolicy> {
|
||||
NearbyStreamingPolicyScreen(vm::getNsAppPolicy, vm::setNsAppPolicy,
|
||||
vm::getNsNotificationPolicy, vm::setNsNotificationPolicy, ::navigateUp)
|
||||
}
|
||||
composable<LockTaskMode> {
|
||||
LockTaskModeScreen(vm.chosenPackage, ::choosePackage, vm.lockTaskPackages,
|
||||
vm::getLockTaskPackages, vm::setLockTaskPackage, vm::startLockTaskMode,
|
||||
vm:: getLockTaskFeatures, vm::setLockTaskFeatures, ::navigateUp)
|
||||
}
|
||||
composable<CaCert> {
|
||||
CaCertScreen(vm.installedCaCerts, vm::getCaCerts, vm::installCaCert, vm::parseCaCert,
|
||||
vm::exportCaCert, vm::uninstallCaCert, vm::uninstallAllCaCerts, ::navigateUp)
|
||||
}
|
||||
composable<CaCert> { CaCertScreen(::navigateUp) }
|
||||
composable<SecurityLogging> { SecurityLoggingScreen(::navigateUp) }
|
||||
composable<DisableAccountManagement> { DisableAccountManagementScreen(::navigateUp) }
|
||||
composable<SetSystemUpdatePolicy> { SystemUpdatePolicyScreen(::navigateUp) }
|
||||
composable<InstallSystemUpdate> { InstallSystemUpdateScreen(::navigateUp) }
|
||||
composable<FrpPolicy> { FrpPolicyScreen(::navigateUp) }
|
||||
composable<WipeData> { WipeDataScreen(::navigateUp) }
|
||||
composable<DisableAccountManagement> {
|
||||
DisableAccountManagementScreen(vm.mdAccountTypes, vm::getMdAccountTypes,
|
||||
vm::setMdAccountType, ::navigateUp)
|
||||
}
|
||||
composable<SetSystemUpdatePolicy> {
|
||||
SystemUpdatePolicyScreen(vm::getSystemUpdatePolicy, vm::setSystemUpdatePolicy,
|
||||
vm::getPendingSystemUpdate, ::navigateUp)
|
||||
}
|
||||
composable<InstallSystemUpdate> {
|
||||
InstallSystemUpdateScreen(vm::installSystemUpdate, ::navigateUp)
|
||||
}
|
||||
composable<FrpPolicy> {
|
||||
FrpPolicyScreen(vm::getFrpPolicy, vm::setFrpPolicy, ::navigateUp)
|
||||
}
|
||||
composable<WipeData> { WipeDataScreen(vm::wipeData, ::navigateUp) }
|
||||
|
||||
composable<Network> { NetworkScreen(::navigateUp, ::navigate) }
|
||||
composable<WiFi> { WifiScreen(::navigateUp, ::navigate) { navController.navigate(AddNetwork, it)} }
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
package com.bintianqi.owndroid
|
||||
|
||||
import android.app.ActivityOptions
|
||||
import android.app.Application
|
||||
import android.app.PendingIntent
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback
|
||||
import android.app.admin.FactoryResetProtectionPolicy
|
||||
import android.app.admin.PackagePolicy
|
||||
import android.app.admin.SystemUpdateInfo
|
||||
import android.app.admin.SystemUpdatePolicy
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build.VERSION
|
||||
import android.os.HardwarePropertiesManager
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
@@ -22,16 +31,28 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.bintianqi.owndroid.Privilege.DAR
|
||||
import com.bintianqi.owndroid.Privilege.DPM
|
||||
import com.bintianqi.owndroid.dpm.AppStatus
|
||||
import com.bintianqi.owndroid.dpm.CaCertInfo
|
||||
import com.bintianqi.owndroid.dpm.FrpPolicyInfo
|
||||
import com.bintianqi.owndroid.dpm.HardwareProperties
|
||||
import com.bintianqi.owndroid.dpm.PendingSystemUpdateInfo
|
||||
import com.bintianqi.owndroid.dpm.SystemOptionsStatus
|
||||
import com.bintianqi.owndroid.dpm.SystemUpdatePolicyInfo
|
||||
import com.bintianqi.owndroid.dpm.getPackageInstaller
|
||||
import com.bintianqi.owndroid.dpm.isValidPackageName
|
||||
import com.bintianqi.owndroid.dpm.parsePackageInstallerMessage
|
||||
import com.bintianqi.owndroid.dpm.permissionList
|
||||
import com.bintianqi.owndroid.dpm.temperatureTypes
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import java.security.MessageDigest
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||
@@ -377,6 +398,395 @@ class MyViewModel(application: Application): AndroidViewModel(application) {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(24)
|
||||
fun reboot() {
|
||||
DPM.reboot(DAR)
|
||||
}
|
||||
@RequiresApi(24)
|
||||
fun requestBugReport(): Boolean {
|
||||
return DPM.requestBugreport(DAR)
|
||||
}
|
||||
@RequiresApi(24)
|
||||
fun getOrgName(): String {
|
||||
return DPM.getOrganizationName(DAR).toString()
|
||||
}
|
||||
@RequiresApi(24)
|
||||
fun setOrgName(name: String) {
|
||||
DPM.setOrganizationName(DAR, name)
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun setOrgId(id: String) {
|
||||
DPM.setOrganizationId(id)
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun getEnrollmentSpecificId(): String {
|
||||
return DPM.enrollmentSpecificId
|
||||
}
|
||||
val systemOptionsStatus = MutableStateFlow(SystemOptionsStatus())
|
||||
fun getSystemOptionsStatus() {
|
||||
val privilege = Privilege.status.value
|
||||
systemOptionsStatus.value = SystemOptionsStatus(
|
||||
cameraDisabled = DPM.getCameraDisabled(null),
|
||||
screenCaptureDisabled = DPM.getScreenCaptureDisabled(null),
|
||||
statusBarDisabled = if (VERSION.SDK_INT >= 34 &&
|
||||
privilege.run { device || (profile && affiliated) })
|
||||
DPM.isStatusBarDisabled else false,
|
||||
autoTimeEnabled = if (VERSION.SDK_INT >= 30 && privilege.run { device || org })
|
||||
DPM.getAutoTimeEnabled(DAR) else false,
|
||||
autoTimeZoneEnabled = if (VERSION.SDK_INT >= 30 && privilege.run { device || org })
|
||||
DPM.getAutoTimeZoneEnabled(DAR) else false,
|
||||
autoTimeRequired = if (VERSION.SDK_INT < 30) DPM.autoTimeRequired else false,
|
||||
masterVolumeMuted = DPM.isMasterVolumeMuted(DAR),
|
||||
backupServiceEnabled = if (VERSION.SDK_INT >= 26) DPM.isBackupServiceEnabled(DAR) else false,
|
||||
btContactSharingDisabled = if (VERSION.SDK_INT >= 23 && privilege.work)
|
||||
DPM.getBluetoothContactSharingDisabled(DAR) else false,
|
||||
commonCriteriaMode = if (VERSION.SDK_INT >= 30) DPM.isCommonCriteriaModeEnabled(DAR) else false,
|
||||
usbSignalEnabled = if (VERSION.SDK_INT >= 31) DPM.isUsbDataSignalingEnabled else false,
|
||||
canDisableUsbSignal = if (VERSION.SDK_INT >= 31) DPM.canUsbDataSignalingBeDisabled() else false
|
||||
)
|
||||
}
|
||||
fun setCameraDisabled(disabled: Boolean) {
|
||||
DPM.setCameraDisabled(DAR, disabled)
|
||||
createShortcuts(application)
|
||||
systemOptionsStatus.update { it.copy(cameraDisabled = DPM.getCameraDisabled(null)) }
|
||||
}
|
||||
fun setScreenCaptureDisabled(disabled: Boolean) {
|
||||
DPM.setScreenCaptureDisabled(DAR, disabled)
|
||||
systemOptionsStatus.update {
|
||||
it.copy(screenCaptureDisabled = DPM.getScreenCaptureDisabled(null))
|
||||
}
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun setStatusBarDisabled(disabled: Boolean) {
|
||||
val result = DPM.setStatusBarDisabled(DAR, disabled)
|
||||
if (result) systemOptionsStatus.update { it.copy(statusBarDisabled = disabled) }
|
||||
}
|
||||
@RequiresApi(30)
|
||||
fun setAutoTimeEnabled(enabled: Boolean) {
|
||||
DPM.setAutoTimeEnabled(DAR, enabled)
|
||||
systemOptionsStatus.update { it.copy(autoTimeEnabled = DPM.getAutoTimeEnabled(DAR)) }
|
||||
}
|
||||
@RequiresApi(30)
|
||||
fun setAutoTimeZoneEnabled(enabled: Boolean) {
|
||||
DPM.setAutoTimeZoneEnabled(DAR, enabled)
|
||||
systemOptionsStatus.update {
|
||||
it.copy(autoTimeZoneEnabled = DPM.getAutoTimeZoneEnabled(DAR))
|
||||
}
|
||||
}
|
||||
@Suppress("DEPRECATION")
|
||||
fun setAutoTimeRequired(required: Boolean) {
|
||||
DPM.setAutoTimeRequired(DAR, required)
|
||||
systemOptionsStatus.update { it.copy(autoTimeRequired = DPM.autoTimeRequired) }
|
||||
}
|
||||
fun setMasterVolumeMuted(muted: Boolean) {
|
||||
DPM.setMasterVolumeMuted(DAR, muted)
|
||||
createShortcuts(application)
|
||||
systemOptionsStatus.update { it.copy(masterVolumeMuted = DPM.isMasterVolumeMuted(DAR)) }
|
||||
}
|
||||
@RequiresApi(26)
|
||||
fun setBackupServiceEnabled(enabled: Boolean) {
|
||||
DPM.setBackupServiceEnabled(DAR, enabled)
|
||||
systemOptionsStatus.update {
|
||||
it.copy(backupServiceEnabled = DPM.isBackupServiceEnabled(DAR))
|
||||
}
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun setBtContactSharingDisabled(disabled: Boolean) {
|
||||
DPM.setBluetoothContactSharingDisabled(DAR, disabled)
|
||||
systemOptionsStatus.update {
|
||||
it.copy(btContactSharingDisabled = DPM.getBluetoothContactSharingDisabled(DAR))
|
||||
}
|
||||
}
|
||||
@RequiresApi(30)
|
||||
fun setCommonCriteriaModeEnabled(enabled: Boolean) {
|
||||
DPM.setCommonCriteriaModeEnabled(DAR, enabled)
|
||||
systemOptionsStatus.update {
|
||||
it.copy(commonCriteriaMode = DPM.isCommonCriteriaModeEnabled(DAR))
|
||||
}
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun setUsbSignalEnabled(enabled: Boolean) {
|
||||
DPM.isUsbDataSignalingEnabled = enabled
|
||||
systemOptionsStatus.update { it.copy(usbSignalEnabled = DPM.isUsbDataSignalingEnabled) }
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun setKeyguardDisabled(disabled: Boolean): Boolean {
|
||||
return DPM.setKeyguardDisabled(DAR, disabled)
|
||||
}
|
||||
fun lockScreen(evictKey: Boolean) {
|
||||
if (VERSION.SDK_INT >= 26 && Privilege.status.value.work) {
|
||||
DPM.lockNow(if (evictKey) DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY else 0)
|
||||
} else {
|
||||
DPM.lockNow()
|
||||
}
|
||||
}
|
||||
val hardwareProperties = MutableStateFlow(HardwareProperties())
|
||||
var hpRefreshInterval = 1000L
|
||||
fun setHpRefreshInterval(interval: Float) {
|
||||
hpRefreshInterval = (interval * 1000).toLong()
|
||||
}
|
||||
@RequiresApi(24)
|
||||
suspend fun getHardwareProperties() {
|
||||
val hpm = application.getSystemService(HardwarePropertiesManager::class.java)
|
||||
while (true) {
|
||||
val properties = HardwareProperties(
|
||||
temperatureTypes.map { (type, _) ->
|
||||
type to hpm.getDeviceTemperatures(type, HardwarePropertiesManager.TEMPERATURE_CURRENT).toList()
|
||||
}.toMap(),
|
||||
hpm.cpuUsages.map { it.active to it.total },
|
||||
hpm.fanSpeeds.toList()
|
||||
)
|
||||
if (properties.cpuUsages.isEmpty() && properties.fanSpeeds.isEmpty() &&
|
||||
properties.temperatures.isEmpty()) {
|
||||
break
|
||||
}
|
||||
delay(hpRefreshInterval)
|
||||
}
|
||||
}
|
||||
@RequiresApi(28)
|
||||
fun setTime(time: Long): Boolean {
|
||||
return DPM.setTime(DAR, time)
|
||||
}
|
||||
@RequiresApi(28)
|
||||
fun setTimeZone(tz: String): Boolean {
|
||||
return DPM.setTimeZone(DAR, tz)
|
||||
}
|
||||
@RequiresApi(36)
|
||||
fun getAutoTimePolicy(): Int {
|
||||
return DPM.autoTimePolicy
|
||||
}
|
||||
@RequiresApi(36)
|
||||
fun setAutoTimePolicy(policy: Int) {
|
||||
DPM.autoTimePolicy = policy
|
||||
}
|
||||
@RequiresApi(36)
|
||||
fun getAutoTimeZonePolicy(): Int {
|
||||
return DPM.autoTimeZonePolicy
|
||||
}
|
||||
@RequiresApi(36)
|
||||
fun setAutoTimeZonePolicy(policy: Int) {
|
||||
DPM.autoTimeZonePolicy = policy
|
||||
}
|
||||
@RequiresApi(35)
|
||||
fun getContentProtectionPolicy(): Int {
|
||||
return DPM.getContentProtectionPolicy(DAR)
|
||||
}
|
||||
@RequiresApi(35)
|
||||
fun setContentProtectionPolicy(policy: Int) {
|
||||
DPM.setContentProtectionPolicy(DAR, policy)
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun getPermissionPolicy(): Int {
|
||||
return DPM.getPermissionPolicy(DAR)
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun setPermissionPolicy(policy: Int) {
|
||||
DPM.setPermissionPolicy(DAR, policy)
|
||||
}
|
||||
@RequiresApi(34)
|
||||
fun getMtePolicy(): Int {
|
||||
return DPM.mtePolicy
|
||||
}
|
||||
@RequiresApi(34)
|
||||
fun setMtePolicy(policy: Int): Boolean {
|
||||
return try {
|
||||
DPM.mtePolicy = policy
|
||||
true
|
||||
} catch (_: UnsupportedOperationException) {
|
||||
false
|
||||
}
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun getNsAppPolicy(): Int {
|
||||
return DPM.nearbyAppStreamingPolicy
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun setNsAppPolicy(policy: Int) {
|
||||
DPM.nearbyAppStreamingPolicy = policy
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun getNsNotificationPolicy(): Int {
|
||||
return DPM.nearbyNotificationStreamingPolicy
|
||||
}
|
||||
@RequiresApi(31)
|
||||
fun setNsNotificationPolicy(policy: Int) {
|
||||
DPM.nearbyNotificationStreamingPolicy = policy
|
||||
}
|
||||
val lockTaskPackages = MutableStateFlow(emptyList<AppInfo>())
|
||||
@RequiresApi(26)
|
||||
fun getLockTaskPackages() {
|
||||
lockTaskPackages.value = DPM.getLockTaskPackages(DAR).map { getAppInfo(it) }
|
||||
}
|
||||
@RequiresApi(26)
|
||||
fun setLockTaskPackage(name: String, status: Boolean) {
|
||||
DPM.setLockTaskPackages(DAR,
|
||||
lockTaskPackages.value.map { it.name }
|
||||
.run { if (status) plus(name) else minus(name) }
|
||||
.toTypedArray()
|
||||
)
|
||||
getLockTaskPackages()
|
||||
}
|
||||
@RequiresApi(28)
|
||||
fun startLockTaskMode(packageName: String, activity: String): Int {
|
||||
if (!NotificationUtils.checkPermission(application)) return 0
|
||||
if (!DPM.isLockTaskPermitted(packageName)) return 1
|
||||
val options = ActivityOptions.makeBasic().setLockTaskEnabled(true)
|
||||
val intent = if(activity.isNotEmpty()) {
|
||||
Intent().setComponent(ComponentName(packageName, activity))
|
||||
} else PM.getLaunchIntentForPackage(packageName)
|
||||
if (intent != null) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
application.startActivity(intent, options.toBundle())
|
||||
return 0
|
||||
} else {
|
||||
return 2
|
||||
}
|
||||
}
|
||||
@RequiresApi(28)
|
||||
fun getLockTaskFeatures(): Int {
|
||||
return DPM.getLockTaskFeatures(DAR)
|
||||
}
|
||||
@RequiresApi(28)
|
||||
fun setLockTaskFeatures(flags: Int): String? {
|
||||
try {
|
||||
DPM.setLockTaskFeatures(DAR, flags)
|
||||
return null
|
||||
} catch (e: IllegalArgumentException) {
|
||||
return e.message
|
||||
}
|
||||
}
|
||||
val installedCaCerts = MutableStateFlow(emptyList<CaCertInfo>())
|
||||
fun getCaCerts() {
|
||||
viewModelScope.launch {
|
||||
installedCaCerts.value = DPM.getInstalledCaCerts(DAR).mapNotNull { parseCaCert(it) }
|
||||
}
|
||||
}
|
||||
fun parseCaCert(uri: Uri): CaCertInfo? {
|
||||
return try {
|
||||
application.contentResolver.openInputStream(uri)?.use {
|
||||
parseCaCert(it.readBytes())
|
||||
}
|
||||
} catch(e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
fun parseCaCert(bytes: ByteArray): CaCertInfo? {
|
||||
val hash = MessageDigest.getInstance("SHA-256").digest(bytes).toHexString()
|
||||
return try {
|
||||
val factory = CertificateFactory.getInstance("X.509")
|
||||
val cert = factory.generateCertificate(bytes.inputStream()) as X509Certificate
|
||||
CaCertInfo(
|
||||
hash, cert.serialNumber.toString(16),
|
||||
cert.issuerX500Principal.name, cert.subjectX500Principal.name,
|
||||
parseDate(cert.notBefore), parseDate(cert.notAfter), bytes
|
||||
)
|
||||
} catch (e: CertificateException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
fun installCaCert(cert: CaCertInfo): Boolean {
|
||||
val result = DPM.installCaCert(DAR, cert.bytes)
|
||||
if (result) getCaCerts()
|
||||
return result
|
||||
}
|
||||
fun uninstallCaCert(cert: CaCertInfo) {
|
||||
DPM.uninstallCaCert(DAR, cert.bytes)
|
||||
getCaCerts()
|
||||
}
|
||||
fun uninstallAllCaCerts() {
|
||||
DPM.uninstallAllUserCaCerts(DAR)
|
||||
getCaCerts()
|
||||
}
|
||||
fun exportCaCert(uri: Uri, cert: CaCertInfo) {
|
||||
application.contentResolver.openOutputStream(uri)?.use {
|
||||
it.write(cert.bytes)
|
||||
}
|
||||
}
|
||||
val mdAccountTypes = MutableStateFlow(emptyList<String>())
|
||||
fun getMdAccountTypes() {
|
||||
mdAccountTypes.value = DPM.accountTypesWithManagementDisabled?.toList() ?: emptyList()
|
||||
}
|
||||
fun setMdAccountType(type: String, disabled: Boolean) {
|
||||
DPM.setAccountManagementDisabled(DAR, type, disabled)
|
||||
getMdAccountTypes()
|
||||
}
|
||||
@RequiresApi(30)
|
||||
fun getFrpPolicy(): FrpPolicyInfo {
|
||||
return try {
|
||||
val policy = DPM.getFactoryResetProtectionPolicy(DAR)
|
||||
FrpPolicyInfo(
|
||||
true, policy != null, policy?.isFactoryResetProtectionEnabled ?: false,
|
||||
policy?.factoryResetProtectionAccounts ?: emptyList()
|
||||
)
|
||||
} catch (_: UnsupportedOperationException) {
|
||||
FrpPolicyInfo(false, false, false, emptyList())
|
||||
}
|
||||
}
|
||||
@RequiresApi(30)
|
||||
fun setFrpPolicy(info: FrpPolicyInfo) {
|
||||
val policy = if (info.usePolicy) {
|
||||
FactoryResetProtectionPolicy.Builder()
|
||||
.setFactoryResetProtectionEnabled(info.enabled)
|
||||
.setFactoryResetProtectionAccounts(info.accounts)
|
||||
.build()
|
||||
} else null
|
||||
DPM.setFactoryResetProtectionPolicy(DAR, policy)
|
||||
}
|
||||
fun wipeData(wipeDevice: Boolean, flags: Int, reason: String) {
|
||||
if (wipeDevice && VERSION.SDK_INT >= 34) {
|
||||
DPM.wipeDevice(flags)
|
||||
} else {
|
||||
if(VERSION.SDK_INT >= 28 && reason.isNotEmpty()) {
|
||||
DPM.wipeData(flags, reason)
|
||||
} else {
|
||||
DPM.wipeData(flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun getSystemUpdatePolicy(): SystemUpdatePolicyInfo {
|
||||
val policy = DPM.systemUpdatePolicy
|
||||
return SystemUpdatePolicyInfo(
|
||||
policy?.policyType ?: -1, policy?.installWindowStart ?: 0, policy?.installWindowEnd ?: 0
|
||||
)
|
||||
}
|
||||
@RequiresApi(23)
|
||||
fun setSystemUpdatePolicy(info: SystemUpdatePolicyInfo) {
|
||||
val policy = when (info.type) {
|
||||
SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC -> SystemUpdatePolicy.createAutomaticInstallPolicy()
|
||||
SystemUpdatePolicy.TYPE_INSTALL_WINDOWED ->
|
||||
SystemUpdatePolicy.createWindowedInstallPolicy(info.start, info.end)
|
||||
SystemUpdatePolicy.TYPE_POSTPONE -> SystemUpdatePolicy.createPostponeInstallPolicy()
|
||||
else -> null
|
||||
}
|
||||
DPM.setSystemUpdatePolicy(DAR, policy)
|
||||
}
|
||||
@RequiresApi(26)
|
||||
fun getPendingSystemUpdate(): PendingSystemUpdateInfo {
|
||||
val update = DPM.getPendingSystemUpdate(DAR)
|
||||
return PendingSystemUpdateInfo(update != null, update?.receivedTime ?: 0,
|
||||
update?.securityPatchState == SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE)
|
||||
}
|
||||
@RequiresApi(29)
|
||||
fun installSystemUpdate(uri: Uri, callback: (String) -> Unit) {
|
||||
val callback = object: InstallSystemUpdateCallback() {
|
||||
override fun onInstallUpdateError(errorCode: Int, errorMessage: String) {
|
||||
super.onInstallUpdateError(errorCode, errorMessage)
|
||||
val errDetail = when(errorCode) {
|
||||
UPDATE_ERROR_BATTERY_LOW -> R.string.battery_low
|
||||
UPDATE_ERROR_UPDATE_FILE_INVALID -> R.string.update_file_invalid
|
||||
UPDATE_ERROR_INCORRECT_OS_VERSION -> R.string.incorrect_os_ver
|
||||
UPDATE_ERROR_FILE_NOT_FOUND -> R.string.file_not_exist
|
||||
else -> R.string.unknown_error
|
||||
}
|
||||
callback(application.getString(errDetail) + "\n$errorMessage")
|
||||
}
|
||||
}
|
||||
DPM.installSystemUpdate(DAR, uri, application.mainExecutor, callback)
|
||||
}
|
||||
}
|
||||
|
||||
data class ThemeSettings(
|
||||
|
||||
@@ -54,6 +54,7 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
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
|
||||
@@ -556,7 +557,8 @@ fun CredentialManagerPolicyScreen(
|
||||
cmPackages: MutableStateFlow<List<AppInfo>>, getCmPolicy: () -> Int,
|
||||
setCmPackage: (String, Boolean) -> Unit, setCmPolicy: (Int) -> Unit, onNavigateUp: () -> Unit
|
||||
) {
|
||||
var policy by remember { mutableIntStateOf(getCmPolicy()) }
|
||||
val context = LocalContext.current
|
||||
var policy by rememberSaveable { mutableIntStateOf(getCmPolicy()) }
|
||||
val packages by cmPackages.collectAsStateWithLifecycle()
|
||||
var packageName by remember { mutableStateOf("") }
|
||||
LaunchedEffect(Unit) {
|
||||
@@ -574,26 +576,29 @@ fun CredentialManagerPolicyScreen(
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 4.dp))
|
||||
}
|
||||
items(packages, { it.name }) {
|
||||
if (policy != -1) items(packages, { it.name }) {
|
||||
ApplicationItem(it) { setCmPackage(it.name, false) }
|
||||
}
|
||||
item {
|
||||
Column(Modifier.padding(horizontal = HorizontalPadding)) {
|
||||
PackageNameTextField(packageName, onChoosePackage,
|
||||
Modifier.padding(vertical = 8.dp)) { packageName = it }
|
||||
Button(
|
||||
{
|
||||
setCmPackage(packageName, true)
|
||||
packageName = ""
|
||||
},
|
||||
Modifier.fillMaxWidth(),
|
||||
enabled = packageName.isValidPackageName
|
||||
) {
|
||||
Text(stringResource(R.string.add))
|
||||
if (policy != -1) {
|
||||
PackageNameTextField(packageName, onChoosePackage,
|
||||
Modifier.padding(vertical = 8.dp)) { packageName = it }
|
||||
Button(
|
||||
{
|
||||
setCmPackage(packageName, true)
|
||||
packageName = ""
|
||||
},
|
||||
Modifier.fillMaxWidth(),
|
||||
enabled = packageName.isValidPackageName
|
||||
) {
|
||||
Text(stringResource(R.string.add))
|
||||
}
|
||||
}
|
||||
Button(
|
||||
{
|
||||
setCmPolicy(policy)
|
||||
context.showOperationResultToast(true)
|
||||
},
|
||||
Modifier.fillMaxWidth()
|
||||
) {
|
||||
@@ -617,9 +622,8 @@ fun PermittedAsAndImPackages(
|
||||
val context = LocalContext.current
|
||||
val packages by packagesState.collectAsStateWithLifecycle()
|
||||
var packageName by remember { mutableStateOf("") }
|
||||
var allowAll by remember { mutableStateOf(false) }
|
||||
var allowAll by rememberSaveable { mutableStateOf(getPackages()) }
|
||||
LaunchedEffect(Unit) {
|
||||
allowAll = getPackages()
|
||||
packageName = chosenPackage.receive()
|
||||
}
|
||||
MyLazyScaffold(title, onNavigateUp) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -233,6 +233,22 @@ fun SwitchItem(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SwitchItem(
|
||||
title: Int, state: Boolean, onCheckedChange: (Boolean) -> Unit, icon: Int? = null
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(25.dp, 5.dp, 15.dp, 5.dp),
|
||||
Arrangement.SpaceBetween, Alignment.CenterVertically
|
||||
) {
|
||||
Row(Modifier.weight(1F), verticalAlignment = Alignment.CenterVertically) {
|
||||
if (icon != null) Icon(painterResource(icon), null, Modifier.padding(end = 20.dp))
|
||||
Text(stringResource(title), style = typography.titleLarge)
|
||||
}
|
||||
Switch(state, onCheckedChange, Modifier.padding(start = 10.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun InfoItem(title: Int, text: Int, withInfo: Boolean = false, onClick: () -> Unit = {}) =
|
||||
InfoItem(title, stringResource(text), withInfo, onClick)
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
<string name="backup_service">Служба резервного копирования</string>
|
||||
<string name="disable_bt_contact_share">Отключить обмен контактами по Bluetooth</string>
|
||||
<string name="common_criteria_mode">Режим общих критериев</string>
|
||||
<string name="disable_usb_signal">Отключить USB-сигнал</string>
|
||||
<string name="enable_usb_signal">Enable USB signal</string> <!--TODO-->
|
||||
<string name="keyguard">Блокировка экрана (Keyguard)</string>
|
||||
<string name="lock_now">Заблокировать сейчас</string>
|
||||
<string name="evict_credential_encryption_key">Удалить ключ шифрования учетных данных</string>
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
<string name="backup_service">Yedekleme Servisi</string>
|
||||
<string name="disable_bt_contact_share">Bluetooth Kişi Paylaşımını Devre Dışı Bırak</string>
|
||||
<string name="common_criteria_mode">Ortak Kriterler Modu</string>
|
||||
<string name="disable_usb_signal">USB Sinyalini Devre Dışı Bırak</string>
|
||||
<string name="enable_usb_signal">Enable USB signal</string> <!--TODO-->
|
||||
<string name="keyguard">Kilit Ekranı</string>
|
||||
<string name="lock_now">Ekranı Şimdi Kilitle</string>
|
||||
<string name="lock_screen">Kilit Ekranı</string>
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
<string name="backup_service">备份服务</string>
|
||||
<string name="disable_bt_contact_share">禁止蓝牙分享联系人</string>
|
||||
<string name="common_criteria_mode">通用标准模式</string>
|
||||
<string name="disable_usb_signal">禁用USB信号</string>
|
||||
<string name="enable_usb_signal">启用USB信号</string>
|
||||
<string name="keyguard">锁屏</string>
|
||||
<string name="lock_now">立即锁屏</string>
|
||||
<string name="lock_screen">锁屏</string>
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<string name="backup_service">Backup service</string>
|
||||
<string name="disable_bt_contact_share">Disable bluetooth contact sharing</string>
|
||||
<string name="common_criteria_mode">Common criteria mode</string>
|
||||
<string name="disable_usb_signal">Disable USB signal</string>
|
||||
<string name="enable_usb_signal">Enable USB signal</string>
|
||||
<string name="keyguard">Keyguard</string>
|
||||
<string name="lock_now">Lock screen now</string>
|
||||
<string name="lock_screen">Lock screen</string>
|
||||
|
||||
Reference in New Issue
Block a user