fixup! Allow secondary user backup to USB

Issue: calyxos#1058
Change-Id: I4aaadef5954e9c091f7048bffd8e0ed700fdd2e6
This commit is contained in:
Oliver Scott 2023-11-01 14:23:10 -04:00
parent 6ce2e27a99
commit 97d2d18a73
No known key found for this signature in database
6 changed files with 19 additions and 17 deletions

View file

@ -5,12 +5,11 @@ import android.app.Application
import android.app.backup.BackupManager.PACKAGE_MANAGER_SENTINEL import android.app.backup.BackupManager.PACKAGE_MANAGER_SENTINEL
import android.app.backup.IBackupManager import android.app.backup.IBackupManager
import android.content.Context import android.content.Context
import android.content.Context.BACKUP_SERVICE
import android.content.pm.PackageManager.PERMISSION_GRANTED import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Build import android.os.Build
import android.os.ServiceManager.getService import android.os.ServiceManager.getService
import android.os.StrictMode import android.os.StrictMode
import android.os.UserHandle import android.os.UserManager
import com.stevesoltys.seedvault.crypto.cryptoModule import com.stevesoltys.seedvault.crypto.cryptoModule
import com.stevesoltys.seedvault.header.headerModule import com.stevesoltys.seedvault.header.headerModule
import com.stevesoltys.seedvault.metadata.MetadataManager import com.stevesoltys.seedvault.metadata.MetadataManager
@ -143,8 +142,11 @@ fun <T> permitDiskReads(func: () -> T): T {
} }
} }
fun Context.getSystemContext(isUsbStorage: () -> Boolean): Context { @Suppress("MissingPermission")
return if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED && fun Context.getStorageContext(isUsbStorage: () -> Boolean): Context {
isUsbStorage() if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED && isUsbStorage()) {
) createContextAsUser(UserHandle.SYSTEM, 0) else this UserManager.get(this).getProfileParent(user)
?.let { parent -> return createContextAsUser(parent, 0) }
}
return this
} }

View file

