@@ -418,23 +418,29 @@ public class SafeBox private constructor(
418
418
stateListener?.let (safeBox.stateManager::setStateListener)
419
419
return safeBox
420
420
}
421
- val aesGcmCipherProvider = AesGcmCipherProvider .create(
422
- alias = valueKeyStoreAlias,
423
- aad = additionalAuthenticatedData,
424
- )
425
- val keyProvider = SecureRandomKeyProvider .create(
426
- context = context,
427
- fileName = keyAlias,
428
- keySize = ChaCha20CipherProvider .KEY_SIZE ,
429
- algorithm = ChaCha20CipherProvider .ALGORITHM ,
430
- cipherProvider = aesGcmCipherProvider,
431
- )
432
- val keyCipherProvider = ChaCha20CipherProvider (keyProvider, deterministic = true )
433
- val valueCipherProvider = ChaCha20CipherProvider (keyProvider, deterministic = false )
434
- val stateManager = SafeBoxStateManager (fileName, stateListener, ioDispatcher)
435
- val blobStore = SafeBoxBlobStore .create(context, fileName)
436
- return SafeBox (blobStore, keyCipherProvider, valueCipherProvider, stateManager)
437
- .also { instances[fileName] = it }
421
+ return synchronized(instances) {
422
+ instances[fileName]?.let { safeBox ->
423
+ stateListener?.let (safeBox.stateManager::setStateListener)
424
+ return safeBox
425
+ }
426
+ val aesGcmCipherProvider = AesGcmCipherProvider .create(
427
+ alias = valueKeyStoreAlias,
428
+ aad = additionalAuthenticatedData,
429
+ )
430
+ val keyProvider = SecureRandomKeyProvider .create(
431
+ context = context,
432
+ fileName = keyAlias,
433
+ keySize = ChaCha20CipherProvider .KEY_SIZE ,
434
+ algorithm = ChaCha20CipherProvider .ALGORITHM ,
435
+ cipherProvider = aesGcmCipherProvider,
436
+ )
437
+ val keyCipherProvider = ChaCha20CipherProvider (keyProvider, deterministic = true )
438
+ val valueCipherProvider = ChaCha20CipherProvider (keyProvider, deterministic = false )
439
+ val stateManager = SafeBoxStateManager (fileName, stateListener, ioDispatcher)
440
+ val blobStore = SafeBoxBlobStore .create(context, fileName)
441
+ SafeBox (blobStore, keyCipherProvider, valueCipherProvider, stateManager)
442
+ .also { instances[fileName] = it }
443
+ }
438
444
}
439
445
440
446
/* *
@@ -472,10 +478,34 @@ public class SafeBox private constructor(
472
478
stateListener?.let (safeBox.stateManager::setStateListener)
473
479
return safeBox
474
480
}
475
- val stateManager = SafeBoxStateManager (fileName, stateListener, ioDispatcher)
476
- val blobStore = SafeBoxBlobStore .create(context, fileName)
477
- return SafeBox (blobStore, keyCipherProvider, valueCipherProvider, stateManager)
478
- .also { instances[fileName] = it }
481
+ return synchronized(instances) {
482
+ instances[fileName]?.let { safeBox ->
483
+ stateListener?.let (safeBox.stateManager::setStateListener)
484
+ return safeBox
485
+ }
486
+ val stateManager = SafeBoxStateManager (fileName, stateListener, ioDispatcher)
487
+ val blobStore = SafeBoxBlobStore .create(context, fileName)
488
+ SafeBox (blobStore, keyCipherProvider, valueCipherProvider, stateManager)
489
+ .also { instances[fileName] = it }
490
+ }
479
491
}
492
+
493
+ /* *
494
+ * Returns the previously created instance for [fileName].
495
+ *
496
+ * @return The existing [SafeBox] instance.
497
+ * @throws IllegalStateException if [create] has not been called for this file.
498
+ */
499
+ @JvmStatic
500
+ public fun get (fileName : String ): SafeBox =
501
+ instances[fileName] ? : error(" SafeBox '$fileName ' is not initialized." )
502
+
503
+ /* *
504
+ * Returns the previously created instance for [fileName], or null if not initialized.
505
+ *
506
+ * @return The existing [SafeBox] instance, or null.
507
+ */
508
+ @JvmStatic
509
+ public fun getOrNull (fileName : String ): SafeBox ? = instances[fileName]
480
510
}
481
511
}
0 commit comments