diff --git a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/domain/UseCasesModule.kt b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/domain/UseCasesModule.kt index 5185b40..f339c6d 100644 --- a/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/domain/UseCasesModule.kt +++ b/app/src/main/java/com/github/nullptroma/wallenc/app/di/modules/domain/UseCasesModule.kt @@ -5,6 +5,7 @@ import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager import com.github.nullptroma.wallenc.domain.usecases.GetOpenedStoragesUseCase import com.github.nullptroma.wallenc.domain.usecases.ManageLocalVaultUseCase import com.github.nullptroma.wallenc.domain.usecases.ManageStoragesEncryptionUseCase +import com.github.nullptroma.wallenc.domain.usecases.RemoveStorageUseCase import com.github.nullptroma.wallenc.domain.usecases.RenameStorageUseCase import com.github.nullptroma.wallenc.domain.usecases.StorageFileManagementUseCase import dagger.Module @@ -45,4 +46,13 @@ class UseCasesModule { fun provideManageStoragesEncryptionUseCase(unlockManager: IUnlockManager): ManageStoragesEncryptionUseCase { return ManageStoragesEncryptionUseCase(unlockManager) } + + @Provides + @Singleton + fun provideRemoveStorageUseCase( + vaultsManager: IVaultsManager, + unlockManager: IUnlockManager, + ): RemoveStorageUseCase { + return RemoveStorageUseCase(vaultsManager, unlockManager) + } } \ No newline at end of file diff --git a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/LocalVault.kt b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/LocalVault.kt index 73096a4..55dda56 100644 --- a/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/LocalVault.kt +++ b/data/src/main/java/com/github/nullptroma/wallenc/data/vaults/LocalVault.kt @@ -89,7 +89,7 @@ class LocalVault(private val ioDispatcher: CoroutineDispatcher, context: Context throw Exception("Not available") val curStorages = _storages.value.toMutableList() - val index = curStorages.indexOf(storage) + val index = curStorages.indexOfFirst { it.uuid == storage.uuid } if(index != -1) { val localStorage = curStorages[index] curStorages.removeAt(index) diff --git a/domain/src/main/java/com/github/nullptroma/wallenc/domain/enums/StorageDeletionPolicy.kt b/domain/src/main/java/com/github/nullptroma/wallenc/domain/enums/StorageDeletionPolicy.kt new file mode 100644 index 0000000..098fc4e --- /dev/null +++ b/domain/src/main/java/com/github/nullptroma/wallenc/domain/enums/StorageDeletionPolicy.kt @@ -0,0 +1,15 @@ +package com.github.nullptroma.wallenc.domain.enums + +/** + * Политика удаления/закрытия хранилища. + * + * [CLOSE_ENCRYPTED_OVERLAYS_ONLY] — только закрыть расшифрованные представления (overlay), + * физические данные не трогаем. + * + * [REMOVE_PHYSICAL] — удалить физическое хранилище у провайдера (сейчас local vault), + * предварительно закрыв все overlay. + */ +enum class StorageDeletionPolicy { + CLOSE_ENCRYPTED_OVERLAYS_ONLY, + REMOVE_PHYSICAL, +} diff --git a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/GetOpenedStoragesUseCase.kt b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/GetOpenedStoragesUseCase.kt index 661ca28..805b822 100644 --- a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/GetOpenedStoragesUseCase.kt +++ b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/GetOpenedStoragesUseCase.kt @@ -3,7 +3,6 @@ package com.github.nullptroma.wallenc.domain.usecases import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.map import java.util.UUID class GetOpenedStoragesUseCase(private val unlockManager: IUnlockManager) { diff --git a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/ManageLocalVaultUseCase.kt b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/ManageLocalVaultUseCase.kt index f98c250..9fa9b65 100644 --- a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/ManageLocalVaultUseCase.kt +++ b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/ManageLocalVaultUseCase.kt @@ -1,6 +1,5 @@ package com.github.nullptroma.wallenc.domain.usecases -import com.github.nullptroma.wallenc.domain.interfaces.IStorage import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager import kotlinx.coroutines.flow.StateFlow @@ -12,10 +11,4 @@ class ManageLocalVaultUseCase(private val manager: IVaultsManager) { suspend fun createStorage() { manager.localVault.createStorage() } - - suspend fun remove(storage: IStorageInfo) { - when(storage) { - is IStorage -> manager.localVault.remove(storage) - } - } } \ No newline at end of file diff --git a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/RemoveStorageUseCase.kt b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/RemoveStorageUseCase.kt index 54b375d..0d3090a 100644 --- a/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/RemoveStorageUseCase.kt +++ b/domain/src/main/java/com/github/nullptroma/wallenc/domain/usecases/RemoveStorageUseCase.kt @@ -1,12 +1,45 @@ package com.github.nullptroma.wallenc.domain.usecases +import com.github.nullptroma.wallenc.domain.enums.StorageDeletionPolicy import com.github.nullptroma.wallenc.domain.interfaces.IStorage import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo +import com.github.nullptroma.wallenc.domain.interfaces.IUnlockManager +import com.github.nullptroma.wallenc.domain.interfaces.IVaultsManager +import java.util.UUID -class RemoveStorageUseCase { - suspend fun rename(storage: IStorageInfo, newName: String) { - when (storage) { - is IStorage -> storage.rename(newName) +class RemoveStorageUseCase( + private val vaultsManager: IVaultsManager, + private val unlockManager: IUnlockManager, +) { + + suspend fun remove(storage: IStorageInfo, policy: StorageDeletionPolicy) { + if (storage !is IStorage) return + + when (policy) { + StorageDeletionPolicy.CLOSE_ENCRYPTED_OVERLAYS_ONLY -> { + unlockManager.close(storage) + } + StorageDeletionPolicy.REMOVE_PHYSICAL -> { + val physical = findPhysicalRootStorage(storage) ?: return + unlockManager.close(physical.uuid) + vaultsManager.localVault.remove(physical) + } } } -} \ No newline at end of file + + /** + * Поднимается по цепочке overlay (sourceUuid -> decrypted view), пока не дойдёт + * до корневого физического storage из [IVaultsManager.localVault]. + */ + private fun findPhysicalRootStorage(storage: IStorage): IStorage? { + val locals = vaultsManager.localVault.storages.value ?: return null + val opened = unlockManager.openedStorages.value + + var id: UUID = storage.uuid + while (true) { + val parent = opened.entries.firstOrNull { it.value.uuid == id }?.key ?: break + id = parent + } + return locals.firstOrNull { it.uuid == id } + } +} diff --git a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt index 0ec2fc6..619577e 100644 --- a/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt +++ b/presentation/src/main/java/com/github/nullptroma/wallenc/presentation/screens/main/screens/local/vault/LocalVaultViewModel.kt @@ -7,9 +7,11 @@ import com.github.nullptroma.wallenc.domain.interfaces.IDirectory import com.github.nullptroma.wallenc.domain.interfaces.IFile import com.github.nullptroma.wallenc.domain.interfaces.ILogger import com.github.nullptroma.wallenc.domain.interfaces.IStorageInfo +import com.github.nullptroma.wallenc.domain.enums.StorageDeletionPolicy import com.github.nullptroma.wallenc.domain.usecases.GetOpenedStoragesUseCase import com.github.nullptroma.wallenc.domain.usecases.ManageLocalVaultUseCase import com.github.nullptroma.wallenc.domain.usecases.ManageStoragesEncryptionUseCase +import com.github.nullptroma.wallenc.domain.usecases.RemoveStorageUseCase import com.github.nullptroma.wallenc.domain.usecases.RenameStorageUseCase import com.github.nullptroma.wallenc.domain.usecases.StorageFileManagementUseCase import com.github.nullptroma.wallenc.presentation.ViewModelBase @@ -24,6 +26,7 @@ import kotlin.system.measureTimeMillis @HiltViewModel class LocalVaultViewModel @Inject constructor( private val manageLocalVaultUseCase: ManageLocalVaultUseCase, + private val removeStorageUseCase: RemoveStorageUseCase, private val getOpenedStoragesUseCase: GetOpenedStoragesUseCase, private val storageFileManagementUseCase: StorageFileManagementUseCase, private val manageStoragesEncryptionUseCase: ManageStoragesEncryptionUseCase, @@ -136,9 +139,12 @@ class LocalVaultViewModel @Inject constructor( } } - fun remove(storage: IStorageInfo) { + fun remove( + storage: IStorageInfo, + policy: StorageDeletionPolicy = StorageDeletionPolicy.REMOVE_PHYSICAL, + ) { viewModelScope.launch { - manageLocalVaultUseCase.remove(storage) + removeStorageUseCase.remove(storage, policy) } } } \ No newline at end of file