mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-08-15 03:18:09 +02:00
Switch back to serial BG installs (#984)
This commit is contained in:
@@ -1369,12 +1369,6 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
|||||||
(<List<MapEntry<String, int>>>[]))
|
(<List<MapEntry<String, int>>>[]))
|
||||||
];
|
];
|
||||||
|
|
||||||
bool installMode = toCheck.isEmpty &&
|
|
||||||
toInstall.isNotEmpty; // Task is either in update mode or install mode
|
|
||||||
|
|
||||||
logs.add(
|
|
||||||
'BG ${installMode ? 'install' : 'update'} task $taskId: Started (${installMode ? toInstall.length : toCheck.length}).');
|
|
||||||
|
|
||||||
var netResult = await (Connectivity().checkConnectivity());
|
var netResult = await (Connectivity().checkConnectivity());
|
||||||
|
|
||||||
if (netResult == ConnectivityResult.none) {
|
if (netResult == ConnectivityResult.none) {
|
||||||
@@ -1399,110 +1393,103 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!installMode) {
|
|
||||||
// If in update mode, we check for updates.
|
|
||||||
// We divide the results into 4 groups:
|
|
||||||
// - toNotify - Apps with updates that the user will be notified about (can't be silently installed)
|
|
||||||
// - toRetry - Apps with update check errors that will be retried in a while
|
|
||||||
// - toThrow - Apps with update check errors that the user will be notified about (no retry)
|
|
||||||
// - toInstall - Apps with updates that will be installed silently
|
|
||||||
// After grouping the updates, we take care of toNotify and toThrow first
|
|
||||||
// Then if toRetry is not empty, we schedule another update task to run in a while (toInstall is retained)
|
|
||||||
// If toRetry is empty, we take care of toInstall
|
|
||||||
|
|
||||||
// Init. vars.
|
|
||||||
List<App> updates = [];
|
|
||||||
List<App> toNotify = [];
|
|
||||||
List<MapEntry<String, int>> toRetry = [];
|
|
||||||
var retryAfterXSeconds = 0;
|
|
||||||
MultiAppMultiError toThrow = MultiAppMultiError();
|
|
||||||
var networkRestricted = false;
|
var networkRestricted = false;
|
||||||
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
if (appsProvider.settingsProvider.bgUpdatesOnWiFiOnly) {
|
||||||
var netResult = await (Connectivity().checkConnectivity());
|
|
||||||
networkRestricted = (netResult != ConnectivityResult.wifi) &&
|
networkRestricted = (netResult != ConnectivityResult.wifi) &&
|
||||||
(netResult != ConnectivityResult.ethernet);
|
(netResult != ConnectivityResult.ethernet);
|
||||||
}
|
}
|
||||||
MultiAppMultiError? errors;
|
|
||||||
CheckingUpdatesNotification notif =
|
|
||||||
CheckingUpdatesNotification(plural('apps', toCheck.length));
|
|
||||||
|
|
||||||
try {
|
bool installMode =
|
||||||
// Check for updates
|
toCheck.isEmpty; // Task is either in update mode or install mode
|
||||||
notificationsProvider.notify(notif, cancelExisting: true);
|
|
||||||
updates = await appsProvider.checkUpdates(
|
// In install mode, grab all available silent updates unless explicitly told otherwise
|
||||||
specificIds: toCheck.map((e) => e.key).toList());
|
if (installMode && toInstall.isEmpty && !networkRestricted) {
|
||||||
} catch (e) {
|
var temp = appsProvider.findExistingUpdates(installedOnly: true);
|
||||||
// If there were errors, group them into toRetry and toThrow
|
for (var i = 0; i < temp.length; i++) {
|
||||||
if (e is Map) {
|
if (await appsProvider
|
||||||
updates = e['updates'];
|
.canInstallSilently(appsProvider.apps[temp[i]]!.app)) {
|
||||||
errors = e['errors'];
|
toInstall.add(MapEntry(temp[i], 0));
|
||||||
errors!.rawErrors.forEach((key, err) {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logs.add(
|
logs.add(
|
||||||
'BG update task $taskId: Got error on checking for $key \'${err.toString()}\'.');
|
'BG ${installMode ? 'install' : 'update'} task $taskId: Started (${installMode ? toInstall.length : toCheck.length}).');
|
||||||
var toCheckApp = toCheck.where((element) => element.key == key).first;
|
|
||||||
if (toCheckApp.value < maxAttempts) {
|
if (!installMode) {
|
||||||
toRetry.add(MapEntry(toCheckApp.key, toCheckApp.value + 1));
|
// If in update mode...
|
||||||
var minRetryIntervalForThisApp = err is RateLimitError
|
var didCompleteChecking = false;
|
||||||
? (err.remainingMinutes * 60)
|
CheckingUpdatesNotification? notif;
|
||||||
|
// Loop through all updates and check each
|
||||||
|
List<App> toNotify = [];
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < toCheck.length; i++) {
|
||||||
|
var appId = toCheck[i].key;
|
||||||
|
var attemptCount = toCheck[i].value + 1;
|
||||||
|
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))) {
|
||||||
|
toNotify.add(newApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 (attemptCount < maxAttempts) {
|
||||||
|
var remainingSeconds = e is RateLimitError
|
||||||
|
? (i == 0 ? (e.remainingMinutes * 60) : (5 * 60))
|
||||||
: e is ClientException
|
: e is ClientException
|
||||||
? (15 * 60)
|
? (15 * 60)
|
||||||
: pow(toCheckApp.value + 1, 2).toInt();
|
: pow(attemptCount, 2).toInt();
|
||||||
if (minRetryIntervalForThisApp > retryAfterXSeconds) {
|
logs.add(
|
||||||
retryAfterXSeconds = minRetryIntervalForThisApp;
|
'BG update task $taskId: Will continue in $remainingSeconds seconds (with $appId moved to the end of the line).');
|
||||||
}
|
var remainingToCheck = moveStrToEndMapEntryWithCount(
|
||||||
} else {
|
toCheck.sublist(i), MapEntry(appId, attemptCount));
|
||||||
toThrow.add(key, err, appName: errors?.appIdNames[key]);
|
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 {
|
} else {
|
||||||
// We don't expect to ever get here in any situation so no need to catch
|
// If the offender has reached its fail limit, notify the user and remove it from the list (task can continue)
|
||||||
logs.add('Fatal error in BG update task: ${e.toString()}');
|
toCheck.removeAt(i);
|
||||||
rethrow;
|
i--;
|
||||||
|
notificationsProvider
|
||||||
|
.notify(ErrorCheckingUpdatesNotification(e.toString()));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (notif != null) {
|
||||||
notificationsProvider.cancel(notif.id);
|
notificationsProvider.cancel(notif.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group the updates into toNotify and toInstall
|
|
||||||
for (var i = 0; i < updates.length; i++) {
|
|
||||||
if (networkRestricted ||
|
|
||||||
!(await appsProvider.canInstallSilently(updates[i]))) {
|
|
||||||
toNotify.add(updates[i]);
|
|
||||||
} else {
|
|
||||||
toInstall.add(MapEntry(updates[i].id, 0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Send the update notification
|
} finally {
|
||||||
if (toNotify.isNotEmpty) {
|
if (toNotify.isNotEmpty) {
|
||||||
notificationsProvider.notify(UpdateNotification(toNotify));
|
notificationsProvider.notify(UpdateNotification(toNotify));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the error notifications
|
|
||||||
if (toThrow.rawErrors.isNotEmpty) {
|
|
||||||
for (var element in toThrow.idsByErrorString.entries) {
|
|
||||||
notificationsProvider.notify(ErrorCheckingUpdatesNotification(
|
|
||||||
errors!.errorsAppsString(element.key, element.value),
|
|
||||||
id: Random().nextInt(10000)));
|
|
||||||
}
|
}
|
||||||
}
|
// If you're done checking and found some silently installable updates, schedule another task which will run in install mode
|
||||||
|
if (didCompleteChecking) {
|
||||||
// if there are update checks to retry, schedule a retry task
|
|
||||||
if (toRetry.isNotEmpty) {
|
|
||||||
logs.add(
|
|
||||||
'BG update task $taskId: Will retry in $retryAfterXSeconds seconds.');
|
|
||||||
AndroidAlarmManager.oneShot(
|
|
||||||
Duration(seconds: retryAfterXSeconds), taskId + 1, bgUpdateCheck,
|
|
||||||
params: {
|
|
||||||
'toCheck': toRetry
|
|
||||||
.map((entry) => {'key': entry.key, 'value': entry.value})
|
|
||||||
.toList(),
|
|
||||||
'toInstall': toInstall
|
|
||||||
.map((entry) => {'key': entry.key, 'value': entry.value})
|
|
||||||
.toList(),
|
|
||||||
});
|
|
||||||
} else if (toInstall.isNotEmpty) {
|
|
||||||
// If there are no more update checks, schedule an install task
|
|
||||||
logs.add(
|
logs.add(
|
||||||
'BG update task $taskId: Done. Scheduling install task to run immediately.');
|
'BG update task $taskId: Done. Scheduling install task to run immediately.');
|
||||||
AndroidAlarmManager.oneShot(
|
AndroidAlarmManager.oneShot(
|
||||||
@@ -1513,14 +1500,11 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
|
|||||||
.map((entry) => {'key': entry.key, 'value': entry.value})
|
.map((entry) => {'key': entry.key, 'value': entry.value})
|
||||||
.toList()
|
.toList()
|
||||||
});
|
});
|
||||||
|
} else if (didCompleteChecking) {
|
||||||
|
logs.add('BG update task $taskId: Done.');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logs.add('BG install task $taskId: Done.');
|
// If in install mode...
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (installMode) {
|
|
||||||
// If in install mode, we install silent updates.
|
|
||||||
|
|
||||||
var didCompleteInstalling = false;
|
var didCompleteInstalling = false;
|
||||||
var tempObtArr = toInstall.where((element) => element.key == obtainiumId);
|
var tempObtArr = toInstall.where((element) => element.key == obtainiumId);
|
||||||
if (tempObtArr.isNotEmpty) {
|
if (tempObtArr.isNotEmpty) {
|
||||||
|
Reference in New Issue
Block a user