Skip to content

feat: Complete app module thinning and feature module extraction#4844

Merged
jamesarich merged 30 commits intomainfrom
feat/app-thinning-nav
Mar 19, 2026
Merged

feat: Complete app module thinning and feature module extraction#4844
jamesarich merged 30 commits intomainfrom
feat/app-thinning-nav

Conversation

@jamesarich
Copy link
Copy Markdown
Collaborator

This pull request continues the modularization and thinning of the Android app module by extracting navigation logic and background services/workers into their respective feature modules. The changes improve maintainability, testability, and alignment with KMP (Kotlin Multiplatform) best practices. The most important changes are grouped below by theme.

Navigation Graph Extraction and Refactoring:

  • Moved all feature-specific navigation graph implementations (e.g., channelsGraph, connectionsGraph, contactsGraph, firmwareGraph, mapGraph, nodesGraph, settingsGraph) out of the app module and into their respective feature:* modules. The root app module now only assembles these graphs from the feature modules, reducing tight coupling and matching the Desktop architecture. [1] [2] [3] [4]
  • Added a new test NavigationAssemblyTest to verify that all navigation graphs assemble correctly in the root NavHost without crashing.

Widget and Background Service Extraction:

  • Extracted the LocalStatsWidget implementation and related classes from the app module to a new feature:widget module. Updated all references, imports, and the AndroidManifest to point to the new module. [1] [2] [3] [4]
  • Updated dependency injection configuration to include the new FeatureWidgetModule in the app's Koin DI graph. [1] [2]

Documentation and Planning:

  • Added detailed specifications, implementation plans, and metadata for both the navigation extraction (extract_android_navigation_20260318) and remaining background service extraction (extract_remaining_background_20260318) tracks in the conductor/archive directory. This documents the motivation, requirements, and phased implementation steps for these refactors. [1] [2] [3] [4] [5] [6] [7] [8]

Service Implementation Relocation:

  • Clarified in the documentation that the implementation of MeshService now resides in the :core:service module, with only the declaration remaining in the :app manifest for system visibility.

These changes collectively advance the modularization effort, ensuring a thinner, more maintainable app module and better separation of concerns across the codebase.

@jamesarich jamesarich requested a review from Copilot March 18, 2026 21:26
@github-actions github-actions bot added the enhancement New feature or request label Mar 18, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues thinning the :app Android shell by relocating feature-owned navigation graphs and the Local Stats widget into their respective feature:* modules, updating DI wiring and documentation accordingly (aligning Android with the existing Desktop modular architecture).

Changes:

  • Extracted Navigation 3 graph registrations from :app into each feature:* module and updated the root NavHost assembly.
  • Created a new :feature:widget module and moved the Local Stats widget implementation + resources into it; updated manifest and Koin includes.
  • Updated docs/plans and added a Robolectric smoke test to ensure graph assembly doesn’t crash.

Reviewed changes

