diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 89adc1eb..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,178 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -## [1.4.0] - 2025-10-15 -### Fixed -- fix: Resolve debug settings bottom sheet crash on some devices (Issue #472) - - Fixed IllegalFormatConversionException in DebugSettingsSheet.kt when scrolling through debug settings - - Corrected string formatting for debug_target_fpr_fmt and debug_derived_p_fmt string resources - - Improved string resource parameter handling for numeric values - -## [0.7.2] - 2025-07-20 -### Fixed -- fix: battery optimization screen content scrollable with fixed buttons - -## [0.7.1] - 2025-07-19 - -### Added -- feat(battery): add battery optimization management for background reliability - -### Fixed -- fix: center align toolbar item in ChatHeader - passed modifier.fillmaxHeight so the content inside the row can actually be centered -- fix: update sidebar text to use string resources -- fix(chat): cursor location and enhance message input with slash command styling - -### Changed -- refactor: remove context attribute at ChatViewModel.kt -- Refactor: Migrate MainViewModel to use StateFlow - -### Improved -- Use HorizontalDivider instead of deprecated Divider -- Use contentPadding instead of padding so items remain fully visible - - -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.7] - -### Added -- Location services check during app startup with educational UI -- Message text selection functionality in chat interface -- Enhanced RSSI tracking and unread message indicators -- Major Bluetooth connection architecture refactoring with dedicated managers - -### Fixed -- **Critical**: Android-iOS message fragmentation compatibility issues - - Fixed fragment size (500→150 bytes) and ID generation for cross-platform messaging - - Ensures Android can properly communicate with iOS devices -- DirectMessage notifications and text copying functionality -- Smart routing optimizations (no relay loops, targeted delivery) -- Build system compilation issues and null pointer exceptions - -### Changed -- Comprehensive dependency updates (AGP 8.10.1, Kotlin 2.2.0, Compose 2025.06.01) -- Optimized BLE scan intervals for better battery performance -- Reduced excessive logging output - -### Improved -- Cross-platform compatibility with iOS and Rust implementations -- Connection stability through architectural improvements -- Battery performance via scan duty cycling -- User onboarding with location services education - -## [0.6] - -### Added -- Channel password management with `/pass` command for channel owners -- Monochrome/themed launcher icon for Android 12+ dynamic theming support -- Unit tests package with initial testing infrastructure -- Production build optimization with code minification and shrinking -- Native back gesture/button handling for all app views - -### Fixed -- Favorite peer functionality completely restored and improved - - Enhanced favorite system with fallback mechanism for peers without key exchange - - Fixed UI state updates for favorite stars in both header and sidebar - - Improved favorite persistence across app sessions -- `/w` command now displays user nicknames instead of peer IDs -- Button styling and layout improvements across the app - - Enhanced back button positioning and styling - - Improved private chat and channel header button layouts - - Fixed button padding and alignment issues -- Color scheme consistency updates - - Updated orange color throughout the app to match iOS version - - Consistent color usage for private messages and UI elements -- App startup reliability improvements - - Better initialization sequence handling - - Fixed null pointer exceptions during startup - - Enhanced error handling and logging -- Input field styling and behavior improvements -- Sidebar user interaction enhancements -- Permission explanation screen layout fixes with proper vertical padding - -### Changed -- Updated GitHub organization references in project files -- Improved README documentation with updated clone URLs -- Enhanced logging throughout the application for better debugging - -## [0.5.1] - 2025-07-10 - -### Added -- Bluetooth startup check with user prompt to enable Bluetooth if disabled - -### Fixed -- Improved Bluetooth initialization reliability on first app launch - -## [0.5] - 2025-07-10 - -### Added -- New user onboarding screen with permission explanations -- Educational content explaining why each permission is required -- Privacy assurance messaging (no tracking, no servers, local-only data) - -### Fixed -- Comprehensive permission validation - ensures all required permissions are granted -- Proper Bluetooth stack initialization on first app load -- Eliminated need for manual app restart after installation -- Enhanced permission request coordination and error handling - -### Changed -- Improved first-time user experience with guided setup flow - -## [0.4] - 2025-07-10 - -### Added -- Push notifications for direct messages -- Enhanced notification system with proper click handling and grouping - -### Improved -- Direct message (DM) view with better user interface -- Enhanced private messaging experience - -### Known Issues -- Favorite peer functionality currently broken - -## [0.3] - 2025-07-09 - -### Added -- Battery-aware scanning policies for improved power management -- Dynamic scan behavior based on device battery state - -### Fixed -- Android-to-Android Bluetooth Low Energy connections -- Peer discovery reliability between Android devices -- Connection stability improvements - -## [0.2] - 2025-07-09 - -### Added -- Initial Android implementation of bitchat protocol -- Bluetooth Low Energy mesh networking -- End-to-end encryption for private messages -- Channel-based messaging with password protection -- Store-and-forward message delivery -- IRC-style commands (/msg, /join, /clear, etc.) -- RSSI-based signal quality indicators - -### Fixed -- Various Bluetooth handling improvements -- User interface refinements -- Connection reliability enhancements - -## [0.1] - 2025-07-08 - -### Added -- Initial release of bitchat Android client -- Basic mesh networking functionality -- Core messaging features -- Protocol compatibility with iOS bitchat client - -[Unreleased]: https://github.com/permissionlesstech/bitchat-android/compare/0.5.1...HEAD -[0.5.1]: https://github.com/permissionlesstech/bitchat-android/compare/0.5...0.5.1 -[0.5]: https://github.com/permissionlesstech/bitchat-android/compare/0.4...0.5 -[0.4]: https://github.com/permissionlesstech/bitchat-android/compare/0.3...0.4 -[0.3]: https://github.com/permissionlesstech/bitchat-android/compare/0.2...0.3 -[0.2]: https://github.com/permissionlesstech/bitchat-android/compare/0.1...0.2 -[0.1]: https://github.com/permissionlesstech/bitchat-android/releases/tag/0.1 diff --git a/GOOGLE_PLAY.md b/GOOGLE_PLAY.md deleted file mode 100644 index bdea715e..00000000 --- a/GOOGLE_PLAY.md +++ /dev/null @@ -1 +0,0 @@ -I, callebtc, creator of bitchat for android, owner of the copyright claims, and owner of the official bitchat android repository (https://github.com/permissionlesstech/bitchat-android), hereby authorize Verse Communication PBC to publish bitchat (com.bitchat.doid) on the Google Play Store. diff --git a/PRIVACY_POLICY.md b/PRIVACY_POLICY.md deleted file mode 100644 index a90dd78d..00000000 --- a/PRIVACY_POLICY.md +++ /dev/null @@ -1,156 +0,0 @@ -# bitchat Privacy Policy - -*Last updated: January 2025* - -## Our Commitment - -bitchat is designed with privacy as its foundation. We believe private communication is a fundamental human right. This policy explains how bitchat protects your privacy. - -## Summary - -**WE DO NOT COLLECT ANY INFORMATION.** - -- **No personal data collection** - We don't collect names, emails, or phone numbers -- **No location data collection** - Location is accessed only for local processing (BLE/Geohash) and is never collected or sent to us -- **Hybrid Functionality** - bitchat offers two modes of communication: - - **Bluetooth Mesh Chat**: This mode is completely offline, using peer-to-peer Bluetooth connections. It does not use any servers or internet connection. - - **Geohash Chat**: This mode uses an internet connection to communicate with others in a specific geographic area. It relies on Nostr relays for message transport. -- **No tracking** - We have no analytics, telemetry, or user tracking -- **Open source** - You can verify these claims by reading our code - -## What Information bitchat Stores - -### On Your Device Only - -1. **Identity Key** - - A cryptographic key generated on first launch - - Stored locally in your device's secure storage - - Allows you to maintain "favorite" relationships across app restarts - - Never leaves your device - -2. **Nickname** - - The display name you choose (or auto-generated) - - Stored only on your device - - Shared with peers you communicate with - -3. **Message History** (if enabled) - - When room owners enable retention, messages are saved locally - - Stored encrypted on your device - - You can delete this at any time - -4. **Favorite Peers** - - Public keys of peers you mark as favorites - - Stored only on your device - - Allows you to recognize these peers in future sessions - -### Temporary Session Data - -During each session, bitchat temporarily maintains: -- Active peer connections (forgotten when app closes) -- Routing information for message delivery -- Cached messages for offline peers (12 hours max) - -## What Information is Shared - -### With Other bitchat Users - -When you use bitchat, nearby peers can see: -- Your chosen nickname -- Your ephemeral public key (changes each session) -- Messages you send to public rooms or directly to them -- Your approximate Bluetooth signal strength (for connection quality) - -### With Room Members - -When you join a password-protected room: -- Your messages are visible to others with the password -- Your nickname appears in the member list -- Room owners can see you've joined - -## What We DON'T Do - -bitchat **never**: -- Collects personal information -- Collects location history -- Transmits any data to us (the developers) -- Stores data on servers -- Shares data with third parties -- Uses analytics or telemetry -- Creates user profiles -- Requires registration - -## Encryption - -All private messages use end-to-end encryption: -- **X25519** for key exchange -- **AES-256-GCM** for message encryption -- **Ed25519** for digital signatures -- **Argon2id** for password-protected rooms - -## Your Rights - -You have complete control: -- **Delete Everything**: Triple-tap the logo to instantly wipe all data -- **Leave Anytime**: Close the app and your presence disappears -- **No Account**: Nothing to delete from servers because there are none -- **Portability**: Your data never leaves your device unless you export it - -## Location Data & Permissions - -To provide the core functionality of bitchat, we access your device's location data. This access is necessary for the following specific purposes: - -### 1. Bluetooth Low Energy (BLE) Scanning -- **Why we need it:** The Android operating system requires Location permission to scan for nearby Bluetooth LE devices (especially on Android 11 and lower). This is a system-level requirement because Bluetooth scans can theoretically be used to derive location. -- **How we use it:** We use this permission strictly to discover other bitchat peers nearby for the "Bluetooth Mesh Chat" mode. -- **Privacy protection:** We do not record or store your location during this process. The data is processed instantaneously by the Android system to facilitate the connection. - -### 2. Geohash Chat Functionality -- **Why we need it:** The "Geohash Chat" mode allows you to communicate with others in your approximate geographic area. -- **How we use it:** If you enable this mode, we access your location to calculate a "geohash" (a short alphanumeric string representing a geographic region). This geohash is used to find and subscribe to relevant channels on decentralized Nostr relays. -- **Privacy protection:** - - Your precise GPS coordinates are **never** sent to any server or peer. - - Only the coarse geohash (representing an area, not a pinpoint) is shared with the Nostr network. - - You can use the "Bluetooth Mesh Chat" mode without this feature if you prefer. - -**We do not collect, store, or share your location history.** Location data is processed locally on your device to enable these specific features. - -## Children's Privacy - -bitchat does not knowingly collect information from children. The app has no age verification because it collects no personal information from anyone. - -## Data Retention - -- **Messages**: Deleted from memory when app closes (unless room retention is enabled) -- **Identity Key**: Persists until you delete the app -- **Favorites**: Persist until you remove them or delete the app -- **Everything Else**: Exists only during active sessions - -## Security Measures - -- All communication is encrypted -- No data transmitted to servers (there are none) -- Open source code for public audit -- Regular security updates -- Cryptographic signatures prevent tampering - -## Changes to This Policy - -If we update this policy: -- The "Last updated" date will change -- The updated policy will be included in the app -- No retroactive changes can affect data (since we don't collect any) - -## Contact - -bitchat is an open source project. For privacy questions: -- Review our code: https://github.com/yourusername/bitchat -- Open an issue on GitHub -- Join the discussion in public rooms - -## Philosophy - -Privacy isn't just a feature—it's the entire point. bitchat proves that modern communication doesn't require surrendering your privacy. No accounts, no servers, no surveillance. Just people talking freely. - ---- - -*This policy is released into the public domain under The Unlicense, just like bitchat itself.* \ No newline at end of file diff --git a/README.md b/README.md index c9b0091d..93d740c4 100644 --- a/README.md +++ b/README.md @@ -1,308 +1,86 @@ -
-
-
](https://play.google.com/store/apps/details?id=com.bitchat.droid)
-**Instructions:**
-
-1. **Download the APK:** On your Android device, navigate to the link above and download the latest `.apk` file. Open it.
-2. **Allow Unknown Sources:** On some devices, before you can install the APK, you may need to enable "Install from unknown sources" in your device's settings. This is typically found under **Settings > Security** or **Settings > Apps & notifications > Special app access**.
-3. **Install:** Open the downloaded `.apk` file to begin the installation.
-
## License
This project is released into the public domain. See the [LICENSE](LICENSE.md) file for details.
## Features
-- **✅ Cross-Platform Compatible**: Full protocol compatibility with iOS bitchat
-- **✅ Decentralized Mesh Network**: Automatic peer discovery and multi-hop message relay over Bluetooth LE
-- **✅ End-to-End Encryption**: X25519 key exchange + AES-256-GCM for private messages
-- **✅ Channel-Based Chats**: Topic-based group messaging with optional password protection
-- **✅ Store & Forward**: Messages cached for offline peers and delivered when they reconnect
-- **✅ Privacy First**: No accounts, no phone numbers, no persistent identifiers
-- **✅ IRC-Style Commands**: Familiar `/join`, `/msg`, `/who` style interface
-- **✅ Message Retention**: Optional channel-wide message saving controlled by channel owners
-- **✅ Emergency Wipe**: Triple-tap logo to instantly clear all data
-- **✅ Modern Android UI**: Jetpack Compose with Material Design 3
-- **✅ Dark/Light Themes**: Terminal-inspired aesthetic matching iOS version
-- **✅ Battery Optimization**: Adaptive scanning and power management
-
-## Android Setup
-
-### Prerequisites
-
-- **Android Studio**: Arctic Fox (2020.3.1) or newer
-- **Android SDK**: API level 26 (Android 8.0) or higher
-- **Kotlin**: 1.8.0 or newer
-- **Gradle**: 7.0 or newer
-
-### Build Instructions
-
-1. **Clone the repository:**
- ```bash
- git clone https://github.com/permissionlesstech/bitchat-android.git
- cd bitchat-android
- ```
-
-2. **Open in Android Studio:**
- ```bash
- # Open Android Studio and select "Open an Existing Project"
- # Navigate to the bitchat-android directory
- ```
-
-3. **Build the project:**
- ```bash
- ./gradlew build
- ```
-
-4. **Install on device:**
- ```bash
- ./gradlew installDebug
- ```
-
-### Development Build
-
-For development builds with debugging enabled:
-
-```bash
-./gradlew assembleDebug
-adb install -r app/build/outputs/apk/debug/app-debug.apk
-```
-
-### Release Build
-
-For production releases:
-
-```bash
-./gradlew assembleRelease
-```
-
-## Android-Specific Requirements
-
-### Permissions
-
-The app requires the following permissions (automatically requested):
-
-- **Bluetooth**: Core BLE functionality
-- **Location**: Required for BLE scanning on Android
-- **Network**: Expand your mesh through public internet relays
-- **Notifications**: Message alerts and background updates
-
-### Hardware Requirements
-
-- **Bluetooth LE (BLE)**: Required for mesh networking
-- **Android 8.0+**: API level 26 minimum
-- **RAM**: 2GB recommended for optimal performance
-
-## Usage
-
-### Basic Commands
-
-- `/j #channel` - Join or create a channel
-- `/m @name message` - Send a private message
-- `/w` - List online users
-- `/channels` - Show all discovered channels
-- `/block @name` - Block a peer from messaging you
-- `/block` - List all blocked peers
-- `/unblock @name` - Unblock a peer
-- `/clear` - Clear chat messages
-- `/pass [password]` - Set/change channel password (owner only)
-- `/transfer @name` - Transfer channel ownership
-- `/save` - Toggle message retention for channel (owner only)
-
-### Getting Started
-
-1. **Install the app** on your Android device (requires Android 8.0+)
-2. **Grant permissions** for Bluetooth and location when prompted
-3. **Launch bitchat** - it will auto-start mesh networking
-4. **Set your nickname** or use the auto-generated one
-5. **Connect automatically** to nearby iOS and Android bitchat users
-6. **Join a channel** with `/j #general` or start chatting in public
-7. **Messages relay** through the mesh network to reach distant peers
-
-### Android UI Features
-
-- **Jetpack Compose UI**: Modern Material Design 3 interface
-- **Dark/Light Themes**: Terminal-inspired aesthetic matching iOS
-- **Haptic Feedback**: Vibrations for interactions and notifications
-- **Adaptive Layout**: Optimized for various Android screen sizes
-- **Message Status**: Real-time delivery and read receipts
-- **RSSI Indicators**: Signal strength colors for each peer
-
-### Channel Features
-
-- **Password Protection**: Channel owners can set passwords with `/pass`
-- **Message Retention**: Owners can enable mandatory message saving with `/save`
-- **@ Mentions**: Use `@nickname` to mention users (with autocomplete)
-- **Ownership Transfer**: Pass control to trusted users with `/transfer`
-
-## Security & Privacy
-
-### Encryption
-- **Private Messages**: X25519 key exchange + AES-256-GCM encryption
-- **Channel Messages**: Argon2id password derivation + AES-256-GCM
-- **Digital Signatures**: Ed25519 for message authenticity
-- **Forward Secrecy**: New key pairs generated each session
-
-### Privacy Features
-- **No Registration**: No accounts, emails, or phone numbers required
-- **Ephemeral by Default**: Messages exist only in device memory
-- **Cover Traffic**: Random delays and dummy messages prevent traffic analysis
-- **Emergency Wipe**: Triple-tap logo to instantly clear all data
-- **Bundled Tor Support**: Built-in Tor network integration for enhanced privacy when internet connectivity is available
-
-## Performance & Efficiency
-
-### Message Compression
-- **LZ4 Compression**: Automatic compression for messages >100 bytes
-- **30-70% bandwidth savings** on typical text messages
-- **Smart compression**: Skips already-compressed data
-
-### Battery Optimization
-- **Adaptive Power Modes**: Automatically adjusts based on battery level
- - Performance mode: Full features when charging or >60% battery
- - Balanced mode: Default operation (30-60% battery)
- - Power saver: Reduced scanning when <30% battery
- - Ultra-low power: Emergency mode when <10% battery
-- **Background efficiency**: Automatic power saving when app backgrounded
-- **Configurable scanning**: Duty cycle adapts to battery state
-
-### Network Efficiency
-- **Optimized Bloom filters**: Faster duplicate detection with less memory
-- **Message aggregation**: Batches small messages to reduce transmissions
-- **Adaptive connection limits**: Adjusts peer connections based on power mode
+- **Dual Transport Architecture**: Bluetooth LE mesh for offline messaging, Nostr relays for internet-based messaging
+- **Location-Based Channels**: Geographic chat rooms using geohash coordinates over Nostr relays
+- **Intelligent Message Routing**: Automatically chooses the best transport, with queuing and retry when a peer is unreachable
+- **End-to-End Encryption**: [Noise Protocol](https://noiseprotocol.org) (XX pattern, X25519 + ChaCha20-Poly1305) for private messages over the mesh
+- **Decentralized Mesh Network**: Automatic peer discovery and multi-hop relay over Bluetooth LE (max 7 hops)
+- **Wi-Fi Aware Transport**: Higher-bandwidth local mesh on supported devices
+- **Channel Chats**: Topic-based group messaging with optional password protection (Argon2id + AES-256-GCM)
+- **IRC-Style Commands**: Familiar `/join`, `/msg`, `/who` style interface
+- **Tor Support**: Built-in Tor (Arti) for private internet connectivity
+- **Emergency Wipe**: Triple-tap to instantly clear all data
+- **Cross-Platform**: Binary protocol compatible with bitchat on iOS and macOS
## Technical Architecture
-### Binary Protocol
-bitchat uses an efficient binary protocol optimized for Bluetooth LE:
-- Compact packet format with 1-byte type field
-- TTL-based message routing (max 7 hops)
-- Automatic fragmentation for large messages
-- Message deduplication via unique IDs
+### Bluetooth Mesh Network (Offline)
-### Mesh Networking
-- Each device acts as both client and peripheral
-- Automatic peer discovery and connection management
-- Store-and-forward for offline message delivery
-- Adaptive duty cycling for battery optimization
+- Direct peer-to-peer within Bluetooth range, multi-hop relay through nearby devices
+- Noise Protocol sessions with forward secrecy; peer identities derived from static keys
+- Compact binary packet format with fragmentation, TTL routing, and deduplication
+- Adaptive duty cycling and connection limits for battery efficiency
+- Foreground service keeps the mesh alive within Android background execution limits
-### Android-Specific Optimizations
-- **Coroutine Architecture**: Asynchronous operations for mesh networking
-- **Kotlin Coroutines**: Thread-safe concurrent mesh operations
-- **EncryptedSharedPreferences**: Secure storage for user settings
-- **Lifecycle-Aware**: Proper handling of Android app lifecycle
-- **Battery Optimization**: Foreground service and adaptive scanning
+### Nostr Protocol (Internet)
-## Android Technical Architecture
+- Global reach via public relays, geohash-based location channels
+- Private messages fall back to Nostr for mutual favorites when the mesh is unavailable
+- Ephemeral keys per geohash area
-### Core Components
+### Android Stack
-1. **BitchatApplication.kt**: Application-level initialization and dependency injection
-2. **MainActivity.kt**: Main activity handling permissions and UI hosting
-3. **ChatViewModel.kt**: MVVM pattern managing app state and business logic
-4. **BluetoothMeshService.kt**: Core BLE mesh networking (central + peripheral roles)
-5. **EncryptionService.kt**: Cryptographic operations using BouncyCastle
-6. **BinaryProtocol.kt**: Binary packet encoding/decoding matching iOS format
-7. **ChatScreen.kt**: Jetpack Compose UI with Material Design 3
+- Kotlin, Jetpack Compose (Material 3), MVVM
+- Coroutines and Flow for all networking and state
+- Core components: `MeshForegroundService` (persistent connectivity), `BluetoothMeshService` / `WifiAwareMeshService` (transports), `UnifiedMeshService` (transport selection), `NoiseSessionManager` (encryption sessions), `MessageRouter` (mesh/Nostr routing with outbox retry)
-### Dependencies
+## Building
-- **Jetpack Compose**: Modern declarative UI
-- **BouncyCastle**: Cryptographic operations (X25519, Ed25519, AES-GCM)
-- **Nordic BLE Library**: Reliable Bluetooth LE operations
-- **Kotlin Coroutines**: Asynchronous programming
-- **LZ4**: Message compression (when enabled)
-- **EncryptedSharedPreferences**: Secure local storage
+Requires Android Studio and the Android SDK (API 26+).
-### Binary Protocol Compatibility
+```bash
+git clone https://github.com/permissionlesstech/bitchat-android.git
+cd bitchat-android
+./gradlew assembleDebug
+```
-The Android implementation maintains 100% binary protocol compatibility with iOS:
-- **Header Format**: Identical 13-byte header structure
-- **Packet Types**: Same message types and routing logic
-- **Encryption**: Identical cryptographic algorithms and key exchange
-- **UUIDs**: Same Bluetooth service and characteristic identifiers
-- **Fragmentation**: Compatible message fragmentation for large content
+Install on a connected device:
-## Publishing to Google Play
+```bash
+adb install -r app/build/outputs/apk/debug/app-debug.apk
+```
-### Preparation
+The app requests Bluetooth, location (required for BLE scanning), and notification permissions at runtime.
-1. **Update version information:**
- ```kotlin
- // In app/build.gradle.kts
- defaultConfig {
- versionCode = 2 // Increment for each release
- versionName = "1.1.0" // User-visible version
- }
- ```
+## Testing
-2. **Create a signed release build:**
- ```bash
- ./gradlew assembleRelease
- ```
+```bash
+# Unit tests
+./gradlew test
-3. **Generate app bundle (recommended for Play Store):**
- ```bash
- ./gradlew bundleRelease
- ```
+# Lint
+./gradlew lint
-### Play Store Requirements
+# Instrumented tests (requires a device or emulator)
+./gradlew connectedAndroidTest
+```
-- **Target API**: Latest Android API (currently 34)
-- **Privacy Policy**: Required for apps requesting sensitive permissions
-- **App Permissions**: Justify Bluetooth and location usage
-- **Content Rating**: Complete questionnaire for age-appropriate content
-
-### Distribution
-
-- **Google Play Store**: Main distribution channel
-- **F-Droid**: For open-source distribution
-- **Direct APK**: For testing and development
-
-## Cross-Platform Communication
-
-This Android port enables seamless communication with the original iOS bitchat app:
-
-- **iPhone ↔ Android**: Full bidirectional messaging
-- **Mixed Groups**: iOS and Android users in same channels
-- **Feature Parity**: All commands and encryption work across platforms
-- **Protocol Sync**: Identical message format and routing behavior
-
-**iOS Version**: For iPhone/iPad users, get the original bitchat at [github.com/jackjackbits/bitchat](https://github.com/jackjackbits/bitchat)
-
-## Contributing
-
-Contributions are welcome! Key areas for enhancement:
-
-1. **Performance**: Battery optimization and connection reliability
-2. **UI/UX**: Additional Material Design 3 features
-3. **Security**: Enhanced cryptographic features
-4. **Testing**: Unit and integration test coverage
-5. **Documentation**: API documentation and development guides
-
-## Support & Issues
-
-- **Bug Reports**: [Create an issue](../../issues) with device info and logs
-- **Feature Requests**: [Start a discussion](https://github.com/orgs/permissionlesstech/discussions)
-- **Security Issues**: Email security concerns privately
-- **iOS Compatibility**: Cross-reference with [original iOS repo](https://github.com/jackjackbits/bitchat)
-
-For iOS-specific issues, please refer to the [original iOS bitchat repository](https://github.com/jackjackbits/bitchat).
+Note that BLE mesh behavior is difficult to emulate; protocol and session logic is covered by unit tests, while radio-level behavior needs real devices.
diff --git a/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt b/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt
index 47f89db4..027066c7 100644
--- a/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt
+++ b/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt
@@ -142,6 +142,17 @@ class BluetoothMeshService(private val context: Context) : TransportBridgeServic
messageHandler.packetProcessor = packetProcessor
//startPeriodicDebugLogging()
+ // Flush queued private messages as soon as a BLE Noise session authenticates,
+ // instead of relying on the foreground-only UI poll.
+ encryptionService.onSessionEstablished = { peerID ->
+ Log.d(TAG, "BLE Noise session established with ${peerID.take(8)}")
+ try {
+ com.bitchat.android.services.MessageRouter
+ .tryGetInstance()
+ ?.onSessionEstablished(peerID)
+ } catch (_: Exception) { }
+ }
+
// Initialize sync manager (needs serviceScope)
gossipSyncManager = GossipSyncManager(
myPeerID = myPeerID,
diff --git a/app/src/main/java/com/bitchat/android/service/MeshForegroundService.kt b/app/src/main/java/com/bitchat/android/service/MeshForegroundService.kt
index 117ba413..d2fda746 100644
--- a/app/src/main/java/com/bitchat/android/service/MeshForegroundService.kt
+++ b/app/src/main/java/com/bitchat/android/service/MeshForegroundService.kt
@@ -156,6 +156,7 @@ class MeshForegroundService : Service() {
when (intent?.action) {
ACTION_STOP -> {
// Stop FGS and mesh cleanly
+ try { com.bitchat.android.services.MessageRouter.tryGetInstance()?.stopOutboxScheduler() } catch (_: Exception) { }
try { unifiedMeshService?.stopServices() ?: meshService?.stopServices() } catch (_: Exception) { }
try { MeshServiceHolder.clear() } catch (_: Exception) { }
try { stopForeground(true) } catch (_: Exception) { }
diff --git a/app/src/main/java/com/bitchat/android/services/MessageRouter.kt b/app/src/main/java/com/bitchat/android/services/MessageRouter.kt
index 652e0c93..a09fa31e 100644
--- a/app/src/main/java/com/bitchat/android/services/MessageRouter.kt
+++ b/app/src/main/java/com/bitchat/android/services/MessageRouter.kt
@@ -6,6 +6,15 @@ import com.bitchat.android.favorites.FavoriteControlMessage
import com.bitchat.android.mesh.MeshService
import com.bitchat.android.model.ReadReceipt
import com.bitchat.android.nostr.NostrTransport
+import com.bitchat.android.util.AppConstants
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.SupervisorJob
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.launch
+import java.util.concurrent.ConcurrentHashMap
/**
* Routes messages between local mesh transports and Nostr, matching iOS behavior.
@@ -22,9 +31,27 @@ class MessageRouter private constructor(
DROPPED
}
+ private data class QueuedMessage(
+ val content: String,
+ val nickname: String,
+ val messageID: String,
+ val enqueuedAtMs: Long
+ )
+
+ private data class ConversationRetry(
+ val handshakeAttempts: Int,
+ val nextHandshakeAttemptAtMs: Long
+ )
+
companion object {
private const val TAG = "MessageRouter"
+ private const val OUTBOX_TICK_MS = AppConstants.Router.OUTBOX_TICK_MS
+ private const val OUTBOX_MESSAGE_TTL_MS = AppConstants.Router.OUTBOX_MESSAGE_TTL_MS
+ private const val OUTBOX_MAX_PER_PEER = AppConstants.Router.OUTBOX_MAX_PER_PEER
+ private val HANDSHAKE_RETRY_BACKOFF_MS = AppConstants.Router.HANDSHAKE_RETRY_BACKOFF_MS
+
@Volatile private var INSTANCE: MessageRouter? = null
+ internal var disableSchedulerForTesting = false
fun tryGetInstance(): MessageRouter? = INSTANCE
fun getInstance(context: Context, mesh: MeshService): MessageRouter {
val instance = INSTANCE ?: synchronized(this) {
@@ -39,15 +66,38 @@ class MessageRouter private constructor(
}
}
}
- // Always update mesh reference and sync peer ID
+ // Always update mesh reference and sync peer ID, and make sure the retry
+ // scheduler is running (it is stopped together with MeshForegroundService).
instance.mesh = mesh
instance.nostr.senderPeerID = mesh.myPeerID
+ instance.startOutboxScheduler()
return instance
}
+
+ internal fun resetForTesting() {
+ INSTANCE?.schedulerScope?.cancel()
+ INSTANCE = null
+ }
}
- // Outbox: peerID -> queued (content, nickname, messageID)
- private val outbox = mutableMapOf