Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify Storage Backends #734

Open
wants to merge 12 commits into
base: android15
Choose a base branch
from

Conversation

grote
Copy link
Collaborator

@grote grote commented Aug 29, 2024

We had two storage plugin interfaces: One for app backup and one for files backup. Therefore we had two different WebDAV implementations and two different Storage Access Framework implementations. The storage interface was application specific to its use-case.

This MR unifies those implementations using a single storage backend interface which is rather generic and mostly independent of application specific use cases:

public interface Backend {
    public suspend fun test(): Boolean
    public suspend fun getFreeSpace(): Long?
    public suspend fun save(handle: FileHandle): OutputStream
    public suspend fun load(handle: FileHandle): InputStream
    public suspend fun list(topLevelFolder: TopLevelFolder?, vararg fileTypes: KClass<out FileHandle>, callback: (FileInfo) -> Unit)
    public suspend fun remove(handle: FileHandle)
    public suspend fun rename(from: TopLevelFolder, to: TopLevelFolder)
    public val providerPackageName: String?
}

This should make writing new storage backends easier. It reduces lots of duplicated code and allows for future modernizations such as retrying operations after I/O errors.

The new unified implementations also improve upon their old separate implementations. There are no more init() or startRestoreSet() methods where we created new folders. Instead, all folders are now created on-demand, only when they are needed and in the case of SAF also cached for faster access. Initializing a new backup location is faster, because we don't need to create the 255 folders for file backup.

The implementation now lives in a new core gradle module, so the app and the storage module can both make use of it. In the future, common cryptographic code should also get moved there to further reduce duplication.

This creates a KeyManager interface in the new core module which the storage module can use to get the key from.
because it is one extra request for packages that do have data and from the looks of it not really needed.
When changing backends, the ChunkWriter could still use the old one causing data loss, because chunks assumed to exist on new backend, were written to old one.
@grote grote changed the base branch from android14 to android15 September 12, 2024 12:38
@grote grote marked this pull request as ready for review September 12, 2024 12:49
@t-m-w
Copy link
Collaborator

t-m-w commented Sep 12, 2024

I've been running this on my daily driver and haven't encountered problems. I've been seeing notifications of successful backups daily. I tested restoring a single app after making a small change - a notes app - and it appears to work fine. Haven't done full-blown testing, but haven't encountered errors, either.

I use WebDAV as a backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants