mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
Use main NavHost to navigate across all pages
Upgrade dependencies Upload dependencies to GitHub in workflow
This commit is contained in:
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@@ -58,6 +58,9 @@ jobs:
|
|||||||
name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed
|
name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed
|
||||||
path: app/build/outputs/apk/release/app-release.apk
|
path: app/build/outputs/apk/release/app-release.apk
|
||||||
|
|
||||||
|
- name: Generate and submit dependency graph
|
||||||
|
uses: gradle/actions/dependency-submission@v4
|
||||||
|
|
||||||
upload-telegram:
|
upload-telegram:
|
||||||
name: Upload Builds
|
name: Upload Builds
|
||||||
if: ${{ success() }}
|
if: ${{ success() }}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.imePadding
|
import androidx.compose.foundation.layout.imePadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
@@ -27,6 +26,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
|||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -53,15 +53,70 @@ import androidx.navigation.NavHostController
|
|||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.bintianqi.owndroid.dpm.AffiliationID
|
||||||
|
import com.bintianqi.owndroid.dpm.AlwaysOnVPNPackage
|
||||||
import com.bintianqi.owndroid.dpm.ApplicationManage
|
import com.bintianqi.owndroid.dpm.ApplicationManage
|
||||||
import com.bintianqi.owndroid.dpm.DpmPermissions
|
import com.bintianqi.owndroid.dpm.CACert
|
||||||
import com.bintianqi.owndroid.dpm.ManagedProfile
|
import com.bintianqi.owndroid.dpm.ChangeTime
|
||||||
|
import com.bintianqi.owndroid.dpm.ChangeTimeZone
|
||||||
|
import com.bintianqi.owndroid.dpm.ChangeUserIcon
|
||||||
|
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.DeleteWorkProfile
|
||||||
|
import com.bintianqi.owndroid.dpm.DeviceAdmin
|
||||||
|
import com.bintianqi.owndroid.dpm.DeviceInfo
|
||||||
|
import com.bintianqi.owndroid.dpm.DeviceOwner
|
||||||
|
import com.bintianqi.owndroid.dpm.DisableAccountManagement
|
||||||
|
import com.bintianqi.owndroid.dpm.DisableKeyguardFeatures
|
||||||
|
import com.bintianqi.owndroid.dpm.FRPPolicy
|
||||||
|
import com.bintianqi.owndroid.dpm.InstallSystemUpdate
|
||||||
|
import com.bintianqi.owndroid.dpm.IntentFilter
|
||||||
|
import com.bintianqi.owndroid.dpm.Keyguard
|
||||||
|
import com.bintianqi.owndroid.dpm.LockScreenInfo
|
||||||
|
import com.bintianqi.owndroid.dpm.LockTaskMode
|
||||||
|
import com.bintianqi.owndroid.dpm.MTEPolicy
|
||||||
|
import com.bintianqi.owndroid.dpm.WorkProfile
|
||||||
|
import com.bintianqi.owndroid.dpm.NearbyStreamingPolicy
|
||||||
import com.bintianqi.owndroid.dpm.Network
|
import com.bintianqi.owndroid.dpm.Network
|
||||||
|
import com.bintianqi.owndroid.dpm.NetworkLogging
|
||||||
|
import com.bintianqi.owndroid.dpm.NetworkOptions
|
||||||
|
import com.bintianqi.owndroid.dpm.OrgOwnedProfile
|
||||||
|
import com.bintianqi.owndroid.dpm.OverrideAPN
|
||||||
import com.bintianqi.owndroid.dpm.Password
|
import com.bintianqi.owndroid.dpm.Password
|
||||||
|
import com.bintianqi.owndroid.dpm.PasswordComplexity
|
||||||
|
import com.bintianqi.owndroid.dpm.PasswordInfo
|
||||||
|
import com.bintianqi.owndroid.dpm.PasswordQuality
|
||||||
|
import com.bintianqi.owndroid.dpm.PermissionPolicy
|
||||||
|
import com.bintianqi.owndroid.dpm.Permissions
|
||||||
|
import com.bintianqi.owndroid.dpm.PreferentialNetworkService
|
||||||
|
import com.bintianqi.owndroid.dpm.PrivateDNS
|
||||||
|
import com.bintianqi.owndroid.dpm.ProfileOwner
|
||||||
|
import com.bintianqi.owndroid.dpm.RecommendedGlobalProxy
|
||||||
|
import com.bintianqi.owndroid.dpm.ResetPassword
|
||||||
|
import com.bintianqi.owndroid.dpm.ResetPasswordToken
|
||||||
|
import com.bintianqi.owndroid.dpm.RestrictionData
|
||||||
|
import com.bintianqi.owndroid.dpm.SecurityLogging
|
||||||
|
import com.bintianqi.owndroid.dpm.Shizuku
|
||||||
|
import com.bintianqi.owndroid.dpm.SupportMessages
|
||||||
|
import com.bintianqi.owndroid.dpm.SuspendPersonalApp
|
||||||
import com.bintianqi.owndroid.dpm.SystemManage
|
import com.bintianqi.owndroid.dpm.SystemManage
|
||||||
import com.bintianqi.owndroid.dpm.UserManage
|
import com.bintianqi.owndroid.dpm.SystemOptions
|
||||||
|
import com.bintianqi.owndroid.dpm.SystemUpdatePolicy
|
||||||
|
import com.bintianqi.owndroid.dpm.TransferOwnership
|
||||||
|
import com.bintianqi.owndroid.dpm.UserOperation
|
||||||
|
import com.bintianqi.owndroid.dpm.UserOptions
|
||||||
import com.bintianqi.owndroid.dpm.UserRestriction
|
import com.bintianqi.owndroid.dpm.UserRestriction
|
||||||
|
import com.bintianqi.owndroid.dpm.UserRestrictionItem
|
||||||
|
import com.bintianqi.owndroid.dpm.UserSessionMessage
|
||||||
|
import com.bintianqi.owndroid.dpm.Users
|
||||||
|
import com.bintianqi.owndroid.dpm.WifiAuthKeypair
|
||||||
|
import com.bintianqi.owndroid.dpm.WifiSecurityLevel
|
||||||
|
import com.bintianqi.owndroid.dpm.WifiSsidPolicy
|
||||||
|
import com.bintianqi.owndroid.dpm.WipeData
|
||||||
import com.bintianqi.owndroid.dpm.dhizukuErrorStatus
|
import com.bintianqi.owndroid.dpm.dhizukuErrorStatus
|
||||||
|
import com.bintianqi.owndroid.dpm.dhizukuPermissionGranted
|
||||||
import com.bintianqi.owndroid.dpm.getDPM
|
import com.bintianqi.owndroid.dpm.getDPM
|
||||||
import com.bintianqi.owndroid.dpm.getReceiver
|
import com.bintianqi.owndroid.dpm.getReceiver
|
||||||
import com.bintianqi.owndroid.dpm.isDeviceAdmin
|
import com.bintianqi.owndroid.dpm.isDeviceAdmin
|
||||||
@@ -70,6 +125,7 @@ import com.bintianqi.owndroid.dpm.isProfileOwner
|
|||||||
import com.bintianqi.owndroid.dpm.setDefaultAffiliationID
|
import com.bintianqi.owndroid.dpm.setDefaultAffiliationID
|
||||||
import com.bintianqi.owndroid.dpm.toggleInstallAppActivity
|
import com.bintianqi.owndroid.dpm.toggleInstallAppActivity
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
import com.bintianqi.owndroid.ui.Animations
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
||||||
import com.rosan.dhizuku.api.Dhizuku
|
import com.rosan.dhizuku.api.Dhizuku
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -119,7 +175,7 @@ class MainActivity : FragmentActivity() {
|
|||||||
}
|
}
|
||||||
if (sharedPref.getBoolean("dhizuku", false)) {
|
if (sharedPref.getBoolean("dhizuku", false)) {
|
||||||
if (Dhizuku.init(applicationContext)) {
|
if (Dhizuku.init(applicationContext)) {
|
||||||
if (!Dhizuku.isPermissionGranted()) { dhizukuErrorStatus.value = 2 }
|
if (!dhizukuPermissionGranted()) { dhizukuErrorStatus.value = 2 }
|
||||||
} else {
|
} else {
|
||||||
sharedPref.edit().putBoolean("dhizuku", false).apply()
|
sharedPref.edit().putBoolean("dhizuku", false).apply()
|
||||||
dhizukuErrorStatus.value = 1
|
dhizukuErrorStatus.value = 1
|
||||||
@@ -157,20 +213,105 @@ fun Home(vm: MyViewModel) {
|
|||||||
popExitTransition = Animations.navHostPopExitTransition
|
popExitTransition = Animations.navHostPopExitTransition
|
||||||
) {
|
) {
|
||||||
composable(route = "HomePage") { HomePage(navCtrl) }
|
composable(route = "HomePage") { HomePage(navCtrl) }
|
||||||
|
|
||||||
|
composable(route = "Permissions") { Permissions(navCtrl) }
|
||||||
|
composable(route = "Shizuku") { Shizuku(navCtrl) }
|
||||||
|
composable(route = "DeviceAdmin") { DeviceAdmin(navCtrl) }
|
||||||
|
composable(route = "ProfileOwner") { ProfileOwner(navCtrl) }
|
||||||
|
composable(route = "DeviceOwner") { DeviceOwner(navCtrl) }
|
||||||
|
composable(route = "DeviceInfo") { DeviceInfo(navCtrl) }
|
||||||
|
composable(route = "LockScreenInfo") { LockScreenInfo(navCtrl) }
|
||||||
|
composable(route = "SupportMessages") { SupportMessages(navCtrl) }
|
||||||
|
composable(route = "TransferOwnership") { TransferOwnership(navCtrl) }
|
||||||
|
|
||||||
composable(route = "System") { SystemManage(navCtrl) }
|
composable(route = "System") { SystemManage(navCtrl) }
|
||||||
composable(route = "ManagedProfile") { ManagedProfile(navCtrl) }
|
composable(route = "SystemOptions") { SystemOptions(navCtrl) }
|
||||||
composable(route = "Permissions") { DpmPermissions(navCtrl) }
|
composable(route = "Keyguard") { Keyguard(navCtrl) }
|
||||||
composable(route = "Applications") { ApplicationManage(navCtrl, dialogStatus) }
|
composable(route = "ChangeTime") { ChangeTime(navCtrl) }
|
||||||
composable(route = "UserRestriction") { UserRestriction(navCtrl) }
|
composable(route = "ChangeTimeZone") { ChangeTimeZone(navCtrl) }
|
||||||
composable(route = "Users") { UserManage(navCtrl) }
|
composable(route = "PermissionPolicy") { PermissionPolicy(navCtrl) }
|
||||||
composable(route = "Password") { Password(navCtrl) }
|
composable(route = "MTEPolicy") { MTEPolicy(navCtrl) }
|
||||||
composable(route = "Settings") { AppSetting(navCtrl, vm) }
|
composable(route = "NearbyStreamingPolicy") { NearbyStreamingPolicy(navCtrl) }
|
||||||
|
composable(route = "LockTaskMode") { LockTaskMode(navCtrl) }
|
||||||
|
composable(route = "CACert") { CACert(navCtrl) }
|
||||||
|
composable(route = "SecurityLogs") { SecurityLogging(navCtrl) }
|
||||||
|
composable(route = "DisableAccountManagement") { DisableAccountManagement(navCtrl) }
|
||||||
|
composable(route = "SystemUpdatePolicy") { SystemUpdatePolicy(navCtrl) }
|
||||||
|
composable(route = "InstallSystemUpdate") { InstallSystemUpdate(navCtrl) }
|
||||||
|
composable(route = "FRPPolicy") { FRPPolicy(navCtrl) }
|
||||||
|
composable(route = "WipeData") { WipeData(navCtrl) }
|
||||||
|
|
||||||
composable(route = "Network") { Network(navCtrl) }
|
composable(route = "Network") { Network(navCtrl) }
|
||||||
|
composable(route = "NetworkOptions") { NetworkOptions(navCtrl) }
|
||||||
|
composable(route = "MinWifiSecurityLevel") { WifiSecurityLevel(navCtrl) }
|
||||||
|
composable(route = "WifiSsidPolicy") { WifiSsidPolicy(navCtrl) }
|
||||||
|
composable(route = "PrivateDNS") { PrivateDNS(navCtrl) }
|
||||||
|
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(navCtrl) }
|
||||||
|
composable(route = "RecommendedGlobalProxy") { RecommendedGlobalProxy(navCtrl) }
|
||||||
|
composable(route = "NetworkLog") { NetworkLogging(navCtrl) }
|
||||||
|
composable(route = "WifiAuthKeypair") { WifiAuthKeypair(navCtrl) }
|
||||||
|
composable(route = "PreferentialNetworkService") { PreferentialNetworkService(navCtrl) }
|
||||||
|
composable(route = "OverrideAPN") { OverrideAPN(navCtrl) }
|
||||||
|
|
||||||
|
composable(route = "WorkProfile") { WorkProfile(navCtrl) }
|
||||||
|
composable(route = "OrgOwnedWorkProfile") { OrgOwnedProfile(navCtrl) }
|
||||||
|
composable(route = "CreateWorkProfile") { CreateWorkProfile(navCtrl) }
|
||||||
|
composable(route = "SuspendPersonalApp") { SuspendPersonalApp(navCtrl) }
|
||||||
|
composable(route = "IntentFilter") { IntentFilter(navCtrl) }
|
||||||
|
composable(route = "DeleteWorkProfile") { DeleteWorkProfile(navCtrl) }
|
||||||
|
|
||||||
|
composable(route = "Applications") { ApplicationManage(navCtrl, dialogStatus) }
|
||||||
|
|
||||||
|
composable(route = "UserRestriction") { UserRestriction(navCtrl) }
|
||||||
|
composable(route = "UR-Internet") {
|
||||||
|
MyScaffold(R.string.network_and_internet, 0.dp, navCtrl) { RestrictionData.internet.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
composable(route = "UR-Connectivity") {
|
||||||
|
MyScaffold(R.string.connectivity, 0.dp, navCtrl) { RestrictionData.connectivity.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
composable(route = "UR-Applications") {
|
||||||
|
MyScaffold(R.string.applications, 0.dp, navCtrl) { RestrictionData.applications.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
composable(route = "UR-Users") {
|
||||||
|
MyScaffold(R.string.users, 0.dp, navCtrl) { RestrictionData.users.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
composable(route = "UR-Media") {
|
||||||
|
MyScaffold(R.string.media, 0.dp, navCtrl) { RestrictionData.media.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
composable(route = "UR-Other") {
|
||||||
|
MyScaffold(R.string.other, 0.dp, navCtrl) { RestrictionData.other.forEach { UserRestrictionItem(it) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
composable(route = "Users") { Users(navCtrl) }
|
||||||
|
composable(route = "UserInfo") { CurrentUserInfo(navCtrl) }
|
||||||
|
composable(route = "UserOptions") { UserOptions(navCtrl) }
|
||||||
|
composable(route = "UserOperation") { UserOperation(navCtrl) }
|
||||||
|
composable(route = "CreateUser") { CreateUser(navCtrl) }
|
||||||
|
composable(route = "ChangeUsername") { ChangeUsername(navCtrl) }
|
||||||
|
composable(route = "ChangeUserIcon") { ChangeUserIcon(navCtrl) }
|
||||||
|
composable(route = "UserSessionMessage") { UserSessionMessage(navCtrl) }
|
||||||
|
composable(route = "AffiliationID") { AffiliationID(navCtrl) }
|
||||||
|
|
||||||
|
composable(route = "Password") { Password(navCtrl) }
|
||||||
|
composable(route = "PasswordInfo") { PasswordInfo(navCtrl) }
|
||||||
|
composable(route = "ResetPasswordToken") { ResetPasswordToken(navCtrl) }
|
||||||
|
composable(route = "ResetPassword") { ResetPassword(navCtrl) }
|
||||||
|
composable(route = "RequirePasswordComplexity") { PasswordComplexity(navCtrl) }
|
||||||
|
composable(route = "DisableKeyguardFeatures") { DisableKeyguardFeatures(navCtrl) }
|
||||||
|
composable(route = "RequirePasswordQuality") { PasswordQuality(navCtrl) }
|
||||||
|
|
||||||
|
composable(route = "Settings") { Settings(navCtrl) }
|
||||||
|
composable(route = "Options") { SettingsOptions(navCtrl) }
|
||||||
|
composable(route = "Appearance") { Appearance(navCtrl, vm) }
|
||||||
|
composable(route = "AuthSettings") { AuthSettings(navCtrl) }
|
||||||
|
composable(route = "Automation") { Automation(navCtrl) }
|
||||||
|
composable(route = "About") { About(navCtrl) }
|
||||||
|
|
||||||
composable(route = "PackageSelector") { PackageSelector(navCtrl) }
|
composable(route = "PackageSelector") { PackageSelector(navCtrl) }
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
val profileInited = sharedPref.getBoolean("ManagedProfileActivated", false)
|
val profileInitialized = sharedPref.getBoolean("ManagedProfileActivated", false)
|
||||||
val profileNotActivated = !profileInited && context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))
|
val profileNotActivated = !profileInitialized && context.isProfileOwner && (VERSION.SDK_INT < 24 || dpm.isManagedProfile(receiver))
|
||||||
if(profileNotActivated) {
|
if(profileNotActivated) {
|
||||||
dpm.setProfileEnabled(receiver)
|
dpm.setProfileEnabled(receiver)
|
||||||
sharedPref.edit().putBoolean("ManagedProfileActivated", true).apply()
|
sharedPref.edit().putBoolean("ManagedProfileActivated", true).apply()
|
||||||
@@ -203,58 +344,60 @@ private fun HomePage(navCtrl:NavHostController) {
|
|||||||
else if(deviceAdmin) R.string.device_admin else R.string.click_to_activate
|
else if(deviceAdmin) R.string.device_admin else R.string.click_to_activate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.background(colorScheme.background).statusBarsPadding().verticalScroll(rememberScrollState())) {
|
Scaffold {
|
||||||
Spacer(Modifier.padding(vertical = 25.dp))
|
Column(modifier = Modifier.padding(it).verticalScroll(rememberScrollState())) {
|
||||||
Text(
|
Spacer(Modifier.padding(vertical = 25.dp))
|
||||||
text = stringResource(R.string.app_name), style = typography.headlineLarge,
|
Text(
|
||||||
modifier = Modifier.padding(start = 10.dp), color = colorScheme.onBackground
|
text = stringResource(R.string.app_name), style = typography.headlineLarge,
|
||||||
)
|
modifier = Modifier.padding(start = 10.dp)
|
||||||
Spacer(Modifier.padding(vertical = 8.dp))
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 8.dp, horizontal = 8.dp)
|
|
||||||
.clip(RoundedCornerShape(15))
|
|
||||||
.background(color = colorScheme.primary)
|
|
||||||
.clickable(onClick = { navCtrl.navigate("Permissions") })
|
|
||||||
.padding(vertical = 16.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
|
||||||
Spacer(modifier = Modifier.padding(start = 22.dp))
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(if(activated) R.drawable.check_circle_fill1 else R.drawable.block_fill0),
|
|
||||||
contentDescription = null,
|
|
||||||
tint = colorScheme.onPrimary
|
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.padding(start = 10.dp))
|
Spacer(Modifier.padding(vertical = 8.dp))
|
||||||
Column {
|
Row(
|
||||||
Text(
|
modifier = Modifier
|
||||||
text = stringResource(if(activated) R.string.activated else R.string.deactivated),
|
.fillMaxWidth()
|
||||||
style = typography.headlineSmall,
|
.padding(vertical = 8.dp, horizontal = 8.dp)
|
||||||
color = colorScheme.onPrimary,
|
.clip(RoundedCornerShape(15))
|
||||||
modifier = Modifier.padding(bottom = 2.dp)
|
.background(color = colorScheme.primary)
|
||||||
|
.clickable(onClick = { navCtrl.navigate("Permissions") })
|
||||||
|
.padding(vertical = 16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.padding(start = 22.dp))
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(if(activated) R.drawable.check_circle_fill1 else R.drawable.block_fill0),
|
||||||
|
contentDescription = null,
|
||||||
|
tint = colorScheme.onPrimary
|
||||||
)
|
)
|
||||||
if(activateType != "") { Text(text = activateType, color = colorScheme.onPrimary) }
|
Spacer(modifier = Modifier.padding(start = 10.dp))
|
||||||
|
Column {
|
||||||
|
Text(
|
||||||
|
text = stringResource(if(activated) R.string.activated else R.string.deactivated),
|
||||||
|
style = typography.headlineSmall,
|
||||||
|
color = colorScheme.onPrimary,
|
||||||
|
modifier = Modifier.padding(bottom = 2.dp)
|
||||||
|
)
|
||||||
|
if(activateType != "") { Text(text = activateType, color = colorScheme.onPrimary) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
HomePageItem(R.string.system, R.drawable.android_fill0, "System", navCtrl)
|
||||||
|
if(deviceOwner || profileOwner) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) }
|
||||||
|
if(
|
||||||
|
(VERSION.SDK_INT < 24 && !deviceOwner) || (
|
||||||
|
VERSION.SDK_INT >= 24 && (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) ||
|
||||||
|
(profileOwner && dpm.isManagedProfile(receiver)))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile", navCtrl)
|
||||||
|
}
|
||||||
|
if(deviceOwner || profileOwner) HomePageItem(R.string.applications, R.drawable.apps_fill0, "Applications", navCtrl)
|
||||||
|
if(VERSION.SDK_INT >= 24 && (profileOwner || deviceOwner)) {
|
||||||
|
HomePageItem(R.string.user_restriction, R.drawable.person_off, "UserRestriction", navCtrl)
|
||||||
|
}
|
||||||
|
HomePageItem(R.string.users,R.drawable.manage_accounts_fill0,"Users", navCtrl)
|
||||||
|
HomePageItem(R.string.password_and_keyguard, R.drawable.password_fill0, "Password", navCtrl)
|
||||||
|
HomePageItem(R.string.settings, R.drawable.settings_fill0, "Settings", navCtrl)
|
||||||
|
Spacer(Modifier.padding(vertical = 20.dp))
|
||||||
}
|
}
|
||||||
HomePageItem(R.string.system, R.drawable.android_fill0, "System", navCtrl)
|
|
||||||
if(deviceOwner || profileOwner) { HomePageItem(R.string.network, R.drawable.wifi_fill0, "Network", navCtrl) }
|
|
||||||
if(
|
|
||||||
(VERSION.SDK_INT < 24 && !deviceOwner) || (
|
|
||||||
VERSION.SDK_INT >= 24 && (dpm.isProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE) ||
|
|
||||||
(profileOwner && dpm.isManagedProfile(receiver)))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
HomePageItem(R.string.work_profile, R.drawable.work_fill0, "ManagedProfile", navCtrl)
|
|
||||||
}
|
|
||||||
if(deviceOwner || profileOwner) HomePageItem(R.string.applications, R.drawable.apps_fill0, "Applications", navCtrl)
|
|
||||||
if(VERSION.SDK_INT >= 24 && (profileOwner || deviceOwner)) {
|
|
||||||
HomePageItem(R.string.user_restrict, R.drawable.person_off, "UserRestriction", navCtrl)
|
|
||||||
}
|
|
||||||
HomePageItem(R.string.users,R.drawable.manage_accounts_fill0,"Users", navCtrl)
|
|
||||||
HomePageItem(R.string.password_and_keyguard, R.drawable.password_fill0, "Password", navCtrl)
|
|
||||||
HomePageItem(R.string.settings, R.drawable.settings_fill0, "Settings", navCtrl)
|
|
||||||
Spacer(Modifier.padding(vertical = 20.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,22 +406,19 @@ fun HomePageItem(name: Int, imgVector: Int, navTo: String, navCtrl: NavHostContr
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clip(RoundedCornerShape(25))
|
|
||||||
.clickable(onClick = { navCtrl.navigate(navTo) })
|
.clickable(onClick = { navCtrl.navigate(navTo) })
|
||||||
.padding(vertical = 13.dp),
|
.padding(vertical = 12.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Spacer(Modifier.padding(start = 30.dp))
|
Spacer(Modifier.padding(start = 30.dp))
|
||||||
Icon(
|
Icon(
|
||||||
painter = painterResource(imgVector),
|
painter = painterResource(imgVector),
|
||||||
contentDescription = null,
|
contentDescription = null
|
||||||
tint = colorScheme.onBackground
|
|
||||||
)
|
)
|
||||||
Spacer(Modifier.padding(start = 15.dp))
|
Spacer(Modifier.padding(start = 15.dp))
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(name),
|
text = stringResource(name),
|
||||||
style = typography.headlineSmall,
|
style = typography.headlineSmall,
|
||||||
color = colorScheme.onBackground,
|
|
||||||
modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp)
|
modifier = Modifier.padding(bottom = if(zhCN) { 2 } else { 0 }.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,21 +8,15 @@ import android.widget.Toast
|
|||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -37,68 +31,36 @@ import androidx.compose.ui.unit.DpOffset
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import androidx.navigation.compose.composable
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppSetting(navCtrl:NavHostController, vm: MyViewModel) {
|
fun Settings(navCtrl: NavHostController) {
|
||||||
val localNavCtrl = rememberNavController()
|
MyScaffold(R.string.settings, 0.dp, navCtrl) {
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
|
||||||
Scaffold(
|
FunctionItem(R.string.appearance, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Appearance") }
|
||||||
topBar = {
|
FunctionItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("AuthSettings") }
|
||||||
TopBar(backStackEntry, navCtrl, localNavCtrl)
|
FunctionItem(R.string.automation_api, "", R.drawable.apps_fill0) { navCtrl.navigate("Automation") }
|
||||||
}
|
FunctionItem(R.string.about, "", R.drawable.info_fill0) { navCtrl.navigate("About") }
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl) }
|
|
||||||
composable(route = "Options") { Options() }
|
|
||||||
composable(route = "Theme") { ThemeSettings(vm) }
|
|
||||||
composable(route = "Auth") { AuthSettings() }
|
|
||||||
composable(route = "Automation") { Automation() }
|
|
||||||
composable(route = "About") { About() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Home(navCtrl: NavHostController) {
|
fun SettingsOptions(navCtrl: NavHostController) {
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
|
||||||
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
|
|
||||||
SubPageItem(R.string.appearance, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Theme") }
|
|
||||||
SubPageItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("Auth") }
|
|
||||||
SubPageItem(R.string.automation_api, "", R.drawable.apps_fill0) { navCtrl.navigate("Automation") }
|
|
||||||
SubPageItem(R.string.about, "", R.drawable.info_fill0) { navCtrl.navigate("About") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Options() {
|
|
||||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
MyScaffold(R.string.options, 0.dp, navCtrl) {
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
|
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
|
||||||
{ sharedPref.getBoolean("dangerous_features", false) },
|
{ sharedPref.getBoolean("dangerous_features", false) },
|
||||||
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }, padding = false
|
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ThemeSettings(vm: MyViewModel) {
|
fun Appearance(navCtrl: NavHostController, vm: MyViewModel) {
|
||||||
val theme by vm.theme.collectAsStateWithLifecycle()
|
val theme by vm.theme.collectAsStateWithLifecycle()
|
||||||
var darkThemeMenu by remember { mutableStateOf(false) }
|
var darkThemeMenu by remember { mutableStateOf(false) }
|
||||||
val darkThemeTextID = when(theme.darkTheme) {
|
val darkThemeTextID = when(theme.darkTheme) {
|
||||||
@@ -106,7 +68,7 @@ private fun ThemeSettings(vm: MyViewModel) {
|
|||||||
false -> R.string.off
|
false -> R.string.off
|
||||||
null -> R.string.follow_system
|
null -> R.string.follow_system
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.appearance, 0.dp, navCtrl) {
|
||||||
if(VERSION.SDK_INT >= 31) {
|
if(VERSION.SDK_INT >= 31) {
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.material_you_color, "", null,
|
R.string.material_you_color, "", null,
|
||||||
@@ -115,7 +77,7 @@ private fun ThemeSettings(vm: MyViewModel) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Box {
|
Box {
|
||||||
SubPageItem(R.string.dark_theme, stringResource(darkThemeTextID)) { darkThemeMenu = true }
|
FunctionItem(R.string.dark_theme, stringResource(darkThemeTextID)) { darkThemeMenu = true }
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
expanded = darkThemeMenu, onDismissRequest = { darkThemeMenu = false },
|
expanded = darkThemeMenu, onDismissRequest = { darkThemeMenu = false },
|
||||||
offset = DpOffset(x = 25.dp, y = 0.dp)
|
offset = DpOffset(x = 25.dp, y = 0.dp)
|
||||||
@@ -154,44 +116,42 @@ private fun ThemeSettings(vm: MyViewModel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun AuthSettings() {
|
fun AuthSettings(navCtrl: NavHostController) {
|
||||||
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) }
|
var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 16.dp)) {
|
MyScaffold(R.string.security, 0.dp, navCtrl) {
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.lock_owndroid, "", null, auth,
|
R.string.lock_owndroid, "", null, auth,
|
||||||
{
|
{
|
||||||
sharedPref.edit().putBoolean("auth", it).apply()
|
sharedPref.edit().putBoolean("auth", it).apply()
|
||||||
auth = sharedPref.getBoolean("auth", false)
|
auth = sharedPref.getBoolean("auth", false)
|
||||||
}, padding = false
|
}
|
||||||
)
|
)
|
||||||
if(auth) {
|
if(auth) {
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.enable_bio_auth, "", null,
|
R.string.enable_bio_auth, "", null,
|
||||||
{ sharedPref.getBoolean("bio_auth", false) },
|
{ sharedPref.getBoolean("bio_auth", false) },
|
||||||
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }, padding = false
|
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }
|
||||||
)
|
)
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.lock_in_background, stringResource(R.string.developing), null,
|
R.string.lock_in_background, stringResource(R.string.developing), null,
|
||||||
{ sharedPref.getBoolean("lock_in_background", false) },
|
{ sharedPref.getBoolean("lock_in_background", false) },
|
||||||
{ sharedPref.edit().putBoolean("lock_in_background", it).apply() }, padding = false
|
{ sharedPref.edit().putBoolean("lock_in_background", it).apply() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.protect_storage, "", null,
|
R.string.protect_storage, "", null,
|
||||||
{ sharedPref.getBoolean("protect_storage", false) },
|
{ sharedPref.getBoolean("protect_storage", false) },
|
||||||
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }, padding = false
|
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Automation() {
|
fun Automation(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.automation_api, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.automation_api), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
var key by remember { mutableStateOf("") }
|
var key by remember { mutableStateOf("") }
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
@@ -229,18 +189,15 @@ private fun Automation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun About() {
|
fun About(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0)
|
val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0)
|
||||||
val verCode = pkgInfo.versionCode
|
val verCode = pkgInfo.versionCode
|
||||||
val verName = pkgInfo.versionName
|
val verName = pkgInfo.versionName
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.about, 0.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", modifier = Modifier.padding(start = 16.dp))
|
||||||
Text(text = stringResource(R.string.about), style = typography.headlineLarge, modifier = Modifier.padding(start = 26.dp))
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", modifier = Modifier.padding(start = 26.dp))
|
FunctionItem(R.string.project_homepage, "GitHub", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
SubPageItem(R.string.project_homepage, "GitHub", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ import com.bintianqi.owndroid.ui.Information
|
|||||||
import com.bintianqi.owndroid.ui.ListItem
|
import com.bintianqi.owndroid.ui.ListItem
|
||||||
import com.bintianqi.owndroid.ui.NavIcon
|
import com.bintianqi.owndroid.ui.NavIcon
|
||||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
|
|||||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(50))
|
.clip(RoundedCornerShape(50))
|
||||||
.clickable(onClick = {
|
.clickable(onClick = {
|
||||||
@@ -216,7 +216,7 @@ private fun Home(
|
|||||||
if(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver)) {
|
if(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
Text(text = stringResource(R.string.scope_is_work_profile), textAlign = TextAlign.Center,modifier = Modifier.fillMaxWidth())
|
Text(text = stringResource(R.string.scope_is_work_profile), textAlign = TextAlign.Center,modifier = Modifier.fillMaxWidth())
|
||||||
}
|
}
|
||||||
SubPageItem(R.string.app_info,"", R.drawable.open_in_new) {
|
FunctionItem(R.string.app_info,"", R.drawable.open_in_new) {
|
||||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
|
||||||
intent.setData(Uri.parse("package:$pkgName"))
|
intent.setData(Uri.parse("package:$pkgName"))
|
||||||
startActivity(context, intent, null)
|
startActivity(context, intent, null)
|
||||||
@@ -242,37 +242,37 @@ private fun Home(
|
|||||||
onClickBlank = { appControlAction = 3; appControlDialog = true }
|
onClickBlank = { appControlAction = 3; appControlDialog = true }
|
||||||
)
|
)
|
||||||
if((VERSION.SDK_INT >= 33 && profileOwner) || (VERSION.SDK_INT >= 30 && deviceOwner)) {
|
if((VERSION.SDK_INT >= 33 && profileOwner) || (VERSION.SDK_INT >= 30 && deviceOwner)) {
|
||||||
SubPageItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") }
|
FunctionItem(R.string.ucd, "", R.drawable.do_not_touch_fill0) { navCtrl.navigate("UserControlDisabled") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT>=23) {
|
if(VERSION.SDK_INT>=23) {
|
||||||
SubPageItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") }
|
FunctionItem(R.string.permission_manage, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionManage") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
|
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
SubPageItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") }
|
FunctionItem(R.string.cross_profile_package, "", R.drawable.work_fill0) { navCtrl.navigate("CrossProfilePackage") }
|
||||||
}
|
}
|
||||||
if(profileOwner) {
|
if(profileOwner) {
|
||||||
SubPageItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") }
|
FunctionItem(R.string.cross_profile_widget, "", R.drawable.widgets_fill0) { navCtrl.navigate("CrossProfileWidget") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 34 && deviceOwner) {
|
if(VERSION.SDK_INT >= 34 && deviceOwner) {
|
||||||
SubPageItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") }
|
FunctionItem(R.string.credential_manage_policy, "", R.drawable.license_fill0) { navCtrl.navigate("CredentialManagePolicy") }
|
||||||
}
|
}
|
||||||
SubPageItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") }
|
FunctionItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") }
|
||||||
SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
|
FunctionItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
|
||||||
SubPageItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
|
FunctionItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
|
||||||
if(pkgName != "") dialogStatus.intValue = 1
|
if(pkgName != "") dialogStatus.intValue = 1
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
||||||
SubPageItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") }
|
FunctionItem(R.string.keep_uninstalled_packages, "", R.drawable.delete_fill0) { navCtrl.navigate("KeepUninstalled") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28) {
|
if(VERSION.SDK_INT >= 28) {
|
||||||
SubPageItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) {
|
FunctionItem(R.string.clear_app_storage, "", R.drawable.mop_fill0) {
|
||||||
if(pkgName != "") dialogStatus.intValue = 2
|
if(pkgName != "") dialogStatus.intValue = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SubPageItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") }
|
FunctionItem(R.string.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") }
|
||||||
SubPageItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") }
|
FunctionItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") }
|
||||||
if(VERSION.SDK_INT >= 34 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 34 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.set_default_dialer, "", R.drawable.call_fill0) {
|
FunctionItem(R.string.set_default_dialer, "", R.drawable.call_fill0) {
|
||||||
if(pkgName != "") dialogStatus.intValue = 3
|
if(pkgName != "") dialogStatus.intValue = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ private fun binderWrapperPackageInstaller(appContext: Context): PackageInstaller
|
|||||||
fun Context.getPI(): PackageInstaller {
|
fun Context.getPI(): PackageInstaller {
|
||||||
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
if(sharedPref.getBoolean("dhizuku", false)) {
|
if(sharedPref.getBoolean("dhizuku", false)) {
|
||||||
if (!Dhizuku.isPermissionGranted()) {
|
if (!dhizukuPermissionGranted()) {
|
||||||
dhizukuErrorStatus.value = 2
|
dhizukuErrorStatus.value = 2
|
||||||
backToHomeStateFlow.value = true
|
backToHomeStateFlow.value = true
|
||||||
return this.packageManager.packageInstaller
|
return this.packageManager.packageInstaller
|
||||||
@@ -167,7 +167,7 @@ fun Context.getPI(): PackageInstaller {
|
|||||||
fun Context.getDPM(): DevicePolicyManager {
|
fun Context.getDPM(): DevicePolicyManager {
|
||||||
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
if(sharedPref.getBoolean("dhizuku", false)) {
|
if(sharedPref.getBoolean("dhizuku", false)) {
|
||||||
if (!Dhizuku.isPermissionGranted()) {
|
if (!dhizukuPermissionGranted()) {
|
||||||
dhizukuErrorStatus.value = 2
|
dhizukuErrorStatus.value = 2
|
||||||
backToHomeStateFlow.value = true
|
backToHomeStateFlow.value = true
|
||||||
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||||
@@ -193,7 +193,7 @@ fun Context.resetDevicePolicy() {
|
|||||||
val dpm = getDPM()
|
val dpm = getDPM()
|
||||||
val receiver = getReceiver()
|
val receiver = getReceiver()
|
||||||
RestrictionData.getAllRestrictions().forEach {
|
RestrictionData.getAllRestrictions().forEach {
|
||||||
dpm.clearUserRestriction(receiver, it)
|
dpm.clearUserRestriction(receiver, it.id)
|
||||||
}
|
}
|
||||||
dpm.accountTypesWithManagementDisabled?.forEach {
|
dpm.accountTypesWithManagementDisabled?.forEach {
|
||||||
dpm.setAccountManagementDisabled(receiver, it, false)
|
dpm.setAccountManagementDisabled(receiver, it, false)
|
||||||
@@ -428,7 +428,7 @@ fun parseSecurityEventData(event: SecurityLog.SecurityEvent): JsonElement? {
|
|||||||
val payload = event.data as Array<*>
|
val payload = event.data as Array<*>
|
||||||
buildJsonObject {
|
buildJsonObject {
|
||||||
put("mac", payload[0] as String)
|
put("mac", payload[0] as String)
|
||||||
(payload[2] as String).let { if(it != "") put("reason", it) }
|
(payload[1] as String).let { if(it != "") put("reason", it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SecurityLog.TAG_CAMERA_POLICY_SET -> {
|
SecurityLog.TAG_CAMERA_POLICY_SET -> {
|
||||||
@@ -619,3 +619,11 @@ fun setDefaultAffiliationID(context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun dhizukuPermissionGranted() =
|
||||||
|
try {
|
||||||
|
Dhizuku.isPermissionGranted()
|
||||||
|
} catch(_: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,21 +22,17 @@ import android.widget.Toast
|
|||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -55,88 +51,47 @@ import androidx.compose.ui.text.input.ImeAction
|
|||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
import com.bintianqi.owndroid.ui.CardItem
|
||||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||||
import com.bintianqi.owndroid.ui.CopyTextButton
|
import com.bintianqi.owndroid.ui.CopyTextButton
|
||||||
import com.bintianqi.owndroid.ui.InfoCard
|
import com.bintianqi.owndroid.ui.InfoCard
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
import com.bintianqi.owndroid.yesOrNo
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ManagedProfile(navCtrl: NavHostController) {
|
fun WorkProfile(navCtrl: NavHostController) {
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBar(backStackEntry, navCtrl, localNavCtrl)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl) }
|
|
||||||
composable(route = "OrgOwnedWorkProfile") { OrgOwnedProfile() }
|
|
||||||
composable(route = "CreateWorkProfile") { CreateWorkProfile() }
|
|
||||||
composable(route = "SuspendPersonalApp") { SuspendPersonalApp() }
|
|
||||||
composable(route = "IntentFilter") { IntentFilter() }
|
|
||||||
composable(route = "DeleteWorkProfile") { DeleteWorkProfile() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Home(navCtrl: NavHostController) {
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
Column(
|
MyScaffold(R.string.work_profile, 0.dp, navCtrl) {
|
||||||
modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.work_profile),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
|
if(VERSION.SDK_INT >= 30 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
SubPageItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") }
|
FunctionItem(R.string.org_owned_work_profile, "", R.drawable.corporate_fare_fill0) { navCtrl.navigate("OrgOwnedWorkProfile") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) {
|
if(VERSION.SDK_INT<24 || (VERSION.SDK_INT>=24 && dpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))) {
|
||||||
SubPageItem(R.string.create_work_profile, "", R.drawable.work_fill0) { navCtrl.navigate("CreateWorkProfile") }
|
FunctionItem(R.string.create_work_profile, "", R.drawable.work_fill0) { navCtrl.navigate("CreateWorkProfile") }
|
||||||
}
|
}
|
||||||
if(dpm.isOrgProfile(receiver)) {
|
if(dpm.isOrgProfile(receiver)) {
|
||||||
SubPageItem(R.string.suspend_personal_app, "", R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") }
|
FunctionItem(R.string.suspend_personal_app, "", R.drawable.block_fill0) { navCtrl.navigate("SuspendPersonalApp") }
|
||||||
}
|
}
|
||||||
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
||||||
SubPageItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") }
|
FunctionItem(R.string.intent_filter, "", R.drawable.filter_alt_fill0) { navCtrl.navigate("IntentFilter") }
|
||||||
}
|
}
|
||||||
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
if(profileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
||||||
SubPageItem(R.string.delete_work_profile, "", R.drawable.delete_forever_fill0) { navCtrl.navigate("DeleteWorkProfile") }
|
FunctionItem(R.string.delete_work_profile, "", R.drawable.delete_forever_fill0) { navCtrl.navigate("DeleteWorkProfile") }
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CreateWorkProfile() {
|
fun CreateWorkProfile(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.create_work_profile, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.create_work_profile), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
var skipEncrypt by remember { mutableStateOf(false) }
|
var skipEncrypt by remember { mutableStateOf(false) }
|
||||||
var offlineProvisioning by remember { mutableStateOf(true) }
|
var offlineProvisioning by remember { mutableStateOf(true) }
|
||||||
var migrateAccount by remember { mutableStateOf(false) }
|
var migrateAccount by remember { mutableStateOf(false) }
|
||||||
@@ -206,14 +161,11 @@ private fun CreateWorkProfile() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun OrgOwnedProfile() {
|
fun OrgOwnedProfile(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.org_owned_work_profile, 8.dp, navCtrl, false) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
CardItem(R.string.org_owned_work_profile, dpm.isOrganizationOwnedDeviceWithManagedProfile.yesOrNo)
|
||||||
Text(text = stringResource(R.string.org_owned_work_profile), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Text(text = stringResource(R.string.is_org_owned_profile,dpm.isOrganizationOwnedDeviceWithManagedProfile))
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
if(!dpm.isOrganizationOwnedDeviceWithManagedProfile) {
|
if(!dpm.isOrganizationOwnedDeviceWithManagedProfile) {
|
||||||
SelectionContainer {
|
SelectionContainer {
|
||||||
@@ -229,14 +181,13 @@ private fun OrgOwnedProfile() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun SuspendPersonalApp() {
|
fun SuspendPersonalApp(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var suspend by remember { mutableStateOf(dpm.getPersonalAppsSuspendedReasons(receiver) != PERSONAL_APPS_NOT_SUSPENDED) }
|
var suspend by remember { mutableStateOf(dpm.getPersonalAppsSuspendedReasons(receiver) != PERSONAL_APPS_NOT_SUSPENDED) }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.suspend_personal_app, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.suspend_personal_app, "", null,
|
R.string.suspend_personal_app, "", null,
|
||||||
suspend,
|
suspend,
|
||||||
@@ -277,16 +228,13 @@ private fun SuspendPersonalApp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun IntentFilter() {
|
fun IntentFilter(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.intent_filter, 8.dp, navCtrl) {
|
||||||
var action by remember { mutableStateOf("") }
|
var action by remember { mutableStateOf("") }
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.intent_filter), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = action, onValueChange = { action = it },
|
value = action, onValueChange = { action = it },
|
||||||
label = { Text("Action") },
|
label = { Text("Action") },
|
||||||
@@ -328,7 +276,7 @@ private fun IntentFilter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DeleteWorkProfile() {
|
fun DeleteWorkProfile(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
@@ -337,14 +285,7 @@ private fun DeleteWorkProfile() {
|
|||||||
var euicc by remember { mutableStateOf(false) }
|
var euicc by remember { mutableStateOf(false) }
|
||||||
var silent by remember { mutableStateOf(false) }
|
var silent by remember { mutableStateOf(false) }
|
||||||
var reason by remember { mutableStateOf("") }
|
var reason by remember { mutableStateOf("") }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.delete_work_profile, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.delete_work_profile),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(6.dp),color = colorScheme.error
|
|
||||||
)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
CheckBoxItem(R.string.wipe_external_storage, externalStorage, { externalStorage = it })
|
CheckBoxItem(R.string.wipe_external_storage, externalStorage, { externalStorage = it })
|
||||||
if(VERSION.SDK_INT >= 28) { CheckBoxItem(R.string.wipe_euicc, euicc, { euicc = it }) }
|
if(VERSION.SDK_INT >= 28) { CheckBoxItem(R.string.wipe_euicc, euicc, { euicc = it }) }
|
||||||
CheckBoxItem(R.string.wipe_silently, silent, { silent = it })
|
CheckBoxItem(R.string.wipe_silently, silent, { silent = it })
|
||||||
@@ -367,7 +308,6 @@ private fun DeleteWorkProfile() {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.delete))
|
Text(stringResource(R.string.delete))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(warning) {
|
if(warning) {
|
||||||
LaunchedEffect(Unit) { silent = reason == "" }
|
LaunchedEffect(Unit) { silent = reason == "" }
|
||||||
|
|||||||
@@ -43,21 +43,17 @@ import android.telephony.data.ApnSetting.PROTOCOL_UNSTRUCTURED
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
||||||
@@ -69,14 +65,12 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
@@ -88,7 +82,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
@@ -99,72 +92,73 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.exportFile
|
import com.bintianqi.owndroid.exportFile
|
||||||
import com.bintianqi.owndroid.exportFilePath
|
import com.bintianqi.owndroid.exportFilePath
|
||||||
import com.bintianqi.owndroid.formatFileSize
|
import com.bintianqi.owndroid.formatFileSize
|
||||||
import com.bintianqi.owndroid.selectedPackage
|
import com.bintianqi.owndroid.selectedPackage
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
|
||||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||||
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.InfoCard
|
import com.bintianqi.owndroid.ui.InfoCard
|
||||||
import com.bintianqi.owndroid.ui.ListItem
|
import com.bintianqi.owndroid.ui.ListItem
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
import com.bintianqi.owndroid.writeClipBoard
|
import com.bintianqi.owndroid.writeClipBoard
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Network(navCtrl: NavHostController) {
|
fun Network(navCtrl:NavHostController) {
|
||||||
val localNavCtrl = rememberNavController()
|
val context = LocalContext.current
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
val dpm = context.getDPM()
|
||||||
val scrollState = rememberScrollState()
|
val receiver = context.getReceiver()
|
||||||
val wifiMacDialog = remember { mutableStateOf(false) }
|
val deviceOwner = context.isDeviceOwner
|
||||||
Scaffold(
|
val profileOwner = context.isProfileOwner
|
||||||
topBar = {
|
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
TopBar(backStackEntry,navCtrl,localNavCtrl) {
|
val dhizuku = sharedPref.getBoolean("dhizuku", false)
|
||||||
if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 80) {
|
var wifiMacDialog by remember { mutableStateOf(false) }
|
||||||
Text(
|
MyScaffold(R.string.network, 0.dp, navCtrl) {
|
||||||
text = stringResource(R.string.network),
|
if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
|
FunctionItem(R.string.wifi_mac_address, "", R.drawable.wifi_fill0) { wifiMacDialog = true }
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
) {
|
if(VERSION.SDK_INT >= 30) {
|
||||||
NavHost(
|
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("NetworkOptions") }
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
}
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
if(VERSION.SDK_INT >= 33 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
exitTransition = Animations.navHostExitTransition,
|
FunctionItem(R.string.min_wifi_security_level, "", R.drawable.wifi_password_fill0) { navCtrl.navigate("MinWifiSecurityLevel") }
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
}
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
if(VERSION.SDK_INT >= 33 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
FunctionItem(R.string.wifi_ssid_policy, "", R.drawable.wifi_fill0) { navCtrl.navigate("WifiSsidPolicy") }
|
||||||
) {
|
}
|
||||||
composable(route = "Home") { Home(localNavCtrl, scrollState, wifiMacDialog) }
|
if(VERSION.SDK_INT >= 29 && deviceOwner) {
|
||||||
composable(route = "Switches") { Switches() }
|
FunctionItem(R.string.private_dns, "", R.drawable.dns_fill0) { navCtrl.navigate("PrivateDNS") }
|
||||||
composable(route = "MinWifiSecurityLevel") { WifiSecLevel() }
|
}
|
||||||
composable(route = "WifiSsidPolicy") { WifiSsidPolicy() }
|
if(VERSION.SDK_INT >= 24 && (deviceOwner || profileOwner)) {
|
||||||
composable(route = "PrivateDNS") { PrivateDNS() }
|
FunctionItem(R.string.always_on_vpn, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("AlwaysOnVpn") }
|
||||||
composable(route = "AlwaysOnVpn") { AlwaysOnVPNPackage(navCtrl) }
|
}
|
||||||
composable(route = "RecommendedGlobalProxy") { RecommendedGlobalProxy() }
|
if(deviceOwner) {
|
||||||
composable(route = "NetworkLog") { NetworkLog() }
|
FunctionItem(R.string.recommended_global_proxy, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("RecommendedGlobalProxy") }
|
||||||
composable(route = "WifiAuthKeypair") { WifiAuthKeypair() }
|
}
|
||||||
composable(route = "PreferentialNetworkService") { PreferentialNetworkService() }
|
if(VERSION.SDK_INT >= 26 && !dhizuku && (deviceOwner || (profileOwner && dpm.isManagedProfile(receiver)))) {
|
||||||
composable(route = "APN") { APN() }
|
FunctionItem(R.string.network_logging, "", R.drawable.description_fill0) { navCtrl.navigate("NetworkLog") }
|
||||||
|
}
|
||||||
|
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
||||||
|
FunctionItem(R.string.wifi_auth_keypair, "", R.drawable.key_fill0) { navCtrl.navigate("WifiAuthKeypair") }
|
||||||
|
}
|
||||||
|
if(VERSION.SDK_INT >= 33 && (deviceOwner || profileOwner)) {
|
||||||
|
FunctionItem(R.string.preferential_network_service, "", R.drawable.globe_fill0) { navCtrl.navigate("PreferentialNetworkService") }
|
||||||
|
}
|
||||||
|
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
||||||
|
FunctionItem(R.string.override_apn_settings, "", R.drawable.cell_tower_fill0) { navCtrl.navigate("OverrideAPN") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(wifiMacDialog.value && VERSION.SDK_INT >= 24) {
|
if(wifiMacDialog && VERSION.SDK_INT >= 24) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = { wifiMacDialog.value = false },
|
onDismissRequest = { wifiMacDialog = false },
|
||||||
confirmButton = { TextButton(onClick = { wifiMacDialog.value = false }) { Text(stringResource(R.string.confirm)) } },
|
confirmButton = { TextButton(onClick = { wifiMacDialog = false }) { Text(stringResource(R.string.confirm)) } },
|
||||||
title = { Text(stringResource(R.string.wifi_mac_address)) },
|
title = { Text(stringResource(R.string.wifi_mac_address)) },
|
||||||
text = {
|
text = {
|
||||||
val mac = dpm.getWifiMacAddress(receiver)
|
val mac = dpm.getWifiMacAddress(receiver)
|
||||||
@@ -184,66 +178,13 @@ fun Network(navCtrl: NavHostController) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Home(navCtrl:NavHostController, scrollState: ScrollState, wifiMacDialog: MutableState<Boolean>) {
|
fun NetworkOptions(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
|
||||||
val dpm = context.getDPM()
|
|
||||||
val receiver = context.getReceiver()
|
|
||||||
val deviceOwner = context.isDeviceOwner
|
|
||||||
val profileOwner = context.isProfileOwner
|
|
||||||
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
|
||||||
val dhizuku = sharedPref.getBoolean("dhizuku", false)
|
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.network),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
|
||||||
SubPageItem(R.string.wifi_mac_address, "", R.drawable.wifi_fill0) { wifiMacDialog.value = true }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 30) {
|
|
||||||
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 33 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
|
||||||
SubPageItem(R.string.min_wifi_security_level, "", R.drawable.wifi_password_fill0) { navCtrl.navigate("MinWifiSecurityLevel") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 33 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
|
||||||
SubPageItem(R.string.wifi_ssid_policy, "", R.drawable.wifi_fill0) { navCtrl.navigate("WifiSsidPolicy") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 29 && deviceOwner) {
|
|
||||||
SubPageItem(R.string.private_dns, "", R.drawable.dns_fill0) { navCtrl.navigate("PrivateDNS") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 24 && (deviceOwner || profileOwner)) {
|
|
||||||
SubPageItem(R.string.always_on_vpn, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("AlwaysOnVpn") }
|
|
||||||
}
|
|
||||||
if(deviceOwner) {
|
|
||||||
SubPageItem(R.string.recommended_global_proxy, "", R.drawable.vpn_key_fill0) { navCtrl.navigate("RecommendedGlobalProxy") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 26 && !dhizuku && (deviceOwner || (profileOwner && dpm.isManagedProfile(receiver)))) {
|
|
||||||
SubPageItem(R.string.retrieve_net_logs, "", R.drawable.description_fill0) { navCtrl.navigate("NetworkLog") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
|
||||||
SubPageItem(R.string.wifi_auth_keypair, "", R.drawable.key_fill0) { navCtrl.navigate("WifiAuthKeypair") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 33 && (deviceOwner || profileOwner)) {
|
|
||||||
SubPageItem(R.string.preferential_network_service, "", R.drawable.globe_fill0) { navCtrl.navigate("PreferentialNetworkService") }
|
|
||||||
}
|
|
||||||
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
|
||||||
SubPageItem(R.string.override_apn_settings, "", R.drawable.cell_tower_fill0) { navCtrl.navigate("APN") }
|
|
||||||
}
|
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Switches() {
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
MyScaffold(R.string.options, 0.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(VERSION.SDK_INT>=30 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT>=30 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SwitchItem(R.string.lockdown_admin_configured_network, "", R.drawable.wifi_password_fill0,
|
SwitchItem(R.string.lockdown_admin_configured_network, "", R.drawable.wifi_password_fill0,
|
||||||
{ dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) },
|
{ dpm.hasLockdownAdminConfiguredNetworks(receiver) }, { dpm.setConfiguredNetworksLockdownState(receiver,it) },
|
||||||
@@ -262,15 +203,12 @@ private fun Switches() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun WifiSecLevel() {
|
fun WifiSecurityLevel(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
var selectedWifiSecLevel by remember { mutableIntStateOf(0) }
|
var selectedWifiSecLevel by remember { mutableIntStateOf(0) }
|
||||||
LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel }
|
LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.min_wifi_security_level, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.min_wifi_security_level), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
RadioButtonItem(
|
RadioButtonItem(
|
||||||
R.string.wifi_security_open,
|
R.string.wifi_security_open,
|
||||||
selectedWifiSecLevel == WIFI_SECURITY_OPEN,
|
selectedWifiSecLevel == WIFI_SECURITY_OPEN,
|
||||||
@@ -307,11 +245,11 @@ private fun WifiSecLevel() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun WifiSsidPolicy() {
|
fun WifiSsidPolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.wifi_ssid_policy, 8.dp, navCtrl) {
|
||||||
var selectedPolicyType by remember { mutableIntStateOf(-1) }
|
var selectedPolicyType by remember { mutableIntStateOf(-1) }
|
||||||
val ssidList = remember { mutableStateListOf<WifiSsid>() }
|
val ssidList = remember { mutableStateListOf<WifiSsid>() }
|
||||||
val refreshPolicy = {
|
val refreshPolicy = {
|
||||||
@@ -321,9 +259,6 @@ private fun WifiSsidPolicy() {
|
|||||||
ssidList.addAll(policy?.ssids ?: mutableSetOf())
|
ssidList.addAll(policy?.ssids ?: mutableSetOf())
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { refreshPolicy() }
|
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))
|
|
||||||
RadioButtonItem(
|
RadioButtonItem(
|
||||||
R.string.none,
|
R.string.none,
|
||||||
selectedPolicyType == -1,
|
selectedPolicyType == -1,
|
||||||
@@ -387,20 +322,17 @@ private fun WifiSsidPolicy() {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun PrivateDNS() {
|
fun PrivateDNS(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.private_dns, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.private_dns), style = typography.headlineLarge)
|
|
||||||
val dnsStatus = mapOf(
|
val dnsStatus = mapOf(
|
||||||
PRIVATE_DNS_MODE_UNKNOWN to stringResource(R.string.unknown),
|
PRIVATE_DNS_MODE_UNKNOWN to stringResource(R.string.unknown),
|
||||||
PRIVATE_DNS_MODE_OFF to stringResource(R.string.disabled),
|
PRIVATE_DNS_MODE_OFF to stringResource(R.string.disabled),
|
||||||
@@ -462,7 +394,6 @@ private fun PrivateDNS() {
|
|||||||
Text(stringResource(R.string.set_dns_host))
|
Text(stringResource(R.string.set_dns_host))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_set_private_dns_host)
|
InfoCard(R.string.info_set_private_dns_host)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,9 +430,7 @@ fun AlwaysOnVPNPackage(navCtrl: NavHostController) {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.always_on_vpn, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.always_on_vpn), style = typography.headlineLarge, modifier = Modifier.padding(vertical = 8.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = pkgName,
|
value = pkgName,
|
||||||
onValueChange = { pkgName = it },
|
onValueChange = { pkgName = it },
|
||||||
@@ -509,7 +438,7 @@ fun AlwaysOnVPNPackage(navCtrl: NavHostController) {
|
|||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(50))
|
.clip(RoundedCornerShape(50))
|
||||||
.clickable(onClick = {
|
.clickable(onClick = {
|
||||||
@@ -536,12 +465,11 @@ fun AlwaysOnVPNPackage(navCtrl: NavHostController) {
|
|||||||
Text(stringResource(R.string.clear_current_config))
|
Text(stringResource(R.string.clear_current_config))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_always_on_vpn)
|
InfoCard(R.string.info_always_on_vpn)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun RecommendedGlobalProxy() {
|
fun RecommendedGlobalProxy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -551,10 +479,7 @@ private fun RecommendedGlobalProxy() {
|
|||||||
var specifyPort by remember { mutableStateOf(false) }
|
var specifyPort by remember { mutableStateOf(false) }
|
||||||
var proxyPort by remember { mutableStateOf("") }
|
var proxyPort by remember { mutableStateOf("") }
|
||||||
var exclList by remember { mutableStateOf("") }
|
var exclList by remember { mutableStateOf("") }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.recommended_global_proxy, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.recommended_global_proxy), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
RadioButtonItem(R.string.proxy_type_off, proxyType == 0, { proxyType = 0 })
|
RadioButtonItem(R.string.proxy_type_off, proxyType == 0, { proxyType = 0 })
|
||||||
RadioButtonItem(R.string.proxy_type_pac, proxyType == 1, { proxyType = 1 })
|
RadioButtonItem(R.string.proxy_type_pac, proxyType == 1, { proxyType = 1 })
|
||||||
RadioButtonItem(R.string.proxy_type_direct, proxyType == 2, { proxyType = 2 })
|
RadioButtonItem(R.string.proxy_type_direct, proxyType == 2, { proxyType = 2 })
|
||||||
@@ -641,7 +566,7 @@ private fun RecommendedGlobalProxy() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun NetworkLog() {
|
fun NetworkLogging(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -650,10 +575,7 @@ private fun NetworkLog() {
|
|||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
fileSize = logFile.length()
|
fileSize = logFile.length()
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.network_logging, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.retrieve_net_logs), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
SwitchItem(R.string.enable, "", null, { dpm.isNetworkLoggingEnabled(receiver) }, { dpm.setNetworkLoggingEnabled(receiver,it) }, padding = false)
|
SwitchItem(R.string.enable, "", null, { dpm.isNetworkLoggingEnabled(receiver) }, { dpm.setNetworkLoggingEnabled(receiver,it) }, padding = false)
|
||||||
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
|
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
@@ -688,15 +610,12 @@ private fun NetworkLog() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun WifiAuthKeypair() {
|
fun WifiAuthKeypair(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
var keyPair by remember { mutableStateOf("") }
|
||||||
var keyPair by remember { mutableStateOf("") }
|
MyScaffold(R.string.wifi_auth_keypair, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.wifi_auth_keypair), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = keyPair,
|
value = keyPair,
|
||||||
label = { Text(stringResource(R.string.alias)) },
|
label = { Text(stringResource(R.string.alias)) },
|
||||||
@@ -739,7 +658,7 @@ private fun WifiAuthKeypair() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
fun PreferentialNetworkService() {
|
fun PreferentialNetworkService(navCtrl: NavHostController) {
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
@@ -778,10 +697,7 @@ fun PreferentialNetworkService() {
|
|||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { initialize() }
|
LaunchedEffect(Unit) { initialize() }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.preferential_network_service, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.preferential_network_service), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
title = R.string.enabled, desc = "", icon = null,
|
title = R.string.enabled, desc = "", icon = null,
|
||||||
state = masterEnabled, onCheckedChange = { masterEnabled = it }, padding = false
|
state = masterEnabled, onCheckedChange = { masterEnabled = it }, padding = false
|
||||||
@@ -895,25 +811,21 @@ fun PreferentialNetworkService() {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun APN() {
|
fun OverrideAPN(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
val setting = dpm.getOverrideApns(receiver)
|
||||||
val setting = dpm.getOverrideApns(receiver)
|
var inputNum by remember { mutableStateOf("0") }
|
||||||
var inputNum by remember { mutableStateOf("0") }
|
var nextStep by remember { mutableStateOf(false) }
|
||||||
var nextStep by remember { mutableStateOf(false) }
|
val builder = Builder()
|
||||||
val builder = Builder()
|
MyScaffold(R.string.override_apn_settings, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.override_apn_settings), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Text(text = stringResource(id = R.string.developing))
|
Text(text = stringResource(id = R.string.developing))
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
SwitchItem(R.string.enable, "", null, { dpm.isOverrideApnEnabled(receiver) }, { dpm.setOverrideApnsEnabled(receiver,it) }, padding = false)
|
SwitchItem(R.string.enable, "", null, { dpm.isOverrideApnEnabled(receiver) }, { dpm.setOverrideApnsEnabled(receiver,it) }, padding = false)
|
||||||
@@ -1275,6 +1187,5 @@ private fun APN() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,25 +35,20 @@ import android.os.Build.VERSION
|
|||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -65,7 +60,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -75,103 +69,56 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.toggle
|
import com.bintianqi.owndroid.toggle
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
|
||||||
import com.bintianqi.owndroid.ui.CardItem
|
import com.bintianqi.owndroid.ui.CardItem
|
||||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||||
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.InfoCard
|
import com.bintianqi.owndroid.ui.InfoCard
|
||||||
import com.bintianqi.owndroid.ui.Information
|
import com.bintianqi.owndroid.ui.Information
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
import com.bintianqi.owndroid.yesOrNo
|
import com.bintianqi.owndroid.yesOrNo
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun Password(navCtrl: NavHostController) {
|
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBar(backStackEntry,navCtrl,localNavCtrl) {
|
|
||||||
if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 100) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.password_and_keyguard),
|
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl,scrollState) }
|
|
||||||
composable(route = "PasswordInfo") { PasswordInfo() }
|
|
||||||
composable(route = "ResetPasswordToken") { ResetPasswordToken() }
|
|
||||||
composable(route = "ResetPassword") { ResetPassword() }
|
|
||||||
composable(route = "RequirePasswordComplexity") { PasswordComplexity() }
|
|
||||||
composable(route = "DisableKeyguardFeatures") { DisableKeyguardFeatures() }
|
|
||||||
composable(route = "RequirePasswordQuality") { PasswordQuality() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
|
fun Password(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val sharedPrefs = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
val sharedPrefs = context.getSharedPreferences("data", Context.MODE_PRIVATE)
|
||||||
val deviceAdmin = context.isDeviceAdmin
|
val deviceAdmin = context.isDeviceAdmin
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
|
MyScaffold(R.string.password_and_keyguard, 0.dp, navCtrl) {
|
||||||
Text(
|
FunctionItem(R.string.password_info, "", R.drawable.info_fill0) { navCtrl.navigate("PasswordInfo") }
|
||||||
text = stringResource(R.string.password_and_keyguard),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
SubPageItem(R.string.password_info, "", R.drawable.info_fill0) { navCtrl.navigate("PasswordInfo") }
|
|
||||||
if(sharedPrefs.getBoolean("dangerous_features", false)) {
|
if(sharedPrefs.getBoolean("dangerous_features", false)) {
|
||||||
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.reset_password_token, "", R.drawable.key_vertical_fill0) { navCtrl.navigate("ResetPasswordToken") }
|
FunctionItem(R.string.reset_password_token, "", R.drawable.key_vertical_fill0) { navCtrl.navigate("ResetPasswordToken") }
|
||||||
}
|
}
|
||||||
if(deviceAdmin || deviceOwner || profileOwner) {
|
if(deviceAdmin || deviceOwner || profileOwner) {
|
||||||
SubPageItem(R.string.reset_password, "", R.drawable.lock_reset_fill0) { navCtrl.navigate("ResetPassword") }
|
FunctionItem(R.string.reset_password, "", R.drawable.lock_reset_fill0) { navCtrl.navigate("ResetPassword") }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.required_password_complexity, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordComplexity") }
|
FunctionItem(R.string.required_password_complexity, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordComplexity") }
|
||||||
}
|
}
|
||||||
if(deviceAdmin) {
|
if(deviceAdmin) {
|
||||||
SubPageItem(R.string.disable_keyguard_features, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("DisableKeyguardFeatures") }
|
FunctionItem(R.string.disable_keyguard_features, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("DisableKeyguardFeatures") }
|
||||||
}
|
}
|
||||||
if(deviceOwner) {
|
if(deviceOwner) {
|
||||||
SubPageItem(R.string.max_time_to_lock, "", R.drawable.schedule_fill0) { dialog = 1 }
|
FunctionItem(R.string.max_time_to_lock, "", R.drawable.schedule_fill0) { dialog = 1 }
|
||||||
SubPageItem(R.string.pwd_expiration_timeout, "", R.drawable.lock_clock_fill0) { dialog = 3 }
|
FunctionItem(R.string.pwd_expiration_timeout, "", R.drawable.lock_clock_fill0) { dialog = 3 }
|
||||||
SubPageItem(R.string.max_pwd_fail, "", R.drawable.no_encryption_fill0) { dialog = 4 }
|
FunctionItem(R.string.max_pwd_fail, "", R.drawable.no_encryption_fill0) { dialog = 4 }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.required_strong_auth_timeout, "", R.drawable.fingerprint_off_fill0) { dialog = 2 }
|
FunctionItem(R.string.required_strong_auth_timeout, "", R.drawable.fingerprint_off_fill0) { dialog = 2 }
|
||||||
}
|
}
|
||||||
if(deviceAdmin){
|
if(deviceAdmin){
|
||||||
SubPageItem(R.string.pwd_history, "", R.drawable.history_fill0) { dialog = 5 }
|
FunctionItem(R.string.pwd_history, "", R.drawable.history_fill0) { dialog = 5 }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT < 31 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT < 31 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.required_password_quality, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordQuality") }
|
FunctionItem(R.string.required_password_quality, "", R.drawable.password_fill0) { navCtrl.navigate("RequirePasswordQuality") }
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(dialog != 0) {
|
if(dialog != 0) {
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
@@ -263,16 +210,13 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PasswordInfo() {
|
fun PasswordInfo(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.password_info, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.password_info), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(VERSION.SDK_INT >= 29) {
|
if(VERSION.SDK_INT >= 29) {
|
||||||
val passwordComplexity = mapOf(
|
val passwordComplexity = mapOf(
|
||||||
PASSWORD_COMPLEXITY_NONE to R.string.password_complexity_none,
|
PASSWORD_COMPLEXITY_NONE to R.string.password_complexity_none,
|
||||||
@@ -293,17 +237,14 @@ private fun PasswordInfo() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun ResetPasswordToken() {
|
fun ResetPasswordToken(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var token by remember { mutableStateOf("") }
|
var token by remember { mutableStateOf("") }
|
||||||
val tokenByteArray = token.toByteArray()
|
val tokenByteArray = token.toByteArray()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.reset_password_token, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.reset_password_token), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = token, onValueChange = { token = it },
|
value = token, onValueChange = { token = it },
|
||||||
label = { Text(stringResource(R.string.token)) },
|
label = { Text(stringResource(R.string.token)) },
|
||||||
@@ -367,7 +308,7 @@ private fun ResetPasswordToken() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ResetPassword() {
|
fun ResetPassword(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -378,10 +319,7 @@ private fun ResetPassword() {
|
|||||||
val tokenByteArray = token.toByteArray()
|
val tokenByteArray = token.toByteArray()
|
||||||
val flags = remember { mutableStateListOf<Int>() }
|
val flags = remember { mutableStateListOf<Int>() }
|
||||||
var confirmDialog by remember { mutableStateOf(false) }
|
var confirmDialog by remember { mutableStateOf(false) }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.reset_password, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.reset_password),style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(VERSION.SDK_INT >= 26) {
|
if(VERSION.SDK_INT >= 26) {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = token, onValueChange = { token = it },
|
value = token, onValueChange = { token = it },
|
||||||
@@ -444,7 +382,6 @@ private fun ResetPassword() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_reset_password)
|
InfoCard(R.string.info_reset_password)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(confirmDialog) {
|
if(confirmDialog) {
|
||||||
var confirmPassword by remember { mutableStateOf("") }
|
var confirmPassword by remember { mutableStateOf("") }
|
||||||
@@ -494,7 +431,7 @@ private fun ResetPassword() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun PasswordComplexity() {
|
fun PasswordComplexity(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val passwordComplexity = mapOf(
|
val passwordComplexity = mapOf(
|
||||||
@@ -502,19 +439,12 @@ private fun PasswordComplexity() {
|
|||||||
PASSWORD_COMPLEXITY_LOW to R.string.password_complexity_low,
|
PASSWORD_COMPLEXITY_LOW to R.string.password_complexity_low,
|
||||||
PASSWORD_COMPLEXITY_MEDIUM to R.string.password_complexity_medium,
|
PASSWORD_COMPLEXITY_MEDIUM to R.string.password_complexity_medium,
|
||||||
PASSWORD_COMPLEXITY_HIGH to R.string.password_complexity_high
|
PASSWORD_COMPLEXITY_HIGH to R.string.password_complexity_high
|
||||||
).toList()
|
)
|
||||||
var selectedItem by remember { mutableIntStateOf(passwordComplexity[0].first) }
|
var selectedItem by remember { mutableIntStateOf(PASSWORD_COMPLEXITY_NONE) }
|
||||||
LaunchedEffect(Unit) { selectedItem = dpm.requiredPasswordComplexity }
|
LaunchedEffect(Unit) { selectedItem = dpm.requiredPasswordComplexity }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.required_password_complexity, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
passwordComplexity.forEach {
|
||||||
Text(text = stringResource(R.string.required_password_complexity), style = typography.headlineLarge)
|
RadioButtonItem(it.value, selectedItem == it.key, { selectedItem = it.key })
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
for(index in 0..3) {
|
|
||||||
RadioButtonItem(
|
|
||||||
passwordComplexity[index].second,
|
|
||||||
selectedItem == passwordComplexity[index].first,
|
|
||||||
{ selectedItem = passwordComplexity[index].first }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
Button(
|
Button(
|
||||||
@@ -533,12 +463,11 @@ private fun PasswordComplexity() {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.require_set_new_password))
|
Text(stringResource(R.string.require_set_new_password))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DisableKeyguardFeatures() {
|
fun DisableKeyguardFeatures(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -579,10 +508,7 @@ private fun DisableKeyguardFeatures() {
|
|||||||
}
|
}
|
||||||
calculateCustomFeature()
|
calculateCustomFeature()
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.disable_keyguard_features, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.disable_keyguard_features), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
RadioButtonItem(R.string.enable_all, state == 0, { state = 0 })
|
RadioButtonItem(R.string.enable_all, state == 0, { state = 0 })
|
||||||
RadioButtonItem(R.string.disable_all, state == 1, { state = 1 })
|
RadioButtonItem(R.string.disable_all, state == 1, { state = 1 })
|
||||||
RadioButtonItem(R.string.custom, state == 2 , { state = 2 })
|
RadioButtonItem(R.string.custom, state == 2 , { state = 2 })
|
||||||
@@ -630,12 +556,11 @@ private fun DisableKeyguardFeatures() {
|
|||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.apply))
|
Text(text = stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PasswordQuality() {
|
fun PasswordQuality(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -647,15 +572,12 @@ private fun PasswordQuality() {
|
|||||||
PASSWORD_QUALITY_ALPHANUMERIC to R.string.password_quality_alphanumeric,
|
PASSWORD_QUALITY_ALPHANUMERIC to R.string.password_quality_alphanumeric,
|
||||||
PASSWORD_QUALITY_BIOMETRIC_WEAK to R.string.password_quality_biometrics_weak,
|
PASSWORD_QUALITY_BIOMETRIC_WEAK to R.string.password_quality_biometrics_weak,
|
||||||
PASSWORD_QUALITY_NUMERIC_COMPLEX to R.string.password_quality_numeric_complex
|
PASSWORD_QUALITY_NUMERIC_COMPLEX to R.string.password_quality_numeric_complex
|
||||||
).toList()
|
)
|
||||||
var selectedItem by remember { mutableIntStateOf(passwordQuality[0].first) }
|
var selectedItem by remember { mutableIntStateOf(PASSWORD_QUALITY_UNSPECIFIED) }
|
||||||
LaunchedEffect(Unit) { selectedItem=dpm.getPasswordQuality(receiver) }
|
LaunchedEffect(Unit) { selectedItem=dpm.getPasswordQuality(receiver) }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.required_password_quality, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
passwordQuality.forEach {
|
||||||
Text(text = stringResource(R.string.required_password_quality), style = typography.headlineLarge)
|
RadioButtonItem(it.value, selectedItem == it.key, { selectedItem = it.key })
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
for(index in 1..6) {
|
|
||||||
RadioButtonItem(passwordQuality[index].second, selectedItem == passwordQuality[index].first, { selectedItem = passwordQuality[index].first })
|
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
Button(
|
Button(
|
||||||
@@ -667,7 +589,6 @@ private fun PasswordQuality() {
|
|||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import android.os.RemoteException
|
|||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.*
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
@@ -23,7 +22,6 @@ import androidx.compose.material3.MaterialTheme.colorScheme
|
|||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
@@ -31,10 +29,6 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.backToHomeStateFlow
|
import com.bintianqi.owndroid.backToHomeStateFlow
|
||||||
import com.bintianqi.owndroid.ui.*
|
import com.bintianqi.owndroid.ui.*
|
||||||
@@ -44,47 +38,9 @@ import com.rosan.dhizuku.api.Dhizuku
|
|||||||
import com.rosan.dhizuku.api.DhizukuRequestPermissionListener
|
import com.rosan.dhizuku.api.DhizukuRequestPermissionListener
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun DpmPermissions(navCtrl:NavHostController) {
|
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBar(backStackEntry,navCtrl,localNavCtrl) {
|
|
||||||
if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue > 100) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.permission),
|
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl,scrollState) }
|
|
||||||
composable(route = "Shizuku") { ShizukuActivate() }
|
|
||||||
composable(route = "DeviceAdmin") { DeviceAdmin() }
|
|
||||||
composable(route = "ProfileOwner") { ProfileOwner() }
|
|
||||||
composable(route = "DeviceOwner") { DeviceOwner() }
|
|
||||||
composable(route = "DeviceInfo") { DeviceInfo() }
|
|
||||||
composable(route = "LockScreenInfo") { LockScreenInfo() }
|
|
||||||
composable(route = "SupportMsg") { SupportMsg() }
|
|
||||||
composable(route = "TransformOwnership") { TransferOwnership() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
|
fun Permissions(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -95,12 +51,7 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
|
|||||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) dpm.enrollmentSpecificId else ""
|
val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) dpm.enrollmentSpecificId else ""
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) {
|
MyScaffold(R.string.permissions, 0.dp, navCtrl) {
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.permission),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
if(!dpm.isDeviceOwnerApp(context.packageName)) {
|
if(!dpm.isDeviceOwnerApp(context.packageName)) {
|
||||||
SwitchItem(
|
SwitchItem(
|
||||||
R.string.dhizuku, "", null,
|
R.string.dhizuku, "", null,
|
||||||
@@ -109,43 +60,42 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
|
|||||||
onClickBlank = { dialog = 4 }
|
onClickBlank = { dialog = 4 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SubPageItem(
|
FunctionItem(
|
||||||
R.string.device_admin, stringResource(if(deviceAdmin) R.string.activated else R.string.deactivated),
|
R.string.device_admin, stringResource(if(deviceAdmin) R.string.activated else R.string.deactivated),
|
||||||
operation = { localNavCtrl.navigate("DeviceAdmin") }
|
operation = { navCtrl.navigate("DeviceAdmin") }
|
||||||
)
|
)
|
||||||
if(profileOwner || !userManager.isSystemUser) {
|
if(profileOwner || !userManager.isSystemUser) {
|
||||||
SubPageItem(
|
FunctionItem(
|
||||||
R.string.profile_owner, stringResource(if(profileOwner) R.string.activated else R.string.deactivated),
|
R.string.profile_owner, stringResource(if(profileOwner) R.string.activated else R.string.deactivated),
|
||||||
operation = { localNavCtrl.navigate("ProfileOwner") }
|
operation = { navCtrl.navigate("ProfileOwner") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if(!profileOwner && userManager.isSystemUser) {
|
if(!profileOwner && userManager.isSystemUser) {
|
||||||
SubPageItem(
|
FunctionItem(
|
||||||
R.string.device_owner, stringResource(if(deviceOwner) R.string.activated else R.string.deactivated),
|
R.string.device_owner, stringResource(if(deviceOwner) R.string.activated else R.string.deactivated),
|
||||||
operation = { localNavCtrl.navigate("DeviceOwner") }
|
operation = { navCtrl.navigate("DeviceOwner") }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SubPageItem(R.string.shizuku,"") { localNavCtrl.navigate("Shizuku") }
|
FunctionItem(R.string.shizuku,"") { navCtrl.navigate("Shizuku") }
|
||||||
SubPageItem(R.string.device_info, "", R.drawable.perm_device_information_fill0) { localNavCtrl.navigate("DeviceInfo") }
|
FunctionItem(R.string.device_info, "", 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)) {
|
||||||
SubPageItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { dialog = 2 }
|
FunctionItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { dialog = 2 }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) {
|
if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) {
|
||||||
SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { dialog = 3 }
|
FunctionItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { dialog = 3 }
|
||||||
}
|
}
|
||||||
if(enrollmentSpecificId != "") {
|
if(enrollmentSpecificId != "") {
|
||||||
SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { dialog = 1 }
|
FunctionItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { dialog = 1 }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 24 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.device_owner_lock_screen_info, "", R.drawable.screen_lock_portrait_fill0) { localNavCtrl.navigate("LockScreenInfo") }
|
FunctionItem(R.string.lock_screen_info, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("LockScreenInfo") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 24 && deviceAdmin) {
|
if(VERSION.SDK_INT >= 24 && deviceAdmin) {
|
||||||
SubPageItem(R.string.support_msg, "", R.drawable.chat_fill0) { localNavCtrl.navigate("SupportMsg") }
|
FunctionItem(R.string.support_messages, "", R.drawable.chat_fill0) { navCtrl.navigate("SupportMessages") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 28 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.transfer_ownership, "", R.drawable.admin_panel_settings_fill0) { localNavCtrl.navigate("TransformOwnership") }
|
FunctionItem(R.string.transfer_ownership, "", R.drawable.admin_panel_settings_fill0) { navCtrl.navigate("TransferOwnership") }
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(dialog != 0) {
|
if(dialog != 0) {
|
||||||
var input by remember { mutableStateOf("") }
|
var input by remember { mutableStateOf("") }
|
||||||
@@ -157,7 +107,7 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
|
|||||||
2 -> R.string.org_name
|
2 -> R.string.org_name
|
||||||
3 -> R.string.org_id
|
3 -> R.string.org_id
|
||||||
4 -> R.string.dhizuku
|
4 -> R.string.dhizuku
|
||||||
else -> R.string.permission
|
else -> R.string.permissions
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
@@ -176,7 +126,7 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
|
|||||||
1 -> R.string.enrollment_specific_id
|
1 -> R.string.enrollment_specific_id
|
||||||
2 -> R.string.org_name
|
2 -> R.string.org_name
|
||||||
3 -> R.string.org_id
|
3 -> R.string.org_id
|
||||||
else -> R.string.permission
|
else -> R.string.permissions
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
@@ -237,7 +187,7 @@ private fun toggleDhizukuMode(status: Boolean, context: Context) {
|
|||||||
dhizukuErrorStatus.value = 1
|
dhizukuErrorStatus.value = 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(Dhizuku.isPermissionGranted()) {
|
if(dhizukuPermissionGranted()) {
|
||||||
sharedPref.edit().putBoolean("dhizuku", true).apply()
|
sharedPref.edit().putBoolean("dhizuku", true).apply()
|
||||||
Dhizuku.init(context)
|
Dhizuku.init(context)
|
||||||
backToHomeStateFlow.value = true
|
backToHomeStateFlow.value = true
|
||||||
@@ -260,17 +210,16 @@ private fun toggleDhizukuMode(status: Boolean, context: Context) {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun LockScreenInfo() {
|
fun LockScreenInfo(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var infoText by remember { mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "") }
|
var infoText by remember { mutableStateOf(dpm.deviceOwnerLockScreenInfo?.toString() ?: "") }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.lock_screen_info, 8.dp, navCtrl) {
|
||||||
Text(text = stringResource(R.string.device_owner_lock_screen_info), style = typography.headlineLarge)
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = infoText,
|
value = infoText,
|
||||||
label = { Text(stringResource(R.string.device_owner_lock_screen_info)) },
|
label = { Text(stringResource(R.string.lock_screen_info)) },
|
||||||
onValueChange = { infoText = it },
|
onValueChange = { infoText = it },
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
|
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
|
||||||
@@ -302,15 +251,13 @@ private fun LockScreenInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DeviceAdmin() {
|
fun DeviceAdmin(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var deactivateDialog by remember { mutableStateOf(false) }
|
var deactivateDialog by remember { mutableStateOf(false) }
|
||||||
val deviceAdmin = context.isDeviceAdmin
|
val deviceAdmin = context.isDeviceAdmin
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.device_admin, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.device_admin), style = typography.headlineLarge)
|
|
||||||
Text(text = stringResource(if(context.isDeviceAdmin) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
Text(text = stringResource(if(context.isDeviceAdmin) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
AnimatedVisibility(deviceAdmin) {
|
AnimatedVisibility(deviceAdmin) {
|
||||||
@@ -361,15 +308,13 @@ private fun DeviceAdmin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ProfileOwner() {
|
fun ProfileOwner(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var deactivateDialog by remember { mutableStateOf(false) }
|
var deactivateDialog by remember { mutableStateOf(false) }
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.profile_owner, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.profile_owner), style = typography.headlineLarge)
|
|
||||||
Text(stringResource(if(profileOwner) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
Text(stringResource(if(profileOwner) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
if(VERSION.SDK_INT >= 24 && profileOwner) {
|
if(VERSION.SDK_INT >= 24 && profileOwner) {
|
||||||
@@ -416,14 +361,12 @@ private fun ProfileOwner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DeviceOwner() {
|
fun DeviceOwner(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
var deactivateDialog by remember { mutableStateOf(false) }
|
var deactivateDialog by remember { mutableStateOf(false) }
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.device_owner, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.device_owner), style = typography.headlineLarge)
|
|
||||||
Text(text = stringResource(if(deviceOwner) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
Text(text = stringResource(if(deviceOwner) R.string.activated else R.string.deactivated), style = typography.titleLarge)
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
AnimatedVisibility(deviceOwner) {
|
AnimatedVisibility(deviceOwner) {
|
||||||
@@ -488,15 +431,12 @@ private fun DeviceOwner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DeviceInfo() {
|
fun DeviceInfo(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.device_info, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.device_info), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(VERSION.SDK_INT>=34 && (context.isDeviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT>=34 && (context.isDeviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
CardItem(R.string.financed_device, dpm.isDeviceFinanced.yesOrNo)
|
CardItem(R.string.financed_device, dpm.isDeviceFinanced.yesOrNo)
|
||||||
}
|
}
|
||||||
@@ -532,7 +472,7 @@ fun DeviceInfo() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun SupportMsg() {
|
fun SupportMessages(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -543,10 +483,7 @@ private fun SupportMsg() {
|
|||||||
longMsg = dpm.getLongSupportMessage(receiver)?.toString() ?: ""
|
longMsg = dpm.getLongSupportMessage(receiver)?.toString() ?: ""
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { refreshMsg() }
|
LaunchedEffect(Unit) { refreshMsg() }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.support_messages, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.support_msg), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = shortMsg,
|
value = shortMsg,
|
||||||
label = { Text(stringResource(R.string.short_support_msg)) },
|
label = { Text(stringResource(R.string.short_support_msg)) },
|
||||||
@@ -608,22 +545,18 @@ private fun SupportMsg() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_long_support_message)
|
InfoCard(R.string.info_long_support_message)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun TransferOwnership() {
|
fun TransferOwnership(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var input by remember { mutableStateOf("") }
|
var input by remember { mutableStateOf("") }
|
||||||
val componentName = ComponentName.unflattenFromString(input)
|
val componentName = ComponentName.unflattenFromString(input)
|
||||||
var dialog by remember { mutableStateOf(false) }
|
var dialog by remember { mutableStateOf(false) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.transfer_ownership, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.transfer_ownership), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = input, onValueChange = { input = it }, label = { Text(stringResource(R.string.target_component_name)) },
|
value = input, onValueChange = { input = it }, label = { Text(stringResource(R.string.target_component_name)) },
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
|||||||
@@ -10,14 +10,12 @@ import android.os.IBinder
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.horizontalScroll
|
import androidx.compose.foundation.horizontalScroll
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.wrapContentWidth
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -34,8 +32,10 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import com.bintianqi.owndroid.IUserService
|
import com.bintianqi.owndroid.IUserService
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import rikka.shizuku.Shizuku
|
import rikka.shizuku.Shizuku
|
||||||
@@ -43,7 +43,7 @@ import rikka.shizuku.Shizuku
|
|||||||
private var waitGrantPermission = false
|
private var waitGrantPermission = false
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShizukuActivate() {
|
fun Shizuku(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -69,19 +69,14 @@ fun ShizukuActivate() {
|
|||||||
shizukuService.value = null
|
shizukuService.value = null
|
||||||
userServiceControl(context, true)
|
userServiceControl(context, true)
|
||||||
}
|
}
|
||||||
Column(
|
MyScaffold(R.string.shizuku, 0.dp, navCtrl, false) {
|
||||||
modifier = Modifier
|
AnimatedVisibility(visible = bindShizuku, modifier = Modifier.fillMaxWidth()) {
|
||||||
.fillMaxSize()
|
|
||||||
.padding(horizontal = 8.dp)
|
|
||||||
.verticalScroll(rememberScrollState()),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
AnimatedVisibility(bindShizuku) {
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
userServiceControl(context, true)
|
userServiceControl(context, true)
|
||||||
outputText = ""
|
outputText = ""
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.wrapContentWidth(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(stringResource(R.string.bind_shizuku))
|
Text(stringResource(R.string.bind_shizuku))
|
||||||
}
|
}
|
||||||
@@ -100,7 +95,8 @@ fun ShizukuActivate() {
|
|||||||
coScope.launch {
|
coScope.launch {
|
||||||
outputTextScrollState.animateScrollTo(0)
|
outputTextScrollState.animateScrollTo(0)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.check_shizuku))
|
Text(text = stringResource(R.string.check_shizuku))
|
||||||
}
|
}
|
||||||
@@ -112,7 +108,8 @@ fun ShizukuActivate() {
|
|||||||
outputTextScrollState.animateScrollTo(0)
|
outputTextScrollState.animateScrollTo(0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.list_owners))
|
Text(text = stringResource(R.string.list_owners))
|
||||||
}
|
}
|
||||||
@@ -123,7 +120,8 @@ fun ShizukuActivate() {
|
|||||||
outputTextScrollState.animateScrollTo(0)
|
outputTextScrollState.animateScrollTo(0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.list_users))
|
Text(text = stringResource(R.string.list_users))
|
||||||
}
|
}
|
||||||
@@ -134,7 +132,8 @@ fun ShizukuActivate() {
|
|||||||
outputTextScrollState.animateScrollTo(0)
|
outputTextScrollState.animateScrollTo(0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.list_accounts))
|
Text(text = stringResource(R.string.list_accounts))
|
||||||
}
|
}
|
||||||
@@ -150,7 +149,8 @@ fun ShizukuActivate() {
|
|||||||
showDeviceAdminButton = !context.isDeviceAdmin
|
showDeviceAdminButton = !context.isDeviceAdmin
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.activate_device_admin))
|
Text(text = stringResource(R.string.activate_device_admin))
|
||||||
}
|
}
|
||||||
@@ -166,7 +166,8 @@ fun ShizukuActivate() {
|
|||||||
showDeviceOwnerButton = !context.isDeviceOwner
|
showDeviceOwnerButton = !context.isDeviceOwner
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.activate_device_owner))
|
Text(text = stringResource(R.string.activate_device_owner))
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,8 @@ fun ShizukuActivate() {
|
|||||||
showOrgProfileOwnerButton = !dpm.isOrganizationOwnedDeviceWithManagedProfile
|
showOrgProfileOwnerButton = !dpm.isOrganizationOwnedDeviceWithManagedProfile
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enabled = enabled
|
enabled = enabled,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.activate_org_profile))
|
Text(text = stringResource(R.string.activate_org_profile))
|
||||||
}
|
}
|
||||||
@@ -194,10 +196,8 @@ fun ShizukuActivate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SelectionContainer(modifier = Modifier.fillMaxWidth().horizontalScroll(outputTextScrollState)) {
|
SelectionContainer(modifier = Modifier.fillMaxWidth().horizontalScroll(outputTextScrollState)) {
|
||||||
Text(text = outputText, softWrap = false, modifier = Modifier.padding(4.dp))
|
Text(text = outputText, softWrap = false, modifier = Modifier.padding(vertical = 9.dp, horizontal = 12.dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,23 +44,19 @@ import android.os.UserManager
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.List
|
import androidx.compose.material.icons.automirrored.filled.List
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
@@ -72,7 +68,6 @@ import androidx.compose.material3.IconButton
|
|||||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Switch
|
import androidx.compose.material3.Switch
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@@ -90,7 +85,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
@@ -101,10 +95,6 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.StopLockTaskModeReceiver
|
import com.bintianqi.owndroid.StopLockTaskModeReceiver
|
||||||
import com.bintianqi.owndroid.exportFile
|
import com.bintianqi.owndroid.exportFile
|
||||||
@@ -115,15 +105,14 @@ import com.bintianqi.owndroid.getFile
|
|||||||
import com.bintianqi.owndroid.prepareForNotification
|
import com.bintianqi.owndroid.prepareForNotification
|
||||||
import com.bintianqi.owndroid.selectedPackage
|
import com.bintianqi.owndroid.selectedPackage
|
||||||
import com.bintianqi.owndroid.toggle
|
import com.bintianqi.owndroid.toggle
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
|
||||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||||
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.InfoCard
|
import com.bintianqi.owndroid.ui.InfoCard
|
||||||
import com.bintianqi.owndroid.ui.Information
|
import com.bintianqi.owndroid.ui.Information
|
||||||
import com.bintianqi.owndroid.ui.ListItem
|
import com.bintianqi.owndroid.ui.ListItem
|
||||||
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
import com.bintianqi.owndroid.uriToStream
|
import com.bintianqi.owndroid.uriToStream
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -137,54 +126,9 @@ import java.util.TimeZone
|
|||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SystemManage(navCtrl: NavHostController) {
|
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBar(backStackEntry,navCtrl,localNavCtrl) {
|
|
||||||
if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue > 100) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.system),
|
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30,0)).toFloat()/80)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl, scrollState) }
|
|
||||||
composable(route = "Switches") { Switches() }
|
|
||||||
composable(route = "Keyguard") { Keyguard() }
|
|
||||||
composable(route = "EditTime") { EditTime() }
|
|
||||||
composable(route = "EditTimeZone") { EditTimeZone() }
|
|
||||||
composable(route = "PermissionPolicy") { PermissionPolicy() }
|
|
||||||
composable(route = "MTEPolicy") { MTEPolicy() }
|
|
||||||
composable(route = "NearbyStreamingPolicy") { NearbyStreamingPolicy() }
|
|
||||||
composable(route = "LockTaskMode") { LockTaskMode(navCtrl) }
|
|
||||||
composable(route = "CaCert") { CaCert() }
|
|
||||||
composable(route = "SecurityLogs") { SecurityLogs() }
|
|
||||||
composable(route = "DisableAccountManagement") { DisableAccountManagement() }
|
|
||||||
composable(route = "SystemUpdatePolicy") { SysUpdatePolicy() }
|
|
||||||
composable(route = "InstallSystemUpdate") { InstallSystemUpdate() }
|
|
||||||
composable(route = "WipeData") { WipeData() }
|
|
||||||
composable(route = "FRP") { FactoryResetProtection() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun Home(navCtrl: NavHostController, scrollState: ScrollState) {
|
fun SystemManage(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -194,60 +138,54 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState) {
|
|||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
|
MyScaffold(R.string.system, 0.dp, navCtrl) {
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.system),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
if(deviceOwner || profileOwner) {
|
if(deviceOwner || profileOwner) {
|
||||||
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Switches") }
|
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("SystemOptions") }
|
||||||
}
|
}
|
||||||
SubPageItem(R.string.keyguard, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("Keyguard") }
|
FunctionItem(R.string.keyguard, "", R.drawable.screen_lock_portrait_fill0) { navCtrl.navigate("Keyguard") }
|
||||||
if(VERSION.SDK_INT >= 24 && deviceOwner) {
|
if(VERSION.SDK_INT >= 24 && deviceOwner) {
|
||||||
SubPageItem(R.string.reboot, "", R.drawable.restart_alt_fill0) { dialog = 1 }
|
FunctionItem(R.string.reboot, "", R.drawable.restart_alt_fill0) { dialog = 1 }
|
||||||
}
|
}
|
||||||
if(deviceOwner && ((VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser) || VERSION.SDK_INT >= 24)) {
|
if(deviceOwner && ((VERSION.SDK_INT >= 28 && dpm.isAffiliatedUser) || VERSION.SDK_INT >= 24)) {
|
||||||
SubPageItem(R.string.bug_report, "", R.drawable.bug_report_fill0) { dialog = 2 }
|
FunctionItem(R.string.bug_report, "", R.drawable.bug_report_fill0) { dialog = 2 }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 28 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.change_time, "", R.drawable.schedule_fill0) { navCtrl.navigate("EditTime") }
|
FunctionItem(R.string.change_time, "", R.drawable.schedule_fill0) { navCtrl.navigate("ChangeTime") }
|
||||||
SubPageItem(R.string.change_timezone, "", R.drawable.schedule_fill0) { navCtrl.navigate("EditTimeZone") }
|
FunctionItem(R.string.change_timezone, "", R.drawable.schedule_fill0) { navCtrl.navigate("ChangeTimeZone") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.permission_policy, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionPolicy") }
|
FunctionItem(R.string.permission_policy, "", R.drawable.key_fill0) { navCtrl.navigate("PermissionPolicy") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 34 && deviceOwner) {
|
if(VERSION.SDK_INT >= 34 && deviceOwner) {
|
||||||
SubPageItem(R.string.mte_policy, "", R.drawable.memory_fill0) { navCtrl.navigate("MTEPolicy") }
|
FunctionItem(R.string.mte_policy, "", R.drawable.memory_fill0) { navCtrl.navigate("MTEPolicy") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.nearby_streaming_policy, "", R.drawable.share_fill0) { navCtrl.navigate("NearbyStreamingPolicy") }
|
FunctionItem(R.string.nearby_streaming_policy, "", R.drawable.share_fill0) { navCtrl.navigate("NearbyStreamingPolicy") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
||||||
SubPageItem(R.string.lock_task_mode, "", R.drawable.lock_fill0) { navCtrl.navigate("LockTaskMode") }
|
FunctionItem(R.string.lock_task_mode, "", R.drawable.lock_fill0) { navCtrl.navigate("LockTaskMode") }
|
||||||
}
|
}
|
||||||
if(deviceOwner || profileOwner) {
|
if(deviceOwner || profileOwner) {
|
||||||
SubPageItem(R.string.ca_cert, "", R.drawable.license_fill0) { navCtrl.navigate("CaCert") }
|
FunctionItem(R.string.ca_cert, "", R.drawable.license_fill0) { navCtrl.navigate("CACert") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 26 && !dhizuku && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 26 && !dhizuku && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.security_logs, "", R.drawable.description_fill0) { navCtrl.navigate("SecurityLogs") }
|
FunctionItem(R.string.security_logging, "", R.drawable.description_fill0) { navCtrl.navigate("SecurityLogging") }
|
||||||
}
|
}
|
||||||
if(deviceOwner || profileOwner) {
|
if(deviceOwner || profileOwner) {
|
||||||
SubPageItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { navCtrl.navigate("DisableAccountManagement") }
|
FunctionItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { navCtrl.navigate("DisableAccountManagement") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 23 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 23 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.system_update_policy, "", R.drawable.system_update_fill0) { navCtrl.navigate("SystemUpdatePolicy") }
|
FunctionItem(R.string.system_update_policy, "", R.drawable.system_update_fill0) { navCtrl.navigate("SystemUpdatePolicy") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 29 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 29 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.install_system_update, "", R.drawable.system_update_fill0) { navCtrl.navigate("InstallSystemUpdate") }
|
FunctionItem(R.string.install_system_update, "", R.drawable.system_update_fill0) { navCtrl.navigate("InstallSystemUpdate") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 30 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
if(VERSION.SDK_INT >= 30 && (deviceOwner || dpm.isOrgProfile(receiver))) {
|
||||||
SubPageItem(R.string.frp_policy, "", R.drawable.device_reset_fill0) { navCtrl.navigate("FRP") }
|
FunctionItem(R.string.frp_policy, "", R.drawable.device_reset_fill0) { navCtrl.navigate("FRPPolicy") }
|
||||||
}
|
}
|
||||||
if(dangerousFeatures && context.isDeviceAdmin && !(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver))) {
|
if(dangerousFeatures && context.isDeviceAdmin && !(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver))) {
|
||||||
SubPageItem(R.string.wipe_data, "", R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") }
|
FunctionItem(R.string.wipe_data, "", R.drawable.device_reset_fill0) { navCtrl.navigate("WipeData") }
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
||||||
}
|
}
|
||||||
if(dialog != 0) AlertDialog(
|
if(dialog != 0) AlertDialog(
|
||||||
@@ -279,7 +217,7 @@ private fun Home(navCtrl: NavHostController, scrollState: ScrollState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Switches() {
|
fun SystemOptions(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -287,8 +225,7 @@ private fun Switches() {
|
|||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
val um = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val um = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.options, 0.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(deviceOwner || profileOwner) {
|
if(deviceOwner || profileOwner) {
|
||||||
SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0,
|
SwitchItem(R.string.disable_cam,"", R.drawable.photo_camera_fill0,
|
||||||
{ dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) }
|
{ dpm.getCameraDisabled(null) }, { dpm.setCameraDisabled(receiver,it) }
|
||||||
@@ -344,7 +281,6 @@ private fun Switches() {
|
|||||||
{ dpm.isUsbDataSignalingEnabled = !it },
|
{ dpm.isUsbDataSignalingEnabled = !it },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(dialog != 0) AlertDialog(
|
if(dialog != 0) AlertDialog(
|
||||||
text = {
|
text = {
|
||||||
@@ -364,17 +300,14 @@ private fun Switches() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Keyguard() {
|
fun Keyguard(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.keyguard, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
if(VERSION.SDK_INT >= 23) {
|
if(VERSION.SDK_INT >= 23) {
|
||||||
Text(text = stringResource(R.string.keyguard), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
@@ -401,7 +334,7 @@ private fun Keyguard() {
|
|||||||
InfoCard(R.string.info_disable_keyguard)
|
InfoCard(R.string.info_disable_keyguard)
|
||||||
Spacer(Modifier.padding(vertical = 12.dp))
|
Spacer(Modifier.padding(vertical = 12.dp))
|
||||||
}
|
}
|
||||||
Text(text = stringResource(R.string.lock_now), style = typography.headlineLarge)
|
if(VERSION.SDK_INT >= 23) Text(text = stringResource(R.string.lock_now), style = typography.headlineLarge)
|
||||||
Spacer(Modifier.padding(vertical = 2.dp))
|
Spacer(Modifier.padding(vertical = 2.dp))
|
||||||
var flag by remember { mutableIntStateOf(0) }
|
var flag by remember { mutableIntStateOf(0) }
|
||||||
if(VERSION.SDK_INT >= 26 && profileOwner && dpm.isManagedProfile(receiver)) {
|
if(VERSION.SDK_INT >= 26 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
@@ -424,22 +357,18 @@ private fun Keyguard() {
|
|||||||
if(VERSION.SDK_INT >= 26 && profileOwner && dpm.isManagedProfile(receiver)) {
|
if(VERSION.SDK_INT >= 26 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||||
InfoCard(R.string.info_evict_credential_encryption_key)
|
InfoCard(R.string.info_evict_credential_encryption_key)
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun EditTime() {
|
fun ChangeTime(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var inputTime by remember { mutableStateOf("") }
|
var inputTime by remember { mutableStateOf("") }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.change_time, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.change_time), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = inputTime,
|
value = inputTime,
|
||||||
label = { Text(stringResource(R.string.time_unit_ms)) },
|
label = { Text(stringResource(R.string.time_unit_ms)) },
|
||||||
@@ -459,22 +388,17 @@ private fun EditTime() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun EditTimeZone() {
|
fun ChangeTimeZone(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
var inputTimezone by remember { mutableStateOf("") }
|
var inputTimezone by remember { mutableStateOf("") }
|
||||||
var dialog by remember { mutableStateOf(false) }
|
var dialog by remember { mutableStateOf(false) }
|
||||||
Column(
|
MyScaffold(R.string.change_timezone, 8.dp, navCtrl) {
|
||||||
modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState()),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.change_timezone), style = typography.headlineLarge, modifier = Modifier.align(Alignment.Start))
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = inputTimezone,
|
value = inputTimezone,
|
||||||
label = { Text(stringResource(R.string.timezone_id)) },
|
label = { Text(stringResource(R.string.timezone_id)) },
|
||||||
@@ -533,15 +457,12 @@ private fun EditTimeZone() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun PermissionPolicy() {
|
fun PermissionPolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
var selectedPolicy by remember { mutableIntStateOf(dpm.getPermissionPolicy(receiver)) }
|
||||||
var selectedPolicy by remember { mutableIntStateOf(dpm.getPermissionPolicy(receiver)) }
|
MyScaffold(R.string.permission_policy, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.permission_policy), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
RadioButtonItem(R.string.default_stringres, selectedPolicy == PERMISSION_POLICY_PROMPT, { selectedPolicy = PERMISSION_POLICY_PROMPT })
|
RadioButtonItem(R.string.default_stringres, selectedPolicy == PERMISSION_POLICY_PROMPT, { selectedPolicy = PERMISSION_POLICY_PROMPT })
|
||||||
RadioButtonItem(R.string.auto_grant, selectedPolicy == PERMISSION_POLICY_AUTO_GRANT, { selectedPolicy = PERMISSION_POLICY_AUTO_GRANT })
|
RadioButtonItem(R.string.auto_grant, selectedPolicy == PERMISSION_POLICY_AUTO_GRANT, { selectedPolicy = PERMISSION_POLICY_AUTO_GRANT })
|
||||||
RadioButtonItem(R.string.auto_deny, selectedPolicy == PERMISSION_POLICY_AUTO_DENY, { selectedPolicy = PERMISSION_POLICY_AUTO_DENY })
|
RadioButtonItem(R.string.auto_deny, selectedPolicy == PERMISSION_POLICY_AUTO_DENY, { selectedPolicy = PERMISSION_POLICY_AUTO_DENY })
|
||||||
@@ -561,14 +482,11 @@ private fun PermissionPolicy() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun MTEPolicy() {
|
fun MTEPolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
var selectedMtePolicy by remember { mutableIntStateOf(dpm.mtePolicy) }
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
MyScaffold(R.string.mte_policy, 8.dp, navCtrl) {
|
||||||
Text(text = stringResource(R.string.mte_policy), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
var selectedMtePolicy by remember { mutableIntStateOf(dpm.mtePolicy) }
|
|
||||||
RadioButtonItem(
|
RadioButtonItem(
|
||||||
R.string.decide_by_user,
|
R.string.decide_by_user,
|
||||||
selectedMtePolicy == MTE_NOT_CONTROLLED_BY_POLICY,
|
selectedMtePolicy == MTE_NOT_CONTROLLED_BY_POLICY,
|
||||||
@@ -599,17 +517,16 @@ private fun MTEPolicy() {
|
|||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_mte_policy)
|
InfoCard(R.string.info_mte_policy)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun NearbyStreamingPolicy() {
|
fun NearbyStreamingPolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
var appPolicy by remember { mutableIntStateOf(dpm.nearbyAppStreamingPolicy) }
|
||||||
var appPolicy by remember { mutableIntStateOf(dpm.nearbyAppStreamingPolicy) }
|
MyScaffold(R.string.nearby_streaming_policy, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
Spacer(Modifier.padding(vertical = 10.dp))
|
||||||
Text(text = stringResource(R.string.nearby_app_streaming), style = typography.titleLarge)
|
Text(text = stringResource(R.string.nearby_app_streaming), style = typography.titleLarge)
|
||||||
Spacer(Modifier.padding(vertical = 3.dp))
|
Spacer(Modifier.padding(vertical = 3.dp))
|
||||||
@@ -679,20 +596,19 @@ private fun NearbyStreamingPolicy() {
|
|||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_nearby_notification_streaming_policy)
|
InfoCard(R.string.info_nearby_notification_streaming_policy)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun LockTaskMode(navCtrl: NavHostController) {
|
fun LockTaskMode(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
val coroutine = rememberCoroutineScope()
|
val coroutine = rememberCoroutineScope()
|
||||||
var appSelectorRequest by rememberSaveable { mutableIntStateOf(0) }
|
var appSelectorRequest by rememberSaveable { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.lock_task_mode, 8.dp, navCtrl, false) {
|
||||||
val lockTaskFeatures = remember { mutableStateListOf<Int>() }
|
val lockTaskFeatures = remember { mutableStateListOf<Int>() }
|
||||||
var custom by rememberSaveable { mutableStateOf(false) }
|
var custom by rememberSaveable { mutableStateOf(false) }
|
||||||
val refreshFeature = {
|
val refreshFeature = {
|
||||||
@@ -710,7 +626,7 @@ private fun LockTaskMode(navCtrl: NavHostController) {
|
|||||||
}
|
}
|
||||||
if(calculate - 1 >= 0) { lockTaskFeatures += 1 }
|
if(calculate - 1 >= 0) { lockTaskFeatures += 1 }
|
||||||
custom = true
|
custom = true
|
||||||
}else{
|
} else {
|
||||||
custom = false
|
custom = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -803,7 +719,7 @@ private fun LockTaskMode(navCtrl: NavHostController) {
|
|||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(50))
|
.clip(RoundedCornerShape(50))
|
||||||
.clickable(onClick = {
|
.clickable(onClick = {
|
||||||
@@ -865,7 +781,7 @@ private fun LockTaskMode(navCtrl: NavHostController) {
|
|||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||||
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
|
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(RoundedCornerShape(50))
|
.clip(RoundedCornerShape(50))
|
||||||
.clickable(onClick = {
|
.clickable(onClick = {
|
||||||
@@ -915,12 +831,11 @@ private fun LockTaskMode(navCtrl: NavHostController) {
|
|||||||
Text(stringResource(R.string.start))
|
Text(stringResource(R.string.start))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_start_lock_task_mode)
|
InfoCard(R.string.info_start_lock_task_mode)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CaCert() {
|
fun CACert(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -941,10 +856,7 @@ private fun CaCert() {
|
|||||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.ca_cert, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.ca_cert), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
AnimatedVisibility(uriPath != "") {
|
AnimatedVisibility(uriPath != "") {
|
||||||
Text(text = uriPath)
|
Text(text = uriPath)
|
||||||
}
|
}
|
||||||
@@ -1004,7 +916,7 @@ private fun CaCert() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun SecurityLogs() {
|
fun SecurityLogging(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -1013,10 +925,7 @@ private fun SecurityLogs() {
|
|||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
fileSize = logFile.length()
|
fileSize = logFile.length()
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.security_logging, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.security_logs), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
SwitchItem(R.string.enable, "", null, { dpm.isSecurityLoggingEnabled(receiver) }, { dpm.setSecurityLoggingEnabled(receiver, it) }, padding = false)
|
SwitchItem(R.string.enable, "", null, { dpm.isSecurityLoggingEnabled(receiver) }, { dpm.setSecurityLoggingEnabled(receiver, it) }, padding = false)
|
||||||
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
|
Text(stringResource(R.string.log_file_size_is, formatFileSize(fileSize)))
|
||||||
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = Modifier.fillMaxWidth()) {
|
||||||
@@ -1087,21 +996,18 @@ private fun SecurityLogs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun DisableAccountManagement() {
|
fun DisableAccountManagement(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
|
MyScaffold(R.string.disable_account_management, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.disable_account_management), style = typography.headlineLarge)
|
|
||||||
val list = remember { mutableStateListOf<String>() }
|
val list = remember { mutableStateListOf<String>() }
|
||||||
fun refreshList() {
|
fun refreshList() {
|
||||||
list.clear()
|
list.clear()
|
||||||
dpm.accountTypesWithManagementDisabled?.forEach { list += it }
|
dpm.accountTypesWithManagementDisabled?.forEach { list += it }
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { refreshList() }
|
LaunchedEffect(Unit) { refreshList() }
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Column(modifier = Modifier.animateContentSize()) {
|
Column(modifier = Modifier.animateContentSize()) {
|
||||||
if(list.isEmpty()) Text(stringResource(R.string.none))
|
if(list.isEmpty()) Text(stringResource(R.string.none))
|
||||||
for(i in list) {
|
for(i in list) {
|
||||||
@@ -1139,7 +1045,7 @@ private fun DisableAccountManagement() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
fun FactoryResetProtection() {
|
fun FRPPolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
@@ -1165,12 +1071,7 @@ fun FactoryResetProtection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.frp_policy, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.frp_policy), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 3.dp))
|
|
||||||
Text(stringResource(R.string.factory_reset_protection_policy))
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically,
|
horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.fillMaxWidth().padding(horizontal = 6.dp, vertical = 8.dp)
|
modifier = Modifier.fillMaxWidth().padding(horizontal = 6.dp, vertical = 8.dp)
|
||||||
@@ -1231,13 +1132,12 @@ fun FactoryResetProtection() {
|
|||||||
if(unsupported) Text(stringResource(R.string.frp_policy_not_supported))
|
if(unsupported) Text(stringResource(R.string.frp_policy_not_supported))
|
||||||
Spacer(Modifier.padding(vertical = 6.dp))
|
Spacer(Modifier.padding(vertical = 6.dp))
|
||||||
InfoCard(R.string.info_frp_policy)
|
InfoCard(R.string.info_frp_policy)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun WipeData() {
|
fun WipeData(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
@@ -1249,14 +1149,7 @@ private fun WipeData() {
|
|||||||
var euicc by remember { mutableStateOf(false) }
|
var euicc by remember { mutableStateOf(false) }
|
||||||
var silent by remember { mutableStateOf(false) }
|
var silent by remember { mutableStateOf(false) }
|
||||||
var reason by remember { mutableStateOf("") }
|
var reason by remember { mutableStateOf("") }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.wipe_data, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.wipe_data),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(6.dp),color = colorScheme.error
|
|
||||||
)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
CheckBoxItem(
|
CheckBoxItem(
|
||||||
R.string.wipe_external_storage,
|
R.string.wipe_external_storage,
|
||||||
externalStorage, { externalStorage = it }
|
externalStorage, { externalStorage = it }
|
||||||
@@ -1302,7 +1195,6 @@ private fun WipeData() {
|
|||||||
Text("WipeDevice")
|
Text("WipeDevice")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(warning) {
|
if(warning) {
|
||||||
LaunchedEffect(Unit) { silent = reason == "" }
|
LaunchedEffect(Unit) { silent = reason == "" }
|
||||||
@@ -1360,18 +1252,15 @@ private fun WipeData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun SysUpdatePolicy() {
|
fun SystemUpdatePolicy(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.system_update_policy, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
if(VERSION.SDK_INT >= 23) {
|
if(VERSION.SDK_INT >= 23) {
|
||||||
Column {
|
Column {
|
||||||
var selectedPolicy by remember { mutableStateOf(dpm.systemUpdatePolicy?.policyType) }
|
var selectedPolicy by remember { mutableStateOf(dpm.systemUpdatePolicy?.policyType) }
|
||||||
Text(text = stringResource(R.string.system_update_policy), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
RadioButtonItem(
|
RadioButtonItem(
|
||||||
R.string.system_update_policy_automatic,
|
R.string.system_update_policy_automatic,
|
||||||
selectedPolicy == TYPE_INSTALL_AUTOMATIC, { selectedPolicy = TYPE_INSTALL_AUTOMATIC }
|
selectedPolicy == TYPE_INSTALL_AUTOMATIC, { selectedPolicy = TYPE_INSTALL_AUTOMATIC }
|
||||||
@@ -1447,13 +1336,12 @@ private fun SysUpdatePolicy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
fun InstallSystemUpdate() {
|
fun InstallSystemUpdate(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -1472,10 +1360,7 @@ fun InstallSystemUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val uri by fileUriFlow.collectAsState()
|
val uri by fileUriFlow.collectAsState()
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.install_system_update, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.install_system_update), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||||
@@ -1508,10 +1393,7 @@ fun InstallSystemUpdate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
Spacer(Modifier.padding(vertical = 10.dp))
|
||||||
Information {
|
InfoCard(R.string.auto_reboot_after_install_succeed)
|
||||||
Text(stringResource(R.string.auto_reboot_after_install_succeed))
|
|
||||||
}
|
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,34 +6,20 @@ import android.os.UserManager
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
|
|
||||||
data class Restriction(
|
data class Restriction(
|
||||||
val id: String,
|
val id: String,
|
||||||
@@ -42,92 +28,29 @@ data class Restriction(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserRestriction(navCtrl: NavHostController) {
|
fun UserRestriction(navCtrl:NavHostController) {
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
/*val titleMap = mapOf(
|
|
||||||
"Internet" to R.string.network_internet,
|
|
||||||
"Connectivity" to R.string.more_connectivity,
|
|
||||||
"Users" to R.string.users,
|
|
||||||
"Media" to R.string.media,
|
|
||||||
"Applications" to R.string.applications,
|
|
||||||
"Other" to R.string.other
|
|
||||||
)*/
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
/*TopAppBar(
|
|
||||||
title = {Text(text = stringResource(titleMap[backStackEntry?.destination?.route]?:R.string.user_restrict))},
|
|
||||||
navigationIcon = {NavIcon{if(backStackEntry?.destination?.route=="Home"){navCtrl.navigateUp()}else{localNavCtrl.navigateUp()}}},
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.surfaceVariant)
|
|
||||||
)*/
|
|
||||||
TopBar(backStackEntry,navCtrl,localNavCtrl){
|
|
||||||
if(backStackEntry?.destination?.route=="Home"&&scrollState.maxValue>80){
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.user_restrict),
|
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl, scrollState) }
|
|
||||||
composable(route = "Internet") { UserRestrictionPage(RestrictionData.internet()) }
|
|
||||||
composable(route = "Connectivity") { UserRestrictionPage(RestrictionData.connectivity())}
|
|
||||||
composable(route = "Applications") { UserRestrictionPage(RestrictionData.connectivity()) }
|
|
||||||
composable(route = "Users") { UserRestrictionPage(RestrictionData.user()) }
|
|
||||||
composable(route = "Media") { UserRestrictionPage(RestrictionData.media()) }
|
|
||||||
composable(route = "Other") { UserRestrictionPage(RestrictionData.other()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
|
MyScaffold(R.string.user_restriction, 0.dp, navCtrl) {
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.user_restrict),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 7.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
|
Text(text = stringResource(R.string.switch_to_disable_feature), modifier = Modifier.padding(start = 16.dp))
|
||||||
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
|
if(context.isProfileOwner) { Text(text = stringResource(R.string.profile_owner_is_restricted), modifier = Modifier.padding(start = 16.dp)) }
|
||||||
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
if(context.isProfileOwner && (VERSION.SDK_INT < 24 || (VERSION.SDK_INT >= 24 && dpm.isManagedProfile(receiver)))) {
|
||||||
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
|
Text(text = stringResource(R.string.some_features_invalid_in_work_profile), modifier = Modifier.padding(start = 16.dp))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 2.dp))
|
Spacer(Modifier.padding(vertical = 2.dp))
|
||||||
SubPageItem(R.string.network_internet, "", R.drawable.wifi_fill0) { navCtrl.navigate("Internet") }
|
FunctionItem(R.string.network_and_internet, "", R.drawable.wifi_fill0) { navCtrl.navigate("UR-Internet") }
|
||||||
SubPageItem(R.string.more_connectivity, "", R.drawable.devices_other_fill0) { navCtrl.navigate("Connectivity") }
|
FunctionItem(R.string.connectivity, "", R.drawable.devices_other_fill0) { navCtrl.navigate("UR-Connectivity") }
|
||||||
SubPageItem(R.string.applications, "", R.drawable.apps_fill0) { navCtrl.navigate("Applications") }
|
FunctionItem(R.string.applications, "", R.drawable.apps_fill0) { navCtrl.navigate("UR-Applications") }
|
||||||
SubPageItem(R.string.users, "", R.drawable.account_circle_fill0) { navCtrl.navigate("Users") }
|
FunctionItem(R.string.users, "", R.drawable.account_circle_fill0) { navCtrl.navigate("UR-Users") }
|
||||||
SubPageItem(R.string.media, "", R.drawable.volume_up_fill0) { navCtrl.navigate("Media") }
|
FunctionItem(R.string.media, "", R.drawable.volume_up_fill0) { navCtrl.navigate("UR-Media") }
|
||||||
SubPageItem(R.string.other, "", R.drawable.more_horiz_fill0) { navCtrl.navigate("Other") }
|
FunctionItem(R.string.other, "", R.drawable.more_horiz_fill0) { navCtrl.navigate("UR-Other") }
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun UserRestrictionPage(restrictions: List<Restriction>) {
|
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
|
||||||
restrictions.forEach { UserRestrictionItem(it) }
|
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserRestrictionItem(restriction: Restriction) {
|
fun UserRestrictionItem(restriction: Restriction) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -153,7 +76,7 @@ private fun UserRestrictionItem(restriction: Restriction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object RestrictionData {
|
object RestrictionData {
|
||||||
fun internet(): List<Restriction> {
|
val internet: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
list += Restriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, R.string.config_mobile_network, R.drawable.signal_cellular_alt_fill0)
|
list += Restriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, R.string.config_mobile_network, R.drawable.signal_cellular_alt_fill0)
|
||||||
list += Restriction(UserManager.DISALLOW_CONFIG_WIFI, R.string.config_wifi, R.drawable.wifi_fill0)
|
list += Restriction(UserManager.DISALLOW_CONFIG_WIFI, R.string.config_wifi, R.drawable.wifi_fill0)
|
||||||
@@ -179,7 +102,7 @@ object RestrictionData {
|
|||||||
list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS, R.string.outgoing_calls, R.drawable.phone_forwarded_fill0)
|
list += Restriction(UserManager.DISALLOW_OUTGOING_CALLS, R.string.outgoing_calls, R.drawable.phone_forwarded_fill0)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun connectivity(): List<Restriction> {
|
val connectivity: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
if(VERSION.SDK_INT>=26) {
|
if(VERSION.SDK_INT>=26) {
|
||||||
list += Restriction(UserManager.DISALLOW_BLUETOOTH, R.string.bluetooth, R.drawable.bluetooth_fill0)
|
list += Restriction(UserManager.DISALLOW_BLUETOOTH, R.string.bluetooth, R.drawable.bluetooth_fill0)
|
||||||
@@ -193,7 +116,7 @@ object RestrictionData {
|
|||||||
if(VERSION.SDK_INT>=28) list += Restriction(UserManager.DISALLOW_PRINTING, R.string.printing, R.drawable.print_fill0)
|
if(VERSION.SDK_INT>=28) list += Restriction(UserManager.DISALLOW_PRINTING, R.string.printing, R.drawable.print_fill0)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun application(): List<Restriction> {
|
val applications: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
list += Restriction(UserManager.DISALLOW_INSTALL_APPS, R.string.install_app, R.drawable.android_fill0)
|
list += Restriction(UserManager.DISALLOW_INSTALL_APPS, R.string.install_app, R.drawable.android_fill0)
|
||||||
if(VERSION.SDK_INT>=29) list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, R.string.install_unknown_src_globally, R.drawable.android_fill0)
|
if(VERSION.SDK_INT>=29) list += Restriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, R.string.install_unknown_src_globally, R.drawable.android_fill0)
|
||||||
@@ -203,7 +126,7 @@ object RestrictionData {
|
|||||||
if(VERSION.SDK_INT>=34) list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, R.string.config_default_apps, R.drawable.apps_fill0)
|
if(VERSION.SDK_INT>=34) list += Restriction(UserManager.DISALLOW_CONFIG_DEFAULT_APPS, R.string.config_default_apps, R.drawable.apps_fill0)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun media(): List<Restriction> {
|
val media: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
if(VERSION.SDK_INT>=28) {
|
if(VERSION.SDK_INT>=28) {
|
||||||
list += Restriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, R.string.config_brightness, R.drawable.brightness_5_fill0)
|
list += Restriction(UserManager.DISALLOW_CONFIG_BRIGHTNESS, R.string.config_brightness, R.drawable.brightness_5_fill0)
|
||||||
@@ -218,7 +141,7 @@ object RestrictionData {
|
|||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun user(): List<Restriction> {
|
val users: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
list += Restriction(UserManager.DISALLOW_ADD_USER, R.string.add_user, R.drawable.account_circle_fill0)
|
list += Restriction(UserManager.DISALLOW_ADD_USER, R.string.add_user, R.drawable.account_circle_fill0)
|
||||||
list += Restriction(UserManager.DISALLOW_REMOVE_USER, R.string.remove_user, R.drawable.account_circle_fill0)
|
list += Restriction(UserManager.DISALLOW_REMOVE_USER, R.string.remove_user, R.drawable.account_circle_fill0)
|
||||||
@@ -231,7 +154,7 @@ object RestrictionData {
|
|||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun other(): List<Restriction> {
|
val other: List<Restriction> get() {
|
||||||
val list = mutableListOf<Restriction>()
|
val list = mutableListOf<Restriction>()
|
||||||
if(VERSION.SDK_INT>=26) list += Restriction(UserManager.DISALLOW_AUTOFILL, R.string.autofill, R.drawable.password_fill0)
|
if(VERSION.SDK_INT>=26) list += Restriction(UserManager.DISALLOW_AUTOFILL, R.string.autofill, R.drawable.password_fill0)
|
||||||
list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS, R.string.config_credentials, R.drawable.android_fill0)
|
list += Restriction(UserManager.DISALLOW_CONFIG_CREDENTIALS, R.string.config_credentials, R.drawable.android_fill0)
|
||||||
@@ -254,14 +177,7 @@ object RestrictionData {
|
|||||||
list += Restriction(UserManager.DISALLOW_DEBUGGING_FEATURES, R.string.debug_features, R.drawable.adb_fill0)
|
list += Restriction(UserManager.DISALLOW_DEBUGGING_FEATURES, R.string.debug_features, R.drawable.adb_fill0)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
fun getAllRestrictions(): List<String> {
|
fun getAllRestrictions(): List<Restriction> =
|
||||||
val result = mutableListOf<String>()
|
internet + connectivity + media + applications + users + other
|
||||||
internet().forEach { result.add(it.id) }
|
|
||||||
connectivity().forEach { result.add(it.id) }
|
|
||||||
media().forEach { result.add(it.id) }
|
|
||||||
application().forEach { result.add(it.id) }
|
|
||||||
user().forEach { result.add(it.id) }
|
|
||||||
other().forEach { result.add(it.id) }
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,20 +18,16 @@ import androidx.annotation.StringRes
|
|||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.animateContentSize
|
import androidx.compose.animation.animateContentSize
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.ScrollState
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
@@ -39,9 +35,7 @@ import androidx.compose.material3.Button
|
|||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -55,7 +49,6 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
@@ -65,106 +58,56 @@ import androidx.compose.ui.text.input.ImeAction
|
|||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.fileUriFlow
|
import com.bintianqi.owndroid.fileUriFlow
|
||||||
import com.bintianqi.owndroid.getFile
|
import com.bintianqi.owndroid.getFile
|
||||||
import com.bintianqi.owndroid.parseTimestamp
|
import com.bintianqi.owndroid.parseTimestamp
|
||||||
import com.bintianqi.owndroid.toggle
|
import com.bintianqi.owndroid.toggle
|
||||||
import com.bintianqi.owndroid.ui.Animations
|
|
||||||
import com.bintianqi.owndroid.ui.CardItem
|
import com.bintianqi.owndroid.ui.CardItem
|
||||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||||
|
import com.bintianqi.owndroid.ui.FunctionItem
|
||||||
import com.bintianqi.owndroid.ui.InfoCard
|
import com.bintianqi.owndroid.ui.InfoCard
|
||||||
import com.bintianqi.owndroid.ui.ListItem
|
import com.bintianqi.owndroid.ui.ListItem
|
||||||
import com.bintianqi.owndroid.ui.SubPageItem
|
import com.bintianqi.owndroid.ui.MyScaffold
|
||||||
import com.bintianqi.owndroid.ui.SwitchItem
|
import com.bintianqi.owndroid.ui.SwitchItem
|
||||||
import com.bintianqi.owndroid.ui.TopBar
|
|
||||||
import com.bintianqi.owndroid.uriToStream
|
import com.bintianqi.owndroid.uriToStream
|
||||||
import com.bintianqi.owndroid.yesOrNo
|
import com.bintianqi.owndroid.yesOrNo
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserManage(navCtrl: NavHostController) {
|
fun Users(navCtrl: NavHostController) {
|
||||||
val localNavCtrl = rememberNavController()
|
|
||||||
val backStackEntry by localNavCtrl.currentBackStackEntryAsState()
|
|
||||||
val scrollState = rememberScrollState()
|
|
||||||
Scaffold(
|
|
||||||
topBar = {
|
|
||||||
TopBar(backStackEntry, navCtrl, localNavCtrl) {
|
|
||||||
if(backStackEntry?.destination?.route == "Home" && scrollState.maxValue > 100) {
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.users),
|
|
||||||
modifier = Modifier.alpha((maxOf(scrollState.value-30, 0)).toFloat() / 80)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
navController = localNavCtrl, startDestination = "Home",
|
|
||||||
enterTransition = Animations.navHostEnterTransition,
|
|
||||||
exitTransition = Animations.navHostExitTransition,
|
|
||||||
popEnterTransition = Animations.navHostPopEnterTransition,
|
|
||||||
popExitTransition = Animations.navHostPopExitTransition,
|
|
||||||
modifier = Modifier.padding(top = it.calculateTopPadding())
|
|
||||||
) {
|
|
||||||
composable(route = "Home") { Home(localNavCtrl, scrollState) }
|
|
||||||
composable(route = "UserInfo") { CurrentUserInfo() }
|
|
||||||
composable(route = "Options") { Options() }
|
|
||||||
composable(route = "UserOperation") { UserOperation() }
|
|
||||||
composable(route = "CreateUser") { CreateUser() }
|
|
||||||
composable(route = "EditUsername") { Username() }
|
|
||||||
composable(route = "ChangeUserIcon") { UserIcon() }
|
|
||||||
composable(route = "UserSessionMessage") { UserSessionMessage() }
|
|
||||||
composable(route = "AffiliationID") { AffiliationID() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Home(navCtrl: NavHostController,scrollState: ScrollState) {
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val deviceOwner = context.isDeviceOwner
|
val deviceOwner = context.isDeviceOwner
|
||||||
val profileOwner = context.isProfileOwner
|
val profileOwner = context.isProfileOwner
|
||||||
//var logoutDialog by remember { mutableStateOf(false) }
|
|
||||||
var dialog by remember { mutableIntStateOf(0) }
|
var dialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(scrollState)) {
|
MyScaffold(R.string.users, 0.dp, navCtrl) {
|
||||||
Text(
|
FunctionItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") }
|
||||||
text = stringResource(R.string.users),
|
|
||||||
style = typography.headlineLarge,
|
|
||||||
modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 16.dp)
|
|
||||||
)
|
|
||||||
SubPageItem(R.string.user_info, "", R.drawable.person_fill0) { navCtrl.navigate("UserInfo") }
|
|
||||||
if(deviceOwner && VERSION.SDK_INT >= 28) {
|
if(deviceOwner && VERSION.SDK_INT >= 28) {
|
||||||
SubPageItem(R.string.secondary_users, "", R.drawable.list_fill0) { dialog = 1 }
|
FunctionItem(R.string.secondary_users, "", R.drawable.list_fill0) { dialog = 1 }
|
||||||
SubPageItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
|
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("UserOptions") }
|
||||||
}
|
}
|
||||||
if(deviceOwner) {
|
if(deviceOwner) {
|
||||||
SubPageItem(R.string.user_operation, "", R.drawable.sync_alt_fill0) { navCtrl.navigate("UserOperation") }
|
FunctionItem(R.string.user_operation, "", R.drawable.sync_alt_fill0) { navCtrl.navigate("UserOperation") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 24 && deviceOwner) {
|
if(VERSION.SDK_INT >= 24 && deviceOwner) {
|
||||||
SubPageItem(R.string.create_user, "", R.drawable.person_add_fill0) { navCtrl.navigate("CreateUser") }
|
FunctionItem(R.string.create_user, "", R.drawable.person_add_fill0) { navCtrl.navigate("CreateUser") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && profileOwner && dpm.isAffiliatedUser) {
|
if(VERSION.SDK_INT >= 28 && profileOwner && dpm.isAffiliatedUser) {
|
||||||
SubPageItem(R.string.logout_current_user, "", R.drawable.logout_fill0) { dialog = 2 }
|
FunctionItem(R.string.logout_current_user, "", R.drawable.logout_fill0) { dialog = 2 }
|
||||||
}
|
}
|
||||||
if(deviceOwner || profileOwner) {
|
if(deviceOwner || profileOwner) {
|
||||||
SubPageItem(R.string.change_username, "", R.drawable.edit_fill0) { navCtrl.navigate("EditUsername") }
|
FunctionItem(R.string.change_username, "", R.drawable.edit_fill0) { navCtrl.navigate("ChangeUsername") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 23 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.change_user_icon, "", R.drawable.account_circle_fill0) { navCtrl.navigate("ChangeUserIcon") }
|
FunctionItem(R.string.change_user_icon, "", R.drawable.account_circle_fill0) { navCtrl.navigate("ChangeUserIcon") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
if(VERSION.SDK_INT >= 28 && deviceOwner) {
|
||||||
SubPageItem(R.string.user_session_msg, "", R.drawable.notifications_fill0) { navCtrl.navigate("UserSessionMessage") }
|
FunctionItem(R.string.user_session_msg, "", R.drawable.notifications_fill0) { navCtrl.navigate("UserSessionMessage") }
|
||||||
}
|
}
|
||||||
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
if(VERSION.SDK_INT >= 26 && (deviceOwner || profileOwner)) {
|
||||||
SubPageItem(R.string.affiliation_id, "", R.drawable.id_card_fill0) { navCtrl.navigate("AffiliationID") }
|
FunctionItem(R.string.affiliation_id, "", R.drawable.id_card_fill0) { navCtrl.navigate("AffiliationID") }
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
||||||
}
|
}
|
||||||
if(dialog != 0 && VERSION.SDK_INT >= 28) AlertDialog(
|
if(dialog != 0 && VERSION.SDK_INT >= 28) AlertDialog(
|
||||||
@@ -208,11 +151,11 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Options() {
|
fun UserOptions(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.options, 0.dp, navCtrl) {
|
||||||
if(VERSION.SDK_INT >= 28) {
|
if(VERSION.SDK_INT >= 28) {
|
||||||
SwitchItem(R.string.enable_logout, "", null, { dpm.isLogoutEnabled }, { dpm.setLogoutEnabled(receiver, it) })
|
SwitchItem(R.string.enable_logout, "", null, { dpm.isLogoutEnabled }, { dpm.setLogoutEnabled(receiver, it) })
|
||||||
}
|
}
|
||||||
@@ -220,17 +163,14 @@ private fun Options() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CurrentUserInfo() {
|
fun CurrentUserInfo(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
val user = Process.myUserHandle()
|
val user = Process.myUserHandle()
|
||||||
var infoDialog by remember { mutableIntStateOf(0) }
|
var infoDialog by remember { mutableIntStateOf(0) }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.user_info, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.user_info), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
if(VERSION.SDK_INT >= 24) CardItem(R.string.support_multiuser, UserManager.supportsMultipleUsers().yesOrNo)
|
if(VERSION.SDK_INT >= 24) CardItem(R.string.support_multiuser, UserManager.supportsMultipleUsers().yesOrNo)
|
||||||
if(VERSION.SDK_INT >= 31) CardItem(R.string.headless_system_user_mode, UserManager.isHeadlessSystemUserMode().yesOrNo) { infoDialog = 1 }
|
if(VERSION.SDK_INT >= 31) CardItem(R.string.headless_system_user_mode, UserManager.isHeadlessSystemUserMode().yesOrNo) { infoDialog = 1 }
|
||||||
Spacer(Modifier.padding(vertical = 8.dp))
|
Spacer(Modifier.padding(vertical = 8.dp))
|
||||||
@@ -247,7 +187,6 @@ private fun CurrentUserInfo() {
|
|||||||
}
|
}
|
||||||
CardItem(R.string.user_id, (Binder.getCallingUid() / 100000).toString())
|
CardItem(R.string.user_id, (Binder.getCallingUid() / 100000).toString())
|
||||||
CardItem(R.string.user_serial_number, userManager.getSerialNumberForUser(Process.myUserHandle()).toString())
|
CardItem(R.string.user_serial_number, userManager.getSerialNumberForUser(Process.myUserHandle()).toString())
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
if(infoDialog != 0) AlertDialog(
|
if(infoDialog != 0) AlertDialog(
|
||||||
text = { Text(stringResource(R.string.info_headless_system_user_mode)) },
|
text = { Text(stringResource(R.string.info_headless_system_user_mode)) },
|
||||||
@@ -261,7 +200,7 @@ private fun CurrentUserInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserOperation() {
|
fun UserOperation(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
@@ -287,10 +226,7 @@ private fun UserOperation() {
|
|||||||
} catch(_: Exception) {
|
} catch(_: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.user_operation, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.user_operation), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = idInput,
|
value = idInput,
|
||||||
onValueChange = {
|
onValueChange = {
|
||||||
@@ -365,13 +301,12 @@ private fun UserOperation() {
|
|||||||
Text(stringResource(R.string.delete))
|
Text(stringResource(R.string.delete))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_user_operation)
|
InfoCard(R.string.info_user_operation)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun CreateUser() {
|
fun CreateUser(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
@@ -379,10 +314,7 @@ private fun CreateUser() {
|
|||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var userName by remember { mutableStateOf("") }
|
var userName by remember { mutableStateOf("") }
|
||||||
val flags = remember { mutableStateListOf<Int>() }
|
val flags = remember { mutableStateListOf<Int>() }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.create_user, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.create_user), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = userName,
|
value = userName,
|
||||||
onValueChange = { userName= it },
|
onValueChange = { userName= it },
|
||||||
@@ -423,13 +355,12 @@ private fun CreateUser() {
|
|||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
if(newUserHandle != null) { Text(text = stringResource(R.string.serial_number_of_new_user_is, userManager.getSerialNumberForUser(newUserHandle))) }
|
if(newUserHandle != null) { Text(text = stringResource(R.string.serial_number_of_new_user_is, userManager.getSerialNumberForUser(newUserHandle))) }
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun AffiliationID() {
|
fun AffiliationID(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -441,10 +372,7 @@ private fun AffiliationID() {
|
|||||||
list.addAll(dpm.getAffiliationIds(receiver))
|
list.addAll(dpm.getAffiliationIds(receiver))
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { refreshIds() }
|
LaunchedEffect(Unit) { refreshIds() }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.affiliation_id, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.affiliation_id), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
Column(modifier = Modifier.animateContentSize()) {
|
Column(modifier = Modifier.animateContentSize()) {
|
||||||
if(list.isEmpty()) Text(stringResource(R.string.none))
|
if(list.isEmpty()) Text(stringResource(R.string.none))
|
||||||
for(i in list) {
|
for(i in list) {
|
||||||
@@ -483,21 +411,17 @@ private fun AffiliationID() {
|
|||||||
Text(stringResource(R.string.apply))
|
Text(stringResource(R.string.apply))
|
||||||
}
|
}
|
||||||
InfoCard(R.string.info_affiliated_id)
|
InfoCard(R.string.info_affiliated_id)
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Username() {
|
fun ChangeUsername(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
val focusMgr = LocalFocusManager.current
|
val focusMgr = LocalFocusManager.current
|
||||||
var inputUsername by remember { mutableStateOf("") }
|
var inputUsername by remember { mutableStateOf("") }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.change_username, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.change_username), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = inputUsername,
|
value = inputUsername,
|
||||||
onValueChange = { inputUsername= it },
|
onValueChange = { inputUsername= it },
|
||||||
@@ -527,7 +451,7 @@ private fun Username() {
|
|||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserSessionMessage() {
|
fun UserSessionMessage(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -539,10 +463,7 @@ private fun UserSessionMessage() {
|
|||||||
end = dpm.getEndUserSessionMessage(receiver)?.toString() ?: ""
|
end = dpm.getEndUserSessionMessage(receiver)?.toString() ?: ""
|
||||||
}
|
}
|
||||||
LaunchedEffect(Unit) { refreshMsg() }
|
LaunchedEffect(Unit) { refreshMsg() }
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.user_session_msg, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.user_session_msg), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = start,
|
value = start,
|
||||||
onValueChange = { start= it },
|
onValueChange = { start= it },
|
||||||
@@ -604,13 +525,12 @@ private fun UserSessionMessage() {
|
|||||||
Text(stringResource(R.string.reset))
|
Text(stringResource(R.string.reset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(vertical = 30.dp))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
@Composable
|
@Composable
|
||||||
private fun UserIcon() {
|
fun ChangeUserIcon(navCtrl: NavHostController) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
val receiver = context.getReceiver()
|
val receiver = context.getReceiver()
|
||||||
@@ -623,10 +543,7 @@ private fun UserIcon() {
|
|||||||
bitmap = BitmapFactory.decodeStream(stream)
|
bitmap = BitmapFactory.decodeStream(stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
|
MyScaffold(R.string.change_user_icon, 8.dp, navCtrl) {
|
||||||
Spacer(Modifier.padding(vertical = 10.dp))
|
|
||||||
Text(text = stringResource(R.string.change_user_icon), style = typography.headlineLarge)
|
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
|
||||||
CheckBoxItem(R.string.file_picker_instead_gallery, getContent, { getContent = it })
|
CheckBoxItem(R.string.file_picker_instead_gallery, getContent, { getContent = it })
|
||||||
Spacer(Modifier.padding(vertical = 5.dp))
|
Spacer(Modifier.padding(vertical = 5.dp))
|
||||||
Button(
|
Button(
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import androidx.compose.foundation.background
|
|||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
@@ -18,11 +20,13 @@ import androidx.compose.material3.MaterialTheme.typography
|
|||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavBackStackEntry
|
import androidx.navigation.NavBackStackEntry
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
@@ -33,9 +37,9 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SubPageItem(
|
fun FunctionItem(
|
||||||
@StringRes title: Int,
|
@StringRes title: Int,
|
||||||
desc:String,
|
desc: String,
|
||||||
@DrawableRes icon: Int? = null,
|
@DrawableRes icon: Int? = null,
|
||||||
operation: () -> Unit
|
operation: () -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -48,8 +52,7 @@ fun SubPageItem(
|
|||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
if(icon != null) Icon(
|
if(icon != null) Icon(
|
||||||
painter = painterResource(icon),
|
painter = painterResource(icon), contentDescription = null,
|
||||||
contentDescription = null,
|
|
||||||
modifier = Modifier.padding(top = 1.dp, end = 20.dp).offset(x = (-2).dp)
|
modifier = Modifier.padding(top = 1.dp, end = 20.dp).offset(x = (-2).dp)
|
||||||
)
|
)
|
||||||
Column {
|
Column {
|
||||||
@@ -194,25 +197,6 @@ fun SwitchItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun TopBar(
|
|
||||||
backStackEntry: NavBackStackEntry?,
|
|
||||||
navCtrl: NavHostController,
|
|
||||||
localNavCtrl: NavHostController,
|
|
||||||
title: @Composable ()->Unit = {}
|
|
||||||
) {
|
|
||||||
TopAppBar(
|
|
||||||
title = title,
|
|
||||||
navigationIcon = {
|
|
||||||
NavIcon{
|
|
||||||
if(backStackEntry?.destination?.route == "Home") { navCtrl.navigateUp() } else { localNavCtrl.navigateUp() }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(containerColor = colorScheme.background)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CopyTextButton(@StringRes label: Int, content: String) {
|
fun CopyTextButton(@StringRes label: Int, content: String) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
@@ -287,6 +271,7 @@ fun ListItem(text: String, onDelete: () -> Unit) {
|
|||||||
fun InfoCard(@StringRes strID: Int) {
|
fun InfoCard(@StringRes strID: Int) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
.padding(vertical = 8.dp)
|
.padding(vertical = 8.dp)
|
||||||
.clip(RoundedCornerShape(10))
|
.clip(RoundedCornerShape(10))
|
||||||
.background(color = colorScheme.tertiaryContainer)
|
.background(color = colorScheme.tertiaryContainer)
|
||||||
@@ -296,3 +281,53 @@ fun InfoCard(@StringRes strID: Int) {
|
|||||||
Text(stringResource(strID))
|
Text(stringResource(strID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MyScaffold(
|
||||||
|
@StringRes title: Int,
|
||||||
|
horizonPadding: Dp,
|
||||||
|
navCtrl: NavHostController,
|
||||||
|
displayTitle: Boolean = true,
|
||||||
|
content: @Composable ColumnScope.() -> Unit
|
||||||
|
) = MyScaffold(title, horizonPadding, { navCtrl.navigateUp() }, displayTitle, content)
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun MyScaffold(
|
||||||
|
@StringRes title: Int,
|
||||||
|
horizonPadding: Dp,
|
||||||
|
onNavIconClicked: () -> Unit,
|
||||||
|
displayTitle: Boolean,
|
||||||
|
content: @Composable ColumnScope.() -> Unit
|
||||||
|
) {
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
TopAppBar(
|
||||||
|
title = {
|
||||||
|
Text(
|
||||||
|
text = stringResource(title),
|
||||||
|
modifier = if(displayTitle) Modifier.alpha((maxOf(scrollState.value-90,0)).toFloat()/50) else Modifier
|
||||||
|
)
|
||||||
|
},
|
||||||
|
navigationIcon = { NavIcon (onNavIconClicked) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(horizontal = horizonPadding)
|
||||||
|
.verticalScroll(scrollState)
|
||||||
|
.padding(bottom = 80.dp)
|
||||||
|
) {
|
||||||
|
if(displayTitle) Text(
|
||||||
|
text = stringResource(title),
|
||||||
|
style = typography.headlineLarge,
|
||||||
|
modifier = Modifier.padding(start = if(horizonPadding == 0.dp) 16.dp else 0.dp,top = 10.dp, bottom = 5.dp)
|
||||||
|
)
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,8 +91,8 @@
|
|||||||
<string name="account_type">Тип аккаунта</string>
|
<string name="account_type">Тип аккаунта</string>
|
||||||
<string name="transfer_ownership">Передача прав владения</string>
|
<string name="transfer_ownership">Передача прав владения</string>
|
||||||
<string name="target_component_name">Имя целевого компонента</string>
|
<string name="target_component_name">Имя целевого компонента</string>
|
||||||
<string name="device_owner_lock_screen_info">Информация на экране блокировки</string>
|
<string name="lock_screen_info">Информация на экране блокировки</string>
|
||||||
<string name="support_msg">Сообщение поддержки</string>
|
<string name="support_messages">Сообщение поддержки</string>
|
||||||
<string name="short_support_msg">Краткое сообщение</string>
|
<string name="short_support_msg">Краткое сообщение</string>
|
||||||
<string name="long_support_msg">Подробное сообщение</string>
|
<string name="long_support_msg">Подробное сообщение</string>
|
||||||
<string name="transfer">Передать</string>
|
<string name="transfer">Передать</string>
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
<string name="cert_installed">Сертификат установлен: %1$s</string>
|
<string name="cert_installed">Сертификат установлен: %1$s</string>
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Выберите сертификат...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Выберите сертификат...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">Удалить все пользовательские CA-сертификаты</string>
|
<string name="uninstall_all_user_ca_cert">Удалить все пользовательские CA-сертификаты</string>
|
||||||
<string name="security_logs">Журналы безопасности</string>
|
<string name="security_logging">Security logging</string> <!--TODO-->
|
||||||
<string name="pre_reboot_security_logs">Журналы безопасности перед перезагрузкой</string>
|
<string name="pre_reboot_security_logs">Журналы безопасности перед перезагрузкой</string>
|
||||||
<string name="wipe_data">Стереть данные</string>
|
<string name="wipe_data">Стереть данные</string>
|
||||||
<string name="wipe_external_storage">Стереть внешнее хранилище</string>
|
<string name="wipe_external_storage">Стереть внешнее хранилище</string>
|
||||||
@@ -186,7 +186,6 @@
|
|||||||
<string name="wipe_work_profile_warning">Ваш рабочий профиль будет УДАЛЕН</string>
|
<string name="wipe_work_profile_warning">Ваш рабочий профиль будет УДАЛЕН</string>
|
||||||
<string name="encryption_status">Статус шифрования</string>
|
<string name="encryption_status">Статус шифрования</string>
|
||||||
<string name="frp_policy">Политика FRP</string>
|
<string name="frp_policy">Политика FRP</string>
|
||||||
<string name="factory_reset_protection_policy">Политика защиты от сброса к заводским настройкам</string>
|
|
||||||
<string name="frp_policy_not_supported">Политика FRP не поддерживается на этом устройстве</string>
|
<string name="frp_policy_not_supported">Политика FRP не поддерживается на этом устройстве</string>
|
||||||
<string name="enable_frp">Включить FRP</string>
|
<string name="enable_frp">Включить FRP</string>
|
||||||
<string name="account_list_is">Список аккаунтов: </string>
|
<string name="account_list_is">Список аккаунтов: </string>
|
||||||
@@ -236,12 +235,11 @@
|
|||||||
<string name="specify_port">Указать порт</string>
|
<string name="specify_port">Указать порт</string>
|
||||||
<string name="invalid_config">Неверная конфигурация</string>
|
<string name="invalid_config">Неверная конфигурация</string>
|
||||||
<string name="exclude_hosts">Исключить хосты</string>
|
<string name="exclude_hosts">Исключить хосты</string>
|
||||||
<string name="retrieve_net_logs">Журналы сети</string>
|
<string name="network_logging">Network logging</string> <!--TODO-->
|
||||||
<string name="log_file_size_is">Размер файла журнала: %1$s</string>
|
<string name="log_file_size_is">Размер файла журнала: %1$s</string>
|
||||||
<string name="delete_logs">Удалить журналы</string>
|
<string name="delete_logs">Удалить журналы</string>
|
||||||
<string name="export_logs">Экспортировать журналы</string>
|
<string name="export_logs">Экспортировать журналы</string>
|
||||||
<string name="wifi_auth_keypair">Пара ключей Wi-Fi</string>
|
<string name="wifi_auth_keypair">Пара ключей Wi-Fi</string>
|
||||||
<string name="keypair">Пара ключей</string>
|
|
||||||
<string name="preferential_network_service">Предпочтительная сетевая служба</string>
|
<string name="preferential_network_service">Предпочтительная сетевая служба</string>
|
||||||
<string name="network_id">Идентификатор сети</string>
|
<string name="network_id">Идентификатор сети</string>
|
||||||
<string name="allow_fallback_to_default_connection">Разрешить переход на соединение по умолчанию</string>
|
<string name="allow_fallback_to_default_connection">Разрешить переход на соединение по умолчанию</string>
|
||||||
@@ -286,7 +284,6 @@
|
|||||||
<string name="migrate_account">Перенести аккаунт</string>
|
<string name="migrate_account">Перенести аккаунт</string>
|
||||||
<string name="account_name">Имя аккаунта</string>
|
<string name="account_name">Имя аккаунта</string>
|
||||||
<string name="keep_account">Сохранить аккаунт</string>
|
<string name="keep_account">Сохранить аккаунт</string>
|
||||||
<string name="is_org_owned_profile">Рабочий профиль принадлежит организации: %1$s</string>
|
|
||||||
<string name="org_owned_work_profile">Рабочий профиль организации</string>
|
<string name="org_owned_work_profile">Рабочий профиль организации</string>
|
||||||
<string name="skip_encryption">Пропустить шифрование</string>
|
<string name="skip_encryption">Пропустить шифрование</string>
|
||||||
<string name="create">Создать</string>
|
<string name="create">Создать</string>
|
||||||
@@ -316,7 +313,7 @@
|
|||||||
<string name="always_on_vpn">Постоянный VPN</string>
|
<string name="always_on_vpn">Постоянный VPN</string>
|
||||||
<string name="enable_lockdown">Включить блокировку</string>
|
<string name="enable_lockdown">Включить блокировку</string>
|
||||||
<string name="clear_current_config">Очистить текущую конфигурацию</string>
|
<string name="clear_current_config">Очистить текущую конфигурацию</string>
|
||||||
<string name="permission">Разрешение</string>
|
<string name="permissions">Разрешение</string>
|
||||||
<string name="scope_is_work_profile">Область действия: рабочий профиль</string>
|
<string name="scope_is_work_profile">Область действия: рабочий профиль</string>
|
||||||
<string name="app_info">Информация о приложении</string>
|
<string name="app_info">Информация о приложении</string>
|
||||||
<string name="not_installed">Не установлено</string>
|
<string name="not_installed">Не установлено</string>
|
||||||
@@ -366,12 +363,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<!--Ограничения пользователя-->
|
<!--Ограничения пользователя-->
|
||||||
<string name="user_restrict">Ограничения пользователя</string>
|
<string name="user_restriction">Ограничения пользователя</string>
|
||||||
<string name="profile_owner_is_restricted">Владелец профиля может использовать ограниченные функции</string>
|
<string name="profile_owner_is_restricted">Владелец профиля может использовать ограниченные функции</string>
|
||||||
<string name="switch_to_disable_feature">Включите переключатель, чтобы отключить эту функцию.</string>
|
<string name="switch_to_disable_feature">Включите переключатель, чтобы отключить эту функцию.</string>
|
||||||
<string name="some_features_invalid_in_work_profile">Функции в рабочем профиле ограничены.</string>
|
<string name="some_features_invalid_in_work_profile">Функции в рабочем профиле ограничены.</string>
|
||||||
<string name="network_internet">Сеть</string>
|
<string name="network_and_internet">Сеть</string>
|
||||||
<string name="more_connectivity">Другие подключения</string>
|
<string name="connectivity">Другие подключения</string>
|
||||||
<string name="media">Медиа</string>
|
<string name="media">Медиа</string>
|
||||||
<string name="other">Другое</string>
|
<string name="other">Другое</string>
|
||||||
<string name="require_device_owner">Требуется владелец устройства</string>
|
<string name="require_device_owner">Требуется владелец устройства</string>
|
||||||
@@ -478,7 +475,6 @@
|
|||||||
<string name="change_user_icon">Изменить значок пользователя</string>
|
<string name="change_user_icon">Изменить значок пользователя</string>
|
||||||
<string name="file_picker_instead_gallery">Использовать выборщик файлов вместо галереи</string>
|
<string name="file_picker_instead_gallery">Использовать выборщик файлов вместо галереи</string>
|
||||||
<string name="select_picture" tools:ignore="TypographyEllipsis">Выберите изображение...</string>
|
<string name="select_picture" tools:ignore="TypographyEllipsis">Выберите изображение...</string>
|
||||||
<string name="unknown_result">Неизвестный результат (возможно, ошибка)</string>
|
|
||||||
<string name="fail_managed_profile">Ошибка: управляемый профиль</string>
|
<string name="fail_managed_profile">Ошибка: управляемый профиль</string>
|
||||||
<string name="fail_current_user">Ошибка: текущий пользователь</string>
|
<string name="fail_current_user">Ошибка: текущий пользователь</string>
|
||||||
<string name="user_session_msg">Сообщение о сеансе пользователя</string>
|
<string name="user_session_msg">Сообщение о сеансе пользователя</string>
|
||||||
|
|||||||
@@ -92,8 +92,8 @@
|
|||||||
<string name="account_type">Hesap Türleri</string>
|
<string name="account_type">Hesap Türleri</string>
|
||||||
<string name="transfer_ownership">Sahipliği Devret</string>
|
<string name="transfer_ownership">Sahipliği Devret</string>
|
||||||
<string name="target_component_name">Target component name</string> <!--TODO-->
|
<string name="target_component_name">Target component name</string> <!--TODO-->
|
||||||
<string name="device_owner_lock_screen_info">Ekran Kilidi Bilgisi</string>
|
<string name="lock_screen_info">Ekran Kilidi Bilgisi</string>
|
||||||
<string name="support_msg">Destek Mesajı</string>
|
<string name="support_messages">Destek Mesajı</string>
|
||||||
<string name="short_support_msg">Kısa Mesaj</string>
|
<string name="short_support_msg">Kısa Mesaj</string>
|
||||||
<string name="long_support_msg">Uzun Mesaj</string>
|
<string name="long_support_msg">Uzun Mesaj</string>
|
||||||
<string name="transfer">Transfer</string>
|
<string name="transfer">Transfer</string>
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
<string name="cert_installed">Yüklenen sertifika: %1$s</string> <!--TODO-->
|
<string name="cert_installed">Yüklenen sertifika: %1$s</string> <!--TODO-->
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Sertifika seç...</string> <!--TODO-->
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Sertifika seç...</string> <!--TODO-->
|
||||||
<string name="uninstall_all_user_ca_cert">Tüm kullanıcı sertifikalarını kaldır</string> <!--TODO-->
|
<string name="uninstall_all_user_ca_cert">Tüm kullanıcı sertifikalarını kaldır</string> <!--TODO-->
|
||||||
<string name="security_logs">Güvenlik kayıtları</string>
|
<string name="security_logging">Security logging</string> <!--TODO-->
|
||||||
<string name="pre_reboot_security_logs">Yeniden başlatmadan önce güvenlik kayıtları</string>
|
<string name="pre_reboot_security_logs">Yeniden başlatmadan önce güvenlik kayıtları</string>
|
||||||
<string name="wipe_data">Verileri sil</string>
|
<string name="wipe_data">Verileri sil</string>
|
||||||
<string name="wipe_external_storage">Harici depolamayı sil</string>
|
<string name="wipe_external_storage">Harici depolamayı sil</string>
|
||||||
@@ -188,7 +188,6 @@
|
|||||||
<string name="wipe_work_profile_warning">Your work profile will be DELETED</string> <!--TODO-->
|
<string name="wipe_work_profile_warning">Your work profile will be DELETED</string> <!--TODO-->
|
||||||
<string name="encryption_status">Encryption status</string> <!--TODO-->
|
<string name="encryption_status">Encryption status</string> <!--TODO-->
|
||||||
<string name="frp_policy">FRP politikası</string>
|
<string name="frp_policy">FRP politikası</string>
|
||||||
<string name="factory_reset_protection_policy">Fabrika ayarlarına sıfırlama koruma politikası</string>
|
|
||||||
<string name="frp_policy_not_supported">FRP politikası bu cihazda desteklenmiyor</string>
|
<string name="frp_policy_not_supported">FRP politikası bu cihazda desteklenmiyor</string>
|
||||||
<string name="enable_frp">FRP\'yi etkinleştir</string>
|
<string name="enable_frp">FRP\'yi etkinleştir</string>
|
||||||
<string name="account_list_is">"Hesap listesi: "</string>
|
<string name="account_list_is">"Hesap listesi: "</string>
|
||||||
@@ -237,12 +236,11 @@
|
|||||||
<string name="specify_port">Specify port</string> <!--TODO-->
|
<string name="specify_port">Specify port</string> <!--TODO-->
|
||||||
<string name="invalid_config">Invalid config</string> <!--TODO-->
|
<string name="invalid_config">Invalid config</string> <!--TODO-->
|
||||||
<string name="exclude_hosts">Exclude hosts</string> <!--TODO-->
|
<string name="exclude_hosts">Exclude hosts</string> <!--TODO-->
|
||||||
<string name="retrieve_net_logs">Ağ kayıtları</string>
|
<string name="network_logging">Network logging</string> <!--TODO-->
|
||||||
<string name="log_file_size_is">Log file size: %1$s</string> <!--TODO-->
|
<string name="log_file_size_is">Log file size: %1$s</string> <!--TODO-->
|
||||||
<string name="delete_logs">Delete logs</string> <!--TODO-->
|
<string name="delete_logs">Delete logs</string> <!--TODO-->
|
||||||
<string name="export_logs">Export logs</string> <!--TODO-->
|
<string name="export_logs">Export logs</string> <!--TODO-->
|
||||||
<string name="wifi_auth_keypair">Wi-Fi anahtar çifti</string>
|
<string name="wifi_auth_keypair">Wi-Fi anahtar çifti</string>
|
||||||
<string name="keypair">Anahtar çifti</string>
|
|
||||||
<string name="preferential_network_service">Tercihli ağ hizmeti</string>
|
<string name="preferential_network_service">Tercihli ağ hizmeti</string>
|
||||||
<string name="network_id">Network ID</string> <!--TODO-->
|
<string name="network_id">Network ID</string> <!--TODO-->
|
||||||
<string name="allow_fallback_to_default_connection">Allow fallback to default connection</string> <!--TODO-->
|
<string name="allow_fallback_to_default_connection">Allow fallback to default connection</string> <!--TODO-->
|
||||||
@@ -285,7 +283,6 @@
|
|||||||
<string name="migrate_account">Migrate account</string> <!--TODO-->
|
<string name="migrate_account">Migrate account</string> <!--TODO-->
|
||||||
<string name="account_name">Account name</string> <!--TODO-->
|
<string name="account_name">Account name</string> <!--TODO-->
|
||||||
<string name="keep_account">Keep account</string> <!--TODO-->
|
<string name="keep_account">Keep account</string> <!--TODO-->
|
||||||
<string name="is_org_owned_profile">Kuruluşa ait iş profili: %1$s</string>
|
|
||||||
<string name="org_owned_work_profile">Kuruluş iş profili</string>
|
<string name="org_owned_work_profile">Kuruluş iş profili</string>
|
||||||
<string name="skip_encryption">Şifrelemeyi atla</string>
|
<string name="skip_encryption">Şifrelemeyi atla</string>
|
||||||
<string name="create">Oluştur</string>
|
<string name="create">Oluştur</string>
|
||||||
@@ -314,7 +311,7 @@
|
|||||||
<string name="always_on_vpn">Her zaman açık VPN</string>
|
<string name="always_on_vpn">Her zaman açık VPN</string>
|
||||||
<string name="enable_lockdown">Enable lockdown</string> <!--TODO-->
|
<string name="enable_lockdown">Enable lockdown</string> <!--TODO-->
|
||||||
<string name="clear_current_config">Clear current config</string> <!--TODO-->
|
<string name="clear_current_config">Clear current config</string> <!--TODO-->
|
||||||
<string name="permission">İzin</string>
|
<string name="permissions">İzin</string>
|
||||||
<string name="scope_is_work_profile">Kapsam: iş profili</string>
|
<string name="scope_is_work_profile">Kapsam: iş profili</string>
|
||||||
<string name="app_info">Uygulama bilgisi</string>
|
<string name="app_info">Uygulama bilgisi</string>
|
||||||
<string name="not_installed">Yüklü değil</string>
|
<string name="not_installed">Yüklü değil</string>
|
||||||
@@ -365,12 +362,12 @@
|
|||||||
<string name="status_fail_timeout">Başarısız: zaman aşımı</string>
|
<string name="status_fail_timeout">Başarısız: zaman aşımı</string>
|
||||||
|
|
||||||
<!--UserRestriction-->
|
<!--UserRestriction-->
|
||||||
<string name="user_restrict">Kullanıcı kısıtlaması</string>
|
<string name="user_restriction">Kullanıcı kısıtlaması</string>
|
||||||
<string name="profile_owner_is_restricted">Profil sahibi sınırlı işlev kullanabilir</string>
|
<string name="profile_owner_is_restricted">Profil sahibi sınırlı işlev kullanabilir</string>
|
||||||
<string name="switch_to_disable_feature">Bu işlevi devre dışı bırakmak için bir anahtar açın. </string>
|
<string name="switch_to_disable_feature">Bu işlevi devre dışı bırakmak için bir anahtar açın. </string>
|
||||||
<string name="some_features_invalid_in_work_profile">İş profilindeki işlevler sınırlıdır. </string>
|
<string name="some_features_invalid_in_work_profile">İş profilindeki işlevler sınırlıdır. </string>
|
||||||
<string name="network_internet">Ağ</string>
|
<string name="network_and_internet">Ağ</string>
|
||||||
<string name="more_connectivity">Diğer bağlantı</string>
|
<string name="connectivity">Diğer bağlantı</string>
|
||||||
<string name="media">Medya</string>
|
<string name="media">Medya</string>
|
||||||
<string name="other">Diğer</string>
|
<string name="other">Diğer</string>
|
||||||
<string name="require_device_owner">Cihaz sahibi gerektirir</string>
|
<string name="require_device_owner">Cihaz sahibi gerektirir</string>
|
||||||
@@ -476,7 +473,6 @@
|
|||||||
<string name="change_user_icon">Kullanıcı simgesini değiştir</string>
|
<string name="change_user_icon">Kullanıcı simgesini değiştir</string>
|
||||||
<string name="file_picker_instead_gallery">Galeri yerine dosya seçici kullan</string>
|
<string name="file_picker_instead_gallery">Galeri yerine dosya seçici kullan</string>
|
||||||
<string name="select_picture" tools:ignore="TypographyEllipsis">Resim seç...</string>
|
<string name="select_picture" tools:ignore="TypographyEllipsis">Resim seç...</string>
|
||||||
<string name="unknown_result">Bilinmeyen sonuç (başarısız olabilir)</string>
|
|
||||||
<string name="fail_managed_profile">Başarısız: yönetilen profil</string>
|
<string name="fail_managed_profile">Başarısız: yönetilen profil</string>
|
||||||
<string name="fail_current_user">Başarısız: mevcut kullanıcı</string>
|
<string name="fail_current_user">Başarısız: mevcut kullanıcı</string>
|
||||||
<string name="user_session_msg">Kullanıcı oturum mesajı</string>
|
<string name="user_session_msg">Kullanıcı oturum mesajı</string>
|
||||||
|
|||||||
@@ -87,8 +87,8 @@
|
|||||||
<string name="account_type">账号类型</string>
|
<string name="account_type">账号类型</string>
|
||||||
<string name="transfer_ownership">转移所有权</string>
|
<string name="transfer_ownership">转移所有权</string>
|
||||||
<string name="target_component_name">目标组件名</string>
|
<string name="target_component_name">目标组件名</string>
|
||||||
<string name="device_owner_lock_screen_info">锁屏提示信息</string>
|
<string name="lock_screen_info">锁屏提示信息</string>
|
||||||
<string name="support_msg">提供支持的消息</string>
|
<string name="support_messages">提供支持的消息</string>
|
||||||
<string name="short_support_msg">提供支持的短消息</string>
|
<string name="short_support_msg">提供支持的短消息</string>
|
||||||
<string name="long_support_msg">提供支持的长消息</string>
|
<string name="long_support_msg">提供支持的长消息</string>
|
||||||
<string name="transfer">转移</string>
|
<string name="transfer">转移</string>
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
<string name="cert_installed">证书已安装:%1$s</string>
|
<string name="cert_installed">证书已安装:%1$s</string>
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">选择证书...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">选择证书...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">卸载所有用户证书</string>
|
<string name="uninstall_all_user_ca_cert">卸载所有用户证书</string>
|
||||||
<string name="security_logs">安全日志</string>
|
<string name="security_logging">安全日志</string>
|
||||||
<string name="pre_reboot_security_logs">重启前安全日志</string>
|
<string name="pre_reboot_security_logs">重启前安全日志</string>
|
||||||
<string name="wipe_data">清除数据</string>
|
<string name="wipe_data">清除数据</string>
|
||||||
<string name="wipe_external_storage">清除外部存储</string>
|
<string name="wipe_external_storage">清除外部存储</string>
|
||||||
@@ -183,7 +183,6 @@
|
|||||||
<string name="wipe_work_profile_warning">你的工作资料将会被删除</string>
|
<string name="wipe_work_profile_warning">你的工作资料将会被删除</string>
|
||||||
<string name="encryption_status">加密状态</string>
|
<string name="encryption_status">加密状态</string>
|
||||||
<string name="frp_policy">FRP策略</string>
|
<string name="frp_policy">FRP策略</string>
|
||||||
<string name="factory_reset_protection_policy">恢复出厂设置保护策略</string>
|
|
||||||
<string name="frp_policy_not_supported">这个设备不支持恢复出厂设置保护策略</string>
|
<string name="frp_policy_not_supported">这个设备不支持恢复出厂设置保护策略</string>
|
||||||
<string name="enable_frp">启用FRP</string>
|
<string name="enable_frp">启用FRP</string>
|
||||||
<string name="account_list_is">账户列表:</string>
|
<string name="account_list_is">账户列表:</string>
|
||||||
@@ -232,12 +231,11 @@
|
|||||||
<string name="specify_port">指定端口</string>
|
<string name="specify_port">指定端口</string>
|
||||||
<string name="invalid_config">无效配置</string>
|
<string name="invalid_config">无效配置</string>
|
||||||
<string name="exclude_hosts">排除列表</string>
|
<string name="exclude_hosts">排除列表</string>
|
||||||
<string name="retrieve_net_logs">收集网络日志</string>
|
<string name="network_logging">网络日志</string>
|
||||||
<string name="log_file_size_is">日志文件大小:%1$s</string>
|
<string name="log_file_size_is">日志文件大小:%1$s</string>
|
||||||
<string name="delete_logs">删除日志</string>
|
<string name="delete_logs">删除日志</string>
|
||||||
<string name="export_logs">导出日志</string>
|
<string name="export_logs">导出日志</string>
|
||||||
<string name="wifi_auth_keypair">Wi-Fi密钥对</string>
|
<string name="wifi_auth_keypair">Wi-Fi密钥对</string>
|
||||||
<string name="keypair">密钥对</string>
|
|
||||||
<string name="preferential_network_service">首选网络服务</string>
|
<string name="preferential_network_service">首选网络服务</string>
|
||||||
<string name="network_id">网络ID</string>
|
<string name="network_id">网络ID</string>
|
||||||
<string name="allow_fallback_to_default_connection">允许回落到默认连接</string>
|
<string name="allow_fallback_to_default_connection">允许回落到默认连接</string>
|
||||||
@@ -280,7 +278,6 @@
|
|||||||
<string name="migrate_account">迁移账号</string>
|
<string name="migrate_account">迁移账号</string>
|
||||||
<string name="account_name">账号名</string>
|
<string name="account_name">账号名</string>
|
||||||
<string name="keep_account">保留账号</string>
|
<string name="keep_account">保留账号</string>
|
||||||
<string name="is_org_owned_profile">由组织拥有的工作资料:%1$s</string>
|
|
||||||
<string name="org_owned_work_profile">组织拥有的工作资料</string>
|
<string name="org_owned_work_profile">组织拥有的工作资料</string>
|
||||||
<string name="skip_encryption">跳过加密</string>
|
<string name="skip_encryption">跳过加密</string>
|
||||||
<string name="create">创建</string>
|
<string name="create">创建</string>
|
||||||
@@ -309,7 +306,7 @@
|
|||||||
<string name="always_on_vpn">VPN保持打开</string>
|
<string name="always_on_vpn">VPN保持打开</string>
|
||||||
<string name="enable_lockdown">启用锁定</string>
|
<string name="enable_lockdown">启用锁定</string>
|
||||||
<string name="clear_current_config">清除当前配置</string>
|
<string name="clear_current_config">清除当前配置</string>
|
||||||
<string name="permission">权限</string>
|
<string name="permissions">权限</string>
|
||||||
<string name="scope_is_work_profile">作用域: 工作资料</string>
|
<string name="scope_is_work_profile">作用域: 工作资料</string>
|
||||||
<string name="app_info">应用详情</string>
|
<string name="app_info">应用详情</string>
|
||||||
<string name="not_installed">未安装</string>
|
<string name="not_installed">未安装</string>
|
||||||
@@ -357,12 +354,12 @@
|
|||||||
<string name="status_fail_timeout">超时</string>
|
<string name="status_fail_timeout">超时</string>
|
||||||
|
|
||||||
<!--UserRestriction-->
|
<!--UserRestriction-->
|
||||||
<string name="user_restrict">用户限制</string>
|
<string name="user_restriction">用户限制</string>
|
||||||
<string name="profile_owner_is_restricted">Profile owner无法使用部分功能</string>
|
<string name="profile_owner_is_restricted">Profile owner无法使用部分功能</string>
|
||||||
<string name="switch_to_disable_feature">打开开关后会禁用对应的功能</string>
|
<string name="switch_to_disable_feature">打开开关后会禁用对应的功能</string>
|
||||||
<string name="some_features_invalid_in_work_profile">工作资料中部分功能无效</string>
|
<string name="some_features_invalid_in_work_profile">工作资料中部分功能无效</string>
|
||||||
<string name="network_internet">网络和互联网</string>
|
<string name="network_and_internet">网络和互联网</string>
|
||||||
<string name="more_connectivity">更多连接</string>
|
<string name="connectivity">更多连接</string>
|
||||||
<string name="media">媒体</string>
|
<string name="media">媒体</string>
|
||||||
<string name="other">其他</string>
|
<string name="other">其他</string>
|
||||||
<string name="require_device_owner">需要DeviceOwner</string>
|
<string name="require_device_owner">需要DeviceOwner</string>
|
||||||
@@ -468,7 +465,6 @@
|
|||||||
<string name="change_user_icon">更换用户头像</string>
|
<string name="change_user_icon">更换用户头像</string>
|
||||||
<string name="file_picker_instead_gallery">使用文件选择器而不是相册</string>
|
<string name="file_picker_instead_gallery">使用文件选择器而不是相册</string>
|
||||||
<string name="select_picture" tools:ignore="TypographyEllipsis">选择图片...</string>
|
<string name="select_picture" tools:ignore="TypographyEllipsis">选择图片...</string>
|
||||||
<string name="unknown_result">未知结果(失败)</string>
|
|
||||||
<string name="fail_managed_profile">失败:受管理的资料</string>
|
<string name="fail_managed_profile">失败:受管理的资料</string>
|
||||||
<string name="fail_current_user">失败:当前用户</string>
|
<string name="fail_current_user">失败:当前用户</string>
|
||||||
<string name="user_session_msg">用户会话消息</string>
|
<string name="user_session_msg">用户会话消息</string>
|
||||||
|
|||||||
@@ -94,8 +94,8 @@
|
|||||||
<string name="account_type">Account type</string>
|
<string name="account_type">Account type</string>
|
||||||
<string name="transfer_ownership">Transfer Ownership</string>
|
<string name="transfer_ownership">Transfer Ownership</string>
|
||||||
<string name="target_component_name">Target component name</string>
|
<string name="target_component_name">Target component name</string>
|
||||||
<string name="device_owner_lock_screen_info">Lockscreen info</string>
|
<string name="lock_screen_info">Lockscreen info</string>
|
||||||
<string name="support_msg">Support Message</string>
|
<string name="support_messages">Support Messages</string>
|
||||||
<string name="short_support_msg">Short message</string>
|
<string name="short_support_msg">Short message</string>
|
||||||
<string name="long_support_msg">Long message</string>
|
<string name="long_support_msg">Long message</string>
|
||||||
<string name="transfer">Transfer</string>
|
<string name="transfer">Transfer</string>
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
<string name="cert_installed">Certificate installed: %1$s</string>
|
<string name="cert_installed">Certificate installed: %1$s</string>
|
||||||
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Select certificate...</string>
|
<string name="select_ca_cert" tools:ignore="TypographyEllipsis">Select certificate...</string>
|
||||||
<string name="uninstall_all_user_ca_cert">Uninstall all user CA certificate</string>
|
<string name="uninstall_all_user_ca_cert">Uninstall all user CA certificate</string>
|
||||||
<string name="security_logs">Security logs</string>
|
<string name="security_logging">Security logging</string>
|
||||||
<string name="pre_reboot_security_logs">Pre-reboot security logs</string>
|
<string name="pre_reboot_security_logs">Pre-reboot security logs</string>
|
||||||
<string name="wipe_data">Wipe data</string>
|
<string name="wipe_data">Wipe data</string>
|
||||||
<string name="wipe_external_storage">Wipe external storage</string>
|
<string name="wipe_external_storage">Wipe external storage</string>
|
||||||
@@ -192,7 +192,6 @@
|
|||||||
<string name="wipe_work_profile_warning">Your work profile will be DELETED</string>
|
<string name="wipe_work_profile_warning">Your work profile will be DELETED</string>
|
||||||
<string name="encryption_status">Encryption status</string>
|
<string name="encryption_status">Encryption status</string>
|
||||||
<string name="frp_policy">FRP policy</string>
|
<string name="frp_policy">FRP policy</string>
|
||||||
<string name="factory_reset_protection_policy">Factory reset protection policy</string>
|
|
||||||
<string name="frp_policy_not_supported">FRP policy is not supported on this device</string>
|
<string name="frp_policy_not_supported">FRP policy is not supported on this device</string>
|
||||||
<string name="enable_frp">Enable FRP</string>
|
<string name="enable_frp">Enable FRP</string>
|
||||||
<string name="account_list_is">"Account list: "</string>
|
<string name="account_list_is">"Account list: "</string>
|
||||||
@@ -242,12 +241,11 @@
|
|||||||
<string name="specify_port">Specify port</string>
|
<string name="specify_port">Specify port</string>
|
||||||
<string name="invalid_config">Invalid config</string>
|
<string name="invalid_config">Invalid config</string>
|
||||||
<string name="exclude_hosts">Exclude hosts</string>
|
<string name="exclude_hosts">Exclude hosts</string>
|
||||||
<string name="retrieve_net_logs">Network logs</string>
|
<string name="network_logging">Network logging</string>
|
||||||
<string name="log_file_size_is">Log file size: %1$s</string>
|
<string name="log_file_size_is">Log file size: %1$s</string>
|
||||||
<string name="delete_logs">Delete logs</string>
|
<string name="delete_logs">Delete logs</string>
|
||||||
<string name="export_logs">Export logs</string>
|
<string name="export_logs">Export logs</string>
|
||||||
<string name="wifi_auth_keypair">Wi-Fi keypair</string>
|
<string name="wifi_auth_keypair">Wi-Fi keypair</string>
|
||||||
<string name="keypair">Keypair</string>
|
|
||||||
<string name="preferential_network_service">Preferential network service</string>
|
<string name="preferential_network_service">Preferential network service</string>
|
||||||
<string name="network_id">Network ID</string>
|
<string name="network_id">Network ID</string>
|
||||||
<string name="allow_fallback_to_default_connection">Allow fallback to default connection</string>
|
<string name="allow_fallback_to_default_connection">Allow fallback to default connection</string>
|
||||||
@@ -290,7 +288,6 @@
|
|||||||
<string name="migrate_account">Migrate account</string>
|
<string name="migrate_account">Migrate account</string>
|
||||||
<string name="account_name">Account name</string>
|
<string name="account_name">Account name</string>
|
||||||
<string name="keep_account">Keep account</string>
|
<string name="keep_account">Keep account</string>
|
||||||
<string name="is_org_owned_profile">Organization owned work profile: %1$s</string>
|
|
||||||
<string name="org_owned_work_profile">Organization work profile</string>
|
<string name="org_owned_work_profile">Organization work profile</string>
|
||||||
<string name="activate_org_profile_command" tools:ignore="TypographyDashes" translatable="false">
|
<string name="activate_org_profile_command" tools:ignore="TypographyDashes" translatable="false">
|
||||||
dpm mark-profile-owner-on-organization-owned-device --user %1$s com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver
|
dpm mark-profile-owner-on-organization-owned-device --user %1$s com.bintianqi.owndroid/com.bintianqi.owndroid.Receiver
|
||||||
@@ -322,7 +319,7 @@
|
|||||||
<string name="always_on_vpn">Always-on VPN</string>
|
<string name="always_on_vpn">Always-on VPN</string>
|
||||||
<string name="enable_lockdown">Enable lockdown</string>
|
<string name="enable_lockdown">Enable lockdown</string>
|
||||||
<string name="clear_current_config">Clear current config</string>
|
<string name="clear_current_config">Clear current config</string>
|
||||||
<string name="permission">Permission</string>
|
<string name="permissions">Permissions</string>
|
||||||
<string name="scope_is_work_profile">Scope: work profile</string>
|
<string name="scope_is_work_profile">Scope: work profile</string>
|
||||||
<string name="app_info">App info</string>
|
<string name="app_info">App info</string>
|
||||||
<string name="not_installed">Not installed</string>
|
<string name="not_installed">Not installed</string>
|
||||||
@@ -371,12 +368,12 @@
|
|||||||
<string name="status_fail_timeout">Fail: timeout</string>
|
<string name="status_fail_timeout">Fail: timeout</string>
|
||||||
|
|
||||||
<!--UserRestriction-->
|
<!--UserRestriction-->
|
||||||
<string name="user_restrict">User restriction</string>
|
<string name="user_restriction">User restriction</string>
|
||||||
<string name="profile_owner_is_restricted">Profile owner can use limited function</string>
|
<string name="profile_owner_is_restricted">Profile owner can use limited function</string>
|
||||||
<string name="switch_to_disable_feature">Turn on a switch to disable that function. </string>
|
<string name="switch_to_disable_feature">Turn on a switch to disable that function. </string>
|
||||||
<string name="some_features_invalid_in_work_profile">Functions in work profile is limited. </string>
|
<string name="some_features_invalid_in_work_profile">Functions in work profile is limited. </string>
|
||||||
<string name="network_internet">Network</string>
|
<string name="network_and_internet">Network</string>
|
||||||
<string name="more_connectivity">Other connection</string>
|
<string name="connectivity">Other connection</string>
|
||||||
<string name="media">Media</string>
|
<string name="media">Media</string>
|
||||||
<string name="other">Other</string>
|
<string name="other">Other</string>
|
||||||
<string name="require_device_owner">Require device owner</string>
|
<string name="require_device_owner">Require device owner</string>
|
||||||
@@ -482,7 +479,6 @@
|
|||||||
<string name="change_user_icon">Change user icon</string>
|
<string name="change_user_icon">Change user icon</string>
|
||||||
<string name="file_picker_instead_gallery">Use file picker instead of gallery</string>
|
<string name="file_picker_instead_gallery">Use file picker instead of gallery</string>
|
||||||
<string name="select_picture" tools:ignore="TypographyEllipsis">Select image...</string>
|
<string name="select_picture" tools:ignore="TypographyEllipsis">Select image...</string>
|
||||||
<string name="unknown_result">Unknown result(may failed)</string>
|
|
||||||
<string name="fail_managed_profile">Failed: managed profile</string>
|
<string name="fail_managed_profile">Failed: managed profile</string>
|
||||||
<string name="fail_current_user">Failed: current user</string>
|
<string name="fail_current_user">Failed: current user</string>
|
||||||
<string name="user_session_msg">User session message</string>
|
<string name="user_session_msg">User session message</string>
|
||||||
@@ -631,7 +627,7 @@
|
|||||||
<string name="info_security_log">If a Device owner use this function, all users should be affiliated.</string>
|
<string name="info_security_log">If a Device owner use this function, all users should be affiliated.</string>
|
||||||
<string name="info_pre_reboot_security_log">Not all devices support pre-reboot security logs.</string>
|
<string name="info_pre_reboot_security_log">Not all devices support pre-reboot security logs.</string>
|
||||||
<string name="info_disable_account_management">When account management is disabled for an account type, adding or removing an account of that type will not be possible.</string>
|
<string name="info_disable_account_management">When account management is disabled for an account type, adding or removing an account of that type will not be possible.</string>
|
||||||
<string name="info_frp_policy">FRP can protect the device after untrusted factory reset (in Recovery or Fastboot).\nTo enable this feature, the device must support persistent data block service.</string>
|
<string name="info_frp_policy">Factory reset protection can protect the device after untrusted factory reset (in Recovery or Fastboot).\nTo enable this feature, the device must support persistent data block service.</string>
|
||||||
<string name="info_wipe_data_in_managed_user">All data of this user will be wiped, but that user won\'t be removed.</string>
|
<string name="info_wipe_data_in_managed_user">All data of this user will be wiped, but that user won\'t be removed.</string>
|
||||||
<string name="info_lockdown_admin_configured_network">Control whether the user can change networks configured by the admin.\nWhen this lockdown is enabled, the user can still configure and connect to other Wi-Fi networks, or use other Wi-Fi capabilities such as tethering.</string>
|
<string name="info_lockdown_admin_configured_network">Control whether the user can change networks configured by the admin.\nWhen this lockdown is enabled, the user can still configure and connect to other Wi-Fi networks, or use other Wi-Fi capabilities such as tethering.</string>
|
||||||
<string name="info_minimum_wifi_security_level">Specify the minimum security level required for Wi-Fi networks. The device may not connect to networks that do not meet the minimum security level. If the current network does not meet the minimum security level set, it will be disconnected.</string>
|
<string name="info_minimum_wifi_security_level">Specify the minimum security level required for Wi-Fi networks. The device may not connect to networks that do not meet the minimum security level. If the current network does not meet the minimum security level set, it will be disconnected.</string>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.7.2"
|
agp = "8.7.3"
|
||||||
kotlin = "2.0.21"
|
kotlin = "2.0.21"
|
||||||
|
|
||||||
navigation-compose = "2.8.3"
|
navigation-compose = "2.8.4"
|
||||||
composeBom = "2024.10.01"
|
composeBom = "2024.11.00"
|
||||||
accompanist-drawablepainter = "0.35.0-alpha"
|
accompanist-drawablepainter = "0.35.0-alpha"
|
||||||
shizuku = "13.1.5"
|
shizuku = "13.1.5"
|
||||||
biometric = "1.2.0-alpha05"
|
biometric = "1.2.0-alpha05"
|
||||||
fragment = "1.8.0-beta01"
|
fragment = "1.8.5"
|
||||||
dhizuku = "2.5.2"
|
dhizuku = "2.5.3"
|
||||||
hiddenApiBypass = "4.3"
|
hiddenApiBypass = "4.3"
|
||||||
serialization = "1.7.3"
|
serialization = "1.7.3"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user