Skip to content

Conversation

@gavv
Copy link
Member

@gavv gavv commented May 21, 2025

This PR closes #94 and all its sub-tasks.

Majority of flutter work was done by @Izchomatik, and I mostly took care about the kotlin part and CI.

While I was reworking the kotlin part, I also fixed issues #1, #16, #17, #45, #66.

The project is now a flutter project, that can be potentially built for macos/windows/linux/android/ios. Currently, only android build actually works.

The new UI resembles the old one, this PR can be considered as "refactoring + bug-fix", with no significant features.

The kotlin code now lives in /android. Things that are kept on the kotlin side:

  • android foreground service
  • notification management
  • quick tile management
  • audio io
  • streaming (using roc-java)

The upper layers (models, ui, persistent settings) are now in dart/flutter. Flutter and kotlin communicate via platform channels.

In future, flutter code will communicate with both kotlin code (via platform channels) and with rocd (via http). On desktop, it will use just rocd, and on android, it will tell kotlin to start rocd in context of android service and then will connect to rocd.

There is also new documentation in docs folder in markdown format. It's auto-published using mkdocs here: https://roc-streaming.org/droid/. It covers architecture overview, build instructions, and other hints.

You can build the project either using standard flutter command (instructions), or use doit - python-based alternative to make (instructions). Users don't really need doit to build the project, but it's useful for development because it has rules for various stuff like code generation, building docs, etc.

Izchomatik and others added 30 commits July 12, 2024 22:12
Next PRs will add flutter project, later we will move back some parts of the old project.
Prepare Flutter project for future development.z
- remove __pycache__ at exit
- don't print backtrace on ^C
- add commands:
    doit analyze
    doit test
    doit exec
    doit build_apk
    doit wipe
- use LongRunning()
- add more doit files to .gitignore
- use doit on CI
- separate CI jobs for desktop & android
* Rename identifiers

* Set project version to 0.3.0
metadata/ dir, LICENSE, and screenshot.web are moved back
to project root.

Their contents will be updated in gh-105.
Also fixes: #1, #16, #17, #66

- Initiate request for notification and microphone permissions
  and media projection on the dart side of AndroidBackend.

- Implement those requests in MainActivity.kt and rework
  AndroidConnector to redirect those requests to activity.

- Automatically stop media projection when both sender and receiver
  are stopped. Prevent service from stopping projection while we
  are starting sender and receiver.

- Implement synchronization and fix various races.

- Use foreground service instead of bound service, to keep it
  running when app closes.

- Forbid swiping away notification on lock screen.
  (We can forbid it only for lock screen).

- Stop sender and receiver when notification is swiped away.

- Add AndroidListener, to pass events from kotlin to dart.
  Implement in in AndroidBackend on dart side.

- Add AndroidSenderSettings, AndroidReceiverSettings, and pass them
  from model to kotlin.

- Hard-code ports in model instead of kotlin.

- Implement Backend.getLocalAddresses().

- Improve comments.

- Refactor android service code.

- Remove unused values from strings.xml.
- Merge all kotlin files into on package

- Merge kotlin and java directories

- SenderReceiverService => StreamingService

- android_connector => android_bridge
  (because it now defines AndroidConnector + AndroidListener)

- android_bridge.dart => android_bridge.decl.dart
  (this file is never imported directly)

- screenshot => docs/screenshot/

- tag.py => script/make_tag.py
- Add NoopBackend and use in tests
- Call TestWidgetsFlutterBinding.ensureInitialized()
- Make tests async and properly use await
- Get minSdk, targetSdk, compileSdk from gradle.properties
- Get version and version code from AndroidManifest
- Check AndroidManifest and pubspec versions when building APK
- Run spotless linter and dart analyzer
- Run spotless formatter and dart formatter
- Restore APK signing config
Remove files from _temp_storage that are already
properly restored in new project.
Replace make_tag.py and update_version.py with a single script
version_ctl.py with 3 subcommands:

    - make_release
    - check_release (to run on CI)
    - update_version (low-level command)