@ -4,7 +4,7 @@ import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.util.Log import android.util.Log
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.stevesoltys.seedvault.getSystemContext import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.plugins.EncryptedMetadata import com.stevesoltys.seedvault.plugins.EncryptedMetadata
import com.stevesoltys.seedvault.plugins.StoragePlugin import com.stevesoltys.seedvault.plugins.StoragePlugin
import com.stevesoltys.seedvault.settings.Storage import com.stevesoltys.seedvault.settings.Storage
@ -25,7 +25,7 @@ internal class DocumentsProviderStoragePlugin(
* Attention: This context might be from a different user. Use with care. * Attention: This context might be from a different user. Use with care.
*/ */
private val context: Context private val context: Context
get() = appContext.getSystemContext { get() = appContext.getStorageContext {
storage.storage?.isUsb == true storage.storage?.isUsb == true
} }
@ -83,7 +83,7 @@ internal class DocumentsProviderStoragePlugin(
@Throws(IOException::class) @Throws(IOException::class)
override suspend fun hasBackup(storage: Storage): Boolean { override suspend fun hasBackup(storage: Storage): Boolean {
// potentially get system user context if needed here // potentially get system user context if needed here
val c = appContext.getSystemContext { storage.isUsb } val c = appContext.getStorageContext { storage.isUsb }
val parent = DocumentFile.fromTreeUri(c, storage.uri) ?: throw AssertionError() val parent = DocumentFile.fromTreeUri(c, storage.uri) ?: throw AssertionError()
val rootDir = parent.findFileBlocking(c, DIRECTORY_ROOT) ?: return false val rootDir = parent.findFileBlocking(c, DIRECTORY_ROOT) ?: return false
val backupSets = getBackups(c, rootDir) val backupSets = getBackups(c, rootDir)

View file

@ -16,7 +16,7 @@ import android.provider.DocumentsContract.getDocumentId
import android.util.Log import android.util.Log
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.stevesoltys.seedvault.getSystemContext import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.settings.SettingsManager import com.stevesoltys.seedvault.settings.SettingsManager
import com.stevesoltys.seedvault.settings.Storage import com.stevesoltys.seedvault.settings.Storage
import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.TimeoutCancellationException
@ -55,7 +55,7 @@ internal class DocumentsStorage(
* Attention: This context might be from a different user. Use with care. * Attention: This context might be from a different user. Use with care.
*/ */
private val context: Context private val context: Context
get() = appContext.getSystemContext { get() = appContext.getStorageContext {
storage?.isUsb == true storage?.isUsb == true
} }
private val contentResolver: ContentResolver get() = context.contentResolver private val contentResolver: ContentResolver get() = context.contentResolver

View file

@ -9,7 +9,7 @@ import androidx.annotation.UiThread
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import com.stevesoltys.seedvault.getSystemContext import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.permitDiskReads import com.stevesoltys.seedvault.permitDiskReads
import com.stevesoltys.seedvault.transport.backup.BackupCoordinator import com.stevesoltys.seedvault.transport.backup.BackupCoordinator
import java.util.concurrent.ConcurrentSkipListSet import java.util.concurrent.ConcurrentSkipListSet
@ -131,7 +131,7 @@ class SettingsManager(private val context: Context) {
@WorkerThread @WorkerThread
fun canDoBackupNow(): Boolean { fun canDoBackupNow(): Boolean {
val storage = getStorage() ?: return false val storage = getStorage() ?: return false
val systemContext = context.getSystemContext { storage.isUsb } val systemContext = context.getStorageContext { storage.isUsb }
return !storage.isUnavailableUsb(systemContext) && !storage.isUnavailableNetwork(context) return !storage.isUnavailableUsb(systemContext) && !storage.isUnavailableNetwork(context)
} }

View file

@ -3,7 +3,7 @@ package com.stevesoltys.seedvault.storage
import android.content.Context import android.content.Context
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.stevesoltys.seedvault.crypto.KeyManager import com.stevesoltys.seedvault.crypto.KeyManager
import com.stevesoltys.seedvault.getSystemContext import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.plugins.saf.DocumentsStorage import com.stevesoltys.seedvault.plugins.saf.DocumentsStorage
import org.calyxos.backup.storage.plugin.saf.SafStoragePlugin import org.calyxos.backup.storage.plugin.saf.SafStoragePlugin
import javax.crypto.SecretKey import javax.crypto.SecretKey
@ -17,7 +17,7 @@ internal class SeedvaultStoragePlugin(
* Attention: This context might be from a different user. Use with care. * Attention: This context might be from a different user. Use with care.
*/ */
override val context: Context override val context: Context
get() = appContext.getSystemContext { get() = appContext.getStorageContext {
storage.storage?.isUsb == true storage.storage?.isUsb == true
} }
override val root: DocumentFile override val root: DocumentFile

View file

@ -20,7 +20,7 @@ import android.provider.DocumentsContract.Root.FLAG_SUPPORTS_CREATE
import android.provider.DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD import android.provider.DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD
import android.util.Log import android.util.Log
import com.stevesoltys.seedvault.R import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.getSystemContext import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.ui.storage.StorageOption.SafOption import com.stevesoltys.seedvault.ui.storage.StorageOption.SafOption
internal object StorageRootResolver { internal object StorageRootResolver {
@ -39,7 +39,7 @@ internal object StorageRootResolver {
} }
} }
// add special system user roots for USB devices // add special system user roots for USB devices
val c = context.getSystemContext { val c = context.getStorageContext {
authority == AUTHORITY_STORAGE && UserHandle.myUserId() != UserHandle.USER_SYSTEM authority == AUTHORITY_STORAGE && UserHandle.myUserId() != UserHandle.USER_SYSTEM
} }
// only proceed if we really got a different [Context], e.g. had permission for it // only proceed if we really got a different [Context], e.g. had permission for it