Merge pull request #563 from seedvault-app/bugfix/binder-exception-too-many-packages
Fix binder exception when restoring a large number of applications
diff --git a/app/src/main/java/com/stevesoltys/seedvault/App.kt b/app/src/main/java/com/stevesoltys/seedvault/App.kt
index c035481..f3403de 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/App.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/App.kt
@@ -5,12 +5,11 @@
import android.app.backup.BackupManager.PACKAGE_MANAGER_SENTINEL
import android.app.backup.IBackupManager
import android.content.Context
-import android.content.Context.BACKUP_SERVICE
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Build
import android.os.ServiceManager.getService
import android.os.StrictMode
-import android.os.UserHandle
+import android.os.UserManager
import com.stevesoltys.seedvault.crypto.cryptoModule
import com.stevesoltys.seedvault.header.headerModule
import com.stevesoltys.seedvault.metadata.MetadataManager
@@ -143,8 +142,11 @@
}
}
-fun Context.getSystemContext(isUsbStorage: () -> Boolean): Context {
- return if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED &&
- isUsbStorage()
- ) createContextAsUser(UserHandle.SYSTEM, 0) else this
+@Suppress("MissingPermission")
+fun Context.getStorageContext(isUsbStorage: () -> Boolean): Context {
+ if (checkSelfPermission(INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED && isUsbStorage()) {
+ UserManager.get(this).getProfileParent(user)
+ ?.let { parent -> return createContextAsUser(parent, 0) }
+ }
+ return this
}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderStoragePlugin.kt b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderStoragePlugin.kt
index 94ff8ad..0dbc6c5 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderStoragePlugin.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsProviderStoragePlugin.kt
@@ -4,7 +4,7 @@
import android.content.pm.PackageManager
import android.util.Log
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.StoragePlugin
import com.stevesoltys.seedvault.settings.Storage
@@ -25,7 +25,7 @@
* Attention: This context might be from a different user. Use with care.
*/
private val context: Context
- get() = appContext.getSystemContext {
+ get() = appContext.getStorageContext {
storage.storage?.isUsb == true
}
@@ -83,7 +83,7 @@
@Throws(IOException::class)
override suspend fun hasBackup(storage: Storage): Boolean {
// 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 rootDir = parent.findFileBlocking(c, DIRECTORY_ROOT) ?: return false
val backupSets = getBackups(c, rootDir)
diff --git a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt
index 2ae9699..7e970a7 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/plugins/saf/DocumentsStorage.kt
@@ -16,7 +16,7 @@
import android.util.Log
import androidx.annotation.VisibleForTesting
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.Storage
import kotlinx.coroutines.TimeoutCancellationException
@@ -55,7 +55,7 @@
* Attention: This context might be from a different user. Use with care.
*/
private val context: Context
- get() = appContext.getSystemContext {
+ get() = appContext.getStorageContext {
storage?.isUsb == true
}
private val contentResolver: ContentResolver get() = context.contentResolver
diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsManager.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsManager.kt
index e26e61d..a83c844 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsManager.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsManager.kt
@@ -9,7 +9,7 @@
import androidx.annotation.WorkerThread
import androidx.documentfile.provider.DocumentFile
import androidx.preference.PreferenceManager
-import com.stevesoltys.seedvault.getSystemContext
+import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.permitDiskReads
import com.stevesoltys.seedvault.transport.backup.BackupCoordinator
import java.util.concurrent.ConcurrentSkipListSet
@@ -131,7 +131,7 @@
@WorkerThread
fun canDoBackupNow(): Boolean {
val storage = getStorage() ?: return false
- val systemContext = context.getSystemContext { storage.isUsb }
+ val systemContext = context.getStorageContext { storage.isUsb }
return !storage.isUnavailableUsb(systemContext) && !storage.isUnavailableNetwork(context)
}
diff --git a/app/src/main/java/com/stevesoltys/seedvault/storage/SeedvaultStoragePlugin.kt b/app/src/main/java/com/stevesoltys/seedvault/storage/SeedvaultStoragePlugin.kt
index ca478f1..d965738 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/storage/SeedvaultStoragePlugin.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/storage/SeedvaultStoragePlugin.kt
@@ -3,7 +3,7 @@
import android.content.Context
import androidx.documentfile.provider.DocumentFile
import com.stevesoltys.seedvault.crypto.KeyManager
-import com.stevesoltys.seedvault.getSystemContext
+import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.plugins.saf.DocumentsStorage
import org.calyxos.backup.storage.plugin.saf.SafStoragePlugin
import javax.crypto.SecretKey
@@ -17,7 +17,7 @@
* Attention: This context might be from a different user. Use with care.
*/
override val context: Context
- get() = appContext.getSystemContext {
+ get() = appContext.getStorageContext {
storage.storage?.isUsb == true
}
override val root: DocumentFile
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageRootResolver.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageRootResolver.kt
index 9db71b6..5a48e2e 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageRootResolver.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/storage/StorageRootResolver.kt
@@ -20,7 +20,7 @@
import android.provider.DocumentsContract.Root.FLAG_SUPPORTS_IS_CHILD
import android.util.Log
import com.stevesoltys.seedvault.R
-import com.stevesoltys.seedvault.getSystemContext
+import com.stevesoltys.seedvault.getStorageContext
import com.stevesoltys.seedvault.ui.storage.StorageOption.SafOption
internal object StorageRootResolver {
@@ -39,7 +39,7 @@
}
}
// add special system user roots for USB devices
- val c = context.getSystemContext {
+ val c = context.getStorageContext {
authority == AUTHORITY_STORAGE && UserHandle.myUserId() != UserHandle.USER_SYSTEM
}
// only proceed if we really got a different [Context], e.g. had permission for it