Skip to content

Handle restore on reinstall sync scenario - #9368

Merged
MiSikora merged 2 commits into
developfrom
feature/mehow/simple-sync/recover-on-reinstall
Aug 4, 2026
Merged

Handle restore on reinstall sync scenario#9368
MiSikora merged 2 commits into
developfrom
feature/mehow/simple-sync/recover-on-reinstall

Conversation

@MiSikora

@MiSikora MiSikora commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Task/Issue URL: https://app.asana.com/1/137249556945/project/1216103556496795/task/1216422585541212?focus=true
Tech Design URL (if applicable): https://app.asana.com/1/137249556945/project/1216103556496795/task/1216509582049467?focus=true
API Proposals URL(s) (if applicable): N/A

Description

Adds the recover on reinstall step to the simplified Sync & Backup setup. When the app finds Sync & Backup recovery data preserved from a previous install, starting any sync setup from the simplified Sync Settings first offers to resume the previous session instead of starting from scratch.

  • A new screen titled "Your previous Sync & Backup session is ready." is shown after device authentication when the user taps the "Sync This Device" toggle, "Sync With Another Device", or "I Have a Recovery Code". It only appears when preserved recovery data exists in Block Store and the syncAutoRestore feature flag is enabled.
  • "Resume Sync & Backup" feeds the preserved recovery code into the existing recovery connection flow. On success, the recovery code confirmation screen opens and Sync Settings switches to the enabled state. The preserved recovery data is kept.
  • If the preserved data cannot be read, a generic error dialog is shown and the user stays on the screen.
  • If the recovery itself fails, the standard recovery error dialog is shown. Dismissing it returns to Sync Settings and the setup is treated as cancelled.
  • "Set Up New Sync" clears the preserved recovery data (the server account is untouched) and continues into whichever setup flow the user originally tapped: create account for "Sync This Device", the QR scanner for "Sync With Another Device", or the recovery screen for "I Have a Recovery Code". If clearing fails, an error dialog is shown and the original flow does not start.
  • Closing the screen with the close button or system back keeps the preserved data, so the offer appears again on the next setup attempt.

The screen reports its outcome through the new PreviousSessionReadyContract. A finished recovery is returned as a SyncPairingResult and handled by SyncActivity through the existing handlePairingResult, so completion behaves exactly like the manual recovery flow.

Steps to test this PR

Setup

  • Install the internal build on a device with Google Play services and a device lock set.
  • On another device signed into Sync & Backup, copy the recovery code.
  • On the test device, make sure sync is off.
  • Open Sync Dev Settings.
  • Paste the code into the "Recovery code" field in the "Persistent Storage / Block Store" section.
  • Tap "Write".

Resume the previous session

  • Open Sync Dev Settings.
  • Tap "Launch Sync Settings V2".
  • Tap "Sync With Another Device".
  • Complete the device authentication prompt.
  • Verify the "Your previous Sync & Backup session is ready." screen is shown.
  • Tap "Resume Sync & Backup".
  • Verify the connecting screen appears with the "Recovering data" headline.
  • Verify the recovery code screen opens with the headline "<this device's name> has been added to Sync & Backup".
  • Tap "Done".
  • Verify Sync Settings shows sync as enabled.
  • Verify in Sync Dev Settings that "Current stored value (SyncRecovery key)" still shows the stored payload.

Set up new sync instead

  • With sync off and a preserved session stored, open Sync Settings V2.
  • Turn on the "Sync This Device" toggle.
  • Complete the device authentication prompt.
  • Tap "Set Up New Sync".
  • Verify the Sync This Device screen opens.
  • Verify in Sync Dev Settings that "Current stored value (SyncRecovery key)" is now empty.

Dismiss the offer

  • With sync off and a preserved session stored, open Sync Settings V2.
  • Tap "I Have a Recovery Code".
  • Complete the device authentication prompt.
  • Tap the close button.
  • Verify you are back in Sync Settings with sync still off.
  • Tap "I Have a Recovery Code" again.
  • Complete the device authentication prompt.
  • Verify the previous session screen is shown again.

No preserved session

  • In Sync Dev Settings, tap "Clear" in the "Persistent Storage / Block Store" section.
  • Open Sync Settings V2.
  • Tap "Sync With Another Device".
  • Complete the device authentication prompt.
  • Verify the QR scanner opens directly without the previous session screen.

UI changes

image

Note

Medium Risk
Touches sync setup routing and recovery-code exchange after reinstall; mistakes could block setup or mishandle preserved credentials, though flows reuse existing pairing/recovery infrastructure and add tests.

Overview
When preserved Block Store recovery data exists and auto-restore is enabled, simplified Sync Settings now shows a previous session ready screen after device auth instead of jumping straight into setup.

Resume Sync & Backup returns the stored recovery code through PreviousSessionReadyContract and SyncActivity runs the existing ExchangeSyncCode recovery path, then the normal recovery-code completion flow. Set Up New Sync clears preserved local auto-restore data (server account unchanged) and continues the flow the user originally chose—sync this device, pair with another device, or manual recovery—via the newly implemented LaunchOriginalFlow handling. Dismissal leaves preserved data so the offer can appear again.

SyncActivityViewModel resets the “sync this device” in-progress UI if clearing preserved data fails on skip-restore. Adds screen layout, illustration, strings, and ViewModel tests for the new step.

Reviewed by Cursor Bugbot for commit fe4ce10. Bugbot is set up for automated code reviews on this repo. Configure here.

@MiSikora MiSikora mentioned this pull request Jul 31, 2026
20 tasks
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch 2 times, most recently from e1274a5 to 3055339 Compare July 31, 2026 18:23
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch 2 times, most recently from bf61bfc to f78c412 Compare July 31, 2026 18:52
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch from f78c412 to e589df0 Compare August 3, 2026 12:44
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/ship-review-feedback branch 2 times, most recently from 6863923 to 6867b7f Compare August 3, 2026 13:13
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch 2 times, most recently from 375a2b0 to ce5842d Compare August 3, 2026 16:30
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/ship-review-feedback branch from 6867b7f to 821c26d Compare August 3, 2026 16:30
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch from ce5842d to 9ba6eec Compare August 4, 2026 07:11
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/ship-review-feedback branch from 821c26d to b177968 Compare August 4, 2026 07:11

MiSikora commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Aug 4, 12:40 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 4, 1:11 PM UTC: The Graphite merge of this pull request was cancelled.
  • Aug 4, 1:39 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 4, 2:26 PM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 4, 2:40 PM UTC: @MiSikora merged this pull request with Graphite.

@MiSikora
MiSikora changed the base branch from feature/mehow/simple-sync/ship-review-feedback to graphite-base/9368 August 4, 2026 14:10
@MiSikora
MiSikora changed the base branch from graphite-base/9368 to develop August 4, 2026 14:25
@MiSikora
MiSikora force-pushed the feature/mehow/simple-sync/recover-on-reinstall branch from 9ba6eec to fe4ce10 Compare August 4, 2026 14:25

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fe4ce10. Configure here.

}
previousSessionReadyLauncher.launch(PreviousSessionReadyContract.Input(command.originalFlow))
},
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing onConnectionCancelled on auth cancel for non-SYNC_THIS_DEVICE flows

Low Severity

The ShowPreviousSessionReady handler calls viewModel.onConnectionCancelled() in the previousSessionReadyLauncher dismiss callback but omits it in the onCancelled and onError authentication callbacks. For the SYNC_THIS_DEVICE flow, onSyncThisDevice() calls syncSetupWideEvent.onFlowStarted(), so a subsequent onConnectionCancelled() (which fires syncSetupWideEvent.onFlowCancelled()) is needed to properly close the wide event. When auth is cancelled or errors, only onSyncThisDeviceCanceled() is called, leaving the wide event flow open without a matching cancellation signal.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fe4ce10. Configure here.

@MiSikora
MiSikora merged commit 0bfd737 into develop Aug 4, 2026
22 checks passed
@MiSikora
MiSikora deleted the feature/mehow/simple-sync/recover-on-reinstall branch August 4, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants