Skip to content

Commit

Permalink
Use main NavHost to navigate across all pages
Browse files Browse the repository at this point in the history
Upgrade dependencies
Upload dependencies to GitHub in workflow
  • Loading branch information
BinTianqi committed Dec 7, 2024
1 parent 0c670e9 commit 380675c
Show file tree
Hide file tree
Showing 19 changed files with 647 additions and 1,100 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed
path: app/build/outputs/apk/release/app-release.apk

- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v4

upload-telegram:
name: Upload Builds
if: ${{ success() }}
Expand Down
270 changes: 205 additions & 65 deletions app/src/main/java/com/bintianqi/owndroid/MainActivity.kt

Large diffs are not rendered by default.

97 changes: 27 additions & 70 deletions app/src/main/java/com/bintianqi/owndroid/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,15 @@ import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -37,76 +31,44 @@ import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
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.ui.Animations
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.TopBar
import java.security.SecureRandom

@Composable
fun AppSetting(navCtrl:NavHostController, vm: MyViewModel) {
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 = "Options") { Options() }
composable(route = "Theme") { ThemeSettings(vm) }
composable(route = "Auth") { AuthSettings() }
composable(route = "Automation") { Automation() }
composable(route = "About") { About() }
}
fun Settings(navCtrl: NavHostController) {
MyScaffold(R.string.settings, 0.dp, navCtrl) {
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
FunctionItem(R.string.appearance, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Appearance") }
FunctionItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("AuthSettings") }
FunctionItem(R.string.automation_api, "", R.drawable.apps_fill0) { navCtrl.navigate("Automation") }
FunctionItem(R.string.about, "", R.drawable.info_fill0) { navCtrl.navigate("About") }
}
}

@Composable
private fun Home(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() {
fun SettingsOptions(navCtrl: NavHostController) {
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(
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
{ sharedPref.getBoolean("dangerous_features", false) },
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }, padding = false
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }
)
}
}

