From 244b6df87e885031d1516b45cc213e51eafe4d99 Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 23 Sep 2021 20:06:00 +0200 Subject: [PATCH] Android 12 foreground restrictions --- app/build.gradle | 2 +- .../faircode/email/AlarmManagerCompatEx.java | 7 ++-- .../java/eu/faircode/email/ApplicationEx.java | 9 +++-- .../java/eu/faircode/email/EntityAccount.java | 7 +--- .../faircode/email/FragmentDialogStill.java | 24 +++++-------- .../eu/faircode/email/FragmentMessages.java | 18 ++++++---- .../email/FragmentOptionsSynchronize.java | 3 +- .../java/eu/faircode/email/FragmentSetup.java | 6 +++- .../main/java/eu/faircode/email/Helper.java | 18 +++------- .../eu/faircode/email/ServiceSynchronize.java | 7 ++-- app/src/main/res/layout/dialog_setup.xml | 27 +++++++------- app/src/main/res/layout/fragment_setup.xml | 36 +++++++++++++++---- app/src/main/res/values/strings.xml | 3 +- 13 files changed, 94 insertions(+), 73 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3c0e45d87a..31fc349e4f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -19,7 +19,7 @@ android { defaultConfig { applicationId "eu.faircode.email" minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 31 versionCode getVersionCode() versionName "1." + getVersionCode() archivesBaseName = "FairEmail-v$versionName" diff --git a/app/src/main/java/eu/faircode/email/AlarmManagerCompatEx.java b/app/src/main/java/eu/faircode/email/AlarmManagerCompatEx.java index 5166d76b3a..65c6f4a25d 100644 --- a/app/src/main/java/eu/faircode/email/AlarmManagerCompatEx.java +++ b/app/src/main/java/eu/faircode/email/AlarmManagerCompatEx.java @@ -44,7 +44,7 @@ public class AlarmManagerCompatEx { AlarmManagerCompat.setAndAllowWhileIdle(am, type, trigger, pi); } - static boolean hasExactAlarms(Context context){ + static boolean hasExactAlarms(Context context) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean exact_alarms = prefs.getBoolean("exact_alarms", true); return (exact_alarms && canScheduleExactAlarms(context)); @@ -53,10 +53,13 @@ public class AlarmManagerCompatEx { static boolean canScheduleExactAlarms(Context context) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) return true; - else { + try { // https://developer.android.com/about/versions/12/behavior-changes-12#exact-alarm-permission AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); return am.canScheduleExactAlarms(); + } catch (Throwable ex) { + Log.e(ex); + return false; } } } diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java index aa04fcdd1e..890b866784 100644 --- a/app/src/main/java/eu/faircode/email/ApplicationEx.java +++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java @@ -196,8 +196,10 @@ public class ApplicationEx extends Application DisconnectBlacklist.init(this); - ServiceSynchronize.watchdog(this); - ServiceSend.watchdog(this); + if (!Helper.isOptimizing12(this)) { + ServiceSynchronize.watchdog(this); + ServiceSend.watchdog(this); + } ServiceSynchronize.scheduleWatchdog(this); WorkManager.getInstance(this).cancelUniqueWork("WorkerWatchdog"); @@ -519,6 +521,9 @@ public class ApplicationEx extends Application } else if (version < 1721) { if (!prefs.contains("discard_delete")) editor.putBoolean("discard_delete", false); + } else if (version < 1732) { + if (Helper.isOptimizing12(context)) + editor.remove("setup_reminder"); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !BuildConfig.DEBUG) diff --git a/app/src/main/java/eu/faircode/email/EntityAccount.java b/app/src/main/java/eu/faircode/email/EntityAccount.java index 135c695408..6a79649df7 100644 --- a/app/src/main/java/eu/faircode/email/EntityAccount.java +++ b/app/src/main/java/eu/faircode/email/EntityAccount.java @@ -174,12 +174,7 @@ public class EntityAccount extends EntityOrder implements Serializable { } 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; + return (!Helper.isOptimizing12(context) && this.poll_exempted); } String getProtocol() { diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogStill.java b/app/src/main/java/eu/faircode/email/FragmentDialogStill.java index a148f1a9dd..fc40d20401 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogStill.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogStill.java @@ -49,7 +49,7 @@ public class FragmentDialogStill extends FragmentDialogBase { View dview = LayoutInflater.from(context).inflate(R.layout.dialog_setup, null); TextView tvDozeDevice = dview.findViewById(R.id.tvDozeDevice); TextView tvDozeAndroid = dview.findViewById(R.id.tvDozeAndroid); - ImageButton ibInfo = dview.findViewById(R.id.ibInfo); + TextView tvInexact = dview.findViewById(R.id.tvInexact); CheckBox cbNotAgain = dview.findViewById(R.id.cbNotAgain); Group grp2 = dview.findViewById(R.id.grp2); Group grp3 = dview.findViewById(R.id.grp3); @@ -62,13 +62,6 @@ public class FragmentDialogStill extends FragmentDialogBase { } }); - ibInfo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Helper.view(v.getContext(), Uri.parse(Helper.DONTKILL_URI), true); - } - }); - cbNotAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -80,11 +73,12 @@ public class FragmentDialogStill extends FragmentDialogBase { boolean hasPermissions = Helper.hasPermission(context, Manifest.permission.READ_CONTACTS); Boolean isIgnoring = Helper.isIgnoringOptimizations(context); boolean isKilling = Helper.isKilling() && !(isIgnoring == null || isIgnoring); - boolean isRequired = Helper.isDozeRequired() && !(isIgnoring == null || isIgnoring); + boolean isOptimizing = Helper.isOptimizing12(context); + boolean canSchedule = AlarmManagerCompatEx.canScheduleExactAlarms(context); - tvDozeDevice.setVisibility(isKilling && !isRequired ? View.VISIBLE : View.GONE); - tvDozeAndroid.setVisibility(isRequired ? View.VISIBLE : View.GONE); - cbNotAgain.setVisibility(isRequired ? View.GONE : View.VISIBLE); + tvDozeDevice.setVisibility(isKilling && !isOptimizing ? View.VISIBLE : View.GONE); + tvDozeAndroid.setVisibility(isOptimizing ? View.VISIBLE : View.GONE); + tvInexact.setVisibility(canSchedule ? View.GONE : View.VISIBLE); grp2.setVisibility(hasPermissions ? View.GONE : View.VISIBLE); grp3.setVisibility(isIgnoring == null || isIgnoring ? View.GONE : View.VISIBLE); @@ -96,10 +90,8 @@ public class FragmentDialogStill extends FragmentDialogBase { public void onClick(DialogInterface dialog, int which) { sendResult(Activity.RESULT_OK); } - }); - - if (!isRequired) - builder.setNegativeButton(android.R.string.cancel, null); + }) + .setNegativeButton(android.R.string.cancel, null); return builder.create(); } diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index c221148b09..2509469075 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -4189,15 +4189,21 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. if (viewType != AdapterMessage.ViewType.UNIFIED) return false; - if (!Helper.isDozeRequired()) - return false; - final Context context = getContext(); - Boolean isIgnoring = Helper.isIgnoringOptimizations(context); - if (isIgnoring == null || isIgnoring) + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean setup_reminder = prefs.getBoolean("setup_reminder", true); + if (!setup_reminder) return false; - final Snackbar snackbar = Snackbar.make(view, R.string.title_setup_doze, Snackbar.LENGTH_INDEFINITE) + boolean isOptimizing = Helper.isOptimizing12(context); + boolean canSchedule = AlarmManagerCompatEx.canScheduleExactAlarms(context); + + if (!isOptimizing && canSchedule) + return false; + + final Snackbar snackbar = Snackbar.make(view, + canSchedule ? R.string.title_setup_doze_12 : R.string.title_setup_alarm_12, + Snackbar.LENGTH_INDEFINITE) .setGestureInsetBottomIgnored(true); snackbar.setAction(R.string.title_fix, new View.OnClickListener() { @Override diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java index 5ad2644bb8..0acb82fe2c 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsSynchronize.java @@ -556,7 +556,8 @@ public class FragmentOptionsSynchronize extends FragmentBase implements SharedPr } private void bindTo(EntityAccount account) { - cbExempted.setEnabled(!account.ondemand && account.protocol == EntityAccount.TYPE_IMAP); + cbExempted.setEnabled(!Helper.isOptimizing12(context) && + !account.ondemand && account.protocol == EntityAccount.TYPE_IMAP); cbExempted.setChecked(account.poll_exempted); cbExempted.setText(account.name); } diff --git a/app/src/main/java/eu/faircode/email/FragmentSetup.java b/app/src/main/java/eu/faircode/email/FragmentSetup.java index 44a05fc0f5..a3a9128e13 100644 --- a/app/src/main/java/eu/faircode/email/FragmentSetup.java +++ b/app/src/main/java/eu/faircode/email/FragmentSetup.java @@ -93,6 +93,7 @@ public class FragmentSetup extends FragmentBase { private TextView tvDozeDone; private Button btnDoze; + private TextView tvDoze12; private Button btnInexactAlarms; private Button btnBackgroundRestricted; @@ -158,6 +159,7 @@ public class FragmentSetup extends FragmentBase { tvDozeDone = view.findViewById(R.id.tvDozeDone); btnDoze = view.findViewById(R.id.btnDoze); + tvDoze12 = view.findViewById(R.id.tvDoze12); btnInexactAlarms = view.findViewById(R.id.btnInexactAlarms); btnBackgroundRestricted = view.findViewById(R.id.btnBackgroundRestricted); @@ -534,6 +536,7 @@ public class FragmentSetup extends FragmentBase { tvDozeDone.setText(null); tvDozeDone.setCompoundDrawables(null, null, null, null); btnDoze.setEnabled(false); + tvDoze12.setVisibility(View.GONE); btnInbox.setEnabled(false); @@ -660,9 +663,10 @@ public class FragmentSetup extends FragmentBase { tvDozeDone.setTextColor(ignoring == null || ignoring ? textColorPrimary : colorWarning); tvDozeDone.setTypeface(null, ignoring == null || ignoring ? Typeface.NORMAL : Typeface.BOLD); tvDozeDone.setCompoundDrawablesWithIntrinsicBounds(ignoring == null || ignoring ? check : null, null, null, null); + tvDoze12.setVisibility(Helper.isOptimizing12(getContext()) ? View.VISIBLE : View.GONE); grpInexactAlarms.setVisibility( - !AlarmManagerCompatEx.canScheduleExactAlarms(getContext()) + !AlarmManagerCompatEx.canScheduleExactAlarms(getContext()) || BuildConfig.DEBUG ? View.VISIBLE : View.GONE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java index dea39fb6ae..2fa5d3823c 100644 --- a/app/src/main/java/eu/faircode/email/Helper.java +++ b/app/src/main/java/eu/faircode/email/Helper.java @@ -433,20 +433,12 @@ public class Helper { return pm.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID); } - private static Integer targetSdk = null; + static boolean isOptimizing12(Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) + return false; - 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); + Boolean ignoring = Helper.isIgnoringOptimizations(context); + return (ignoring != null && !ignoring); } static Integer getBatteryLevel(Context context) { diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index 969708b7f2..104df35879 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -2721,11 +2721,8 @@ 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; - } + if (Helper.isOptimizing12(context)) + return (BuildConfig.DEBUG ? 2 : 15); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); return prefs.getInt("poll_interval", 0); // minutes diff --git a/app/src/main/res/layout/dialog_setup.xml b/app/src/main/res/layout/dialog_setup.xml index c5180d5d7c..bb25bc91b3 100644 --- a/app/src/main/res/layout/dialog_setup.xml +++ b/app/src/main/res/layout/dialog_setup.xml @@ -89,7 +89,7 @@ android:id="@+id/tvDozeDevice" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="6dp" + android:layout_marginTop="12dp" android:drawableEnd="@drawable/twotone_open_in_new_12" android:drawablePadding="6dp" android:drawableTint="?attr/colorWarning" @@ -104,24 +104,25 @@ android:id="@+id/tvDozeAndroid" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="6dp" - android:text="@string/title_setup_doze_android" - android:textAppearance="@style/TextAppearance.AppCompat.Small" + android:layout_marginTop="12dp" + android:text="@string/title_setup_doze_12" + android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textColor="?attr/colorWarning" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvDozeDevice" /> - + app:layout_constraintTop_toBottomOf="@id/tvDozeAndroid" /> + app:layout_constraintTop_toBottomOf="@id/tvInexact" /> + app:constraint_referenced_ids="three,title3,tvDoze" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_setup.xml b/app/src/main/res/layout/fragment_setup.xml index 4c91be0afc..09fbf4bb73 100644 --- a/app/src/main/res/layout/fragment_setup.xml +++ b/app/src/main/res/layout/fragment_setup.xml @@ -703,17 +703,41 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/btnDoze" /> + + + app:layout_constraintTop_toBottomOf="@id/tvDoze12" /> + +