14 KiB
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. Слои и границы
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:
DISCONNECTEDCONNECTINGHANDSHAKINGAUTHENTICATEDBOOTSTRAPPINGREADYDEVICE_VERIFICATION_REQUIRED
Переход в READY происходит только когда одновременно выполнено:
- аккаунт инициализирован,
- протокол аутентифицирован,
- sync завершён,
- own-profile резолвнут (или истёк fallback timeout).
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
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 Отправка
- UI (
ChatViewModel) вызывает отправку черезMessageRepository.sendMessage(...). - Репозиторий делает optimistic insert в
messages(WAITING). - Формируется
PacketMessage. - Отправка идёт в
ProtocolManager.send(...). - Если состояние не
READY, пакет ставится вReadyPacketGate. - После
READYочередь сбрасывается вProtocol.sendPacket(...).
7.2 Подтверждение доставки
- Сервер присылает
PacketDelivery (0x08). ProtocolManagerмаршрутизирует вMessageRepository.handleDelivery(...).- Репозиторий обновляет статус в Room.
- UI получает апдейт через
Flow/события.
7.3 Входящие
PacketMessage (0x06)приходит вProtocol.ProtocolManagerdispatch →MessageRepository.handleIncomingMessage(...).- Сообщение сохраняется в Room, обновляется
dialogsи индексы поиска. - UI реактивно перерисовывается.
8. Sync-пайплайн
Используется пакет PacketSync (0x19) и режимы:
BATCH_START- поток синк-пакетов (
MESSAGE/READ/DELIVERY/...) BATCH_ENDNOT_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.
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:
- запрашивает update server через
PacketRequestUpdate (0x0A); - ходит на SDU HTTP endpoint;
- скачивает APK через
DownloadManager; - ведёт 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;
- отдельные диагностические логи для звонков (
CallManagerbreadcrumbs).
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.ktapp/src/main/java/com/rosetta/messenger/RosettaApplication.ktapp/src/main/java/com/rosetta/messenger/network/Protocol.ktapp/src/main/java/com/rosetta/messenger/network/ProtocolManager.ktapp/src/main/java/com/rosetta/messenger/network/ProtocolConnectionModels.ktapp/src/main/java/com/rosetta/messenger/network/ProtocolConnectionSupervisor.ktapp/src/main/java/com/rosetta/messenger/network/ReadyPacketGate.ktapp/src/main/java/com/rosetta/messenger/network/CallManager.ktapp/src/main/java/com/rosetta/messenger/network/TransportManager.ktapp/src/main/java/com/rosetta/messenger/push/RosettaFirebaseMessagingService.ktapp/src/main/java/com/rosetta/messenger/update/UpdateManager.ktapp/src/main/java/com/rosetta/messenger/data/MessageRepository.ktapp/src/main/java/com/rosetta/messenger/database/RosettaDatabase.ktapp/src/main/java/com/rosetta/messenger/crypto/CryptoManager.ktapp/src/main/java/com/rosetta/messenger/crypto/MessageCrypto.kt