private async Task <RestoreResult> RestoreFromDir(Uri destUri) { if (!HasPersistablePermissionsAtUri(destUri)) { throw new Exception("No permission at URI"); } var directory = DocumentFile.FromTreeUri(_context, destUri); var files = directory.ListFiles(); var mostRecentBackup = files .Where(f => f.IsFile && f.Type == Backup.MimeType && f.Name.EndsWith(Backup.FileExtension) && f.Length() > 0 && f.CanRead()) .OrderByDescending(f => f.LastModified()) .FirstOrDefault(); if (mostRecentBackup == null || mostRecentBackup.LastModified() <= _preferences.MostRecentBackupModifiedAt) { return(new RestoreResult()); } _preferences.MostRecentBackupModifiedAt = mostRecentBackup.LastModified(); var password = await SecureStorageWrapper.GetAutoBackupPassword(); if (password == null) { throw new Exception("No password defined."); } var data = await FileUtil.ReadFile(_context, mostRecentBackup.Uri); var backup = Backup.FromBytes(data, password); var(authsAdded, authsUpdated) = await _authSource.AddOrUpdateMany(backup.Authenticators); var categoriesAdded = backup.Categories != null ? await _categorySource.AddMany(backup.Categories) : 0; if (backup.AuthenticatorCategories != null) { await _authSource.AddOrUpdateManyCategoryBindings(backup.AuthenticatorCategories); } var customIconsAdded = backup.CustomIcons != null ? await _customIconSource.AddMany(backup.CustomIcons) : 0; try { await _customIconSource.CullUnused(); } catch (Exception e) { // ignored Logger.Error(e); } return(new RestoreResult(authsAdded, authsUpdated, categoriesAdded, customIconsAdded)); }