Skip to content

feat: settings rework part 2, domain and usecase abstraction, tests#4680

Merged
jamesarich merged 17 commits intomainfrom
feat/settings2
Mar 2, 2026
Merged

feat: settings rework part 2, domain and usecase abstraction, tests#4680
jamesarich merged 17 commits intomainfrom
feat/settings2

Conversation

@jamesarich
Copy link
Copy Markdown
Collaborator

This pull request refactors how offline/queued message packets are handled and sent after reconnecting to the radio, and makes related dependency and cleanup changes. The main improvement is moving the responsibility for storing and processing queued packets from the in-memory MeshCommandSender to a persistent PacketRepository, and processing them using Android's WorkManager for reliability. It also removes unused code and updates imports to reflect changes in module structure. Additionally, the early packet buffer size is increased to handle more packets, and several AndroidManifest changes improve receiver security and initialization.

Queued packet handling changes:

  • Offline/queued packet storage and processing is moved from MeshCommandSender to PacketRepository, with queued packets now sent using SendMessageWorker via WorkManager after radio config loads, improving reliability and persistence. (MeshCommandSender.kt, MeshConnectionManager.kt) [1] [2] [3] [4] [5] [6] [7] [8]
  • The previous in-memory queue and related logic (offlineSentPackets, enqueueForSending, processQueuedPackets) are removed from MeshCommandSender. [1] [2] [3] [4]

Dependency and import updates:

  • Imports of ConnectionState are updated throughout the codebase to use org.meshtastic.core.model.ConnectionState instead of the previous location. [1] [2] [3] [4] [5] [6] [7] [8] [9]
  • The method for loading cached node DB is updated to use getNodeEntityDBbyNumFlow instead of getNodeDBbyNum, improving consistency with the repository API. (MeshNodeManager.kt, MeshServiceNotificationsImpl.kt) [1] [2]

AndroidManifest and initialization changes:

  • Broadcast receivers (ReplyReceiver, MarkAsReadReceiver, ReactionReceiver) are now explicitly marked as android:exported="false" for improved security.
  • Adds androidx.startup.InitializationProvider to the manifest for library initialization, and removes unnecessary WorkManager initializer meta-data.

Robustness improvements:

  • Adds .catch blocks to several coroutine flows to log errors and prevent crashes in radio and network connection state monitoring. (NordicBleInterface.kt, RadioInterfaceService.kt) [1] [2] [3] [4] [5]

Other changes:

  • Increases the maxEarlyPacketBuffer from 128 to 10240 in MeshMessageProcessor to better handle bursts of early packets.

…oller

- Relocate `ConnectionState` from `org.meshtastic.core.service` to `org.meshtastic.core.model`.
- Introduce `RadioController` interface to abstract radio operations like sending messages and managing favorites.
- Add `AndroidRadioControllerImpl` to bridge `RadioController` with the existing `ServiceRepository`.
- Refactor `SendMessageUseCase` to use `RadioController` instead of direct service access.
- Add flow error handling in `NordicBleInterface` and `RadioInterfaceService`.
- Update unit tests with `FakeRadioController` and add `turbine` dependency for flow testing.
- Update imports across the project to reflect the new `ConnectionState` location.

Signed-off-by: James Rich <[email protected]>
- Replace in-memory offline packet queue in `MeshCommandSender` with persistent `WorkManager`-based `SendMessageWorker`
- Update `SendMessageUseCase` to persist outgoing packets to the database and enqueue workers for background transmission
- Add `clientNotification` state flow and clear functionality to `RadioController` interface
- Increase `maxEarlyPacketBuffer` in `MeshMessageProcessor` from 128 to 10240
- Remove obsolete `MeshCommandSenderQueueTest` and update existing tests to reflect `WorkManager` integration
- Add WorkManager and Hilt-Work dependencies to core and messaging modules

Signed-off-by: James Rich <[email protected]>
- Add `android:exported="false"` to messaging broadcast receivers for improved security.
- Configure `androidx.startup` to remove the default `WorkManagerInitializer`.
- Implement a secondary constructor in `SendMessageWorker` using Hilt `EntryPoint` to support custom WorkManager initialization.
- Fix casing in a comment within `AndroidManifest.xml`.

Signed-off-by: James Rich <[email protected]>
- Move `SendMessageUseCase` and `HomoglyphCharacterStringTransformer` from `:feature/messaging` to the new `:core:domain` module.
- Introduce `MessageQueue` interface to decouple domain logic from Android-specific `WorkManager`.
- Implement `WorkManagerMessageQueue` in `:feature/messaging` to provide the concrete background worker implementation.
- Update project configuration and Hilt modules to support the new `:core:domain` module.
- Move associated unit tests and fakes to the corresponding domain package.

Signed-off-by: James Rich <[email protected]>
…e cases

- Implement new use cases for data export, device profile installation, and preference management.
- Expand the `RadioController` interface and `AndroidRadioControllerImpl` to support remote configuration, admin operations (reboot, shutdown, factory reset), and batch settings editing.
- Decouple `SettingsViewModel` and `RadioConfigViewModel` from repositories and data sources by delegating logic to specific use cases.
- Add `InstallProfileUseCase` to manage the sequential application of `DeviceProfile` settings to a node.
- Move CSV export logic from the UI layer to `ExportDataUseCase`.

Signed-off-by: James Rich <[email protected]>
…e cases

- Extract profile import, export, and installation logic from `RadioConfigViewModel` into dedicated use cases: `ImportProfileUseCase`, `ExportProfileUseCase`, `ExportSecurityConfigUseCase`, and `InstallProfileUseCase`.
- Implement comprehensive unit tests for the new use cases and existing settings-related logic, including `SetMeshLogSettings`, `ExportData`, and various preference toggles.
- Simplify `RadioConfigViewModel` by delegating business logic to the domain layer.

Signed-off-by: James Rich <[email protected]>
…e cases

- Introduce `UpdateRadioConfigUseCase` to handle updating owner, config, and module settings.
- Introduce `ProcessRadioResponseUseCase` to decode and handle incoming radio response packets.
- Refactor `RadioConfigViewModel` to delegate configuration updates and response processing to the new use cases.
- Add unit tests for both use cases.

Signed-off-by: James Rich <[email protected]>
…cases

- Split the monolithic `SettingsScreen` into modular components: `PrivacySection`, `AppearanceSection`, `PersistenceSection`, and `AppInfoSection`.
- Extract administrative and node cleanup logic into `AdminActionsUseCase` and `CleanNodeDatabaseUseCase`.
- Update `RadioConfigViewModel` to utilize use cases for radio configurations and administrative actions instead of direct service calls.
- Expand `RadioController` and `UpdateRadioConfigUseCase` to support setting ringtones and canned messages.
- Rename `getNodeDBbyNum` to `getNodeEntityDBbyNumFlow` in `NodeRepository` to better reflect return types.
- Add comprehensive unit tests for `RadioConfigViewModel` and `CleanNodeDatabaseUseCase`.

Signed-off-by: James Rich <[email protected]>
- Rename `UpdateRadioConfigUseCase` to `RadioConfigUseCase` and add support for "get" operations (owner, config, channels, etc.)
- Introduce `MeshLocationUseCase` to handle mesh location sharing logic
- Move `ExpressiveSection` to a shared component directory and add Compose previews for settings sections
- Update `AdminActionsUseCase` to automatically clear the local node database during factory and NodeDB resets
- Decouple `RadioConfigViewModel` and `SettingsViewModel` from direct service references in favor of use cases and `RadioController`
- Expand `RadioController` interface to include remote administration and location control methods

Signed-off-by: James Rich <[email protected]>
- Add unit tests for `DebugViewModel`, `FilterSettingsViewModel`, `SettingsViewModel`, and `CleanNodeDatabaseViewModel`.
- Add unit tests for `AdminActionsUseCase`, `MeshLocationUseCase`, and `RadioConfigUseCase`.
- Refactor `RadioConfigViewModelTest` to use `UnconfinedTestDispatcher` and expand test coverage for owner, channel, and admin updates.
- Mark several repository and manager classes as `open` to facilitate mocking in tests.
- Replace `UpdateRadioConfigUseCaseTest` with `RadioConfigUseCaseTest`.

