Мета информация о хранилищах хранится в бд

This commit is contained in:
Пытков Роман
2025-01-25 20:19:06 +03:00
parent 8e2ac2f68d
commit d78ed70e0f
25 changed files with 328 additions and 135 deletions

View File

@@ -3,13 +3,17 @@ package com.github.nullptroma.wallenc.data.db.app
import androidx.room.Database
import androidx.room.RoomDatabase
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
interface IAppDb {
val storageKeyMapDao: StorageKeyMapDao
val storageMetaInfoDao: StorageMetaInfoDao
}
@Database(entities = [DbStorageKeyMap::class], version = 2, exportSchema = false)
@Database(entities = [DbStorageKeyMap::class, DbStorageMetaInfo::class], version = 2, exportSchema = false)
abstract class AppDb : IAppDb, RoomDatabase() {
abstract override val storageKeyMapDao: StorageKeyMapDao
abstract override val storageMetaInfoDao: StorageMetaInfoDao
}

View File

@@ -12,11 +12,11 @@ import kotlinx.coroutines.flow.StateFlow
@Dao
interface StorageKeyMapDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun add(keymap: DbStorageKeyMap)
suspend fun add(keymap: DbStorageKeyMap)
@Query("SELECT * FROM storage_key_maps")
fun getAll(): List<DbStorageKeyMap>
suspend fun getAll(): List<DbStorageKeyMap>
@Delete
fun delete(keymap: DbStorageKeyMap)
suspend fun delete(keymap: DbStorageKeyMap)
}

View File

@@ -0,0 +1,35 @@
package com.github.nullptroma.wallenc.data.db.app.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
@Dao
interface StorageMetaInfoDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun add(metaInfo: DbStorageMetaInfo)
@Query("SELECT * FROM storage_meta_infos")
suspend fun getAll(): List<DbStorageMetaInfo>
@Query("SELECT * FROM storage_meta_infos")
fun getAllFlow(): Flow<List<DbStorageMetaInfo>>
@Query("SELECT * FROM storage_meta_infos WHERE uuid == :uuid")
fun getMetaInfoFlow(uuid: UUID): Flow<DbStorageMetaInfo>
@Query("SELECT * FROM storage_meta_infos WHERE uuid == :uuid")
suspend fun getMetaInfo(uuid: UUID): DbStorageMetaInfo?
@Delete
suspend fun delete(metaInfo: DbStorageMetaInfo)
}

View File

