Skip to content

Add the voice retention lock screen lapse Settings notice#25

Merged
MustafaNazeer merged 1 commit into
mainfrom
polish/voice-retention-lapsed-notice
Jun 12, 2026
Merged

Add the voice retention lock screen lapse Settings notice#25
MustafaNazeer merged 1 commit into
mainfrom
polish/voice-retention-lapsed-notice

Conversation

@MustafaNazeer

Copy link
Copy Markdown
Owner

What

Implements ADR 0006 Section 7 behavior (b), the one time Settings advisory that PR #24 (the opt in voice audio retention writer) shipped without and that Compliance Reviewer approved with revisions on the condition it be tracked as a follow up.

Why

The voice audio retention toggle is gated on the device having a lock screen credential (KeyguardManager.isDeviceSecure()). The retention writer already falls back to discard when the user opted in earlier but has since removed that credential. The missing piece was the user facing reconciliation: the toggle still read as on, and nothing told the user why their recordings were no longer being saved. This closes that gap.

Behavior

When a voice session starts with the toggle on but the device no longer secure:

  1. The persisted toggle is reconciled to off, so the Settings switch no longer reads as on when nothing is being saved.
  2. A one time pending flag is armed.
  3. The next time Settings opens, a non blocking advisory renders at the top of the screen and the flag clears, so it shows exactly once per lapse.

The advisory copy is the verbatim text ratified in docs/qa/compliance-reviews.md (PR #24 entry): "Audio saving was turned off because this phone no longer has a lock screen. Your voice tests are no longer being saved. To save them again, set a lock screen, then turn this setting back on."

Implementation

  • resolveVoiceRetentionDecision(saveAudioEnabled, deviceSecure) centralizes the session start gating decision into a pure function returning DISCARD, PERSIST, or DISCARD_LAPSED.
  • VoiceSettings gains the voice_retention_lapsed_notice_pending flag plus markRetentionLapsed, retentionLapsedNoticePending, and clearRetentionLapsedNotice helpers. The mark write flips the save audio toggle off in the same edit.
  • RootScreen.buildVoiceAudioRetention routes through the decision and marks the lapse on the DISCARD_LAPSED branch.
  • SettingsScreen reads the flag once, renders the advisory in a secondaryContainer surface, and clears the flag on display.

Testing

Built test first throughout. 10 new tests (3 decision, 4 settings prefs, 3 Settings render). Full suite: 483 passing, 0 failures, 4 skipped. ./gradlew :app:testDebugUnitTest green.

Notes

  • No new permissions; manifest unchanged.
  • Copy is the verbatim ratified text, so no new Patient Advocate copy decision is introduced.
  • Closes the v1.1 polish queue carryover for ADR 0006 Section 7 behavior (b).

Implements ADR 0006 Section 7 behavior (b), the one time Settings advisory
deferred from PR #24. When the voice audio retention toggle was left on but the
device lock screen credential has since been removed, the next voice session
reconciles the persisted toggle to off and arms a one time advisory that the
Settings screen surfaces once and then clears.

resolveVoiceRetentionDecision centralizes the session start gating decision
(discard, persist, or discard and flag the lapse). VoiceSettings gains the
voice_retention_lapsed_notice_pending flag with mark, read, and clear helpers.
RootScreen routes buildVoiceAudioRetention through the decision. The Settings
screen renders the ratified advisory copy in a secondary container surface and
clears the pending flag on display.

483 unit tests passing, 0 failures, 4 skipped.
@MustafaNazeer MustafaNazeer merged commit 2580f93 into main Jun 12, 2026
1 check passed
@MustafaNazeer MustafaNazeer deleted the polish/voice-retention-lapsed-notice branch June 12, 2026 02:54
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.

1 participant