From d2a6282fbf9b3c1a60584773c3f892987b7ccfda Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 1 Jul 2021 17:10:27 -0300 Subject: [PATCH] Fix crash that happens when starting RestoreActivity without key This instantiates all sorts of classes down to Restore which accessed the streamKey that is still unavailable at this point. Now it is only instantiated lazily when actually starting a restore. --- .../calyxos/backup/storage/restore/Restore.kt | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/storage/lib/src/main/java/org/calyxos/backup/storage/restore/Restore.kt b/storage/lib/src/main/java/org/calyxos/backup/storage/restore/Restore.kt index 1bd0e081..297c1d5c 100644 --- a/storage/lib/src/main/java/org/calyxos/backup/storage/restore/Restore.kt +++ b/storage/lib/src/main/java/org/calyxos/backup/storage/restore/Restore.kt @@ -30,18 +30,27 @@ internal class Restore( streamCrypto: StreamCrypto = StreamCrypto, ) { - private val streamKey = try { - streamCrypto.deriveStreamKey(storagePlugin.getMasterKey()) - } catch (e: GeneralSecurityException) { - throw AssertionError(e) + private val streamKey by lazy { + // This class might get instantiated before the StoragePlugin had time to provide the key + // so we need to get it lazily here to prevent crashes. We can still crash later, + // if the plugin is not providing a key as it should when performing calls into this class. + try { + streamCrypto.deriveStreamKey(storagePlugin.getMasterKey()) + } catch (e: GeneralSecurityException) { + throw AssertionError(e) + } } - private val zipChunkRestore = + // lazily instantiate these, so they don't try to get the streamKey too early + private val zipChunkRestore by lazy { ZipChunkRestore(storagePlugin, fileRestore, streamCrypto, streamKey) - private val singleChunkRestore = + } + private val singleChunkRestore by lazy { SingleChunkRestore(storagePlugin, fileRestore, streamCrypto, streamKey) - private val multiChunkRestore = + } + private val multiChunkRestore by lazy { MultiChunkRestore(context, storagePlugin, fileRestore, streamCrypto, streamKey) + } fun getBackupSnapshots(): Flow = flow { val numSnapshots: Int