From 54daa402e4f020375044f4234c464baf5e9ab539 Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 23 Sep 2021 09:27:15 +0200 Subject: [PATCH] Switch to polling if battery optimizations enabled on Android 12+ --- .../java/eu/faircode/email/EntityAccount.java | 11 +++++++++- .../email/FragmentOptionsSynchronize.java | 3 ++- .../main/java/eu/faircode/email/Helper.java | 17 ++++++++++++++++ .../eu/faircode/email/ServiceSynchronize.java | 20 +++++++++---------- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/EntityAccount.java b/app/src/main/java/eu/faircode/email/EntityAccount.java index 82dc5cfb7d..135c695408 100644 --- a/app/src/main/java/eu/faircode/email/EntityAccount.java +++ b/app/src/main/java/eu/faircode/email/EntityAccount.java @@ -170,7 +170,16 @@ public class EntityAccount extends EntityOrder implements Serializable { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean enabled = prefs.getBoolean("enabled", true); int pollInterval = ServiceSynchronize.getPollInterval(context); - return (!enabled || this.ondemand || (pollInterval > 0 && !this.poll_exempted)); + return (!enabled || this.ondemand || (pollInterval > 0 && !isExempted(context))); + } + + boolean isExempted(Context context) { + if (Helper.isTarget(context, Build.VERSION_CODES.R)) { + Boolean ignoring = Helper.isIgnoringOptimizations(context); + if (ignoring != null && !ignoring) + return false; + } + return this.poll_exempted; } String getProtocol() { diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java index cace97facb..5ad2644bb8 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java @@ -23,6 +23,7 @@ import android.app.Dialog; import android.app.TimePickerDialog; import android.content.Context; import android.content.SharedPreferences; +import android.os.Build; import android.os.Bundle; import android.text.format.DateFormat; import android.view.LayoutInflater; @@ -449,7 +450,7 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr swEnabled.setChecked(prefs.getBoolean("enabled", true)); swOptimize.setChecked(prefs.getBoolean("auto_optimize", false)); - int pollInterval = ServiceSynchronize.getPollInterval(getContext()); + int pollInterval = prefs.getInt("poll_interval", 0); int[] pollIntervalValues = getResources().getIntArray(R.array.pollIntervalValues); for (int pos = 0; pos < pollIntervalValues.length; pos++) if (pollIntervalValues[pos] == pollInterval) { diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index 2e0e575ca0..dea39fb6ae 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -34,6 +34,7 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -432,6 +433,22 @@ public class Helper { return pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID); } + private static Integer targetSdk = null; + + static boolean isTarget(Context context, int sdk) { + if (targetSdk == null) + try { + PackageManager pm = context.getPackageManager(); + ApplicationInfo ai = pm.getApplicationInfo(BuildConfig.APPLICATION_ID, 0); + targetSdk = ai.targetSdkVersion; + } catch (Throwable ex) { + Log.e(ex); + targetSdk = Build.VERSION.SDK_INT; + } + + return (targetSdk >= sdk); + } + static Integer getBatteryLevel(Context context) { try { BatteryManager bm = (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index b8f922ec05..969708b7f2 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -2145,7 +2145,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences int pollInterval = getPollInterval(this); long now = new Date().getTime(); long delayed = now - account.last_connected - account.poll_interval * 60 * 1000L; - long maxDelayed = (pollInterval > 0 && !account.poll_exempted + long maxDelayed = (pollInterval > 0 && !account.isExempted(this) ? pollInterval * ACCOUNT_ERROR_AFTER_POLL : ACCOUNT_ERROR_AFTER) * 60 * 1000L; if (delayed > maxDelayed && state.getBackoff() >= CONNECT_BACKOFF_ALARM_START * 60) { @@ -2408,7 +2408,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences db.endTransaction(); } prefs.edit().putInt("poll_interval", OPTIMIZE_POLL_INTERVAL).apply(); - } else if (pollInterval <= 60 && account.poll_exempted) { + } else if (pollInterval <= 60 && account.isExempted(this)) { db.account().setAccountPollExempted(account.id, false); eval(this, "Optimize=" + reason); } @@ -2609,7 +2609,7 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences List result = new ArrayList<>(); for (TupleAccountState accountState : accountStates) result.add(new TupleAccountNetworkState( - enabled && (pollInterval == 0 || accountState.poll_exempted) && scheduled, + enabled && (pollInterval == 0 || accountState.isExempted(ServiceSynchronize.this)) && scheduled, command, networkState, accountState)); @@ -2721,14 +2721,14 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences } static int getPollInterval(Context context) { + if (Helper.isTarget(context, Build.VERSION_CODES.R)) { + Boolean ignoring = Helper.isIgnoringOptimizations(context); + if (ignoring != null && !ignoring) + return 15; + } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - int poll_interval = prefs.getInt("poll_interval", 0); // minutes - //if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) { - // Boolean ignoring = Helper.isIgnoringOptimizations(context); - // if (ignoring != null && !ignoring) - // poll_interval = 15; - //} - return poll_interval; + return prefs.getInt("poll_interval", 0); // minutes } static long[] getSchedule(Context context) {