From 5c7289381f888a082d6f79d27d2794c657257528 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Tue, 18 Feb 2025 15:56:16 +0800 Subject: [PATCH] UpdatesPreference: Allow to configure automated updates constraints Signed-off-by: Aayush Gupta --- .../aurora/store/data/helper/UpdateHelper.kt | 17 ++++- .../java/com/aurora/store/util/Preferences.kt | 4 ++ .../{ => updates}/UpdatesPreference.kt | 19 ++++- .../updates/UpdatesRestrictionsDialog.kt | 70 +++++++++++++++++++ .../UpdatesRestrictionsViewModel.kt | 14 ++++ .../dialog_auto_updates_restrictions.xml | 32 +++++++++ .../main/res/navigation/mobile_navigation.xml | 8 ++- app/src/main/res/values/strings.xml | 7 ++ app/src/main/res/xml/preferences_updates.xml | 7 ++ 9 files changed, 172 insertions(+), 6 deletions(-) rename app/src/main/java/com/aurora/store/view/ui/preferences/{ => updates}/UpdatesPreference.kt (85%) create mode 100644 app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesRestrictionsDialog.kt create mode 100644 app/src/main/java/com/aurora/store/viewmodel/preferences/UpdatesRestrictionsViewModel.kt create mode 100644 app/src/main/res/layout/dialog_auto_updates_restrictions.xml diff --git a/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt b/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt index 802ad64d8..d9617df8c 100644 --- a/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt +++ b/app/src/main/java/com/aurora/store/data/helper/UpdateHelper.kt @@ -20,6 +20,9 @@ import com.aurora.store.data.model.UpdateMode import com.aurora.store.data.room.update.UpdateDao import com.aurora.store.data.work.UpdateWorker import com.aurora.store.util.Preferences +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_BATTERY +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_IDLE +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_METERED import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.SharingStarted @@ -160,10 +163,18 @@ class UpdateHelper @Inject constructor( ).toLong() val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) - .setRequiresBatteryNotLow(true) - if (isMAndAbove) constraints.setRequiresDeviceIdle(true) + if (Preferences.getBoolean(context, PREFERENCES_UPDATES_RESTRICTIONS_METERED, true)) { + constraints.setRequiredNetworkType(NetworkType.UNMETERED) + } + + if (Preferences.getBoolean(context, PREFERENCES_UPDATES_RESTRICTIONS_BATTERY, true)) { + constraints.setRequiresBatteryNotLow(true) + } + + if (isMAndAbove && Preferences.getBoolean(context, PREFERENCES_UPDATES_RESTRICTIONS_IDLE, true)) { + constraints.setRequiresDeviceIdle(true) + } return PeriodicWorkRequestBuilder( repeatInterval = updateCheckInterval, diff --git a/app/src/main/java/com/aurora/store/util/Preferences.kt b/app/src/main/java/com/aurora/store/util/Preferences.kt index 2177793b2..393de4c2c 100644 --- a/app/src/main/java/com/aurora/store/util/Preferences.kt +++ b/app/src/main/java/com/aurora/store/util/Preferences.kt @@ -55,6 +55,10 @@ object Preferences { const val PREFERENCE_UPDATES_EXTENDED = "PREFERENCE_UPDATES_EXTENDED" const val PREFERENCE_UPDATES_AUTO = "PREFERENCE_UPDATES_AUTO" const val PREFERENCE_UPDATES_CHECK_INTERVAL = "PREFERENCE_UPDATES_CHECK_INTERVAL" + const val PREFERENCES_UPDATES_RESTRICTIONS = "PREFERENCES_UPDATES_RESTRICTIONS" + const val PREFERENCES_UPDATES_RESTRICTIONS_METERED = "PREFERENCES_UPDATES_RESTRICTIONS_METERED" + const val PREFERENCES_UPDATES_RESTRICTIONS_IDLE = "PREFERENCES_UPDATES_RESTRICTIONS_IDLE" + const val PREFERENCES_UPDATES_RESTRICTIONS_BATTERY = "PREFERENCES_UPDATES_RESTRICTIONS_BATTERY" const val PREFERENCE_MIGRATION_VERSION = "PREFERENCE_MIGRATION_VERSION" diff --git a/app/src/main/java/com/aurora/store/view/ui/preferences/UpdatesPreference.kt b/app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesPreference.kt similarity index 85% rename from app/src/main/java/com/aurora/store/view/ui/preferences/UpdatesPreference.kt rename to app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesPreference.kt index 4becc4c2f..02c511071 100644 --- a/app/src/main/java/com/aurora/store/view/ui/preferences/UpdatesPreference.kt +++ b/app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesPreference.kt @@ -17,7 +17,7 @@ * */ -package com.aurora.store.view.ui.preferences +package com.aurora.store.view.ui.preferences.updates import android.os.Bundle import android.view.View @@ -25,18 +25,21 @@ import androidx.appcompat.widget.Toolbar import androidx.fragment.app.viewModels import androidx.navigation.fragment.findNavController import androidx.preference.ListPreference +import androidx.preference.Preference import androidx.preference.SeekBarPreference import androidx.preference.SwitchPreferenceCompat import com.aurora.store.R import com.aurora.store.data.model.PermissionType import com.aurora.store.data.model.UpdateMode import com.aurora.store.util.Preferences +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS import com.aurora.store.util.Preferences.PREFERENCE_FILTER_AURORA_ONLY import com.aurora.store.util.Preferences.PREFERENCE_FILTER_FDROID import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_EXTENDED import com.aurora.store.util.save +import com.aurora.store.view.ui.preferences.BasePreferenceFragment import com.aurora.store.viewmodel.all.UpdatesViewModel import dagger.hilt.android.AndroidEntryPoint @@ -49,11 +52,13 @@ class UpdatesPreference : BasePreferenceFragment() { setPreferencesFromResource(R.xml.preferences_updates, rootKey) findPreference(PREFERENCE_UPDATES_AUTO)?.setOnPreferenceChangeListener { _, newValue -> + val updateRestrictionsPref = findPreference(PREFERENCES_UPDATES_RESTRICTIONS) val updateCheckIntervalPref = findPreference(PREFERENCE_UPDATES_CHECK_INTERVAL) when (UpdateMode.entries[newValue.toString().toInt()]) { UpdateMode.DISABLED -> { + updateRestrictionsPref?.isEnabled = false updateCheckIntervalPref?.isEnabled = false viewModel.updateHelper.cancelAutomatedCheck() requireContext().save(PREFERENCE_UPDATES_AUTO, 0) @@ -62,12 +67,14 @@ class UpdatesPreference : BasePreferenceFragment() { UpdateMode.CHECK_AND_NOTIFY -> { if (permissionProvider.isGranted(PermissionType.POST_NOTIFICATIONS)) { + updateRestrictionsPref?.isEnabled = true updateCheckIntervalPref?.isEnabled = true viewModel.updateHelper.scheduleAutomatedCheck() true } else { permissionProvider.request(PermissionType.POST_NOTIFICATIONS) { if (it) { + updateRestrictionsPref?.isEnabled = true updateCheckIntervalPref?.isEnabled = true requireContext().save(PREFERENCE_UPDATES_AUTO, 1) viewModel.updateHelper.scheduleAutomatedCheck() @@ -80,12 +87,14 @@ class UpdatesPreference : BasePreferenceFragment() { UpdateMode.CHECK_AND_INSTALL -> { if (permissionProvider.isGranted(PermissionType.DOZE_WHITELIST)) { + updateRestrictionsPref?.isEnabled = true updateCheckIntervalPref?.isEnabled = true viewModel.updateHelper.scheduleAutomatedCheck() true } else { permissionProvider.request(PermissionType.DOZE_WHITELIST) { if (it) { + updateRestrictionsPref?.isEnabled = true updateCheckIntervalPref?.isEnabled = true requireContext().save(PREFERENCE_UPDATES_AUTO, 2) viewModel.updateHelper.scheduleAutomatedCheck() @@ -100,6 +109,14 @@ class UpdatesPreference : BasePreferenceFragment() { } } + findPreference(PREFERENCES_UPDATES_RESTRICTIONS)?.apply { + isEnabled = Preferences.getInteger(requireContext(), PREFERENCE_UPDATES_AUTO) != 0 + setOnPreferenceClickListener { + findNavController().navigate(R.id.updatesRestrictionsDialog) + true + } + } + findPreference(PREFERENCE_UPDATES_CHECK_INTERVAL)?.apply { isEnabled = Preferences.getInteger(requireContext(), PREFERENCE_UPDATES_AUTO) != 0 setOnPreferenceChangeListener { _, _ -> diff --git a/app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesRestrictionsDialog.kt b/app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesRestrictionsDialog.kt new file mode 100644 index 000000000..f9f046cd8 --- /dev/null +++ b/app/src/main/java/com/aurora/store/view/ui/preferences/updates/UpdatesRestrictionsDialog.kt @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2025 The Calyx Institute + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.aurora.store.view.ui.preferences.updates + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.viewModels +import com.aurora.store.R +import com.aurora.store.util.Preferences +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_BATTERY +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_IDLE +import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_METERED +import com.aurora.store.viewmodel.preferences.UpdatesRestrictionsViewModel +import com.google.android.material.checkbox.MaterialCheckBox +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class UpdatesRestrictionsDialog : DialogFragment() { + + private val viewModel: UpdatesRestrictionsViewModel by viewModels() + + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val view = layoutInflater.inflate(R.layout.dialog_auto_updates_restrictions, null) + return MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.pref_updates_restrictions_title) + .setMessage(R.string.pref_updates_restrictions_desc) + .setView(view) + .setPositiveButton(getString(android.R.string.ok)) { _, _ -> dialog?.dismiss()} + .create() + } + + override fun onResume() { + super.onResume() + context?.let { setupRestrictions(it) } + } + + override fun onDestroy() { + viewModel.updateHelper.updateAutomatedCheck() + super.onDestroy() + } + + private fun setupRestrictions(ctx: Context) { + dialog?.findViewById(R.id.checkboxMetered)?.apply { + isChecked = Preferences.getBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_METERED, true) + setOnCheckedChangeListener { _, isChecked -> + Preferences.putBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_METERED, isChecked) + } + } + + dialog?.findViewById(R.id.checkboxIdle)?.apply { + isChecked = Preferences.getBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_IDLE, true) + setOnCheckedChangeListener { _, isChecked -> + Preferences.putBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_IDLE, isChecked) + } + } + + dialog?.findViewById(R.id.checkboxBattery)?.apply { + isChecked = Preferences.getBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_BATTERY, true) + setOnCheckedChangeListener { _, isChecked -> + Preferences.putBoolean(ctx, PREFERENCES_UPDATES_RESTRICTIONS_BATTERY, isChecked) + } + } + } +} diff --git a/app/src/main/java/com/aurora/store/viewmodel/preferences/UpdatesRestrictionsViewModel.kt b/app/src/main/java/com/aurora/store/viewmodel/preferences/UpdatesRestrictionsViewModel.kt new file mode 100644 index 000000000..dd522204d --- /dev/null +++ b/app/src/main/java/com/aurora/store/viewmodel/preferences/UpdatesRestrictionsViewModel.kt @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2025 The Calyx Institute + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package com.aurora.store.viewmodel.preferences + +import androidx.lifecycle.ViewModel +import com.aurora.store.data.helper.UpdateHelper +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class UpdatesRestrictionsViewModel @Inject constructor(val updateHelper: UpdateHelper) : ViewModel() diff --git a/app/src/main/res/layout/dialog_auto_updates_restrictions.xml b/app/src/main/res/layout/dialog_auto_updates_restrictions.xml new file mode 100644 index 000000000..ff662396b --- /dev/null +++ b/app/src/main/res/layout/dialog_auto_updates_restrictions.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index cc9b5c3a3..e1ab67ccc 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -113,7 +113,7 @@ tools:layout="@layout/fragment_setting" /> + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3563b371..90d87d355 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -495,4 +495,11 @@ Proxy disabled successfully View and manage proxy configuration protocol://user:password@host:port + + + Automatic updates restrictions + Configure device restrictions for automated updates. + Only on unmetered networks + When device is idle + When battery is not low diff --git a/app/src/main/res/xml/preferences_updates.xml b/app/src/main/res/xml/preferences_updates.xml index a803bf3a3..7d6ce9be4 100644 --- a/app/src/main/res/xml/preferences_updates.xml +++ b/app/src/main/res/xml/preferences_updates.xml @@ -40,6 +40,13 @@ app:min="1" app:showSeekBarValue="true" /> + +