From 370ec1432e1ceaddcb25da3c4de4022e14fa45bd Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 30 Aug 2023 21:40:05 -0400 Subject: [PATCH 1/5] Fix BG update OS requirement --- lib/providers/apps_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 5017e26..febf2df 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -393,7 +393,7 @@ class AppsProvider with ChangeNotifier { (await getInstalledInfo(app.id))?.applicationInfo?.targetSdkVersion; // The OS must also be new enough and the APK should target a new enough API - return osInfo.version.sdkInt >= 30 && + return osInfo.version.sdkInt >= 31 && targetSDK != null && targetSDK >= // https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(int) (osInfo.version.sdkInt - 3); From 73a3c7eb715111b177d02b3ece8786c4b756c121 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 30 Aug 2023 21:41:26 -0400 Subject: [PATCH 2/5] Temporarily exclude Obtainium from BG updates (#836) --- lib/providers/apps_provider.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index febf2df..e6b87df 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -364,6 +364,9 @@ class AppsProvider with ChangeNotifier { Future canInstallSilently( App app, SettingsProvider settingsProvider) async { + if (app.id == obtainiumId) { + return false; + } if (!settingsProvider.enableBackgroundUpdates) { return false; } From 01f9003b8df9e5f6e8be7f2a9dd68e96232c87b6 Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 30 Aug 2023 22:07:30 -0400 Subject: [PATCH 3/5] Group update notifications into one (#829) --- lib/providers/apps_provider.dart | 120 ++++++++++++++++--------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index e6b87df..057b887 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -1334,67 +1334,75 @@ Future bgUpdateCheck(int taskId, Map? params) async { (netResult != ConnectivityResult.ethernet); } // Loop through all updates and check each - for (int i = 0; i < toCheck.length; i++) { - var appId = toCheck[i].key; - var retryCount = toCheck[i].value; - AppInMemory? app = appsProvider.apps[appId]; - if (app?.app.installedVersion != null) { - try { - notificationsProvider.notify( - notif = CheckingUpdatesNotification(app?.name ?? appId), - cancelExisting: true); - App? newApp = await appsProvider.checkUpdate(appId); - if (newApp != null) { - if (networkRestricted || - !(await appsProvider.canInstallSilently( - app!.app, settingsProvider))) { - notificationsProvider.notify( - UpdateNotification([newApp], id: newApp.id.hashCode - 1)); + List toNotify = []; + try { + for (int i = 0; i < toCheck.length; i++) { + var appId = toCheck[i].key; + var retryCount = toCheck[i].value; + AppInMemory? app = appsProvider.apps[appId]; + if (app?.app.installedVersion != null) { + try { + notificationsProvider.notify( + notif = CheckingUpdatesNotification(app?.name ?? appId), + cancelExisting: true); + App? newApp = await appsProvider.checkUpdate(appId); + if (newApp != null) { + if (networkRestricted || + !(await appsProvider.canInstallSilently( + app!.app, settingsProvider))) { + toNotify.add(newApp); + } else { + toInstall.add(MapEntry(appId, 0)); + } + } + if (i == (toCheck.length - 1)) { + didCompleteChecking = true; + } + } catch (e) { + // If you got an error, move the offender to the back of the line (increment their fail count) and schedule another task to continue checking shortly + logs.add( + 'BG update task $taskId: Got error on checking for $appId \'${e.toString()}\'.'); + if (retryCount < maxAttempts) { + var remainingSeconds = e is RateLimitError + ? (i == 0 ? (e.remainingMinutes * 60) : (5 * 60)) + : e is ClientException + ? (15 * 60) + : (retryCount ^ 2); + logs.add( + 'BG update task $taskId: Will continue in $remainingSeconds seconds (with $appId moved to the end of the line).'); + var remainingToCheck = moveStrToEndMapEntryWithCount( + toCheck.sublist(i), MapEntry(appId, retryCount + 1)); + AndroidAlarmManager.oneShot(Duration(seconds: remainingSeconds), + taskId + 1, bgUpdateCheck, + params: { + 'toCheck': remainingToCheck + .map( + (entry) => {'key': entry.key, 'value': entry.value}) + .toList(), + 'toInstall': toInstall + .map( + (entry) => {'key': entry.key, 'value': entry.value}) + .toList(), + }); + break; } else { - toInstall.add(MapEntry(appId, 0)); + // If the offender has reached its fail limit, notify the user and remove it from the list (task can continue) + toCheck.removeAt(i); + i--; + notificationsProvider + .notify(ErrorCheckingUpdatesNotification(e.toString())); + } + } finally { + if (notif != null) { + notificationsProvider.cancel(notif.id); } } - if (i == (toCheck.length - 1)) { - didCompleteChecking = true; - } - } catch (e) { - // If you got an error, move the offender to the back of the line (increment their fail count) and schedule another task to continue checking shortly - logs.add( - 'BG update task $taskId: Got error on checking for $appId \'${e.toString()}\'.'); - if (retryCount < maxAttempts) { - var remainingSeconds = e is RateLimitError - ? (i == 0 ? (e.remainingMinutes * 60) : (5 * 60)) - : e is ClientException - ? (15 * 60) - : (retryCount ^ 2); - logs.add( - 'BG update task $taskId: Will continue in $remainingSeconds seconds (with $appId moved to the end of the line).'); - var remainingToCheck = moveStrToEndMapEntryWithCount( - toCheck.sublist(i), MapEntry(appId, retryCount + 1)); - AndroidAlarmManager.oneShot( - Duration(seconds: remainingSeconds), taskId + 1, bgUpdateCheck, - params: { - 'toCheck': remainingToCheck - .map((entry) => {'key': entry.key, 'value': entry.value}) - .toList(), - 'toInstall': toInstall - .map((entry) => {'key': entry.key, 'value': entry.value}) - .toList(), - }); - break; - } else { - // If the offender has reached its fail limit, notify the user and remove it from the list (task can continue) - toCheck.removeAt(i); - i--; - notificationsProvider - .notify(ErrorCheckingUpdatesNotification(e.toString())); - } - } finally { - if (notif != null) { - notificationsProvider.cancel(notif.id); - } } } + } finally { + if (toNotify.isNotEmpty) { + notificationsProvider.notify(UpdateNotification(toNotify)); + } } // If you're done checking and found some silently installable updates, schedule another task which will run in install mode if (didCompleteChecking && toInstall.isNotEmpty) { From 9af2c8370d134e7dac38daeba428e802d864c92a Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 30 Aug 2023 22:34:12 -0400 Subject: [PATCH 4/5] Bugfix: BG update fail leads to infinite retries (#838) --- lib/providers/apps_provider.dart | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/providers/apps_provider.dart b/lib/providers/apps_provider.dart index 057b887..cad3b2f 100644 --- a/lib/providers/apps_provider.dart +++ b/lib/providers/apps_provider.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart'; import 'package:android_intent_plus/flag.dart'; @@ -116,16 +117,19 @@ moveStrToEnd(List arr, String str, {String? strB}) { return arr; } -moveStrToEndMapEntryWithCount( +List> moveStrToEndMapEntryWithCount( List> arr, MapEntry str, {MapEntry? strB}) { MapEntry? temp; arr.removeWhere((element) { - bool res = element.key == str.key || element.key == strB?.key; - if (res) { - temp = element; + bool resA = element.key == str.key; + bool resB = element.key == strB?.key; + if (resA) { + temp = str; + } else if (resB) { + temp = strB; } - return res; + return resA || resB; }); if (temp != null) { arr = [...arr, temp!]; @@ -1338,7 +1342,7 @@ Future bgUpdateCheck(int taskId, Map? params) async { try { for (int i = 0; i < toCheck.length; i++) { var appId = toCheck[i].key; - var retryCount = toCheck[i].value; + var attemptCount = toCheck[i].value + 1; AppInMemory? app = appsProvider.apps[appId]; if (app?.app.installedVersion != null) { try { @@ -1362,16 +1366,16 @@ Future bgUpdateCheck(int taskId, Map? params) async { // If you got an error, move the offender to the back of the line (increment their fail count) and schedule another task to continue checking shortly logs.add( 'BG update task $taskId: Got error on checking for $appId \'${e.toString()}\'.'); - if (retryCount < maxAttempts) { + if (attemptCount < maxAttempts) { var remainingSeconds = e is RateLimitError ? (i == 0 ? (e.remainingMinutes * 60) : (5 * 60)) : e is ClientException ? (15 * 60) - : (retryCount ^ 2); + : pow(attemptCount, 2).toInt(); logs.add( 'BG update task $taskId: Will continue in $remainingSeconds seconds (with $appId moved to the end of the line).'); var remainingToCheck = moveStrToEndMapEntryWithCount( - toCheck.sublist(i), MapEntry(appId, retryCount + 1)); + toCheck.sublist(i), MapEntry(appId, attemptCount)); AndroidAlarmManager.oneShot(Duration(seconds: remainingSeconds), taskId + 1, bgUpdateCheck, params: { From 8b01fc03eccb706203354870420a4b7c521a0eac Mon Sep 17 00:00:00 2001 From: Imran Remtulla Date: Wed, 30 Aug 2023 22:35:11 -0400 Subject: [PATCH 5/5] Increment version --- lib/main.dart | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8f5c38d..fb3a711 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,7 +19,7 @@ import 'package:easy_localization/src/easy_localization_controller.dart'; // ignore: implementation_imports import 'package:easy_localization/src/localization.dart'; -const String currentVersion = '0.14.5'; +const String currentVersion = '0.14.6'; const String currentReleaseTag = 'v$currentVersion-beta'; // KEEP THIS IN SYNC WITH GITHUB RELEASES diff --git a/pubspec.yaml b/pubspec.yaml index c32228b..61b3d06 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.14.5+197 # When changing this, update the tag in main() accordingly +version: 0.14.6+198 # When changing this, update the tag in main() accordingly environment: sdk: '>=2.18.2 <3.0.0'