@@ -9,14 +9,14 @@ import java.util.UUID
@Entity(tableName = "storage_key_maps", primaryKeys = [ "source_uuid", "dest_uuid" ])
data class DbStorageKeyMap(
@ColumnInfo(name = "source_uuid") val sourceUuid: String,
@ColumnInfo(name = "dest_uuid") val destUuid: String,
@ColumnInfo(name = "source_uuid") val sourceUuid: UUID,
@ColumnInfo(name = "dest_uuid") val destUuid: UUID,
@ColumnInfo(name = "key") val key: ByteArray
) {
fun toModel(): StorageKeyMap {
return StorageKeyMap(
sourceUuid = UUID.fromString(sourceUuid),
destUuid = UUID.fromString(destUuid),
sourceUuid = sourceUuid,
destUuid = destUuid,
key = EncryptKey(key)
)
}
@@ -44,8 +44,8 @@ data class DbStorageKeyMap(
companion object {
fun fromModel(keymap: StorageKeyMap): DbStorageKeyMap {
return DbStorageKeyMap(
sourceUuid = keymap.sourceUuid.toString(),
destUuid = keymap.destUuid.toString(),
sourceUuid = keymap.sourceUuid,
destUuid = keymap.destUuid,
key = keymap.key.bytes
)
}

View File

@@ -0,0 +1,13 @@
package com.github.nullptroma.wallenc.data.db.app.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
import java.util.UUID
@Entity(tableName = "storage_meta_infos")
data class DbStorageMetaInfo(
@PrimaryKey @ColumnInfo(name = "uuid") val uuid: UUID,
@ColumnInfo(name = "meta_info") val metaInfoJson: String
)

View File

@@ -3,14 +3,20 @@ package com.github.nullptroma.wallenc.data.db.app.repository
import com.github.nullptroma.wallenc.data.db.app.dao.StorageKeyMapDao
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageKeyMap
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
class StorageKeyMapRepository(private val dao: StorageKeyMapDao) {
fun getAll() = dao.getAll().map { it.toModel() }
fun add(keymap: StorageKeyMap) {
class StorageKeyMapRepository(
private val dao: StorageKeyMapDao,
private val ioDispatcher: CoroutineDispatcher
) {
suspend fun getAll() = withContext(ioDispatcher) { dao.getAll().map { it.toModel() } }
suspend fun add(keymap: StorageKeyMap) = withContext(ioDispatcher) {
val dbModel = DbStorageKeyMap.fromModel(keymap)
dao.add(dbModel)
}
fun delete(keymap: StorageKeyMap) {
suspend fun delete(keymap: StorageKeyMap) = withContext(ioDispatcher) {
val dbModel = DbStorageKeyMap.fromModel(keymap)
dao.delete(dbModel)
}

View File

@@ -0,0 +1,52 @@
package com.github.nullptroma.wallenc.data.db.app.repository
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.github.nullptroma.wallenc.data.db.app.dao.StorageMetaInfoDao
import com.github.nullptroma.wallenc.data.db.app.model.DbStorageMetaInfo
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import java.util.UUID
class StorageMetaInfoRepository(
private val dao: StorageMetaInfoDao,
private val ioDispatcher: CoroutineDispatcher
) {
fun getAllFlow() = dao.getAllFlow()
suspend fun getAll() = withContext(ioDispatcher) { dao.getAll() }
suspend fun getMeta(uuid: UUID): CommonStorageMetaInfo? = withContext(ioDispatcher) {
val json = dao.getMetaInfo(uuid)?.metaInfoJson ?: return@withContext null
return@withContext jackson.readValue(
json,
CommonStorageMetaInfo::class.java
)
}
fun observeMeta(uuid: UUID): Flow<CommonStorageMetaInfo> {
return dao.getMetaInfoFlow(uuid)
.map { jackson.readValue(it.metaInfoJson, CommonStorageMetaInfo::class.java) }
}
suspend fun setMeta(uuid: UUID, metaInfo: CommonStorageMetaInfo) = withContext(ioDispatcher) {
val json = jackson.writeValueAsString(metaInfo)
dao.add(DbStorageMetaInfo(uuid, json))
}
fun createSingleStorageProvider(uuid: UUID): SingleStorageMetaInfoProvider {
return SingleStorageMetaInfoProvider(this, uuid)
}
class SingleStorageMetaInfoProvider (
private val repo: StorageMetaInfoRepository,
val uuid: UUID
) {
suspend fun get(): CommonStorageMetaInfo? = repo.getMeta(uuid)
suspend fun set(metaInfo: CommonStorageMetaInfo) = repo.setMeta(uuid, metaInfo)
}
companion object {
private val jackson = jacksonObjectMapper().apply { findAndRegisterModules() }
}
}

View File

@@ -1,9 +1,10 @@
package com.github.nullptroma.wallenc.data.vaults
package com.github.nullptroma.wallenc.data.storages
import com.github.nullptroma.wallenc.data.db.app.repository.StorageKeyMapRepository
import com.github.nullptroma.wallenc.data.db.app.repository.StorageMetaInfoRepository
import com.github.nullptroma.wallenc.data.model.StorageKeyMap
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import com.github.nullptroma.wallenc.domain.encrypt.EncryptedStorage
import com.github.nullptroma.wallenc.data.storages.encrypt.EncryptedStorage
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager
@@ -20,7 +21,8 @@ import kotlinx.coroutines.withContext
import java.util.UUID
class UnlockManager(
private val repo: StorageKeyMapRepository,
private val keymapRepository: StorageKeyMapRepository,
private val metaInfoRepository: StorageMetaInfoRepository,
private val ioDispatcher: CoroutineDispatcher,
vaultsManager: IVaultsManager
) : IUnlockManager {
@@ -33,7 +35,7 @@ class UnlockManager(
CoroutineScope(ioDispatcher).launch {
vaultsManager.allStorages.collectLatest {
mutex.lock()
val allKeys = repo.getAll()
val allKeys = keymapRepository.getAll()
val allStorages = it.associateBy({ it.uuid }, { it })
val map = _openedStorages.value?.toMutableMap() ?: mutableMapOf()
for(keymap in allKeys) {
@@ -49,11 +51,12 @@ class UnlockManager(
}
}
private fun createEncryptedStorage(storage: IStorage, key: EncryptKey, uuid: UUID): EncryptedStorage {
return EncryptedStorage(
_source = storage,
private suspend fun createEncryptedStorage(storage: IStorage, key: EncryptKey, uuid: UUID): EncryptedStorage {
return EncryptedStorage.create(
source = storage,
key = key,
ioDispatcher = ioDispatcher,
metaInfoProvider = metaInfoRepository.createSingleStorageProvider(uuid),
uuid = uuid
)
}
@@ -80,7 +83,7 @@ class UnlockManager(
val encStorage = createEncryptedStorage(storage, keymap.key, keymap.destUuid)
opened[storage.uuid] = encStorage
_openedStorages.value = opened
repo.add(keymap)
keymapRepository.add(keymap)
mutex.unlock()
}
@@ -97,7 +100,7 @@ class UnlockManager(
remove(storage.uuid)
}
enc.dispose()
repo.delete(model)
keymapRepository.delete(model)
mutex.unlock()
}
}

View File

@@ -0,0 +1,96 @@
package com.github.nullptroma.wallenc.data.storages.encrypt
import com.github.nullptroma.wallenc.data.db.app.repository.StorageMetaInfoRepository
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IStorageMetaInfo
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.withContext
import java.util.UUID
class EncryptedStorage private constructor(
private val source: IStorage,
key: EncryptKey,
private val ioDispatcher: CoroutineDispatcher,
private val metaInfoProvider: StorageMetaInfoRepository.SingleStorageMetaInfoProvider,
override val uuid: UUID = UUID.randomUUID()
) : IStorage, DisposableHandle {
override val size: StateFlow<Long?>
get() = source.size
override val numberOfFiles: StateFlow<Int?>
get() = source.numberOfFiles
private val _metaInfo = MutableStateFlow<IStorageMetaInfo>(
CommonStorageMetaInfo()
)
override val metaInfo: StateFlow<IStorageMetaInfo>
get() = _metaInfo
override val isVirtualStorage: Boolean = true
override val isAvailable: StateFlow<Boolean>
get() = source.isAvailable
override val accessor: EncryptedStorageAccessor =
EncryptedStorageAccessor(source.accessor, key, ioDispatcher)
private suspend fun init() {
readMeta()
}
private suspend fun readMeta() = withContext(ioDispatcher) {
var meta = metaInfoProvider.get()
if(meta == null) {
meta = CommonStorageMetaInfo()
metaInfoProvider.set(meta)
}
_metaInfo.value = meta
}
override suspend fun rename(newName: String) = withContext(ioDispatcher) {
val cur = _metaInfo.value
val newMeta = CommonStorageMetaInfo(
encInfo = cur.encInfo,
name = newName
)
_metaInfo.value = newMeta
metaInfoProvider.set(newMeta)
}
override suspend fun setEncInfo(encInfo: StorageEncryptionInfo) = withContext(ioDispatcher) {
val cur = _metaInfo.value
val newMeta = CommonStorageMetaInfo(
encInfo = encInfo,
name = cur.name
)
_metaInfo.value = newMeta
metaInfoProvider.set(newMeta)
}
override fun dispose() {
accessor.dispose()
}
companion object {
suspend fun create(
source: IStorage,
key: EncryptKey,
ioDispatcher: CoroutineDispatcher,
metaInfoProvider: StorageMetaInfoRepository.SingleStorageMetaInfoProvider,
uuid: UUID = UUID.randomUUID()
): EncryptedStorage = withContext(ioDispatcher) {
val storage = EncryptedStorage(
source = source,
key = key,
ioDispatcher = ioDispatcher,
metaInfoProvider = metaInfoProvider,
uuid = uuid
)
storage.init()
return@withContext storage
}
}
}

View File

@@ -0,0 +1,218 @@
package com.github.nullptroma.wallenc.data.storages.encrypt
import com.github.nullptroma.wallenc.domain.common.impl.CommonDirectory
import com.github.nullptroma.wallenc.domain.common.impl.CommonFile
import com.github.nullptroma.wallenc.domain.common.impl.CommonMetaInfo
import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import com.github.nullptroma.wallenc.domain.encrypt.Encryptor
import com.github.nullptroma.wallenc.domain.interfaces.IDirectory
import com.github.nullptroma.wallenc.domain.interfaces.IFile
import com.github.nullptroma.wallenc.domain.interfaces.IMetaInfo
import com.github.nullptroma.wallenc.domain.interfaces.IStorageAccessor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import java.io.InputStream
import java.io.OutputStream
import kotlin.io.path.Path
import kotlin.io.path.pathString
class EncryptedStorageAccessor(
private val source: IStorageAccessor,
key: EncryptKey,
ioDispatcher: CoroutineDispatcher
) : IStorageAccessor, DisposableHandle {
private val job = Job()
private val scope = CoroutineScope(ioDispatcher + job)
override val size: StateFlow<Long?> = source.size
override val numberOfFiles: StateFlow<Int?> = source.numberOfFiles
override val isAvailable: StateFlow<Boolean> = source.isAvailable
private val _filesUpdates = MutableSharedFlow<DataPackage<List<IFile>>>()
override val filesUpdates: SharedFlow<DataPackage<List<IFile>>> = _filesUpdates
private val _dirsUpdates = MutableSharedFlow<DataPackage<List<IDirectory>>>()
override val dirsUpdates: SharedFlow<DataPackage<List<IDirectory>>> = _dirsUpdates
private val encryptor = Encryptor(key.toAesKey())
init {
collectSourceState()
}
private fun collectSourceState() {
scope.launch {
launch {
source.filesUpdates.collect {
val files = it.data.map(::decryptEntity)
_filesUpdates.emit(DataPackage(
data = files,
isLoading = it.isLoading,
isError = it.isError
))
}
}
launch {
source.dirsUpdates.collect {
val dirs = it.data.map(::decryptEntity)
_dirsUpdates.emit(DataPackage(
data = dirs,
isLoading = it.isLoading,
isError = it.isError
))
}
}
}
}
private fun encryptEntity(file: IFile): IFile {
return CommonFile(encryptMeta(file.metaInfo))
}
private fun decryptEntity(file: IFile): IFile {
return CommonFile(decryptMeta(file.metaInfo))
}
private fun encryptEntity(dir: IDirectory): IDirectory {
return CommonDirectory(encryptMeta(dir.metaInfo), dir.elementsCount)
}
private fun decryptEntity(dir: IDirectory): IDirectory {
return CommonDirectory(decryptMeta(dir.metaInfo), dir.elementsCount)
}
private fun encryptMeta(meta: IMetaInfo): CommonMetaInfo {
return CommonMetaInfo(
size = meta.size,
isDeleted = meta.isDeleted,
isHidden = meta.isHidden,
lastModified = meta.lastModified,
path = encryptPath(meta.path)
)
}
private fun decryptMeta(meta: IMetaInfo): CommonMetaInfo {
return CommonMetaInfo(
size = meta.size,
isDeleted = meta.isDeleted,
isHidden = meta.isHidden,
lastModified = meta.lastModified,
path = decryptPath(meta.path)
)
}
private fun encryptPath(pathStr: String): String {
val path = Path(pathStr)
val segments = mutableListOf<String>()
for (segment in path)
segments.add(encryptor.encryptString(segment.pathString))
val res = Path("/",*(segments.toTypedArray()))
return res.pathString
}
private fun decryptPath(pathStr: String): String {
val path = Path(pathStr)
val segments = mutableListOf<String>()
for (segment in path)
segments.add(encryptor.decryptString(segment.pathString))
val res = Path("/",*(segments.toTypedArray()))
return res.pathString
}
override suspend fun getAllFiles(): List<IFile> {
return source.getAllFiles().map(::decryptEntity)
}
override suspend fun getFiles(path: String): List<IFile> {
return source.getFiles(encryptPath(path)).map(::decryptEntity)
}
override fun getFilesFlow(path: String): Flow<DataPackage<List<IFile>>> {
val flow = source.getFilesFlow(encryptPath(path)).map {
DataPackage(
data = it.data.map(::decryptEntity),
isLoading = it.isLoading,
isError = it.isError
)
}
return flow
}
override suspend fun getAllDirs(): List<IDirectory> {
return source.getAllDirs().map(::decryptEntity)
}
override suspend fun getDirs(path: String): List<IDirectory> {
return source.getDirs(encryptPath(path)).map(::decryptEntity)
}
override fun getDirsFlow(path: String): Flow<DataPackage<List<IDirectory>>> {
val flow = source.getDirsFlow(encryptPath(path)).map {
DataPackage(
data = it.data.map(::decryptEntity),
isLoading = it.isLoading,
isError = it.isError
)
}
return flow
}
override suspend fun getFileInfo(path: String): IFile {
val file = source.getFileInfo(encryptPath(path))
val meta = decryptMeta(file.metaInfo)
return CommonFile(meta)
}
override suspend fun getDirInfo(path: String): IDirectory {
val dir = source.getDirInfo(encryptPath(path))
val meta = decryptMeta(dir.metaInfo)
return CommonDirectory(meta, dir.elementsCount)
}
override suspend fun setHidden(path: String, hidden: Boolean) {
source.setHidden(encryptPath(path), hidden)
}
override suspend fun touchFile(path: String) {
source.touchFile(encryptPath(path))
}
override suspend fun touchDir(path: String) {
source.touchDir(encryptPath(path))
}
override suspend fun delete(path: String) {
source.delete(encryptPath(path))
}
override suspend fun openWrite(path: String): OutputStream {
val stream = source.openWrite(encryptPath(path))
return encryptor.encryptStream(stream)
}
override suspend fun openRead(path: String): InputStream {
val stream = source.openRead(encryptPath(path))
return encryptor.decryptStream(stream)
}
override suspend fun moveToTrash(path: String) {
source.moveToTrash(encryptPath(path))
}
override fun dispose() {
job.cancel()
encryptor.dispose()
}
}

View File

@@ -1,4 +1,4 @@
package com.github.nullptroma.wallenc.data.vaults.local
package com.github.nullptroma.wallenc.data.storages.local
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.github.nullptroma.wallenc.domain.common.impl.CommonStorageMetaInfo
@@ -24,14 +24,8 @@ class LocalStorage(
override val numberOfFiles: StateFlow<Int?>
get() = accessor.numberOfFiles
private val _metaInfo = MutableStateFlow(
CommonStorageMetaInfo(
encInfo = StorageEncryptionInfo(
isEncrypted = false,
encryptedTestData = null
),
name = null
)
private val _metaInfo = MutableStateFlow<IStorageMetaInfo>(
CommonStorageMetaInfo()
)
override val metaInfo: StateFlow<IStorageMetaInfo>
get() = _metaInfo
@@ -40,49 +34,60 @@ class LocalStorage(
get() = accessor.isAvailable
private val _accessor = LocalStorageAccessor(absolutePath, ioDispatcher)
override val accessor: IStorageAccessor = _accessor
private val encInfoFileName: String = "$uuid$ENC_INFO_FILE_POSTFIX"
override val isVirtualStorage: Boolean = false
private val metaInfoFileName: String = "$uuid$ENC_INFO_FILE_POSTFIX"
suspend fun init() {
_accessor.init()
readEncInfo()
readMetaInfo()
}
private suspend fun readEncInfo() = withContext(ioDispatcher) {
var enc: StorageEncryptionInfo? = null
private suspend fun readMetaInfo() = withContext(ioDispatcher) {
var meta: CommonStorageMetaInfo
var reader: InputStream? = null
try {
reader = _accessor.openReadSystemFile(encInfoFileName)
enc = jackson.readValue(reader, StorageEncryptionInfo::class.java)
reader = _accessor.openReadSystemFile(metaInfoFileName)
meta = jackson.readValue(reader, CommonStorageMetaInfo::class.java)
}
catch(e: Exception) {
// чтение не удалось, значит нужно записать файл
enc = StorageEncryptionInfo(
isEncrypted = false,
encryptedTestData = null
)
setEncInfo(enc)
meta = CommonStorageMetaInfo()
updateMetaInfo(meta)
}
finally {
reader?.close()
}
_metaInfo.value = _metaInfo.value.copy(encInfo = enc)
_metaInfo.value = meta
}
suspend fun setEncInfo(enc: StorageEncryptionInfo) = withContext(ioDispatcher) {
val writer = _accessor.openWriteSystemFile(encInfoFileName)
private suspend fun updateMetaInfo(meta: IStorageMetaInfo) = withContext(ioDispatcher) {
val writer = _accessor.openWriteSystemFile(metaInfoFileName)
try {
jackson.writeValue(writer, enc)
jackson.writeValue(writer, meta)
}
catch (e: Exception) {
TODO("Это никогда не должно произойти")
throw e
}
writer.close()
_metaInfo.value = _metaInfo.value.copy(encInfo = enc)
finally {
writer.close()
}
_metaInfo.value = meta
}
override suspend fun rename(newName: String) {
TODO("Not yet implemented")
override suspend fun rename(newName: String) = withContext(ioDispatcher) {
val curMeta = metaInfo.value
updateMetaInfo(CommonStorageMetaInfo(
encInfo = curMeta.encInfo,
name = newName
))
}
override suspend fun setEncInfo(encInfo: StorageEncryptionInfo) = withContext(ioDispatcher) {
val curMeta = metaInfo.value
updateMetaInfo(CommonStorageMetaInfo(
encInfo = encInfo,
name = curMeta.name
))
}
companion object {

View File

@@ -1,4 +1,4 @@
package com.github.nullptroma.wallenc.data.vaults.local
package com.github.nullptroma.wallenc.data.storages.local
import com.fasterxml.jackson.core.JacksonException
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
@@ -57,7 +57,7 @@ class LocalStorageAccessor(
private val _dirsUpdates = MutableSharedFlow<DataPage<IDirectory>>()
override val dirsUpdates: SharedFlow<DataPage<IDirectory>> = _dirsUpdates
suspend fun init() {
suspend fun init() = withContext(ioDispatcher) {
// запускам сканирование хранилища
scanSizeAndNumOfFiles()
}
@@ -251,11 +251,11 @@ class LocalStorageAccessor(
* Считает файлы и их размер. Не бросает исключения, если файлы недоступны
* @throws none Если возникла ошибка, оставляет размер и количества файлов равными null
*/
private suspend fun scanSizeAndNumOfFiles() {
private suspend fun scanSizeAndNumOfFiles() = withContext(ioDispatcher) {
if (!checkAvailable()) {
_size.value = null
_numberOfFiles.value = null
return
return@withContext
}
var size = 0L
@@ -280,8 +280,8 @@ class LocalStorageAccessor(
return@withContext listOf()
val list = mutableListOf<IFile>()
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, CommonFile ->
list.add(CommonFile)
scanStorage(baseStoragePath = "/", maxDepth = -1, fileCallback = { _, commonFile ->
list.add(commonFile)
})
return@withContext list
}

View File

@@ -1,6 +1,7 @@
package com.github.nullptroma.wallenc.data.vaults.local
package com.github.nullptroma.wallenc.data.vaults
import android.content.Context
import com.github.nullptroma.wallenc.data.storages.local.LocalStorage
import com.github.nullptroma.wallenc.domain.datatypes.StorageEncryptionInfo
import com.github.nullptroma.wallenc.domain.enums.VaultType
import com.github.nullptroma.wallenc.domain.interfaces.IStorage

View File

@@ -1,7 +1,6 @@
package com.github.nullptroma.wallenc.data.vaults
import android.content.Context
import com.github.nullptroma.wallenc.data.vaults.local.LocalVault
import com.github.nullptroma.wallenc.domain.interfaces.IStorage
import com.github.nullptroma.wallenc.domain.interfaces.IVault
import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager