Skip to content

Commit

Permalink
[UNTESTED] Support a lack of MANAGE_DOCUMENTS permission
Browse files Browse the repository at this point in the history
When `android.permission.MANAGE_DOCUMENTS` is not granted, Seedvault
prompts to select a storage location. Do not insist on resolving the
storage's actual root, as it will likely (or perhaps always) fail.
Use a fake storage root as is done for USB and app-based options.

Known issues:
* Selected location is assumed not to be USB and not to require
  network access in its storage options.

Change-Id: I357b4c68673d71c087be41e9c94c2841c1d6658e
  • Loading branch information
t-m-w committed Nov 28, 2022
1 parent 271b9a5 commit 2806853
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class StorageActivity : BackupActivity() {
val authority = uri.authority ?: throw AssertionError("No authority in $uri")
val storageRoot = StorageRootResolver.getStorageRoots(this, authority).getOrNull(0)
if (storageRoot == null) {
viewModel.onUriPermissionResultReceived(null)
viewModel.onSafOptionChosen(
StorageRootResolver.getFakeStorageRootForUri(this, uri))
viewModel.onUriPermissionResultReceived(uri)
} else {
viewModel.onSafOptionChosen(storageRoot)
viewModel.onUriPermissionResultReceived(uri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.stevesoltys.seedvault.ui.storage
import android.content.Context
import android.database.Cursor
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.UserHandle
import android.provider.DocumentsContract
import android.provider.DocumentsContract.Root.COLUMN_AVAILABLE_BYTES
Expand Down Expand Up @@ -57,6 +58,21 @@ internal object StorageRootResolver {
return roots
}

fun getFakeStorageRootForUri(context: Context, uri: Uri): SafOption {
return SafOption(
authority = AUTHORITY_STORAGE,
rootId = "fake",
documentId = "fake",
// TODO: Use something other than the USB icon?
icon = getIcon(context, AUTHORITY_STORAGE, "usb", 0),
title = context.getString(R.string.storage_user_selected_location_title),
summary = context.getString(R.string.storage_user_selected_location_summary),
availableBytes = null,
isUsb = false, // TODO: Check this if possible instead of forcing false
requiresNetwork = false, // TODO: Check this if possible instead of forcing false
)
}

private fun getStorageRoot(context: Context, authority: String, cursor: Cursor): SafOption? {
val flags = cursor.getInt(COLUMN_FLAGS)
val supportsCreate = flags and FLAG_SUPPORTS_CREATE != 0
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
<string name="storage_fragment_restore_title">Where to find your backups?</string>
<string name="storage_fragment_warning">People with access to your storage location can learn which apps you use, but do not get access to the apps\' data.</string>
<string name="storage_fragment_warning_delete">Existing backups in this location will be deleted.</string>
<string name="storage_user_selected_location_title">User-chosen location</string>
<string name="storage_user_selected_location_summary">Chosen using the folder browser</string>
<string name="storage_fake_drive_title">USB flash drive</string>
<string name="storage_fake_drive_summary">Needs to be plugged in</string>
<string name="storage_available_bytes"><xliff:g example="1 GB" id="size">%1$s</xliff:g> free</string>
Expand Down

0 comments on commit 2806853

Please sign in to comment.