Merged
Conversation
- Move `Node`, `Message`, `TAK`, and `NodeSortOption` models from `core:database` to `core:model`. - Create `:core:repository` module to host platform-agnostic repository interfaces and use cases. - Refactor `NodeRepository` into a shared interface with an Android-specific `NodeRepositoryImpl`. - Extract `PacketRepository` and `MessageQueue` interfaces for cross-platform support. - Relocate `SendMessageUseCase` to the common repository layer. - Update model dependencies across messaging, node, and map features. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…hitecture - Introduce interfaces for `NodeManager`, `CommandSender`, `PacketRepository`, `RadioConfigRepository`, `DeviceHardwareRepository`, and `ServiceBroadcasts`. - Move interfaces to the `core:repository` module to decouple logic from concrete implementations. - Relocate concrete implementations to `core:data` and update Hilt modules to bind new implementations. - Standardize the usage of core models (`Node`, `Message`, `Reaction`, `ContactSettings`) across feature modules and services. - Refactor `MeshService` and its handlers to use the new interface types for better testability. - Update unit tests to reflect class renaming and interface migrations. - Move `ContactSettings` and `Reaction` to `core:model` for shared access. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Introduce `HistoryManager` interface in `core:repository` and its implementation in `core:data`. - Move `NodeManager`, `CommandSender`, and `HistoryManager` unit tests from the `app` module to `core:data`. - Update `MeshConnectionManager` and `MeshDataHandler` to use the new `HistoryManager` interface instead of the concrete implementation. - Refactor unit tests and fakes to use domain models (`Node`, `DataPacket`) instead of database entities. - Expose `getOrCreateNode` in `NodeManagerImpl` and `resolveNodeNum` in `CommandSenderImpl` for improved testability. - Update DI module to bind the new `HistoryManager` implementation. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…re modules - Introduce `RadioController` in `core:model` to abstract radio operations and settings. - Extract `ServiceRepository`, `MqttManager`, `TracerouteHandler`, and `NeighborInfoHandler` interfaces into `core:repository`. - Move MQTT repository to `core:network` and handler implementations to `core:data`. - Update ViewModels to interact with `RadioController` instead of `IMeshService` directly. - Relocate `ServiceAction` and `TracerouteResponse` to `core:model` for better module accessibility. - Bind new implementations in `RepositoryModule` and `ServiceModule`. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Move `Node`, `Message`, `TAK`, and `NodeSortOption` models from `core:database` to `core:model`. - Create `:core:repository` module to host platform-agnostic repository interfaces and use cases. - Refactor `NodeRepository` into a shared interface with an Android-specific `NodeRepositoryImpl`. - Extract `PacketRepository` and `MessageQueue` interfaces for cross-platform support. - Relocate `SendMessageUseCase` to the common repository layer. - Update model dependencies across messaging, node, and map features. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…hitecture - Introduce interfaces for `NodeManager`, `CommandSender`, `PacketRepository`, `RadioConfigRepository`, `DeviceHardwareRepository`, and `ServiceBroadcasts`. - Move interfaces to the `core:repository` module to decouple logic from concrete implementations. - Relocate concrete implementations to `core:data` and update Hilt modules to bind new implementations. - Standardize the usage of core models (`Node`, `Message`, `Reaction`, `ContactSettings`) across feature modules and services. - Refactor `MeshService` and its handlers to use the new interface types for better testability. - Update unit tests to reflect class renaming and interface migrations. - Move `ContactSettings` and `Reaction` to `core:model` for shared access. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Introduce `HistoryManager` interface in `core:repository` and its implementation in `core:data`. - Move `NodeManager`, `CommandSender`, and `HistoryManager` unit tests from the `app` module to `core:data`. - Update `MeshConnectionManager` and `MeshDataHandler` to use the new `HistoryManager` interface instead of the concrete implementation. - Refactor unit tests and fakes to use domain models (`Node`, `DataPacket`) instead of database entities. - Expose `getOrCreateNode` in `NodeManagerImpl` and `resolveNodeNum` in `CommandSenderImpl` for improved testability. - Update DI module to bind the new `HistoryManager` implementation. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…re modules - Introduce `RadioController` in `core:model` to abstract radio operations and settings. - Extract `ServiceRepository`, `MqttManager`, `TracerouteHandler`, and `NeighborInfoHandler` interfaces into `core:repository`. - Move MQTT repository to `core:network` and handler implementations to `core:data`. - Update ViewModels to interact with `RadioController` instead of `IMeshService` directly. - Relocate `ServiceAction` and `TracerouteResponse` to `core:model` for better module accessibility. - Bind new implementations in `RepositoryModule` and `ServiceModule`. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…e modules This migration moves core business logic out of the app module and into decoupled core repository and data modules: - Extracts interfaces for `MeshDataHandler`, `MeshActionHandler`, `MeshRouter`, `MeshMessageProcessor`, and others into `core:repository`. - Moves concrete implementations to `core:data` under the `manager` package. - Renames `MessageFilterService` to `MessageFilter` and moves it to the core library. - Updates dependency injection modules to bind the new interfaces to their respective implementations. - Refactors `MeshService` and `MeshConnectionManager` to rely on the new repository-level interfaces. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Relocate `RadioInterfaceService`, `PacketHandler`, and `MeshConnectionManager` from the app module to `core:data` and `core:repository`. - Extract platform-specific implementations for location, workers, and widget updates into Android-specific classes. - Move shared models and exceptions, including `InterfaceId` and `RadioNotConnectedException`, to `core:model`. - Introduce `Lazy` injection in several managers to resolve circular dependencies. - Update Dagger Hilt bindings to support the new interface-driven architecture. - Adjust unit tests to reflect the new package structure and implementation details. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Implement `upsert` in `NodeRepository` and enable it in `NodeManager` - Update `SendMessageWorker` to retry on failure instead of marking as error - Ensure `publicKey` is preserved during `NodeEntity` conversions - Refine packet ID generation to use positive non-zero integers - Remove redundant `Dispatchers.Main` in `SettingsViewModel` - Refactor `MeshDataHandlerTest` to use lazy mocks Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
* Simplify task determination by using capitalized flavor names for Gradle tasks. * Separate code style (Spotless, Detekt) and shared unit tests into dedicated workflow steps. * Ensure flavor-specific assembly, lint, and coverage reports run for all matrix variations. * Improve readability by renaming check steps to distinguish between shared and flavor-specific execution. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Move `ChannelOption.UNSET` to the end of the enum. - Strip base64 padding characters from generated `ChannelSet` URLs. - Update `SharedContactTest` to use `MalformedMeshtasticUrlException` and add additional validation test cases. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR implements a major architectural decoupling refactor for the Meshtastic Android app, moving business logic out of the :app module into specialized core modules and introducing clean interfaces for platform-specific radio and service logic.
Changes:
- Introduced a new
:core:repositorymodule containing interface definitions (NodeRepository,ServiceRepository,RadioConfigRepository,MessageFilter,MessageQueue, etc.) to decouple business logic from implementation details. - Promoted core domain models (
Node,Message,Reaction,NodeSortOption,ContactSettings, etc.) fromcore.database.modelto thecore.modelmodule for KMP readiness. - Replaced direct AIDL
meshServicecalls withRadioControllerabstractions throughout ViewModels, use cases, and firmware update handlers.
Reviewed changes
Copilot reviewed 250 out of 250 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
settings.gradle.kts |
Registers the new :core:repository module |
core/repository/src/commonMain/... |
New interface definitions for the repository layer |
core/model/src/... |
Promoted domain models and new model types |
core/data/src/... |
Implementations renamed with Impl suffix to separate from interfaces |
core/domain/src/... |
Use cases updated to use core.repository interfaces |
core/service/src/... |
Service implementations refactored; MessageFilterImpl replaces MessageFilterService |
feature/*/src/... |
Feature-layer ViewModels and components updated to use new interfaces and model locations |
app/src/... |
App-level service classes refactored to use RadioController and new repository interfaces |
Comments suppressed due to low confidence (2)
feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt:1
- A bare
CoroutineScope(Dispatchers.IO)is created without any lifecycle management. This scope will never be cancelled if the handler is destroyed or if an exception occurs, which can lead to coroutine leaks. The existingEsp32OtaUpdateHandlerclass should have its own managedCoroutineScopeinjected or stored as a member, similar to how other handlers in this codebase (e.g.MeshLocationManager) maintain aprivate var scopethat is replaced via astart(scope: CoroutineScope)method.
core/repository/src/commonMain/kotlin/org/meshtastic/core/repository/MeshConnectionManager.kt:1 - Similar to
MeshServiceNotifications, the return typeAnyis too broad and erases type safety. The same recommendation applies: use a platform-neutral type,Unit, or move the method out of the shared interface.
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
…() to getCurrentCacheLimit() Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
- Add `isBonded(address)` helper to `BluetoothRepository` to verify bonding status with permission and state checks. - Refactor `NordicBleInterfaceSpec` to use the new helper method. - Update `bond()` to call `updateBluetoothState()`. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Update `PacketDao` and `PacketRepositoryImpl` to identify packets using specific fields (`id`, `from`, and `to`) rather than checking for full object equality. This ensures more reliable updates when modifying packet status or IDs. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR implements a major architectural refactor to decouple the application layers, moving the project toward Modern Android Development (MAD) best practices and Kotlin Multiplatform (KMP) readiness. Business logic has been extracted from the
:appmodule into specialized core modules, and platform-specific radio logic is now abstracted behind clean interfaces.Key Changes
:core:model(KMP models),:core:repository(interfaces),:core:domain(business logic/use cases), and:core:data/:core:service(implementations).RadioControllerandServiceRepositoryto decouple the UI from AIDL and background service lifecycle.Node,Message,Position) to the:core:modelmodule.StateFlowandSharedFlowacross all layers.Regressions Fixed During Review
NodeManagerImpl(previously only updating in-memory).publicKeymapping inNodeWithRelationsto ensure PKI features remain functional.SendMessageUseCasewhere packet IDs could be zero or negative.MeshDataHandlerTest.ktandSendMessageWorkerTest.ktto match the new constructor signatures.