@Composable
private fun ThemeSettings(vm: MyViewModel) {
fun Appearance(navCtrl: NavHostController, vm: MyViewModel) {
val theme by vm.theme.collectAsStateWithLifecycle()
var darkThemeMenu by remember { mutableStateOf(false) }
val darkThemeTextID = when(theme.darkTheme) {
true -> R.string.on
false -> R.string.off
null -> R.string.follow_system
}
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
MyScaffold(R.string.appearance, 0.dp, navCtrl) {
if(VERSION.SDK_INT >= 31) {
SwitchItem(
R.string.material_you_color, "", null,
Expand All @@ -115,7 +77,7 @@ private fun ThemeSettings(vm: MyViewModel) {
)
}
Box {
SubPageItem(R.string.dark_theme, stringResource(darkThemeTextID)) { darkThemeMenu = true }
FunctionItem(R.string.dark_theme, stringResource(darkThemeTextID)) { darkThemeMenu = true }
DropdownMenu(
expanded = darkThemeMenu, onDismissRequest = { darkThemeMenu = false },
offset = DpOffset(x = 25.dp, y = 0.dp)
Expand Down Expand Up @@ -154,44 +116,42 @@ private fun ThemeSettings(vm: MyViewModel) {
}

@Composable
private fun AuthSettings() {
fun AuthSettings(navCtrl: NavHostController) {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
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(
R.string.lock_owndroid, "", null, auth,
{
sharedPref.edit().putBoolean("auth", it).apply()
auth = sharedPref.getBoolean("auth", false)
}, padding = false
}
)
if(auth) {
SwitchItem(
R.string.enable_bio_auth, "", null,
{ sharedPref.getBoolean("bio_auth", false) },
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }, padding = false
{ sharedPref.edit().putBoolean("bio_auth", it).apply() }
)
SwitchItem(
R.string.lock_in_background, stringResource(R.string.developing), null,
{ 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(
R.string.protect_storage, "", null,
{ sharedPref.getBoolean("protect_storage", false) },
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }, padding = false
{ sharedPref.edit().putBoolean("protect_storage", it).apply() }
)
}
}

@Composable
private fun Automation() {
fun Automation(navCtrl: NavHostController) {
val context = LocalContext.current
val sharedPref = context.getSharedPreferences("data", Context.MODE_PRIVATE)
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.automation_api), style = typography.headlineLarge)
MyScaffold(R.string.automation_api, 8.dp, navCtrl) {
Spacer(Modifier.padding(vertical = 5.dp))
var key by remember { mutableStateOf("") }
OutlinedTextField(
Expand Down Expand Up @@ -229,18 +189,15 @@ private fun Automation() {
}

@Composable
private fun About() {
fun About(navCtrl: NavHostController) {
val context = LocalContext.current
val pkgInfo = context.packageManager.getPackageInfo(context.packageName,0)
val verCode = pkgInfo.versionCode
val verName = pkgInfo.versionName
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.about), style = typography.headlineLarge, modifier = Modifier.padding(start = 26.dp))
Spacer(Modifier.padding(vertical = 5.dp))
Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", modifier = Modifier.padding(start = 26.dp))
MyScaffold(R.string.about, 0.dp, navCtrl) {
Text(text = stringResource(R.string.app_name)+" v$verName ($verCode)", modifier = Modifier.padding(start = 16.dp))
Spacer(Modifier.padding(vertical = 5.dp))
SubPageItem(R.string.project_homepage, "GitHub", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
FunctionItem(R.string.project_homepage, "GitHub", R.drawable.open_in_new) { shareLink(context, "https://github.com/BinTianqi/OwnDroid") }
}
}

Expand Down
32 changes: 16 additions & 16 deletions app/src/main/java/com/bintianqi/owndroid/dpm/Applications.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import com.bintianqi.owndroid.ui.Information
import com.bintianqi.owndroid.ui.ListItem
import com.bintianqi.owndroid.ui.NavIcon
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 java.util.concurrent.Executors

Expand Down Expand Up @@ -119,7 +119,7 @@ fun ApplicationManage(navCtrl:NavHostController, dialogStatus: MutableIntState)
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
trailingIcon = {
Icon(painter = painterResource(R.drawable.checklist_fill0), contentDescription = null,
Icon(painter = painterResource(R.drawable.list_fill0), contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.clickable(onClick = {
Expand Down Expand Up @@ -216,7 +216,7 @@ private fun Home(
if(VERSION.SDK_INT >= 24 && profileOwner && dpm.isManagedProfile(receiver)) {
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)
intent.setData(Uri.parse("package:$pkgName"))
startActivity(context, intent, null)
Expand All @@ -242,37 +242,37 @@ private fun Home(
onClickBlank = { appControlAction = 3; appControlDialog = true }
)
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) {
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)) {
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) {
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) {
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") }
SubPageItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
SubPageItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
FunctionItem(R.string.permitted_accessibility_services, "", R.drawable.settings_accessibility_fill0) { navCtrl.navigate("Accessibility") }
FunctionItem(R.string.permitted_ime, "", R.drawable.keyboard_fill0) { navCtrl.navigate("IME") }
FunctionItem(R.string.enable_system_app, "", R.drawable.enable_fill0) {
if(pkgName != "") dialogStatus.intValue = 1
}
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) {
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
}
}
SubPageItem(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.install_app, "", R.drawable.install_mobile_fill0) { navCtrl.navigate("InstallApp") }
FunctionItem(R.string.uninstall_app, "", R.drawable.delete_fill0) { navCtrl.navigate("UninstallApp") }
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
}
}
Expand Down
16 changes: 12 additions & 4 deletions app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private fun binderWrapperPackageInstaller(appContext: Context): PackageInstaller
fun Context.getPI(): PackageInstaller {
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
if(sharedPref.getBoolean("dhizuku", false)) {
if (!Dhizuku.isPermissionGranted()) {
if (!dhizukuPermissionGranted()) {
dhizukuErrorStatus.value = 2
backToHomeStateFlow.value = true
return this.packageManager.packageInstaller
Expand All @@ -167,7 +167,7 @@ fun Context.getPI(): PackageInstaller {
fun Context.getDPM(): DevicePolicyManager {
val sharedPref = this.getSharedPreferences("data", Context.MODE_PRIVATE)
if(sharedPref.getBoolean("dhizuku", false)) {
if (!Dhizuku.isPermissionGranted()) {
if (!dhizukuPermissionGranted()) {
dhizukuErrorStatus.value = 2
backToHomeStateFlow.value = true
return this.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
Expand All @@ -193,7 +193,7 @@ fun Context.resetDevicePolicy() {
val dpm = getDPM()
val receiver = getReceiver()
RestrictionData.getAllRestrictions().forEach {
dpm.clearUserRestriction(receiver, it)
dpm.clearUserRestriction(receiver, it.id)
}
dpm.accountTypesWithManagementDisabled?.forEach {
dpm.setAccountManagementDisabled(receiver, it, false)
Expand Down Expand Up @@ -428,7 +428,7 @@ fun parseSecurityEventData(event: SecurityLog.SecurityEvent): JsonElement? {
val payload = event.data as Array<*>
buildJsonObject {
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 -> {
Expand Down Expand Up @@ -619,3 +619,11 @@ fun setDefaultAffiliationID(context: Context) {
}
}
}

fun dhizukuPermissionGranted() =
try {
Dhizuku.isPermissionGranted()
} catch(_: Exception) {
false
}

Loading

0 comments on commit 380675c

Please sign in to comment.