Signed-off-by: James Rich <[email protected]>
- Update copyright headers to include 2026 across multiple files
- Add missing license headers to `RadioController`, `AndroidRadioControllerImpl`, and `SendMessageWorker`
- Remove debug `println` statements from `RadioConfigViewModel`
- Convert `Success` object to `data object` in `ProcessRadioResponseUseCase`
- Refine documentation for `SequentialJob` for better clarity

Signed-off-by: James Rich <[email protected]>
… cleanup SendMessageWorker

- Relocate `HomoglyphCharacterStringTransformer` from `core:domain` to `core:common` to support multiplatform usage.
- Update package names and imports accordingly.
- Remove manual Hilt `@EntryPoint` and fallback constructor from `SendMessageWorker` in favor of standard injection.

Signed-off-by: James Rich <[email protected]>
- Create `IsOtaCapableUseCase` to centralize logic for determining device OTA update compatibility.
- Update `SettingsViewModel` to use the new use case, reducing its responsibility and dependency surface.
- Replace `ServiceRepository` with `RadioController` in `SettingsViewModel` for connection state monitoring.
- Add unit tests for `IsOtaCapableUseCase`.
- Update `feature/messaging` dependencies and fix missing imports in tests.

Signed-off-by: James Rich <[email protected]>
- Decompose the `RadioConfig` composable into smaller, specialized section functions to improve readability and maintainability.
- Refactor `InstallProfileUseCase` and `ProcessRadioResponseUseCase` by extracting private helper methods to handle specific configuration and response types.
- Update copyright headers and license information across multiple core and feature modules.
- Add KDoc documentation to several use cases within the domain layer.
- Standardize code formatting across the codebase, including constructor parameters and lambda expressions.
- Apply lint suppressions for `TooManyFunctions` and `CyclomaticComplexMethod` where applicable in legacy controllers and view models.
- Enhance unit test coverage for `IsOtaCapableUseCase` to include various connection and hardware scenarios.

Signed-off-by: James Rich <[email protected]>
- Use `error()` instead of throwing `IllegalStateException` in `MeshCommandSender`
- Suppress generic exception lint in `MeshConnectionManager`
- Add unit test for processing canned message responses in `ProcessRadioResponseUseCaseTest`
- Add unit test for neighbor info module configuration in `InstallProfileUseCaseTest`

Signed-off-by: James Rich <[email protected]>
@github-actions github-actions bot added the enhancement New feature or request label Mar 2, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 62.50000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 15.18%. Comparing base (9ba4d50) to head (c71c6a4).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...sville/mesh/repository/radio/NordicBleInterface.kt 33.33% 2 Missing ⚠️
...lle/mesh/repository/radio/RadioInterfaceService.kt 0.00% 2 Missing ⚠️
...m/geeksville/mesh/service/MeshConnectionManager.kt 85.71% 1 Missing and 1 partial ⚠️
...a/com/geeksville/mesh/service/MeshCommandSender.kt 50.00% 1 Missing ⚠️
...ava/com/geeksville/mesh/service/MeshNodeManager.kt 0.00% 1 Missing ⚠️
...ville/mesh/service/MeshServiceNotificationsImpl.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4680      +/-   ##
==========================================
- Coverage   15.31%   15.18%   -0.14%     
==========================================
  Files          83       83              
  Lines        4354     4353       -1     
  Branches      734      734              
==========================================
- Hits          667      661       -6     
- Misses       3563     3566       +3     
- Partials      124      126       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

jamesarich and others added 2 commits March 2, 2026 11:38
Increased JVM memory allocation for Gradle.

Signed-off-by: James Rich <[email protected]>
@jamesarich jamesarich added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit 8c6bd8a Mar 2, 2026
8 checks passed
@jamesarich jamesarich deleted the feat/settings2 branch March 2, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant