Enable experimental BG update support (not well tested) (#25)

This commit is contained in:
Imran Remtulla
2023-08-20 22:32:33 -04:00
parent 7c41692d5f
commit b59d3e77f9
15 changed files with 164 additions and 44 deletions

View File

@@ -88,10 +88,8 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
: null;
logs.add(tr('bgUpdateIgnoreAfterIs', args: [ignoreAfter.toString()]));
var notificationsProvider = NotificationsProvider();
await notificationsProvider.notify(checkingUpdatesNotification);
try {
var appsProvider = AppsProvider();
await notificationsProvider.cancel(ErrorCheckingUpdatesNotification('').id);
await appsProvider.loadApps();
List<String> existingUpdateIds =
appsProvider.findExistingUpdates(installedOnly: true);
@@ -100,7 +98,9 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
try {
logs.add(tr('startedActualBGUpdateCheck'));
await appsProvider.checkUpdates(
ignoreAppsCheckedAfter: ignoreAfter, throwErrorsForRetry: true);
ignoreAppsCheckedAfter: ignoreAfter,
throwErrorsForRetry: true,
notificationsProvider: notificationsProvider);
} catch (e) {
if (e is RateLimitError || e is ClientException) {
var remainingMinutes = e is RateLimitError ? e.remainingMinutes : 15;
@@ -124,34 +124,29 @@ Future<void> bgUpdateCheck(int taskId, Map<String, dynamic>? params) async {
.where((id) => !existingUpdateIds.contains(id))
.map((e) => appsProvider.apps[e]!.app)
.toList();
// TODO: This silent update code doesn't work yet
// List<String> silentlyUpdated = await appsProvider
// .downloadAndInstallLatestApp(
// [...newUpdates.map((e) => e.id), ...existingUpdateIds], null);
// if (silentlyUpdated.isNotEmpty) {
// newUpdates = newUpdates
// .where((element) => !silentlyUpdated.contains(element.id))
// .toList();
// notificationsProvider.notify(
// SilentUpdateNotification(
// silentlyUpdated.map((e) => appsProvider.apps[e]!.app).toList()),
// cancelExisting: true);
// }
logs.add(
plural('bgCheckFoundUpdatesWillNotifyIfNeeded', newUpdates.length));
if (newUpdates.isNotEmpty) {
notificationsProvider.notify(UpdateNotification(newUpdates));
List<App> nonSilentUpdates = [];
List<App> silentUpdates = [];
for (var a in newUpdates) {
if (await appsProvider.canInstallSilently(a)) {
silentUpdates.add(a);
} else {
nonSilentUpdates.add(a);
}
}
if (silentUpdates.isNotEmpty) {
await appsProvider.downloadAndInstallLatestApps(
silentUpdates.map((e) => e.id).toList(), null,
notificationsProvider: notificationsProvider);
}
logs.add(plural(
'bgCheckFoundUpdatesWillNotifyIfNeeded', nonSilentUpdates.length));
if (err != null) {
throw err;
}
} catch (e) {
notificationsProvider
.notify(ErrorCheckingUpdatesNotification(e.toString()));
logs.add('${tr('errorCheckingUpdates')}: ${e.toString()}');
} finally {
logs.add(tr('bgUpdateTaskFinished'));
await notificationsProvider.cancel(checkingUpdatesNotification.id);
}
}

View File

@@ -239,9 +239,8 @@ class AppsProvider with ChangeNotifier {
return downloadedFile;
}
Future<Object> downloadApp(App app, BuildContext? context) async {
NotificationsProvider? notificationsProvider =
context?.read<NotificationsProvider>();
Future<Object> downloadApp(App app, BuildContext? context,
{NotificationsProvider? notificationsProvider}) async {
var notifId = DownloadNotification(app.finalName, 0).id;
if (apps[app.id] != null) {
apps[app.id]!.downloadProgress = 0;
@@ -507,7 +506,10 @@ class AppsProvider with ChangeNotifier {
// Returns an array of Ids for Apps that were successfully downloaded, regardless of installation result
Future<List<String>> downloadAndInstallLatestApps(
List<String> appIds, BuildContext? context,
{SettingsProvider? settingsProvider}) async {
{SettingsProvider? settingsProvider,
NotificationsProvider? notificationsProvider}) async {
notificationsProvider =
notificationsProvider ?? context?.read<NotificationsProvider>();
List<String> appsToInstall = [];
List<String> trackOnlyAppsToUpdate = [];
// For all specified Apps, filter out those for which:
@@ -567,8 +569,10 @@ class AppsProvider with ChangeNotifier {
for (var id in appsToInstall) {
try {
// ignore: use_build_context_synchronously
var downloadedArtifact = await downloadApp(apps[id]!.app, context);
var downloadedArtifact =
// ignore: use_build_context_synchronously
await downloadApp(apps[id]!.app, context,
notificationsProvider: notificationsProvider);
DownloadedApk? downloadedFile;
DownloadedXApkDir? downloadedDir;
if (downloadedArtifact is DownloadedApk) {
@@ -576,8 +580,8 @@ class AppsProvider with ChangeNotifier {
} else {
downloadedDir = downloadedArtifact as DownloadedXApkDir;
}
bool willBeSilent = await canInstallSilently(
apps[downloadedFile?.appId ?? downloadedDir!.appId]!.app);
var appId = downloadedFile?.appId ?? downloadedDir!.appId;
bool willBeSilent = await canInstallSilently(apps[appId]!.app);
if (!(await settingsProvider?.getInstallPermission(enforce: false) ??
true)) {
throw ObtainiumError(tr('cancelled'));
@@ -590,9 +594,24 @@ class AppsProvider with ChangeNotifier {
notifyListeners();
try {
if (downloadedFile != null) {
await installApk(downloadedFile);
if (willBeSilent) {
// Would await forever - workaround - TODO
installApk(downloadedFile);
} else {
await installApk(downloadedFile);
}
} else {
await installXApkDir(downloadedDir!);
if (willBeSilent) {
// Would await forever - workaround - TODO
installXApkDir(downloadedDir!);
} else {
await installXApkDir(downloadedDir!);
}
}
if (willBeSilent) {
notificationsProvider?.notify(SilentUpdateAttemptNotification(
[apps[appId]!.app],
id: appId.hashCode));
}
} finally {
apps[id]?.downloadProgress = null;
@@ -608,8 +627,6 @@ class AppsProvider with ChangeNotifier {
throw errors;
}
NotificationsProvider().cancel(UpdateNotification([]).id);
return installedIds;
}
@@ -971,7 +988,8 @@ class AppsProvider with ChangeNotifier {
Future<List<App>> checkUpdates(
{DateTime? ignoreAppsCheckedAfter,
bool throwErrorsForRetry = false}) async {
bool throwErrorsForRetry = false,
NotificationsProvider? notificationsProvider}) async {
List<App> updates = [];
MultiAppMultiError errors = MultiAppMultiError();
if (!gettingUpdates) {
@@ -998,9 +1016,14 @@ class AppsProvider with ChangeNotifier {
rethrow;
}
errors.add(appIds[i], e.toString());
notificationsProvider?.notify(ErrorCheckingUpdatesNotification(
'${appIds[i]}: ${e.toString()}',
id: appIds[i].hashCode));
}
if (newApp != null) {
updates.add(newApp);
notificationsProvider
?.notify(UpdateNotification([newApp], id: newApp.id.hashCode));
}
}
} finally {

View File

@@ -22,9 +22,9 @@ class ObtainiumNotification {
}
class UpdateNotification extends ObtainiumNotification {
UpdateNotification(List<App> updates)
UpdateNotification(List<App> updates, {int? id})
: super(
2,
id ?? 2,
tr('updatesAvailable'),
'',
'UPDATES_AVAILABLE',
@@ -41,8 +41,8 @@ class UpdateNotification extends ObtainiumNotification {
}
class SilentUpdateNotification extends ObtainiumNotification {
SilentUpdateNotification(List<App> updates)
: super(3, tr('appsUpdated'), '', 'APPS_UPDATED', tr('appsUpdated'),
SilentUpdateNotification(List<App> updates, {int? id})
: super(id ?? 3, tr('appsUpdated'), '', 'APPS_UPDATED', tr('appsUpdated'),
tr('appsUpdatedNotifDescription'), Importance.defaultImportance) {
message = updates.length == 1
? tr('xWasUpdatedToY',
@@ -52,10 +52,28 @@ class SilentUpdateNotification extends ObtainiumNotification {
}
}
class ErrorCheckingUpdatesNotification extends ObtainiumNotification {
ErrorCheckingUpdatesNotification(String error)
class SilentUpdateAttemptNotification extends ObtainiumNotification {
SilentUpdateAttemptNotification(List<App> updates, {int? id})
: super(
5,
id ?? 3,
tr('appsPossiblyUpdated'),
'',
'APPS_POSSIBLY_UPDATED',
tr('appsPossiblyUpdated'),
tr('appsPossiblyUpdatedNotifDescription'),
Importance.defaultImportance) {
message = updates.length == 1
? tr('xWasPossiblyUpdatedToY',
args: [updates[0].finalName, updates[0].latestVersion])
: plural('xAndNMoreUpdatesPossiblyInstalled', updates.length - 1,
args: [updates[0].finalName, (updates.length - 1).toString()]);
}
}
class ErrorCheckingUpdatesNotification extends ObtainiumNotification {
ErrorCheckingUpdatesNotification(String error, {int? id})
: super(
id ?? 5,
tr('errorCheckingUpdates'),
error,
'BG_UPDATE_CHECK_ERROR',