Copilot reviewed 53 out of 54 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
settings.gradle.kts Adds :feature:widget to the Gradle settings includes.
mesh_service_example/README.md Updates AIDL module attribution/link (needs correction).
feature/widget/src/main/res/xml/local_stats_widget_info.xml New AppWidgetProvider info for the extracted widget.
feature/widget/src/main/res/drawable/ic_refresh.xml Adds widget refresh icon resource in the new module.
feature/widget/src/main/res/drawable/app_icon.xml Adds widget header icon resource in the new module.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/di/FeatureWidgetModule.kt Adds Koin annotations module for widget feature scanning.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/RefreshLocalStatsAction.kt Updates package to feature.widget after extraction.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/LocalStatsWidgetState.kt Updates package to feature.widget after extraction.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/LocalStatsWidgetReceiver.kt Updates package to feature.widget after extraction.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/LocalStatsWidget.kt Updates resources + click intent wiring after extraction out of :app.
feature/widget/src/main/kotlin/org/meshtastic/feature/widget/AndroidAppWidgetUpdater.kt Moves widget updater into feature:widget and adds logging.
feature/widget/build.gradle.kts Defines the new Android library module and its dependencies (Glance, Koin, resources).
feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/SettingsNavigation.kt Moves Settings graph wiring into feature:settings.
feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/ChannelsNavigation.kt Moves Channels graph wiring into feature:settings.
feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/navigation/Channel.kt Moves Channel screen/navigation code into feature:settings package.
feature/settings/build.gradle.kts Adds Navigation 3 runtime/ui dependencies to the feature.
feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/navigation/NodesNavigation.kt Moves Nodes graph wiring into feature:node and injects NodeMap screen via a lambda.
feature/node/src/androidMain/kotlin/org/meshtastic/feature/node/navigation/AdaptiveNodeListScreen.kt Moves adaptive node list UI into feature:node navigation package.
feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/worker/WorkManagerMessageQueue.kt Moves WorkManager message queue implementation into feature:messaging.
feature/messaging/src/androidMain/kotlin/org/meshtastic/feature/messaging/navigation/ContactsNavigation.kt Moves Contacts graph wiring into feature:messaging.
feature/map/src/androidMain/kotlin/org/meshtastic/feature/map/navigation/MapNavigation.kt Moves Map graph wiring into feature:map.
feature/map/build.gradle.kts Adds Navigation 3 runtime/ui deps to feature:map.
feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/navigation/FirmwareNavigation.kt Moves Firmware graph wiring into feature:firmware.
feature/firmware/build.gradle.kts Adds Navigation 3 runtime/ui deps to feature:firmware.
feature/connections/src/androidMain/kotlin/org/meshtastic/feature/connections/navigation/ConnectionsNavigation.kt Moves Connections graph wiring into feature:connections.
docs/roadmap.md Updates roadmap priorities to reflect modularization progress.
docs/kmp-status.md Updates KMP readiness status and notes extracted navigation/worker/widget pieces.
docs/decisions/navigation3-parity-2026-03.md Updates documentation pointers to new feature-owned nav graph locations.
docs/decisions/architecture-review-2026-03.md Updates architecture review stats and notes about app thinning/extractions.
docs/agent-playbooks/task-playbooks.md Updates playbooks to reference feature-module navigation locations.
docs/agent-playbooks/di-navigation3-anti-patterns-playbook.md Updates references for Navigation 3 graph patterns after extraction.
docs/agent-playbooks/common-practices.md Updates guidance/examples to match removed app-level navigation wrappers.
core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshServiceClient.kt Moves service client into core:service package namespace.
core/service/src/androidMain/kotlin/org/meshtastic/core/service/AndroidMeshLocationManager.kt Moves location manager into core:service package namespace.
core/api/src/main/aidl/org/meshtastic/core/service/IMeshService.aidl Updates service binding documentation comments (explicit intent example).
conductor/tracks.md Removes an outdated completed track entry.
conductor/tech-stack.md Documents extracted nav graphs and thinner :app shell.
conductor/product.md Updates product doc to mention navigation decoupling into feature modules.
conductor/archive/extract_remaining_background_20260318/spec.md Adds spec doc for background extraction workstream.
conductor/archive/extract_remaining_background_20260318/plan.md Adds phased plan doc for background extraction workstream.
conductor/archive/extract_remaining_background_20260318/metadata.json Adds metadata for the background extraction workstream.
conductor/archive/extract_remaining_background_20260318/index.md Adds index for background extraction workstream.
conductor/archive/extract_android_navigation_20260318/spec.md Adds spec doc for navigation extraction workstream.
conductor/archive/extract_android_navigation_20260318/plan.md Adds phased plan doc for navigation extraction workstream.
conductor/archive/extract_android_navigation_20260318/metadata.json Adds metadata for navigation extraction workstream.
conductor/archive/extract_android_navigation_20260318/index.md Adds index for navigation extraction workstream.
app/src/test/kotlin/org/meshtastic/app/ui/NavigationAssemblyTest.kt Adds Robolectric test to smoke-check nav graph assembly.
app/src/main/kotlin/org/meshtastic/app/ui/Main.kt Switches nav graph imports to feature modules and adapts nodes graph wiring.
app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt Includes FeatureWidgetModule in the root Koin graph.
app/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt Updates widget receiver/state provider references to feature:widget.
app/src/main/kotlin/org/meshtastic/app/MainActivity.kt Updates import to use core:service MeshServiceClient.
app/src/main/AndroidManifest.xml Updates widget receiver class to org.meshtastic.feature.widget.LocalStatsWidgetReceiver.
app/build.gradle.kts Adds dependency on projects.feature.widget.
app/README.md Clarifies MeshService implementation location vs manifest declaration.
Comments suppressed due to low confidence (1)

feature/widget/src/main/kotlin/org/meshtastic/feature/widget/AndroidAppWidgetUpdater.kt:22

  • Logger is imported but not used (the code calls co.touchlab.kermit.Logger.e fully-qualified). This will be flagged by formatting/static-analysis tools; either remove the unused import or use the imported Logger reference in the catch block.

You can also share your feedback on Copilot code review. Take the survey.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 18.18182% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 7.63%. Comparing base (df3a094) to head (7028aec).
⚠️ Report is 3 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
.../org/meshtastic/feature/widget/LocalStatsWidget.kt 0.00% 7 Missing ⚠️
...n/kotlin/org/meshtastic/app/MeshUtilApplication.kt 0.00% 1 Missing ⚠️
app/src/main/kotlin/org/meshtastic/app/ui/Main.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             main   #4844      +/-   ##
=========================================
- Coverage   13.49%   7.63%   -5.86%     
=========================================
  Files         543     544       +1     
  Lines       17842   18071     +229     
  Branches     2666    2689      +23     
=========================================
- Hits         2407    1380    -1027     
- Misses      15112   16557    +1445     
+ Partials      323     134     -189     
Flag Coverage Δ
host-unit 7.63% <18.18%> (-5.86%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

- Update architecture review, roadmap, and kmp status to reflect the app module thinning and navigation extraction.
- Update agent playbooks to point to the new navigation graph locations in feature modules.
- Update navigation parity decision doc with the correct paths.
…s and workers from app module'

This commit removes the track directory and associated documentation for the background service extraction project, signaling its completion or archival.

Specific changes include:
- Deleted `conductor/tracks/extract_remaining_background_20260318/index.md`
- Deleted `conductor/tracks/extract_remaining_background_20260318/metadata.json`
- Deleted the implementation plan in `plan.md`, which covered the relocation of `AndroidMeshLocationManager`, `WorkManagerMessageQueue`, widgets, and DI refactoring.
- Deleted the specification in `spec.md` regarding the app module thinning effort.
… widgets

- Update architecture review, roadmap, and kmp status to reflect the app module thinning and extraction of services, workers, and widgets.
- Update agent playbooks to remove outdated references to Android wrapper ViewModels that were eliminated.
- Update mesh_service_example README to point to the new location of the AIDL interface in core:service.
- Fix outdated class name in IMeshService.aidl binding guidance.
- Emphasize action-based binding best practices for third-party consumers.
- Clarify MeshService implementation location in app/README.md.
- Update architecture review, roadmap, and kmp status to reflect that the app module has reached its final target state of a 6-file thin shell.
- Move 'App module thinning', 'Serial/USB', and 'MQTT' out of the active priority list as they are now complete.
- Define new Near-Term priorities: KMP-native testing tools (Mokkery/Turbine), Desktop Map integration, iOS CI gating, and dependency stabilization.
- Define new Medium-Term priorities: iOS proof target, core:api contract split, and Firmware DFU decoupling.
- Clean up Longer-Term list to focus on UI Interop and architectural splits.
- Mark MapViewModel as partially extracted in kmp-status.md.
- Detail the MapComposeMP and Web Mercator strategy for Desktop in roadmap.md.
- Add task for final MapViewModel unification in commonMain.
This commit refactors `MQTTRepositoryImpl` to improve error handling and code formatting. It replaces generic `Exception` catches with specific MQTT, IO, and Serialization exceptions, ensuring better diagnostic logging and lifecycle management of the client loop.

Specific changes include:
- **Error Handling**: Updated `MQTTRepositoryImpl` to catch specific exceptions (`MQTTException`, `IOException`, `SerializationException`) instead of a generic `Exception` block.
- **Client Logic**:
    - Improved address parsing to dynamically select the default port (8883 for TLS, 1883 otherwise).
    - Added explicit handling for `CancellationException` in the MQTT client loop.
- **Code Style & Formatting**:
    - Applied consistent formatting across `MQTTRepositoryImpl.kt`, `MQTTRepositoryImplTest.kt`, and `MqttJsonPayload.kt`.
    - Removed the unused `DEFAULT_QOS` constant.
    - Simplified subscription logic and address parsing expressions for readability.
- **Testing**: Updated test files to match new formatting standards while maintaining coverage for address parsing and JSON payload serialization.
@jamesarich jamesarich force-pushed the feat/app-thinning-nav branch from 9326289 to 7028aec Compare March 18, 2026 23:43
@jamesarich jamesarich added this pull request to the merge queue Mar 19, 2026
Merged via the queue into main with commit 1b0dc75 Mar 19, 2026
7 checks passed
@jamesarich jamesarich deleted the feat/app-thinning-nav branch March 19, 2026 00:33
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.

2 participants