Address book android auto backup (#1641)
* Address book android auto backup * Documentation update * Address book container folder added * Address book general error handling * Address book memory storage hotfix * Documentation update --------- Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
parent
95285c5133
commit
32b132950c
|
@ -8,6 +8,7 @@ and this application adheres to [Semantic Versioning](https://semver.org/spec/v2
|
|||
|
||||
### Added
|
||||
- Address book encryption
|
||||
- Android auto backup support for address book encryption
|
||||
- The device authentication feature on the Zashi app launch has been added
|
||||
- Zashi app now supports Spanish language. It can be changed in the System settings options.
|
||||
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
<application
|
||||
android:name="co.electriccoin.zcash.app.ZcashApplication"
|
||||
android:allowBackup="false"
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/auto_backup_config"
|
||||
android:dataExtractionRules="@xml/auto_backup_config_android_12"
|
||||
android:backupInForeground="true"
|
||||
android:icon="@mipmap/ic_launcher_square"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<full-backup-content>
|
||||
<include
|
||||
domain="file"
|
||||
path="address_book/." />
|
||||
</full-backup-content>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<data-extraction-rules>
|
||||
<cloud-backup disableIfNoEncryptionCapabilities="false">
|
||||
<include
|
||||
domain="file"
|
||||
path="address_book/." />
|
||||
</cloud-backup>
|
||||
</data-extraction-rules>
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<application
|
||||
android:name="co.electriccoin.zcash.app.ZcashApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher_square"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name">
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<application
|
||||
android:name="co.electriccoin.zcash.app.ZcashApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher_square"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name">
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
<application
|
||||
android:name="co.electriccoin.zcash.app.ZcashApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher_square"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name">
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
# Documentation
|
||||
|
||||
Here you'll find documentation
|
||||
TBD
|
||||
# Android auto backup testing
|
||||
|
||||
To force the android system back up the app use the following commands:
|
||||
```
|
||||
adb shell bmgr enable true
|
||||
adb shell bmgr backupnow co.electriccoin.zcash.debug
|
||||
```
|
||||
|
|
|
@ -11,6 +11,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
|||
|
||||
### Added
|
||||
- Address book encryption
|
||||
- Android auto backup support for address book encryption
|
||||
- The device authentication feature on the Zashi app launch has been added
|
||||
- Zashi app now supports Spanish language. It can be changed in the System settings options.
|
||||
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
|
||||
|
|
|
@ -11,6 +11,7 @@ directly impact users rather than highlighting other key architectural updates.*
|
|||
|
||||
### Added
|
||||
- Address book encryption
|
||||
- Android auto backup support for address book encryption
|
||||
- The device authentication feature on the Zashi app launch has been added
|
||||
- Zashi app now supports Spanish language. It can be changed in the System settings options.
|
||||
- The Flexa SDK has been adopted to enable payments using the embedded Flexa UI
|
||||
|
|
|
@ -11,8 +11,6 @@ import co.electriccoin.zcash.ui.common.serialization.addressbook.AddressBookKey
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.datetime.Clock
|
||||
import java.io.IOException
|
||||
import java.security.GeneralSecurityException
|
||||
|
||||
interface LocalAddressBookDataSource {
|
||||
suspend fun getContacts(addressBookKey: AddressBookKey): AddressBook
|
||||
|
@ -61,7 +59,9 @@ class LocalAddressBookDataSourceImpl(
|
|||
lastUpdated = Clock.System.now(),
|
||||
version = ADDRESS_BOOK_SERIALIZATION_V1,
|
||||
contacts = emptyList(),
|
||||
)
|
||||
).also {
|
||||
this@LocalAddressBookDataSourceImpl.addressBook = it
|
||||
}
|
||||
writeAddressBookToLocalStorage(newAddressBook, addressBookKey)
|
||||
}
|
||||
newAddressBook
|
||||
|
@ -88,7 +88,9 @@ class LocalAddressBookDataSourceImpl(
|
|||
address = address,
|
||||
lastUpdated = lastUpdated,
|
||||
),
|
||||
)
|
||||
).also {
|
||||
addressBook = it
|
||||
}
|
||||
writeAddressBookToLocalStorage(newAddressBook, addressBookKey)
|
||||
newAddressBook
|
||||
}
|
||||
|
@ -118,7 +120,9 @@ class LocalAddressBookDataSourceImpl(
|
|||
)
|
||||
}
|
||||
.toList(),
|
||||
)
|
||||
).also {
|
||||
addressBook = it
|
||||
}
|
||||
writeAddressBookToLocalStorage(newAddressBook, addressBookKey)
|
||||
newAddressBook
|
||||
}
|
||||
|
@ -139,7 +143,9 @@ class LocalAddressBookDataSourceImpl(
|
|||
remove(addressBookContact)
|
||||
}
|
||||
.toList(),
|
||||
)
|
||||
).also {
|
||||
addressBook = it
|
||||
}
|
||||
writeAddressBookToLocalStorage(newAddressBook, addressBookKey)
|
||||
newAddressBook
|
||||
}
|
||||
|
@ -158,22 +164,15 @@ class LocalAddressBookDataSourceImpl(
|
|||
|
||||
@Suppress("ReturnCount")
|
||||
private suspend fun readLocalFileToAddressBook(addressBookKey: AddressBookKey): AddressBook? {
|
||||
val encryptedFile = addressBookStorageProvider.getStorageFile(addressBookKey)
|
||||
val unencryptedFile = addressBookStorageProvider.getLegacyUnencryptedStorageFile()
|
||||
val encryptedFile = runCatching { addressBookStorageProvider.getStorageFile(addressBookKey) }.getOrNull()
|
||||
val unencryptedFile = runCatching { addressBookStorageProvider.getLegacyUnencryptedStorageFile() }.getOrNull()
|
||||
|
||||
if (encryptedFile != null) {
|
||||
return try {
|
||||
addressBookProvider.readAddressBookFromFile(encryptedFile, addressBookKey)
|
||||
.also {
|
||||
unencryptedFile?.deleteSuspend()
|
||||
}
|
||||
} catch (e: GeneralSecurityException) {
|
||||
Twig.warn(e) { "Failed to decrypt address book" }
|
||||
null
|
||||
} catch (e: IOException) {
|
||||
Twig.warn(e) { "Failed to decrypt address book" }
|
||||
null
|
||||
}
|
||||
return runCatching {
|
||||
addressBookProvider
|
||||
.readAddressBookFromFile(encryptedFile, addressBookKey)
|
||||
.also { unencryptedFile?.deleteSuspend() }
|
||||
}.onFailure { e -> Twig.warn(e) { "Failed to decrypt address book" } }.getOrNull()
|
||||
}
|
||||
|
||||
return if (unencryptedFile != null) {
|
||||
|
@ -191,7 +190,9 @@ class LocalAddressBookDataSourceImpl(
|
|||
addressBook: AddressBook,
|
||||
addressBookKey: AddressBookKey
|
||||
) {
|
||||
val file = addressBookStorageProvider.getOrCreateStorageFile(addressBookKey)
|
||||
addressBookProvider.writeAddressBookToFile(file, addressBook, addressBookKey)
|
||||
runCatching {
|
||||
val file = addressBookStorageProvider.getOrCreateStorageFile(addressBookKey)
|
||||
addressBookProvider.writeAddressBookToFile(file, addressBook, addressBookKey)
|
||||
}.onFailure { e -> Twig.warn(e) { "Failed to write address book" } }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,17 +11,17 @@ interface AddressBookStorageProvider {
|
|||
|
||||
fun getOrCreateStorageFile(addressBookKey: AddressBookKey): File
|
||||
|
||||
/**
|
||||
* Create a temporary file into which data from remote is written. This file is removed after usage.
|
||||
*/
|
||||
fun getOrCreateTempStorageFile(): File
|
||||
// /**
|
||||
// * Create a temporary file into which data from remote is written. This file is removed after usage.
|
||||
// */
|
||||
// fun getOrCreateTempStorageFile(): File
|
||||
}
|
||||
|
||||
class AddressBookStorageProviderImpl(
|
||||
private val context: Context
|
||||
) : AddressBookStorageProvider {
|
||||
override fun getStorageFile(addressBookKey: AddressBookKey): File? {
|
||||
return File(context.noBackupFilesDir, addressBookKey.fileIdentifier())
|
||||
return File(getOrCreateAddressBookDir(), addressBookKey.fileIdentifier())
|
||||
.takeIf { it.exists() && it.isFile }
|
||||
}
|
||||
|
||||
|
@ -31,19 +31,30 @@ class AddressBookStorageProviderImpl(
|
|||
}
|
||||
|
||||
override fun getOrCreateStorageFile(addressBookKey: AddressBookKey): File {
|
||||
return getOrCreateFile(addressBookKey.fileIdentifier())
|
||||
}
|
||||
|
||||
override fun getOrCreateTempStorageFile(): File = getOrCreateFile(REMOTE_ADDRESS_BOOK_FILE_NAME_LOCAL_COPY)
|
||||
|
||||
private fun getOrCreateFile(name: String): File {
|
||||
val file = File(context.noBackupFilesDir, name)
|
||||
val file = File(getOrCreateAddressBookDir(), addressBookKey.fileIdentifier())
|
||||
if (!file.exists()) {
|
||||
file.createNewFile()
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
// override fun getOrCreateTempStorageFile(): File {
|
||||
// val file = File(context.noBackupFilesDir, REMOTE_ADDRESS_BOOK_FILE_NAME_LOCAL_COPY)
|
||||
// if (!file.exists()) {
|
||||
// file.createNewFile()
|
||||
// }
|
||||
// return file
|
||||
// }
|
||||
|
||||
private fun getOrCreateAddressBookDir(): File {
|
||||
val filesDir = context.filesDir
|
||||
val addressBookDir = File(filesDir, "address_book")
|
||||
if (!addressBookDir.exists()) {
|
||||
addressBookDir.mkdir()
|
||||
}
|
||||
return addressBookDir
|
||||
}
|
||||
}
|
||||
|
||||
private const val LEGACY_UNENCRYPTED_ADDRESS_BOOK_FILE_NAME = "address_book"
|
||||
private const val REMOTE_ADDRESS_BOOK_FILE_NAME_LOCAL_COPY = "address_book_temp"
|
||||
// private const val REMOTE_ADDRESS_BOOK_FILE_NAME_LOCAL_COPY = "address_book_temp"
|
||||
|
|
Loading…
Reference in New Issue