- add macOS and Windows
- build debug & release apk
- job to publish release
- rework "automation.md" and update to recent changes
- add "release_management.md"
- add "development.md"
- minor cleanup
- add mkdocs.yml
- docs structure: architecture/, building/, development/
- cleanup instructions for windows setup
- add instruction for macos and linux setup
- add instructions for building project
- source code links converted to absolute links
- naked links converted to <links>

DOC FIX
- bump gradle and plugin versions
- add proguard-rules.pro
- fix build of debug apk
- copy apk to dist/ in gradle instead of doit
gavv added 23 commits May 16, 2025 22:53
This is preparation for the new design where we're going to
port rocd to android and use it in roc-droid.

- Rename AndroidBackend to AndroidConnector.
  AndroidConnector combines AndroidController + AndroidListener
  for bi-directional communication with kotlin.

- Rename Backend to Agent.

- Separate Agent and AndroidConnector.
  Agent is now a class, not an interface.
  AndroidConnector does not implement Agent.
  Agent delegates work to AndroidConnector.

- Models now use Agent class.

- In future, Agent will combine AndroidConnector (to
  communicate with Kotlin) + DaemonConnector (to
  communicate with rocd).
- Combine FailureEvent and StateEvent into one AgentEvent.

- Use AgentEvent in models.

- Translate agent.AgentEvent to model.FailureEvent for UI when
  background error occurs.
Agent:

  - Move error codes to AgentErrorCode enum.

  - Introduce AgentEvent, base class for agent events, with two
    subclasses: AgentErrorEvent (with error code) and AgentStateEvent.

  - Replace failureEvent and stateEvent into a single AgentEvent.

  - Introduce AgentException, base class for agent exceptions,
    with error code.

  - Translate PlatformExceptions from Android to AgentException.

Model:

  - Introduce FailureCode, enum with codes mapped from AgentErrorCode.
    For now it mirrors agent codes, but it isolates model's users
    from agent package.

  - Make FailureEvent an EventArgs implementation with FailureCode.

  - Share Event<FailureEvent> from ModelRoot with Sender and Receiver.

  - In Sender and Receiver, handle exceptions from agent and convert
    them to failure events.
- use material theme
- enable dark mode support
- enable search support
- update 'automation' page
- New package 'dto' with plain data (no logic, just fields),
  for reuse across other packages.

  Model, agent, storage, and ui - all use same types from dto.

  DTO types use freezed to create immutable serializable
  classes with copyWith() and toJson() / fromJson().

  This allowed to remove duplication across model, agent,
  and storage.

- New package 'storage' that implements persistent storage
  for sender and receiver configs.

- Models now use dto classes internally.

- Models load settings from storage in constructors and save
  them back on change.

  Models' @actions are now async.

- Agent doesn't expose android-specific classes, instead it
  uses dto classes and internally translates them to
  android-specific ones.

- UI is updated to use async methods of models and DTOs.
If android notification is dismissed (swiped away):

    - stop sender and receiver (this works as before)

    - hide notification and don't re-create it until sender/receiver
      is explicitly started again

    - if there no active clients connected to the service,
      stop service

    - if there are active clients, but then they are closed,
      and sender/receiver wasn't started before the close,
      then also stop service
1. AlertDialog.Builder requires AppCompat theme, so use
   it for the dialog.

2. Don't show OK/Cancel, just show information message
   with OK button. The actual choice will be done later
   when the system asks the user.

3. Improve rationale messages.
@gavv gavv requested a review from ortex May 21, 2025 13:53
@gavv gavv added the category: flutter migration Task related to migration to Flutter label May 21, 2025
@gavv gavv force-pushed the flutter branch 2 times, most recently from c1904f8 to ff35a1d Compare May 23, 2025 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: flutter migration Task related to migration to Flutter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flutter migration

3 participants