feat(sync): перевёл группы синхронизации на Room и добавил контроль совместимости

This commit is contained in:
2026-05-17 18:03:14 +03:00
parent 15f13577c8
commit e562e4d9e9
28 changed files with 518 additions and 159 deletions

View File

@@ -30,6 +30,15 @@ class UnlockManager(
get() = _openedStorages
private val mutex = Mutex()
override fun getOpenedStorageKey(uuid: UUID): EncryptKey? {
val opened = _openedStorages.value
val direct = opened[uuid]
if (direct != null) {
return direct.getKey()
}
return null
}
init {
CoroutineScope(ioDispatcher).launch {
vaultsManager.allStorages.collect {

View File

@@ -53,6 +53,8 @@ class EncryptedStorage private constructor(
throw Exception("Incorrect key") // TODO
}
fun getKey(): EncryptKey = EncryptKey(key.bytes)
override fun dispose() {
_accessor.dispose()
job.cancel()

View File

@@ -263,14 +263,7 @@ class EncryptedStorageAccessor(
appendSyncEntry(path = path, operation = StorageSyncOperation.DELETE)
}
override suspend fun openWrite(path: String): OutputStream {
val stream = source.openWrite(encryptPath(path))
return dataEncryptor.encryptStream(stream).onClosed {
scope.launch {
appendSyncEntry(path = path, operation = StorageSyncOperation.UPSERT)
}
}
}
override suspend fun openWrite(path: String): OutputStream = openWriteInternal(path, recordJournal = true)
override suspend fun openRead(path: String): InputStream {
val stream = source.openRead(encryptPath(path))
@@ -290,7 +283,7 @@ class EncryptedStorageAccessor(
val path = Path(systemHiddenDirName, name).pathString
return@run try {
openRead(path)
} catch (_: FileNotFoundException) {
} catch (_: Exception) {
// Как у Yandex/Local: системного файла ещё нет — создаём пустой и читаем снова.
openWriteSystemFile(name).use { }
openRead(path)
@@ -300,7 +293,7 @@ class EncryptedStorageAccessor(
override suspend fun openWriteSystemFile(name: String): OutputStream = scope.run {
val path = Path(systemHiddenDirName, name).pathString
systemHiddenFilesIsActual = false
return@run openWrite(path).onClosing {
return@run openWriteInternal(path, recordJournal = false).onClosing {
systemHiddenFilesIsActual = false
}
}
@@ -393,6 +386,9 @@ class EncryptedStorageAccessor(
private suspend fun appendSyncEntry(path: String, operation: StorageSyncOperation) {
val cleanedPath = if (path.startsWith("/")) path else "/$path"
if (cleanedPath.startsWith("/$systemHiddenDirName/")) {
return
}
val entries = readSyncJournal()
val nextSequence = (entries.maxOfOrNull { it.revision.sequence } ?: 0L) + 1L
appendSyncJournal(
@@ -410,6 +406,19 @@ class EncryptedStorageAccessor(
)
}
private suspend fun openWriteInternal(path: String, recordJournal: Boolean): OutputStream {
val stream = source.openWrite(encryptPath(path))
val encrypted = dataEncryptor.encryptStream(stream)
if (!recordJournal) {
return encrypted
}
return encrypted.onClosed {
scope.launch {
appendSyncEntry(path = path, operation = StorageSyncOperation.UPSERT)
}
}
}
private fun Iterable<IFile>.filterSystemHiddenFiles(): List<IFile> {
return this.filter { file ->
!file.metaInfo.path.contains(