Use a global state for the app being in background

This commit is contained in:
Vishnu Mohandas 2021-03-03 21:33:03 +05:30
parent b2ea5fbfa0
commit 2d4fc30de3
2 changed files with 31 additions and 20 deletions

View file

@ -29,7 +29,7 @@ void main() async {
Future<void> _runInForeground() async {
return await _runWithLogs(() async {
_logger.info("Starting app in foreground");
await _init();
await _init(false);
_sync();
runApp(MyApp());
});
@ -39,13 +39,13 @@ Future _runInBackground(String taskId) async {
if (_initializationStatus == null) {
_runWithLogs(() async {
_logger.info("[BackgroundFetch] Event received: $taskId");
await _init();
await _init(true);
await _sync(isAppInBackground: true);
BackgroundFetch.finish(taskId);
});
}, prefix: "[bg]");
} else {
_logger.info("[BackgroundFetch] Event received: $taskId");
await _init();
await _init(true);
await _sync(isAppInBackground: true);
BackgroundFetch.finish(taskId);
}
@ -59,7 +59,7 @@ void _headlessTaskHandler(HeadlessTask task) {
}
}
Future<void> _init() async {
Future<void> _init(bool isBackground) async {
if (_initializationStatus != null) {
return _initializationStatus.future;
}
@ -70,7 +70,7 @@ Future<void> _init() async {
await Configuration.instance.init();
await BillingService.instance.init();
await CollectionsService.instance.init();
await SyncService.instance.init();
await SyncService.instance.init(isBackground);
await MemoriesService.instance.init();
_logger.info("Initialization done");
_initializationStatus.complete();
@ -85,19 +85,20 @@ Future<void> _sync({bool isAppInBackground = false}) async {
_logger.info("Syncing in background");
}
try {
await SyncService.instance.sync(isAppInBackground: isAppInBackground);
await SyncService.instance.sync();
} catch (e, s) {
_logger.severe("Sync error", e, s);
}
}
Future _runWithLogs(Function() function) async {
Future _runWithLogs(Function() function, {String prefix = ""}) async {
await SuperLogging.main(LogConfig(
body: function,
logDirPath: (await getTemporaryDirectory()).path + "/logs",
maxLogFiles: 5,
sentryDsn: kDebugMode ? SENTRY_DEBUG_DSN : SENTRY_DSN,
enableInDebugMode: true,
prefix: prefix,
));
}

View file

@ -35,6 +35,7 @@ class SyncService {
final _collectionsService = CollectionsService.instance;
final _diffFetcher = DiffFetcher();
bool _syncStopRequested = false;
bool _isBackground;
Completer<void> _existingSync;
SharedPreferences _prefs;
SyncStatusUpdate _lastSyncStatusEvent;
@ -53,7 +54,7 @@ class SyncService {
_logger.info("Connectivity change detected " + result.toString());
if (Configuration.instance.hasConfiguredAccount() &&
BillingService.instance.getSubscription() != null) {
sync(isAppInBackground: true);
sync();
}
});
@ -67,7 +68,8 @@ class SyncService {
static final SyncService instance = SyncService._privateConstructor();
Future<void> init() async {
Future<void> init(bool isBackground) async {
_isBackground = isBackground;
_prefs = await SharedPreferences.getInstance();
if (Platform.isIOS) {
_logger.info("Clearing file cache");
@ -76,7 +78,7 @@ class SyncService {
}
}
Future<void> sync({bool isAppInBackground = false}) async {
Future<void> sync() async {
_syncStopRequested = false;
if (_existingSync != null) {
_logger.warning("Sync already in progress, skipping.");
@ -85,7 +87,7 @@ class SyncService {
_existingSync = Completer<void>();
bool successful = false;
try {
await _doSync(isAppInBackground: isAppInBackground);
await _doSync();
if (_lastSyncStatusEvent != null &&
_lastSyncStatusEvent.status != SyncStatus.applying_local_diff) {
Bus.instance.fire(SyncStatusUpdate(SyncStatus.completed));
@ -146,10 +148,10 @@ class SyncService {
return _lastSyncStatusEvent;
}
Future<void> _doSync({bool isAppInBackground = false}) async {
Future<void> _doSync() async {
final existingLocalFileIDs = await _db.getExistingLocalFileIDs();
final syncStartTime = DateTime.now().microsecondsSinceEpoch;
if (isAppInBackground) {
if (_isBackground) {
await PhotoManager.setIgnorePermissionCheck(true);
} else {
final result = await PhotoManager.requestPermission();
@ -262,7 +264,7 @@ class SyncService {
}
}
final foldersToBackUp = Configuration.instance.getPathsToBackUp();
final filesToBeUploaded =
var filesToBeUploaded =
await _db.getFilesToBeUploadedWithinFolders(foldersToBackUp);
if (kDebugMode) {
filesToBeUploaded
@ -281,15 +283,21 @@ class SyncService {
Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparing_for_upload));
}
final numberOfFilesCurrentlyUploaded =
await FilesDB.instance.getNumberOfUploadedFiles();
final futures = List<Future>();
for (final uploadedFileID in updatedFileIDs) {
final file = await _db.getUploadedFileInAnyCollection(uploadedFileID);
final future = _uploader.upload(file, file.collectionID).then((value) {
final future =
_uploader.upload(file, file.collectionID).then((value) async {
uploadCounter++;
final newTotal = await FilesDB.instance.getNumberOfUploadedFiles();
Bus.instance
.fire(CollectionUpdatedEvent(collectionID: file.collectionID));
Bus.instance.fire(SyncStatusUpdate(SyncStatus.in_progress,
completed: uploadCounter, total: totalUploads));
completed: newTotal - numberOfFilesCurrentlyUploaded,
total: totalUploads));
});
futures.add(future);
}
@ -298,17 +306,19 @@ class SyncService {
final collectionID = (await CollectionsService.instance
.getOrCreateForPath(file.deviceFolder))
.id;
final future = _uploader.upload(file, collectionID).then((value) {
final future = _uploader.upload(file, collectionID).then((value) async {
uploadCounter++;
final newTotal = await FilesDB.instance.getNumberOfUploadedFiles();
Bus.instance
.fire(CollectionUpdatedEvent(collectionID: file.collectionID));
Bus.instance.fire(SyncStatusUpdate(SyncStatus.in_progress,
completed: uploadCounter, total: totalUploads));
completed: newTotal - numberOfFilesCurrentlyUploaded,
total: totalUploads));
});
futures.add(future);
}
try {
await Future.wait(futures, eagerError: true);
await Future.wait(futures);
} on InvalidFileError {
// Do nothing
} on FileSystemException {