Перенос localVault в domain-storage
This commit is contained in:
@@ -1,105 +0,0 @@
|
||||
package com.github.nullptroma.wallenc.infrastructure.vaults.local
|
||||
|
||||
import android.content.Context
|
||||
import com.github.nullptroma.wallenc.infrastructure.storages.local.LocalStorage
|
||||
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
|
||||
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
|
||||
import com.github.nullptroma.wallenc.vault.contract.DescribedVault
|
||||
import com.github.nullptroma.wallenc.vault.contract.VaultDescriptor
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.createDirectory
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class LocalVault(
|
||||
private val ioDispatcher: CoroutineDispatcher,
|
||||
context: Context,
|
||||
idStore: LocalVaultIdStore,
|
||||
) : DescribedVault {
|
||||
|
||||
override val uuid: UUID = idStore.getOrCreate()
|
||||
|
||||
override val descriptor: VaultDescriptor = VaultDescriptor.LocalDevice(uuid)
|
||||
|
||||
private val _storages = MutableStateFlow<List<IStorage>>(emptyList())
|
||||
override val storages: StateFlow<List<IStorage>> = _storages
|
||||
|
||||
private val _isAvailable = MutableStateFlow(false)
|
||||
override val isAvailable: StateFlow<Boolean> = _isAvailable
|
||||
|
||||
private val _totalSpace = MutableStateFlow<Long?>(null)
|
||||
override val totalSpace: StateFlow<Long?> = _totalSpace
|
||||
|
||||
private val _availableSpace = MutableStateFlow<Long?>(null)
|
||||
override val availableSpace: StateFlow<Long?> = _availableSpace
|
||||
|
||||
private val path = MutableStateFlow<File?>(null)
|
||||
|
||||
init {
|
||||
CoroutineScope(ioDispatcher).launch {
|
||||
path.value = context.getExternalFilesDir("LocalVault")
|
||||
_isAvailable.value = path.value != null
|
||||
readStorages()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun readStorages() {
|
||||
val path = path.value
|
||||
if (path == null || !_isAvailable.value)
|
||||
throw Exception("Not available")
|
||||
|
||||
val dirs = path.listFiles()?.filter { it.isDirectory }
|
||||
if (dirs != null) {
|
||||
_storages.value = dirs.map {
|
||||
val uuid = UUID.fromString(it.name)
|
||||
LocalStorage(uuid, it.path, ioDispatcher).apply { init() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun createStorage(): LocalStorage = withContext(ioDispatcher) {
|
||||
val path = path.value
|
||||
if (path == null || !_isAvailable.value)
|
||||
throw Exception("Not available")
|
||||
|
||||
val uuid = UUID.randomUUID()
|
||||
val next = Path(path.path, uuid.toString())
|
||||
next.createDirectory()
|
||||
val newStorage = LocalStorage(uuid, next.pathString, ioDispatcher)
|
||||
newStorage.init()
|
||||
_storages.value = _storages.value.toMutableList().apply {
|
||||
add(newStorage)
|
||||
}
|
||||
return@withContext newStorage
|
||||
}
|
||||
|
||||
override suspend fun createStorage(
|
||||
enc: StorageEncryptionInfo,
|
||||
): LocalStorage = withContext(ioDispatcher) {
|
||||
val storage = createStorage()
|
||||
storage.setEncInfo(enc)
|
||||
return@withContext storage
|
||||
}
|
||||
|
||||
override suspend fun remove(storage: IStorage) = withContext(ioDispatcher) {
|
||||
val path = path.value
|
||||
if (path == null || !_isAvailable.value)
|
||||
throw Exception("Not available")
|
||||
|
||||
val curStorages = _storages.value.toMutableList()
|
||||
val index = curStorages.indexOfFirst { it.uuid == storage.uuid }
|
||||
if (index != -1) {
|
||||
val localStorage = curStorages[index] as LocalStorage
|
||||
curStorages.removeAt(index)
|
||||
_storages.value = curStorages
|
||||
File(localStorage.absolutePath).deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.github.nullptroma.wallenc.infrastructure.vaults.local
|
||||
|
||||
import android.content.Context
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Хранит/восстанавливает идентификатор единственного локального vault'а
|
||||
* в [android.content.SharedPreferences]. При первом обращении генерирует новый UUID
|
||||
* и записывает его синхронно (`commit`), чтобы к моменту, когда другие подсистемы
|
||||
* (DB, шифр-ключи) начнут связывать с ним записи, значение уже было персистентно.
|
||||
*/
|
||||
class LocalVaultIdStore(context: Context) {
|
||||
|
||||
private val prefs = context.applicationContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||
|
||||
/** Возвращает существующий идентификатор или, если его нет, генерирует и сохраняет новый. */
|
||||
fun getOrCreate(): UUID {
|
||||
prefs.getString(KEY_LOCAL_VAULT_UUID, null)?.let { stored ->
|
||||
runCatching { UUID.fromString(stored) }.getOrNull()?.let { return it }
|
||||
}
|
||||
val generated = UUID.randomUUID()
|
||||
prefs.edit().putString(KEY_LOCAL_VAULT_UUID, generated.toString()).commit()
|
||||
return generated
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val PREFS_NAME = "wallenc.vaults"
|
||||
const val KEY_LOCAL_VAULT_UUID = "local_vault_uuid"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user