From d030a7ac2e4f95171ae566f642f2755873ab3b60 Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Mon, 18 Mar 2024 19:43:28 +0530 Subject: [PATCH] Respect battery optimization setting when auto-updating * Don't enable auto-install for updates if battery optimization permission is not granted during onboarding. * Drop showing warning in toolbar, show it instead if they want auto-install * Don't check for the same during downloads. Failing is better instead. Signed-off-by: Aayush Gupta --- .../java/com/aurora/extensions/Context.kt | 8 +++++--- .../java/com/aurora/store/MainActivity.kt | 14 ------------- .../aurora/store/data/work/UpdateWorker.kt | 20 ++++++++++++++----- .../aurora/store/util/DownloadWorkerUtil.kt | 13 +++--------- .../view/ui/onboarding/OnboardingFragment.kt | 9 +++++++-- .../view/ui/preferences/UpdatesPreference.kt | 19 +++++++++++++++--- .../store/view/ui/sheets/DozeWarningSheet.kt | 16 +++++++++++---- app/src/main/res/menu/menu_main.xml | 7 ------- .../main/res/navigation/mobile_navigation.xml | 10 +++++++++- 9 files changed, 67 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/aurora/extensions/Context.kt b/app/src/main/java/com/aurora/extensions/Context.kt index c1d21206e..d6f3a0a24 100644 --- a/app/src/main/java/com/aurora/extensions/Context.kt +++ b/app/src/main/java/com/aurora/extensions/Context.kt @@ -177,7 +177,9 @@ fun Context.accentColor(): Int { } fun Context.isIgnoringBatteryOptimizations(): Boolean { - if (!isMAndAbove()) return true - return !(getSystemService(Context.POWER_SERVICE) as PowerManager) - .isIgnoringBatteryOptimizations(packageName) + return if (isMAndAbove()) { + (getSystemService(Context.POWER_SERVICE) as PowerManager).isIgnoringBatteryOptimizations(packageName) + } else { + true + } } diff --git a/app/src/main/java/com/aurora/store/MainActivity.kt b/app/src/main/java/com/aurora/store/MainActivity.kt index 9cfecb79d..fd93817e5 100644 --- a/app/src/main/java/com/aurora/store/MainActivity.kt +++ b/app/src/main/java/com/aurora/store/MainActivity.kt @@ -20,13 +20,11 @@ package com.aurora.store -import android.content.Context import android.content.Intent import android.content.res.ColorStateList import android.os.Build import android.os.Bundle import android.os.Environment -import android.os.PowerManager import android.provider.Settings import android.view.Menu import android.view.MenuItem @@ -51,7 +49,6 @@ import coil.transform.RoundedCornersTransformation import com.aurora.Constants import com.aurora.extensions.accentColor import com.aurora.extensions.applyThemeAccent -import com.aurora.extensions.isMAndAbove import com.aurora.store.data.model.NetworkStatus import com.aurora.store.data.providers.NetworkProvider import com.aurora.store.databinding.ActivityMainBinding @@ -171,12 +168,6 @@ class MainActivity : AppCompatActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) - - // Show warning if battery optimizations is enabled - val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager - if (isMAndAbove() && !powerManager.isIgnoringBatteryOptimizations(packageName)) { - menu.findItem(R.id.menu_doze_info)?.isVisible = true - } return true } @@ -186,11 +177,6 @@ class MainActivity : AppCompatActivity() { navController.navigate(R.id.downloadFragment) return true } - - R.id.menu_doze_info -> { - navController.navigate(R.id.dozeWarningSheet) - return true - } } return super.onOptionsItemSelected(item) } diff --git a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt index 7d66e8d3e..daf7a3076 100644 --- a/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/UpdateWorker.kt @@ -15,6 +15,7 @@ import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import androidx.work.WorkerParameters import com.aurora.Constants +import com.aurora.extensions.isIgnoringBatteryOptimizations import com.aurora.extensions.isMAndAbove import com.aurora.gplayapi.data.models.App import com.aurora.gplayapi.data.models.AuthData @@ -32,6 +33,7 @@ import com.aurora.store.util.PackageUtil import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL +import com.aurora.store.util.save import com.google.gson.Gson import dagger.assisted.Assisted import dagger.assisted.AssistedInject @@ -150,6 +152,7 @@ class UpdateWorker @AssistedInject constructor( override suspend fun doWork(): Result { val autoUpdatesMode = Preferences.getInteger(appContext, PREFERENCE_UPDATES_AUTO, 3) + val notifyManager = appContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager // Exit if auto-updates is turned off in settings if (autoUpdatesMode == 0) { @@ -214,16 +217,23 @@ class UpdateWorker @AssistedInject constructor( if (updatesList.isNotEmpty()) { if (autoUpdatesMode == 1) { Log.i(TAG,"Found updates, notifying!") - val notifyManager = - appContext.getSystemService(Context.NOTIFICATION_SERVICE) - as NotificationManager notifyManager.notify( notificationID, NotificationUtil.getUpdateNotification(appContext, updatesList) ) } else { - Log.i(TAG,"Found updates, updating!") - updatesList.forEach { downloadWorkerUtil.enqueueApp(it) } + if (appContext.isIgnoringBatteryOptimizations()) { + Log.i(TAG,"Found updates, updating!") + updatesList.forEach { downloadWorkerUtil.enqueueApp(it) } + } else { + // Fallback to notification if battery optimizations are enabled + Log.i(TAG,"Found updates, but battery optimizations are enabled!") + notifyManager.notify( + notificationID, + NotificationUtil.getUpdateNotification(appContext, updatesList) + ) + appContext.save(PREFERENCE_UPDATES_AUTO, 1) + } } return@withContext Result.success() } diff --git a/app/src/main/java/com/aurora/store/util/DownloadWorkerUtil.kt b/app/src/main/java/com/aurora/store/util/DownloadWorkerUtil.kt index 07f8b34a5..a2f20d720 100644 --- a/app/src/main/java/com/aurora/store/util/DownloadWorkerUtil.kt +++ b/app/src/main/java/com/aurora/store/util/DownloadWorkerUtil.kt @@ -7,7 +7,6 @@ import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequestBuilder import androidx.work.OutOfQuotaPolicy import androidx.work.WorkManager -import com.aurora.extensions.isIgnoringBatteryOptimizations import com.aurora.gplayapi.data.models.App import com.aurora.store.data.model.DownloadStatus import com.aurora.store.data.room.download.Download @@ -18,7 +17,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Inject import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.filter @@ -64,16 +62,11 @@ class DownloadWorkerUtil @Inject constructor( val enqueuedDownloads = list.filter { it.downloadStatus == DownloadStatus.QUEUED } enqueuedDownloads.firstOrNull()?.let { try { - if (context.isIgnoringBatteryOptimizations() || CommonUtil.inForeground()) { - Log.i(DOWNLOAD_WORKER, "Downloading ${it.packageName}") - trigger(it) - } else { - Log.i(TAG, "Not in foreground or ignoring battery optimization") - cancel() - } + Log.i(DOWNLOAD_WORKER, "Downloading ${it.packageName}") + trigger(it) } catch (exception: Exception) { Log.i(DOWNLOAD_WORKER, "Failed to download app", exception) - downloadDao.delete(it.packageName) + downloadDao.updateStatus(it.packageName, DownloadStatus.FAILED) } } } diff --git a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt index 8ba7f6cde..a9c211836 100644 --- a/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt +++ b/app/src/main/java/com/aurora/store/view/ui/onboarding/OnboardingFragment.kt @@ -27,6 +27,7 @@ import androidx.lifecycle.Lifecycle import androidx.navigation.fragment.findNavController import androidx.viewpager2.adapter.FragmentStateAdapter import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback +import com.aurora.extensions.isIgnoringBatteryOptimizations import com.aurora.store.R import com.aurora.store.data.work.UpdateWorker import com.aurora.store.databinding.FragmentOnboardingBinding @@ -127,8 +128,8 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) { binding.btnForward.text = getString(R.string.action_finish) binding.btnForward.isEnabled = true binding.btnForward.setOnClickListener { + setupAutoUpdates() save(PREFERENCE_INTRO, true) - UpdateWorker.scheduleAutomatedCheck(requireContext()) findNavController().navigate( OnboardingFragmentDirections.actionOnboardingFragmentToSplashFragment() ) @@ -165,7 +166,11 @@ class OnboardingFragment : Fragment(R.layout.fragment_onboarding) { /*Updates*/ save(PREFERENCE_UPDATES_EXTENDED, false) - save(PREFERENCE_UPDATES_AUTO, 2) save(PREFERENCE_UPDATES_CHECK_INTERVAL, 3) } + + private fun setupAutoUpdates() { + save(PREFERENCE_UPDATES_AUTO, if (requireContext().isIgnoringBatteryOptimizations()) 2 else 1) + UpdateWorker.scheduleAutomatedCheck(requireContext()) + } } 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/UpdatesPreference.kt index ce8ab4edf..56347ad0f 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/UpdatesPreference.kt @@ -25,6 +25,8 @@ import androidx.appcompat.widget.Toolbar import androidx.navigation.fragment.findNavController import androidx.preference.ListPreference import androidx.preference.SeekBarPreference +import com.aurora.extensions.isIgnoringBatteryOptimizations +import com.aurora.store.MobileNavigationDirections import com.aurora.store.R import com.aurora.store.data.work.UpdateWorker import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO @@ -39,11 +41,22 @@ class UpdatesPreference : BasePreferenceFragment() { findPreference(PREFERENCE_UPDATES_AUTO) ?.setOnPreferenceChangeListener { _, newValue -> - when (newValue.toString().toInt()) { + val value = newValue.toString().toInt() + when (value) { 0 -> UpdateWorker.cancelAutomatedCheck(requireContext()) - else -> UpdateWorker.scheduleAutomatedCheck(requireContext()) + 1 -> UpdateWorker.scheduleAutomatedCheck(requireContext()) + else -> { + if (requireContext().isIgnoringBatteryOptimizations()) { + UpdateWorker.scheduleAutomatedCheck(requireContext()) + return@setOnPreferenceChangeListener true + } else { + findNavController().navigate( + MobileNavigationDirections.actionGlobalDozeWarningSheet(true) + ) + } + } } - true + value != 2 } findPreference(PREFERENCE_UPDATES_CHECK_INTERVAL) diff --git a/app/src/main/java/com/aurora/store/view/ui/sheets/DozeWarningSheet.kt b/app/src/main/java/com/aurora/store/view/ui/sheets/DozeWarningSheet.kt index c7e31a3c6..a32dd944a 100644 --- a/app/src/main/java/com/aurora/store/view/ui/sheets/DozeWarningSheet.kt +++ b/app/src/main/java/com/aurora/store/view/ui/sheets/DozeWarningSheet.kt @@ -1,27 +1,35 @@ package com.aurora.store.view.ui.sheets -import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle -import android.os.PowerManager import android.provider.Settings import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.activity.result.contract.ActivityResultContracts +import androidx.navigation.fragment.navArgs +import com.aurora.extensions.isIgnoringBatteryOptimizations import com.aurora.extensions.isMAndAbove import com.aurora.extensions.toast import com.aurora.store.R +import com.aurora.store.data.work.UpdateWorker import com.aurora.store.databinding.SheetDozeWarningBinding +import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_AUTO +import com.aurora.store.util.save class DozeWarningSheet : BaseBottomSheet() { + private val args: DozeWarningSheetArgs by navArgs() + private val startForDozeResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { context?.let { - val powerManager = it.getSystemService(Context.POWER_SERVICE) as PowerManager - if (isMAndAbove() && powerManager.isIgnoringBatteryOptimizations(it.packageName)) { + if (it.isIgnoringBatteryOptimizations()) { + if (args.enableAutoUpdate) { + requireContext().save(PREFERENCE_UPDATES_AUTO, 2) + UpdateWorker.scheduleAutomatedCheck(requireContext()) + } toast(R.string.toast_permission_granted) activity?.recreate() } else { diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index be59081ee..9e1845862 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -25,11 +25,4 @@ android:icon="@drawable/ic_download_manager" android:title="@string/title_download_manager" app:showAsAction="always" /> - - diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml index c775272ac..3cde4cdb9 100644 --- a/app/src/main/res/navigation/mobile_navigation.xml +++ b/app/src/main/res/navigation/mobile_navigation.xml @@ -47,6 +47,9 @@ + + tools:layout="@layout/sheet_doze_warning"> + +