Add Android device deployment flow#15146
Conversation
Notify the Android Flutter UI when the server requires deployment, add a deploy dialog with API token/custom ID inputs, and reuse shared deploy logic for CLI and FFI Signed-off-by: 21pages <sunboeasy@gmail.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughImplements device deployment end-to-end: adds DeployResult + deploy_device API client, Android one-shot "needs deploy" notification and reset, FFI entrypoint, Flutter settings tile + dialogs and event hook, CLI wiring to use DeployResult, and i18n placeholders across many locales. ChangesDevice Deployment Feature
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds an Android device deployment flow so the Rust backend can notify Flutter when a server requires deployment, and Android users can deploy from Settings or a prompt.
Changes:
- Refactors deployment into
ui_interface::deploy_deviceand reuses it from CLI and Android FFI. - Sends an Android
android_needs_deployglobal event onNOT_DEPLOYED. - Adds Android deploy prompt/form UI plus translation keys.
Reviewed changes
Copilot reviewed 58 out of 58 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/ui_interface.rs |
Adds shared deployment API and result mapping. |
src/core_main.rs |
Replaces inline CLI deploy logic with shared API. |
src/rendezvous_mediator.rs |
Adds Android deploy notification state and event push. |
src/flutter_ffi.rs |
Exposes Android deploy FFI and resets notification on service start. |
flutter/lib/main.dart |
Registers Android deploy event handler. |
flutter/lib/mobile/pages/settings_page.dart |
Adds Deploy settings entry and dialogs. |
flutter/lib/web/bridge.dart |
Adds web stub for deploy FFI. |
src/lang/en.rs |
Adds English deploy prompt text. |
src/lang/cn.rs |
Adds Chinese deploy translations. |
src/lang/template.rs |
Adds deploy translation keys. |
src/lang/ar.rs |
Adds deploy translation placeholders. |
src/lang/be.rs |
Adds deploy translation placeholders. |
src/lang/bg.rs |
Adds deploy translation placeholders. |
src/lang/ca.rs |
Adds deploy translation placeholders. |
src/lang/cs.rs |
Adds deploy translation placeholders. |
src/lang/da.rs |
Adds deploy translation placeholders. |
src/lang/de.rs |
Adds deploy translation placeholders. |
src/lang/el.rs |
Adds deploy translation placeholders. |
src/lang/eo.rs |
Adds deploy translation placeholders. |
src/lang/es.rs |
Adds deploy translation placeholders. |
src/lang/et.rs |
Adds deploy translation placeholders. |
src/lang/eu.rs |
Adds deploy translation placeholders. |
src/lang/fa.rs |
Adds deploy translation placeholders. |
src/lang/fi.rs |
Adds deploy translation placeholders. |
src/lang/fr.rs |
Adds deploy translation placeholders. |
src/lang/ge.rs |
Adds deploy translation placeholders. |
src/lang/gu.rs |
Adds deploy translation placeholders. |
src/lang/he.rs |
Adds deploy translation placeholders. |
src/lang/hi.rs |
Adds deploy translation placeholders. |
src/lang/hr.rs |
Adds deploy translation placeholders. |
src/lang/hu.rs |
Adds deploy translation placeholders. |
src/lang/id.rs |
Adds deploy translation placeholders. |
src/lang/it.rs |
Adds deploy translation placeholders. |
src/lang/ja.rs |
Adds deploy translation placeholders. |
src/lang/ko.rs |
Adds deploy translation placeholders. |
src/lang/kz.rs |
Adds deploy translation placeholders. |
src/lang/lt.rs |
Adds deploy translation placeholders. |
src/lang/lv.rs |
Adds deploy translation placeholders. |
src/lang/ml.rs |
Adds deploy translation placeholders. |
src/lang/nb.rs |
Adds deploy translation placeholders. |
src/lang/nl.rs |
Adds deploy translation placeholders. |
src/lang/pl.rs |
Adds deploy translation placeholders. |
src/lang/pt_PT.rs |
Adds deploy translation placeholders. |
src/lang/ptbr.rs |
Adds deploy translation placeholders. |
src/lang/ro.rs |
Adds deploy translation placeholders. |
src/lang/ru.rs |
Adds deploy translation placeholders. |
src/lang/sc.rs |
Adds deploy translation placeholders. |
src/lang/sk.rs |
Adds deploy translation placeholders. |
src/lang/sl.rs |
Adds deploy translation placeholders. |
src/lang/sq.rs |
Adds deploy translation placeholders. |
src/lang/sr.rs |
Adds deploy translation placeholders. |
src/lang/sv.rs |
Adds deploy translation placeholders. |
src/lang/ta.rs |
Adds deploy translation placeholders. |
src/lang/th.rs |
Adds deploy translation placeholders. |
src/lang/tr.rs |
Adds deploy translation placeholders. |
src/lang/tw.rs |
Adds deploy translation placeholders. |
src/lang/uk.rs |
Adds deploy translation placeholders. |
src/lang/vi.rs |
Adds deploy translation placeholders. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: 21pages <sunboeasy@gmail.com>
Signed-off-by: 21pages <sunboeasy@gmail.com>
|
• The Android deployment flow has a state-reset bug that can delay or suppress the deploy prompt after a stop/start cycle. This breaks a user-visible behavior introduced by the patch. Review comment:
|
Signed-off-by: 21pages <sunboeasy@gmail.com>
Signed-off-by: 21pages <sunboeasy@gmail.com>
Signed-off-by: 21pages <sunboeasy@gmail.com>
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
flutter/lib/mobile/pages/settings_page.dart (1)
731-737:⚠️ Potential issue | 🟠 Major | ⚡ Quick winKeep the Deploy tile gated on the Android service state.
Line 731 now shows this entry for every Android non-outgoing-only client, but the intended behavior for this flow is to expose Deploy only while the service is running. Without the
gFFI.serverModel.isStartguard, users can open a deploy action from the stopped-service state.Suggested fix
- if (isAndroid && !bind.isOutgoingOnly()) + if (isAndroid && gFFI.serverModel.isStart && !bind.isOutgoingOnly())🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@flutter/lib/mobile/pages/settings_page.dart` around lines 731 - 737, The Deploy SettingsTile is currently shown for any Android non-outgoing-only client; wrap the tile rendering condition to also require the service to be running by adding a guard using gFFI.serverModel.isStart (i.e., only show the SettingsTile when isAndroid && !bind.isOutgoingOnly() && gFFI.serverModel.isStart), so the SettingsTile (and its onPressed that calls showDeployDialog) is only available while the Android service is started.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@flutter/lib/mobile/pages/settings_page.dart`:
- Around line 731-737: The Deploy SettingsTile is currently shown for any
Android non-outgoing-only client; wrap the tile rendering condition to also
require the service to be running by adding a guard using
gFFI.serverModel.isStart (i.e., only show the SettingsTile when isAndroid &&
!bind.isOutgoingOnly() && gFFI.serverModel.isStart), so the SettingsTile (and
its onPressed that calls showDeployDialog) is only available while the Android
service is started.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 240b3776-ba44-434b-ba07-ac54f631b0fa
📒 Files selected for processing (55)
flutter/lib/mobile/pages/settings_page.dartsrc/core_main.rssrc/lang/ar.rssrc/lang/be.rssrc/lang/bg.rssrc/lang/ca.rssrc/lang/cn.rssrc/lang/cs.rssrc/lang/da.rssrc/lang/de.rssrc/lang/el.rssrc/lang/en.rssrc/lang/eo.rssrc/lang/es.rssrc/lang/et.rssrc/lang/eu.rssrc/lang/fa.rssrc/lang/fi.rssrc/lang/fr.rssrc/lang/ge.rssrc/lang/gu.rssrc/lang/he.rssrc/lang/hi.rssrc/lang/hr.rssrc/lang/hu.rssrc/lang/id.rssrc/lang/it.rssrc/lang/ja.rssrc/lang/ko.rssrc/lang/kz.rssrc/lang/lt.rssrc/lang/lv.rssrc/lang/ml.rssrc/lang/nb.rssrc/lang/nl.rssrc/lang/pl.rssrc/lang/pt_PT.rssrc/lang/ptbr.rssrc/lang/ro.rssrc/lang/ru.rssrc/lang/sc.rssrc/lang/sk.rssrc/lang/sl.rssrc/lang/sq.rssrc/lang/sr.rssrc/lang/sv.rssrc/lang/ta.rssrc/lang/template.rssrc/lang/th.rssrc/lang/tr.rssrc/lang/tw.rssrc/lang/uk.rssrc/lang/vi.rssrc/rendezvous_mediator.rssrc/ui_interface.rs
✅ Files skipped from review due to trivial changes (15)
- src/lang/template.rs
- src/lang/ca.rs
- src/lang/pt_PT.rs
- src/lang/he.rs
- src/lang/gu.rs
- src/lang/el.rs
- src/lang/hi.rs
- src/lang/ptbr.rs
- src/lang/sl.rs
- src/lang/tw.rs
- src/lang/fi.rs
- src/lang/ar.rs
- src/lang/lv.rs
- src/lang/lt.rs
- src/lang/eo.rs
🚧 Files skipped from review as they are similar to previous changes (19)
- src/lang/th.rs
- src/core_main.rs
- src/lang/tr.rs
- src/lang/vi.rs
- src/lang/fa.rs
- src/lang/kz.rs
- src/lang/be.rs
- src/lang/es.rs
- src/lang/ro.rs
- src/lang/et.rs
- src/lang/sv.rs
- src/lang/id.rs
- src/lang/eu.rs
- src/lang/ml.rs
- src/lang/it.rs
- src/lang/fr.rs
- src/ui_interface.rs
- src/lang/ru.rs
- src/lang/de.rs
Signed-off-by: 21pages <sunboeasy@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
flutter/lib/mobile/widgets/deploy_dialog.dart (1)
65-69: 💤 Low valueRedundant
toString()on aString.
resis already aString, sores.toString()is a no-op; passresdirectly.♻️ Proposed tweak
- errorText = translate(res.toString()); + errorText = translate(res);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@flutter/lib/mobile/widgets/deploy_dialog.dart` around lines 65 - 69, Redundant toString() on a String: in the setState block where errorText is assigned, replace translate(res.toString()) with translate(res) and keep isInProgress = false unchanged. Update only the assignment to errorText, using the existing variables res, errorText, isInProgress, and the translate() call for easy location.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@flutter/lib/mobile/widgets/deploy_dialog.dart`:
- Around line 30-35: showDeployDialog creates TextEditingController instances
(tokenController, idController) but never disposes them, leaking resources;
update showDeployDialog to dispose both controllers after the dialog completes
by awaiting the dialog future and calling tokenController.dispose() and
idController.dispose() in a finally/whenComplete block so disposal happens
whether the dialog was accepted or cancelled; reference tokenController,
idController and the show dialog call inside showDeployDialog to locate where to
await the future and run the disposals.
---
Nitpick comments:
In `@flutter/lib/mobile/widgets/deploy_dialog.dart`:
- Around line 65-69: Redundant toString() on a String: in the setState block
where errorText is assigned, replace translate(res.toString()) with
translate(res) and keep isInProgress = false unchanged. Update only the
assignment to errorText, using the existing variables res, errorText,
isInProgress, and the translate() call for easy location.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 41491f49-051c-4b6a-97b9-ccb80c715841
📒 Files selected for processing (3)
flutter/lib/main.dartflutter/lib/mobile/pages/settings_page.dartflutter/lib/mobile/widgets/deploy_dialog.dart
Signed-off-by: 21pages <sunboeasy@gmail.com>
…5633) `rustdesk --deploy --id ""` (e.g. an unset variable in a deployment script) deploys a blank id, then wipes the local id and unconfirms the key through the IPC config write. The Android deploy flow already guards an empty id (#15146); apply the same guard to the CLI, and reject an empty id at the IPC write boundary the same way the read path was fixed in #15626.
Notify the Android Flutter UI when the server requires deployment, and show the Deploy menu in Settings.
Testing
ID_TAKEN, request failures, missing token, and custom ID deployment.Summary by CodeRabbit
New Features
Localization