34 KiB
Domain Term Glossary -- SimpleX Chat (Android & Desktop, Kotlin Multiplatform)
This glossary is self-contained and covers the Android and Desktop (Kotlin/Compose Multiplatform) codebase only.
Table of Contents
- Protocols & Cryptography
- Core Data Types
- Commands & Events
- Connection & Identity
- Messaging Features
- Calling & Media
- Notifications & Background
- Application Architecture
- Configuration & Preferences
1. Protocols & Cryptography
SMP (SimpleX Messaging Protocol)
The core message-relay protocol. Clients send and receive messages through SMP relay servers without exposing sender/receiver identity correlation. The protocol uses unidirectional queues -- each contact pair maintains separate send and receive queues on potentially different servers.
See: common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt -- SMPErrorType, SMPProxyMode, SMPProxyFallback, SMPWebPortServers
XFTP (SimpleX File Transfer Protocol)
Protocol for transferring files through relay servers. Files are chunked, encrypted, and uploaded to XFTP relays. Recipients download chunks and reassemble locally. Supports inline transfer for small files.
See: common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt -- CC.ApiUploadStandaloneFile, CC.ApiDownloadStandaloneFile, CC.ApiStandaloneFileInfo
E2E Encryption (End-to-End Encryption)
All messages are encrypted end-to-end. The app never transmits plaintext to relay servers. Encryption keys are negotiated during connection establishment using X3DH-like key agreement and then maintained via the double-ratchet algorithm.
Double Ratchet
The core key-management algorithm. After initial key agreement, each message derives a new symmetric key, providing forward secrecy per message. Ratchet state can be re-synchronized via APISyncContactRatchet / APISyncGroupMemberRatchet commands.
See: SimpleXAPI.kt -- CC.APISyncContactRatchet(contactId, force), CC.APISyncGroupMemberRatchet(groupId, groupMemberId, force), CR.ContactRatchetSync, CR.GroupMemberRatchetSync
PQ (Post-Quantum)
Post-quantum key exchange support. Connections track PQ state via Connection.pqSupport, Connection.pqEncryption, Connection.pqSndEnabled, and Connection.pqRcvEnabled fields. When both peers support PQ, the key exchange incorporates a post-quantum KEM to resist future quantum attacks.
See: ChatModel.kt -- Connection.pqSupport, Connection.pqEncryption; SimpleXAPI.kt -- SHARED_PREFS_PQ_EXPERIMENTAL_ENABLED (legacy, no longer used)
SMP Proxy / Private Routing
Messages can be sent through an intermediate SMP proxy relay to hide the sender's IP from the destination relay. Controlled by SMPProxyMode (Always, Unknown, Unprotected, Never) and SMPProxyFallback (Allow, AllowProtected, Prohibit).
See: SimpleXAPI.kt -- AppPreferences.networkSMPProxyMode, AppPreferences.networkSMPProxyFallback
Transport Session Mode
Controls how TCP sessions to SMP relays are multiplexed. Options: User (one session per user profile), Session (single shared session), Server (one per server), Entity (one per queue/entity -- maximum metadata protection).
See: SimpleXAPI.kt -- AppPreferences.networkSessionMode, TransportSessionMode
2. Core Data Types
ChatItem
A single item in a conversation -- a sent or received message, call event, group event, connection event, feature change, or moderation action. Contains direction (CIDirection), metadata (CIMeta), content (CIContent), optional formatted text, mentions, quoted item, reactions, and file attachment.
See: ChatModel.kt:2720 -- data class ChatItem
ChatInfo
The top-level discriminated union representing a conversation. Variants:
ChatInfo.Direct-- wraps aContactChatInfo.Group-- wraps aGroupInfoChatInfo.Local-- wraps aNoteFolder(saved messages / notes to self)ChatInfo.ContactRequest-- wraps aUserContactRequestChatInfo.ContactConnection-- wraps aPendingContactConnectionChatInfo.InvalidJSON-- fallback for unrecognized data
See: ChatModel.kt:1391 -- sealed class ChatInfo
CIContent (Chat Item Content)
The content payload of a ChatItem. Over 30 variants including:
SndMsgContent/RcvMsgContent-- regular message withMsgContentSndCall/RcvCall-- call event with status and durationRcvIntegrityError-- message integrity violationRcvDecryptionError-- decryption failure with error type and countRcvGroupInvitation/SndGroupInvitation-- group inviteRcvGroupEventContent/SndGroupEventContent-- group lifecycle eventsRcvChatFeature/SndChatFeature-- per-chat feature toggle notificationsSndModerated/RcvModerated/RcvBlocked-- moderation eventsRcvDirectEventContent-- direct chat lifecycle events
See: ChatModel.kt:3554 -- sealed class CIContent
MsgContent
The wire-format message body. Variants: MCText, MCLink, MCImage, MCVideo, MCVoice, MCFile, MCReport, MCUnknown. Each carries text plus optional media/file metadata.
See: ChatModel.kt -- sealed class MsgContent
User
The local user profile. Fields: userId, userContactId, localDisplayName, profile (LocalProfile), fullPreferences (FullChatPreferences), activeUser, activeOrder, showNtfs, sendRcptsContacts, sendRcptsSmallGroups, viewPwdHash (for hidden profiles), uiThemes, remoteHostId (Long?), autoAcceptMemberContacts (Boolean).
See: ChatModel.kt:1208 -- data class User
Contact
A remote contact. Fields: contactId, localDisplayName, profile (LocalProfile), activeConn (Connection?), viaGroup, contactUsed, contactStatus, chatSettings, userPreferences, mergedPreferences, preparedContact, contactRequestId, contactGroupMemberId, chatTags, chatItemTTL.
See: ChatModel.kt:1711 -- data class Contact
GroupInfo
Metadata for a group conversation. Fields: groupId, localDisplayName, groupProfile (GroupProfile), businessChat (BusinessChatInfo?), fullGroupPreferences, membership (GroupMember -- the local user's membership), chatSettings, preparedGroup, membersRequireAttention, chatTags, chatItemTTL.
See: ChatModel.kt:2004 -- data class GroupInfo
GroupMember
A member of a group. Fields: groupMemberId, groupId, memberId, memberRole (GroupMemberRole), memberCategory (GroupMemberCategory), memberStatus (GroupMemberStatus), memberSettings (GroupMemberSettings), blockedByAdmin, invitedBy, localDisplayName, memberProfile, memberContactId, memberContactProfileId, activeConn (Connection?), supportChat (GroupSupportChat?).
See: ChatModel.kt:2177 -- data class GroupMember
GroupMemberRole
Enumeration of group roles, ordered for comparison: Observer < Author < Member < Moderator < Admin < Owner. Selectable roles for assignment: Observer, Member, Moderator, Admin, Owner.
See: ChatModel.kt:2369 -- enum class GroupMemberRole
Connection
An active or pending cryptographic connection to a peer. Fields: connId, agentConnId, peerChatVRange (VersionRange), connStatus (ConnStatus), connLevel, viaGroupLink, customUserProfileId, connectionCode (SecurityCode?), pqSupport, pqEncryption, pqSndEnabled, pqRcvEnabled, connectionStats, authErrCounter, quotaErrCounter.
See: ChatModel.kt:1882 -- data class Connection
Chat
A composite type holding chatInfo (ChatInfo), chatItems (list of ChatItem), and chatStats (ChatStats -- unread count, min unread item ID, etc.). Represents a full conversation for the chat list.
See: ChatModel.kt -- data class Chat
PendingContactConnection
Represents an in-progress connection that has not yet been established. Contains the connection link and state but no contact profile yet.
See: ChatModel.kt -- referenced in ChatInfo.ContactConnection
CryptoFile
A file reference that optionally carries CryptoFileArgs (key + nonce) for local encryption. CryptoFile.plain(path) creates an unencrypted reference.
See: ChatModel.kt -- data class CryptoFile
3. Commands & Events
The codebase uses short type names for the command/event protocol: CC (Chat Command), CR (Chat Response -- also carries asynchronous events), API (top-level response wrapper), and ChatError (error hierarchy). There is no separate "ChatEvent" class; asynchronous events from the core (new messages, connection changes, call signaling) are all CR subclasses received via the recvMsg loop.
CC (Chat Command)
The sealed class representing all commands the app can send to the Haskell core library. Over 140 command variants organized by domain:
User management: ShowActiveUser, CreateActiveUser, ListUsers, ApiSetActiveUser, ApiHideUser, ApiUnhideUser, ApiMuteUser, ApiUnmuteUser, ApiDeleteUser
Chat lifecycle: StartChat, CheckChatRunning, ApiStopChat, ApiSetAppFilePaths, ApiSetEncryptLocalFiles
Database: ApiExportArchive, ApiImportArchive, ApiDeleteStorage, ApiStorageEncryption, TestStorageEncryption
Messaging: ApiSendMessages, ApiUpdateChatItem, ApiDeleteChatItem, ApiDeleteMemberChatItem, ApiChatItemReaction, ApiForwardChatItems, ApiPlanForwardChatItems, ApiReportMessage
Groups: ApiNewGroup, ApiAddMember, ApiJoinGroup, ApiAcceptMember, ApiMembersRole, ApiBlockMembersForAll, ApiRemoveMembers, ApiLeaveGroup, ApiListMembers, ApiUpdateGroupProfile, APICreateGroupLink, APIDeleteGroupLink, APIGetGroupLink, ApiAddGroupShortLink
Connections: APIAddContact, APIConnect, APIConnectPlan, APIPrepareContact, APIPrepareGroup, APIConnectPreparedContact, APIConnectPreparedGroup, ApiConnectContactViaAddress
Contacts: ApiDeleteChat, ApiClearChat, ApiListContacts, ApiUpdateProfile, ApiSetContactPrefs, ApiSetContactAlias
Address: ApiCreateMyAddress, ApiDeleteMyAddress, ApiShowMyAddress, ApiAddMyAddressShortLink, ApiSetProfileAddress, ApiSetAddressSettings
Calls: ApiGetCallInvitations, ApiSendCallInvitation, ApiRejectCall, ApiSendCallOffer, ApiSendCallAnswer, ApiSendCallExtraInfo, ApiEndCall, ApiCallStatus
Server config: ApiGetServerOperators, ApiSetServerOperators, ApiGetUserServers, ApiSetUserServers, ApiValidateServers, APITestProtoServer
Network: APISetNetworkConfig, APIGetNetworkConfig, APISetNetworkInfo, ReconnectServer, ReconnectAllServers
Files: ReceiveFile, CancelFile, ApiUploadStandaloneFile, ApiDownloadStandaloneFile, ApiStandaloneFileInfo
Remote access: SetLocalDeviceName, ListRemoteHosts, StartRemoteHost, SwitchRemoteHost, StopRemoteHost, DeleteRemoteHost, StoreRemoteFile, GetRemoteFile, ConnectRemoteCtrl, FindKnownRemoteCtrl, ConfirmRemoteCtrl, VerifyRemoteCtrlSession, ListRemoteCtrls, StopRemoteCtrl, DeleteRemoteCtrl
Read status: ApiChatRead, ApiChatItemsRead, ApiChatUnread
Settings: APISetChatSettings, ApiSetMemberSettings, APISetChatItemTTL, APIGetChatItemTTL, APISetChatTTL, ApiSaveSettings, ApiGetSettings
Ratchet & verification: APISwitchContact, APISwitchGroupMember, APIAbortSwitchContact, APIAbortSwitchGroupMember, APISyncContactRatchet, APISyncGroupMemberRatchet, APIGetContactCode, APIGetGroupMemberCode, APIVerifyContact, APIVerifyGroupMember
Each command variant has a cmdString property that serializes it to the text protocol consumed by the Haskell FFI.
See: SimpleXAPI.kt:3529 -- sealed class CC
CR (Chat Response)
The sealed class representing all responses / events received from the Haskell core. Over 130 response types. Examples:
ActiveUser,UsersList-- user management resultsChatStarted,ChatRunning,ChatStopped-- lifecycleApiChats,ApiChat-- chat list dataNewChatItems,ChatItemUpdated,ChatItemsDeleted-- message eventsContactConnected,ContactConnecting,ContactSndReady-- connection lifecycleGroupCreated,ReceivedGroupInvitation,JoinedGroupMemberConnecting,MemberAccepted-- group eventsRcvFileStart,RcvFileComplete,SndFileComplete-- file transfer progressCallInvitation,CallOffer,CallAnswer,CallExtraInfo,CallEnded-- call signalingChatError-- error wrapper
See: SimpleXAPI.kt:6114 -- sealed class CR
API
The top-level response wrapper. Two variants:
API.Result(remoteHostId, res: CR)-- successful responseAPI.Error(remoteHostId, err: ChatError)-- error response
Properties: ok (Boolean -- true if CR.CmdOk), result (CR?), rhId (Long? -- remote host ID).
See: SimpleXAPI.kt:5975 -- sealed class API
ChatError
The error hierarchy returned from the Haskell core:
ChatErrorChat(errorType: ChatErrorType)-- application-level errors (NoActiveUser, UserUnknown, DifferentActiveUser, etc.)ChatErrorAgent(agentError: AgentErrorType)-- SMP agent errors (BROKER, SMP, PROXY, etc.)ChatErrorStore(storeError: StoreError)-- database/store errorsChatErrorDatabase(databaseError: DatabaseError)-- database migration/encryption errorsChatErrorRemoteHost(remoteHostError)-- remote host control errorsChatErrorRemoteCtrl(remoteCtrlError)-- remote controller errorsChatErrorInvalidJSON(json)-- parse failure
See: SimpleXAPI.kt:6974 -- sealed class ChatError
sendCmd / recvMsg
The core FFI bridge. sendCmd(rhId, cmd) serializes a CC command and sends it to the Haskell backend via chatSendCmd. recvMsg(ctrl) blocks on chatRecvMsg to receive the next API response/event. The receiver loop runs in ChatController.startReceiver() on Dispatchers.IO.
See: SimpleXAPI.kt -- ChatController.sendCmd(), ChatController.startReceiver()
4. Connection & Identity
SimpleX Address (User Address)
A long-lived contact address that others can use to send connection requests. Created via ApiCreateMyAddress, retrieved via ApiShowMyAddress, deleted via ApiDeleteMyAddress. Can optionally include a short link (ApiAddMyAddressShortLink). Stored as ChatModel.userAddress (UserContactLinkRec).
Contact Link / Connection Link
A one-time or reusable invitation link. The CreatedConnLink type wraps the link string. Contact links can be one-time (single use) or long-lived (user address). Created via APIAddContact (one-time) or ApiCreateMyAddress (reusable).
Group Link
A reusable invitation link for joining a group. Created via APICreateGroupLink(groupId, memberRole). The default role for new members joining via the link is configurable. Can also have a short link variant via ApiAddGroupShortLink.
Short Link
A compact form of a contact or group link. Created via ApiAddMyAddressShortLink (for user addresses) or ApiAddGroupShortLink (for groups). Short links resolve to the full connection link data including ContactShortLinkData or GroupShortLinkData.
Incognito Mode
When enabled (AppPreferences.incognito), the app generates a random profile name for new connections instead of using the user's real profile. Each connection gets a unique random identity. The customUserProfileId on a Connection tracks which incognito profile is used for that connection.
See: SimpleXAPI.kt -- AppPreferences.incognito; ChatModel.kt -- Connection.customUserProfileId
Hidden Profile
A user profile protected by a password (viewPwdHash). Hidden profiles do not appear in the profile list unless unlocked with the password. Created via ApiHideUser(userId, viewPwd), revealed via ApiUnhideUser(userId, viewPwd). When switching away from a hidden profile, its notifications are cancelled.
See: SimpleXAPI.kt -- CC.ApiHideUser, CC.ApiUnhideUser; ChatModel.kt -- User.viewPwdHash
Connection Verification (Security Code)
Each connection has an optional SecurityCode (Connection.connectionCode). Users can verify connections out-of-band by comparing security codes displayed via APIGetContactCode / APIGetGroupMemberCode and confirming via APIVerifyContact / APIVerifyGroupMember.
Connection Plan
Before connecting via a link, APIConnectPlan analyzes the link and returns a ConnectionPlan indicating whether the link leads to an existing contact, a new contact, a group join, etc. This prevents duplicate connections.
See: SimpleXAPI.kt -- CC.APIConnectPlan, CR.CRConnectionPlan
Prepared Contact / Prepared Group
An intermediate state in the connection flow. APIPrepareContact / APIPrepareGroup creates the local record and displays the contact/group preview before the user confirms the connection. The user can then change the active profile (APIChangePreparedContactUser / APIChangePreparedGroupUser) and finally confirm via APIConnectPreparedContact / APIConnectPreparedGroup.
5. Messaging Features
Delivery Receipt
Confirmation that a message was delivered to the recipient's device. Controlled per-user via sendRcptsContacts and sendRcptsSmallGroups on User. The global setting flow is triggered by ChatModel.setDeliveryReceipts. Individual overrides per-contact are managed via ApiSetUserContactReceipts / ApiSetUserGroupReceipts.
See: SimpleXAPI.kt -- CC.SetAllContactReceipts, CC.ApiSetUserContactReceipts, CC.ApiSetUserGroupReceipts; AppPreferences.privacyDeliveryReceiptsSet
Timed Message (Disappearing Message)
Messages with a time-to-live after which they are automatically deleted. Configured as a ChatFeature / GroupFeature with a TTL parameter in seconds. The customDisappearingMessageTime preference stores the last custom duration used. Per-chat TTL can be set via APISetChatTTL. Global TTL via APISetChatItemTTL.
See: SimpleXAPI.kt -- CC.APISetChatItemTTL, CC.APISetChatTTL; AppPreferences.customDisappearingMessageTime
Live Message
A message that updates in real-time as the sender types. Controlled by CC.ApiSendMessages with live=true. The ComposeState.liveMessage tracks the current live message being composed. An alert is shown on first use (AppPreferences.liveMessageAlertShown).
Message Reactions
Emoji reactions on messages. Added/removed via ApiChatItemReaction(type, id, scope, itemId, add, reaction). Reaction members in groups can be queried via ApiGetReactionMembers. Each ChatItem carries a reactions: List<CIReactionCount>.
Message Forwarding
Messages can be forwarded between chats. ApiPlanForwardChatItems checks feasibility (e.g., file availability), and ApiForwardChatItems performs the forward. A ForwardConfirmation may be required if files need downloading first.
Message Reports
Users can report messages in groups via ApiReportMessage(groupId, chatItemId, reportReason, reportText). Admins can archive (ApiArchiveReceivedReports) or delete (ApiDeleteReceivedReports) reports.
Mentions
In-message mentions of group members. Stored as mentions: Map<String, CIMention> on ChatItem and mentions: MentionedMembers on ComposeState.
Link Previews
Automatic preview generation for URLs in messages. Controlled by AppPreferences.privacyLinkPreviews. An alert is shown on first use (privacyLinkPreviewsShowAlert).
Local File Encryption
Files stored on device can be encrypted. Controlled by AppPreferences.privacyEncryptLocalFiles and toggled via CC.ApiSetEncryptLocalFiles(enable).
Chat Tags
User-defined tags for organizing conversations. CRUD via ApiCreateChatTag, ApiUpdateChatTag, ApiDeleteChatTag, ApiReorderChatTags. Assignment via ApiSetChatTags. The model tracks userTags, presetTags (system-defined categories), unreadTags, and the active filter (activeChatTagFilter).
6. Calling & Media
WebRTC
The real-time communication framework used for audio and video calls. The app uses WebRTC for peer-to-peer media streams, with SMP used only for call signaling (offer/answer/ICE candidates).
Call (data class)
Represents an active call session. Fields: remoteHostId, userProfile, contact, callUUID, callState (CallState enum), initialCallType (Audio/Video), localMediaSources, localCapabilities, peerMediaSources, sharedKey (for E2E call encryption), connectionInfo, connectedAt.
See: common/src/commonMain/kotlin/chat/simplex/common/views/call/WebRTC.kt:14
CallState
Enum tracking call progression: WaitCapabilities -> InvitationSent / InvitationAccepted -> OfferSent / OfferReceived -> Negotiated -> Connected -> Ended.
WCallCommand / WCallResponse
The command/response protocol between the Kotlin app and the WebRTC JavaScript layer:
- Commands:
Capabilities,Permission,Start,Offer,Answer,Ice,Media,Camera,Description,Layout,End - Responses:
Capabilities,Offer,Answer,Ice,Connection,Connected,PeerMedia,End,Ended,Ok,Error
See: WebRTC.kt:88 -- sealed class WCallCommand; WebRTC.kt:103 -- sealed class WCallResponse
CallManager
Manages incoming call invitations and the active call lifecycle. Handles reporting new incoming calls, accepting calls, switching between calls, and ending calls. Interacts with ChatModel.callInvitations, ChatModel.activeCall, and the platform notification manager.
See: common/src/commonMain/kotlin/chat/simplex/common/views/call/CallManager.kt
Android: CallActivity
A dedicated Android Activity that displays the call UI. Launched when accepting an incoming call or initiating an outgoing call. Uses an Android WebView to host the WebRTC JavaScript.
See: android/src/main/java/chat/simplex/app/views/call/CallActivity.kt
Android: CallService
An Android foreground Service that keeps the call alive when the app is in the background. Holds a WakeLock, displays an ongoing call notification, and manages the call lifecycle. Uses notification channel CALL_SERVICE_NOTIFICATION.
See: android/src/main/java/chat/simplex/app/CallService.kt
Desktop: Browser-based WebRTC via NanoWSD
On Desktop, calls are implemented by opening the system browser to a locally-hosted WebSocket server. A NanoHTTPD/NanoWSD server runs on localhost:50395, serving the WebRTC call page and communicating with the Kotlin app via WebSocket messages. Commands are sent as JSON-serialized WVAPICall objects; responses are parsed as WVAPIMessage objects.
See: common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt
ICE Servers
STUN/TURN servers used for WebRTC NAT traversal. Configurable via AppPreferences.webrtcIceServers. The relay policy (AppPreferences.webrtcPolicyRelay) controls whether calls must use TURN relays (for IP privacy) or can attempt direct connections.
CallMediaType
Enum: Video, Audio. Determines the initial media type of the call.
CallMediaSource
Enum: Mic, Camera, ScreenAudio, ScreenVideo. Used in WCallCommand.Media to toggle individual media streams.
7. Notifications & Background
Android: SimplexService
A foreground Service that keeps the chat backend running in the background. Uses a WakeLock and displays a persistent notification ("SimpleX Chat service" channel). Started with START_STICKY for automatic restart. Manages the chatRecvMsg loop indirectly by keeping the process alive.
Notification channel: chat.simplex.app.SIMPLEX_SERVICE_NOTIFICATION ("SimpleX Chat service")
See: android/src/main/java/chat/simplex/app/SimplexService.kt
Android: MessagesFetcherWorker
A WorkManager periodic worker that wakes the app to fetch new messages when the foreground service is not running (i.e., when NotificationsMode is PERIODIC). Provides a battery-friendly alternative to the always-on service.
See: android/src/main/java/chat/simplex/app/MessagesFetcherWorker.kt
Android: NotificationsMode
Enum controlling background message fetching:
OFF-- no background activity; messages received only when app is openPERIODIC-- usesMessagesFetcherWorkerfor periodic fetchesSERVICE-- usesSimplexServiceforeground service (default)
See: SimpleXAPI.kt:7739 -- enum class NotificationsMode
Android: Notification Channels
Android notification channels registered by the app:
- Messages:
chat.simplex.app.MESSAGE_NOTIFICATION-- high importance, for incoming messages - Calls:
chat.simplex.app.CALL_NOTIFICATION_2-- high importance, for incoming call alerts with custom sound - Service:
chat.simplex.app.SIMPLEX_SERVICE_NOTIFICATION-- low importance, persistent foreground service indicator - Call Service:
chat.simplex.app.CALL_SERVICE_NOTIFICATION-- default importance, ongoing call indicator
See: android/src/main/java/chat/simplex/app/model/NtfManager.android.kt, SimplexService.kt, CallService.kt
Android: NtfManager
The Android-specific notification manager. Handles creating notification channels, displaying message notifications (with grouping via MessageGroup), displaying incoming call notifications (with full-screen intent for lock-screen calls), and managing notification actions (accept/reject call, open chat).
See: android/src/main/java/chat/simplex/app/model/NtfManager.android.kt
Desktop: System Notifications
On Desktop, notifications use the system notification mechanism (typically via the JVM's SystemTray or platform-specific notification APIs). The notification manager interface is shared (ntfManager) but the implementation is platform-specific.
NotificationPreviewMode
Controls what information appears in notifications:
HIDDEN-- no message contentCONTACT-- shows sender name onlyMESSAGE-- shows sender name and message preview (default)
See: ChatModel.kt:4823 -- enum class NotificationPreviewMode
Wake Lock Management
In ChatController.startReceiver(), each received message acquires a wake lock (via getWakeLock(timeout=60000)) that is released after 30 seconds. This ensures the device stays awake long enough to process incoming messages and display notifications, particularly for incoming calls.
8. Application Architecture
ChatController
The singleton controller that bridges the Kotlin UI layer and the Haskell core library. Responsibilities:
- Manages the
chatCtrl(FFI handle to the Haskell runtime) - Sends commands via
sendCmd()and receives events via thestartReceiver()coroutine loop - Processes received messages in
processReceivedMsg() - Holds a reference to
AppPreferencesandChatModel - Provides the
messagesChannel(Kotlin coroutineChannel<API>) for consumers to observe events - Manages retry logic for transient network errors (
sendCmdWithRetry)
See: SimpleXAPI.kt:493 -- object ChatController
ChatModel
The singleton reactive state container for the entire app. Uses Compose mutableStateOf and mutableStateListOf for reactive UI updates. Key state:
currentUser-- the active user profileusers-- list of all user profiles (UserInfo)chatsContext/secondaryChatsContext--ChatsContextholding the chat listchatId-- currently open chatgroupMembers-- members of the currently viewed groupcallInvitations-- pending incoming call invitationsactiveCall-- the currently active calluserAddress-- the user's SimpleX addresschatItemTTL-- global message TTL settinguserTags-- chat tagsterminalItems-- debug terminal log items- Various UI state flags (
showCallView,switchingUsersAndHosts,clearOverlays, etc.)
See: ChatModel.kt:86 -- object ChatModel
AppPreferences
A class wrapping platform-specific key-value storage (Settings from com.russhwolf.settings). On Android, backed by SharedPreferences. On Desktop, backed by Java Properties files. Provides type-safe accessors for all user preferences.
See: SimpleXAPI.kt:94 -- class AppPreferences
ComposeState
Data class holding the state of the message composition area. Fields: message (ComposeMessage), parsedMessage (formatted text), liveMessage, preview (ComposePreview), contextItem (ComposeContextItem -- reply/edit context), inProgress, progressByTimeout, useLinkPreviews, mentions.
See: common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt:98
ModalManager
Manages the modal/sheet presentation stack. Supports multiple placements (default, center, fullscreen, end). Holds an ordered list of ModalViewHolder items and exposes showModal, showCustomModal, showModalCloseable, closeModal. Uses Compose state (modalCount) to trigger recomposition.
See: common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt:92
AlertManager
Singleton for displaying alert dialogs. Provides showAlertMsg, showAlertDialog, showAlertDialogButtons, etc. Works with AlertManager.shared for the default instance.
ChatsContext
Holds the chat list state for a particular scope (main or secondary). Manages chats (State<List>), provides updateChats() to refresh, and supports filtering/keeping specific chats during updates.
ConnectProgressManager
Tracks and displays connection progress in the UI. Methods: startConnectProgress(text, onCancel), stopConnectProgress(), cancelConnectProgress(). Exposes showConnectProgress (nullable string indicating active progress text).
See: ChatModel.kt:48 -- object ConnectProgressManager
withBGApi / withLongRunningApi
Utility functions for launching coroutines on background threads. Used throughout the codebase to perform API calls without blocking the UI thread.
9. Configuration & Preferences
AppPreferences (Storage)
All preferences are accessed through ChatController.appPrefs, which is a lazy-initialized AppPreferences instance. The underlying storage is:
- Android:
SharedPreferenceswith IDchat.simplex.app.SIMPLEX_APP_PREFS - Desktop: Java
Propertiesfiles viacom.russhwolf.settings
Theme overrides have separate storage (SHARED_PREFS_THEMES_ID).
SharedPreference
A generic wrapper providing get() and set(value) for a single preference. All AppPreferences fields are SharedPreference<T> instances created by factory methods (mkBoolPreference, mkStrPreference, mkIntPreference, mkLongPreference, mkFloatPreference, mkEnumPreference, mkSafeEnumPreference, mkDatePreference, mkMapPreference, mkTimeoutPreference).
Key Preference Categories
Notifications:
notificationsMode-- OFF / PERIODIC / SERVICEnotificationPreviewMode-- HIDDEN / CONTACT / MESSAGEcanAskToEnableNotifications-- gate for the notification prompt
Privacy:
privacyProtectScreen-- prevents screenshots (Android FLAG_SECURE)privacyAcceptImages-- auto-accept inline imagesprivacyLinkPreviews-- generate URL previewsprivacySanitizeLinks-- strip tracking parameters from URLsprivacyShowChatPreviews-- show message preview in chat listprivacySaveLastDraft-- persist draft messagesprivacyEncryptLocalFiles-- encrypt files at restprivacyAskToApproveRelays-- prompt before using relays suggested by contactsprivacyMediaBlurRadius-- blur radius for media in notifications/previews
Security:
performLA-- require local authentication (biometric/PIN)laMode-- local authentication modelaLockDelay-- seconds before re-lockingstoreDBPassphrase-- whether to persist the DB passphraseinitialRandomDBPassphrase-- indicates the DB uses a random (non-user-chosen) passphraseselfDestruct-- enable self-destruct profileselfDestructDisplayName-- display name for the self-destruct profile
Network:
networkUseSocksProxy-- route traffic through SOCKS proxynetworkProxy-- SOCKS proxy host/port configurationnetworkSessionMode-- transport session multiplexing modenetworkSMPProxyMode-- SMP proxy / private routing modenetworkSMPProxyFallback-- fallback behavior when proxy failsnetworkHostMode-- onion/public host preferencenetworkRequiredHostMode-- enforce host mode strictly- Various TCP timeout settings (background, interactive, per-KB)
- Keep-alive settings (idle, interval, count)
Calls:
webrtcPolicyRelay-- force TURN relay usagecallOnLockScreen-- DISABLE / SHOW / ACCEPT calls on lock screenwebrtcIceServers-- custom ICE server configurationexperimentalCalls-- enable experimental call features
Appearance:
currentTheme-- active theme namesystemDarkTheme-- theme for system dark modethemeOverrides-- per-theme customizationsprofileImageCornerRadius-- avatar roundingchatItemRoundness-- message bubble roundingchatItemTail-- show/hide message bubble tailfontScale-- text size scalingdensityScale-- UI density scalinginAppBarsAlpha-- toolbar transparencyappearanceBarsBlurRadius-- toolbar blur effect
UI:
oneHandUI-- one-handed UI mode (bottom-aligned navigation)chatBottomBar-- show bottom bar in chat viewsimplexLinkMode-- how SimpleX links are displayed (DESCRIPTION / FULL / BROWSER)showUnreadAndFavorites-- filter chat list to unread/favoritesdeveloperTools-- enable developer tools (terminal, etc.)
Database:
encryptedDBPassphrase-- encrypted form of the DB passphraseinitializationVectorDBPassphrase-- IV for DB passphrase encryptionencryptionStartedAt-- timestamp of encryption operation start (for crash recovery)confirmDBUpgrades-- prompt before database migrationsnewDatabaseInitialized-- flag for incomplete initialization recovery
Remote Access:
deviceNameForRemoteAccess-- device display name for remote controlconfirmRemoteSessions-- require confirmation for remote sessionsconnectRemoteViaMulticast-- use multicast discoveryconnectRemoteViaMulticastAuto-- auto-connect via multicastdesktopWindowState-- persisted window position/size (Desktop only)
Migration:
migrationToStage/migrationFromStage-- track migration progressonboardingStage-- current onboarding steplastMigratedVersionCode-- last app version that ran migrations
See: SimpleXAPI.kt:94-489 -- class AppPreferences with all SHARED_PREFS_* constants