# Rosetta Android — Architecture > Документ описывает **текущую** архитектуру `rosetta-android` (ветка `dev`) по коду, без идеализаций. ## 1. Архитектурный стиль Приложение построено как **layered + feature-oriented** архитектура: - UI на Jetpack Compose (`MainActivity` + `ui/*`). - Бизнес-оркестрация в singleton-сервисах (`ProtocolManager`, `CallManager`, `TransportManager`, `UpdateManager`). - Data слой через репозитории (`MessageRepository`, `GroupRepository`, `AvatarRepository`, `AccountManager`). - Persistence через Room (`RosettaDatabase`). - Crypto изолирован в `crypto/*`. DI-контейнера (Hilt/Koin) сейчас нет: зависимости поднимаются через `object`, `getInstance(...)`, singleton-инициализацию. --- ## 2. Слои и границы ```mermaid flowchart TB subgraph UI["UI Layer (Compose + ViewModel)"] A1["MainActivity"] A2["ui/chats/*"] A3["ui/auth/*"] A4["ui/settings/*"] end subgraph SVC["Service Layer (Singleton orchestrators)"] B1["ProtocolManager"] B2["CallManager"] B3["TransportManager"] B4["UpdateManager"] B5["RosettaFirebaseMessagingService"] end subgraph DATA["Data Layer"] C1["MessageRepository"] C2["GroupRepository"] C3["AvatarRepository"] C4["AccountManager / PreferencesManager"] C5["DraftManager / ForwardManager"] end subgraph DB["Persistence Layer"] D1["Room: RosettaDatabase"] D2["DAO: message/dialog/group/etc"] end subgraph NET["Network Layer"] E1["Protocol (WebSocket)"] E2["Packet* codec"] E3["OkHttp HTTP (transport/update)"] E4["WebRTC"] end subgraph CRYPTO["Crypto Layer"] F1["CryptoManager"] F2["MessageCrypto"] F3["XChaCha20E2EE (calls)"] end UI --> SVC UI --> DATA SVC --> DATA SVC --> NET DATA --> DB DATA --> CRYPTO SVC --> CRYPTO ``` --- ## 3. Главные модули и ответственность ### 3.1 `MainActivity` (composition root) `MainActivity` — главный orchestration entrypoint приложения: - поднимает `ProtocolManager.initialize(...)`, `CallManager.initialize(...)`; - управляет auth-гейтингом, онбордингом и основным nav-stack (`Screen`); - привязывает текущий аккаунт к runtime-сервисам; - триггерит fast reconnect на `onResume`; - следит за разрешениями (уведомления, fullscreen intent и т.д.). ### 3.2 `RosettaApplication` На старте процесса инициализирует глобальные подсистемы: - crash reporting, - draft manager, - transport manager, - update manager. ### 3.3 Репозитории #### `MessageRepository` Ключевой data-центр для чатов: - инициализация аккаунт-контекста (`publicKey/privateKey`); - отправка сообщений (optimistic insert + сетевой send); - обработка входящих `PacketMessage`/`PacketDelivery`/`PacketRead`; - обновление `dialogs`, `messages`, `message_search_index`; - синк timestamp (`accounts_sync_times`); - шина событий для UI (`newMessageEvents`, `deliveryStatusEvents`). #### `GroupRepository` - хранение и операции по группам, - интеграция с `PacketGroup*`. #### `AvatarRepository` - кэш/история аватаров (Room + file storage), - реактивная выдача аватаров через `Flow`. #### `AccountManager` - хранение аккаунтов в DataStore, - last logged public/private hash в SharedPreferences для быстрых синхронных чтений. --- ## 4. Сетевой стек ## 4.1 `Protocol` (низкий уровень) `Protocol` отвечает за: - WebSocket lifecycle (`DISCONNECTED/CONNECTING/CONNECTED/HANDSHAKING/DEVICE_VERIFICATION_REQUIRED/AUTHENTICATED`), - heartbeat, - reconnect/backoff, - packet encode/decode, - `waitPacket/unwaitPacket` обработчики, - queue pre-handshake пакетов. Ключевые механизмы устойчивости: - `lifecycleMutex` для serialized lifecycle операций, - `connectionGeneration` для игнора stale callbacks старых сокетов, - guard `isConnecting` от параллельного `connect()`. ## 4.2 `ProtocolManager` (верхний уровень) `ProtocolManager` — orchestration-слой над `Protocol`: - единая точка для UI/Data слоёв (`send`, `authenticate`, `reconnect`, `waitPacket` и т.д.); - bootstrap после auth (sync, own-profile resolve, push subscribe); - маршрутизация входящих packet-ов в репозитории/подсистемы; - call signaling bridge для `CallManager`; - управление typed caches (`SearchUser`, user info cache). Новый runtime-дизайн connection orchestration: - `ProtocolConnectionModels.kt` — `ConnectionLifecycleState`, `ConnectionEvent`, bootstrap context; - `ProtocolConnectionSupervisor.kt` — actor/event-loop для serialized событий; - `ReadyPacketGate.kt` — очередь пакетов до состояния `READY` (TTL + max size). --- ## 5. Lifecycle состояния соединения (верхний уровень) `ProtocolManager.connectionLifecycleState`: - `DISCONNECTED` - `CONNECTING` - `HANDSHAKING` - `AUTHENTICATED` - `BOOTSTRAPPING` - `READY` - `DEVICE_VERIFICATION_REQUIRED` Переход в `READY` происходит только когда одновременно выполнено: - аккаунт инициализирован, - протокол аутентифицирован, - sync завершён, - own-profile резолвнут (или истёк fallback timeout). ```mermaid stateDiagram-v2 [*] --> DISCONNECTED DISCONNECTED --> CONNECTING CONNECTING --> HANDSHAKING HANDSHAKING --> DEVICE_VERIFICATION_REQUIRED HANDSHAKING --> AUTHENTICATED AUTHENTICATED --> BOOTSTRAPPING BOOTSTRAPPING --> READY READY --> DISCONNECTED DEVICE_VERIFICATION_REQUIRED --> CONNECTING ``` --- ## 6. Поток auth / session bootstrap ```mermaid sequenceDiagram participant UI as AuthFlow/MainActivity participant PM as ProtocolManager participant P as Protocol participant MR as MessageRepository UI->>PM: initializeAccount(public, private) UI->>PM: connect() UI->>PM: authenticate(public, privateHash) PM->>P: connect + startHandshake P-->>PM: AUTHENTICATED PM->>PM: onAuthenticated() PM->>PM: subscribePushTokenIfAvailable() PM->>PM: requestSynchronize() PM->>MR: initialize(...) PM-->>PM: SyncCompleted + OwnProfileResolved PM-->>UI: connectionLifecycleState = READY ``` Критично: отправка пользовательских пакетов до `READY` не теряется, а попадает в `ReadyPacketGate`. --- ## 7. Поток сообщений (send/receive/delivery) ## 7.1 Отправка 1. UI (`ChatViewModel`) вызывает отправку через `MessageRepository.sendMessage(...)`. 2. Репозиторий делает optimistic insert в `messages` (`WAITING`). 3. Формируется `PacketMessage`. 4. Отправка идёт в `ProtocolManager.send(...)`. 5. Если состояние не `READY`, пакет ставится в `ReadyPacketGate`. 6. После `READY` очередь сбрасывается в `Protocol.sendPacket(...)`. ## 7.2 Подтверждение доставки 1. Сервер присылает `PacketDelivery (0x08)`. 2. `ProtocolManager` маршрутизирует в `MessageRepository.handleDelivery(...)`. 3. Репозиторий обновляет статус в Room. 4. UI получает апдейт через `Flow`/события. ## 7.3 Входящие 1. `PacketMessage (0x06)` приходит в `Protocol`. 2. `ProtocolManager` dispatch → `MessageRepository.handleIncomingMessage(...)`. 3. Сообщение сохраняется в Room, обновляется `dialogs` и индексы поиска. 4. UI реактивно перерисовывается. --- ## 8. Sync-пайплайн Используется пакет `PacketSync (0x19)` и режимы: - `BATCH_START` - поток синк-пакетов (`MESSAGE/READ/DELIVERY/...`) - `BATCH_END` - `NOT_NEEDED` Особенности: - есть последовательная очередь inbound задач для сохранения порядка обработки; - after-sync hooks: retry waiting messages, request missing user info; - sync timestamp хранится в `accounts_sync_times`. --- ## 9. Calls (WebRTC + signaling) `CallManager` использует: - signaling пакеты: `PacketSignalPeer (0x1A)`, `PacketWebRTC (0x1B)`; - ICE: `PacketIceServers (0x1C)`; - WebRTC stack (`PeerConnectionFactory`, `PeerConnection`, audio track); - E2EE голоса через `XChaCha20E2EE` обвязки sender/receiver. Основные фазы звонка: - `IDLE` → `INCOMING`/`OUTGOING` → `CONNECTING` → `ACTIVE` → `IDLE`. ```mermaid stateDiagram-v2 [*] --> IDLE IDLE --> OUTGOING IDLE --> INCOMING OUTGOING --> CONNECTING INCOMING --> CONNECTING CONNECTING --> ACTIVE ACTIVE --> IDLE OUTGOING --> IDLE INCOMING --> IDLE ``` --- ## 10. Transport (вложения) `TransportManager`: - получает transport server через `PacketRequestTransport (0x0F)` (desktop parity); - upload/download через OkHttp; - resumable download (HTTP Range); - трекает состояния прогресса через `StateFlow` (`uploading`, `downloading`); - поддерживает cancel/pause/resume через `FileDownloadManager`. --- ## 11. Push Notifications `RosettaFirebaseMessagingService`: - обрабатывает `onNewToken` и подписку токена через `ProtocolManager`; - dedup пушей; - маршрутизация типов (`personal_message`, `group_message`, `call`, `read`); - очистка уведомлений по read events; - wake-up reconnect при silent push. --- ## 12. Обновления (SDU) `UpdateManager`: 1. запрашивает update server через `PacketRequestUpdate (0x0A)`; 2. ходит на SDU HTTP endpoint; 3. скачивает APK через `DownloadManager`; 4. ведёт update state machine (`Idle/Checking/UpdateAvailable/Downloading/ReadyToInstall/Error`). --- ## 13. Persistence (Room) `RosettaDatabase` (version `17`) включает: - `messages` — сообщения, - `dialogs` — диалоги + денормализованные поля для быстрых списков, - `message_search_index` — локальный индекс поиска, - `groups` — группы, - `pinned_messages` — закрепы, - `avatar_cache` — аватары, - `blacklist` — blacklist, - `accounts_sync_times` — sync cursor, - `encrypted_accounts` — аккаунты (legacy Room account storage). Есть длинная цепочка миграций (4→17) с оптимизациями под производительность и денормализацию. --- ## 14. Crypto - `CryptoManager`: - seed phrase / keypair, - PBKDF2-derived key caching, - encrypt/decrypt для локального хранения. - `MessageCrypto`: - message-level XChaCha20-Poly1305, - ECDH/AES-обмен ключом для payload, - attachment decrypt logic. Crypto и network связаны через `MessageRepository`/`ProtocolManager`. --- ## 15. Наблюдаемость и диагностика - wire/protocol логи через `ProtocolManager.addLog(...)` + trace file; - debug logs доступны в UI; - отдельные диагностические логи для звонков (`CallManager` breadcrumbs). --- ## 16. Текущие архитектурные сильные стороны - Реактивная модель состояния (`StateFlow`) на большинстве критических путей. - Сильная декомпозиция packet протокола (`Packet*`). - Наличие ready-gate и serialized supervisor снижает race-condition в соединении. - Room + денормализация ускоряют списки чатов/поиск. --- ## 17. Текущие архитектурные риски - `MainActivity` остаётся очень крупным composition root. - `ProtocolManager` и `MessageRepository` всё ещё крупные “god objects”. - Отсутствие DI усложняет управляемость зависимостей/тестируемость. - Часть жизненного цикла связана через runtime singleton state, что повышает риск регрессий при эволюции. --- ## 18. Карта ключевых файлов - `app/src/main/java/com/rosetta/messenger/MainActivity.kt` - `app/src/main/java/com/rosetta/messenger/RosettaApplication.kt` - `app/src/main/java/com/rosetta/messenger/network/Protocol.kt` - `app/src/main/java/com/rosetta/messenger/network/ProtocolManager.kt` - `app/src/main/java/com/rosetta/messenger/network/ProtocolConnectionModels.kt` - `app/src/main/java/com/rosetta/messenger/network/ProtocolConnectionSupervisor.kt` - `app/src/main/java/com/rosetta/messenger/network/ReadyPacketGate.kt` - `app/src/main/java/com/rosetta/messenger/network/CallManager.kt` - `app/src/main/java/com/rosetta/messenger/network/TransportManager.kt` - `app/src/main/java/com/rosetta/messenger/push/RosettaFirebaseMessagingService.kt` - `app/src/main/java/com/rosetta/messenger/update/UpdateManager.kt` - `app/src/main/java/com/rosetta/messenger/data/MessageRepository.kt` - `app/src/main/java/com/rosetta/messenger/database/RosettaDatabase.kt` - `app/src/main/java/com/rosetta/messenger/crypto/CryptoManager.kt` - `app/src/main/java/com/rosetta/messenger/crypto/MessageCrypto.kt`