Repository navigation
Cover the UI with the boot splash when the app is backgrounded to prevent sensitive data exposure - #100590
Conversation
…vent sensitive data exposure
|
|
|
@OlGierd03 please assign me when the PR is ready to review |
ebcc04a to
ce784a3
Compare
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
| // Covers the UI with the boot splash while the app is leaving the foreground | ||
| public final class PrivacyCover { | ||
|
|
||
| private static final Map<Activity, BootSplashDialog> covers = new HashMap<>(); |
There was a problem hiding this comment.
why do we need multiple covers?
| @Deprecated("Deprecated in Java") | ||
| override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) { |
There was a problem hiding this comment.
Is it safe to use the deprecated method?
Explanation of Change
Mobile-Expensify repo counterpart: https://github.com/Expensify/Mobile-Expensify/pull/14105
Remediation of an audit finding (screenshots of the app UI persisted on disk by the OS). This PR covers the UI with the boot splash whenever the app is backgrounded, so the app-switcher snapshot the OS stores on disk only ever contains the splash or green screen as a fallback.
iOS: a
BootSplashstoryboard overlay is added insceneWillResignActive(after dismissing the keyboard, so it never appears in the snapshot) and removed insceneDidBecomeActive.Android:
setRecentsScreenshotEnabled(false)on every activity (including third-party ones like Plaid) guarantees nothing is written to disk, and theTaskDescriptionbackground color keeps the fallback recents card consistent with the splash. On top of that, aBootSplashDialogcovers our activity on window focus loss when leaving the app (tracked viaonTopResumedActivityChanged, so in-app dialogs don't trigger it) and isn't shown when we start another activity ourselves (Plaid, camera, pickers) or in multi-window. Third-party activities (e.g. Plaid) don't get the dialog, because their focus loss can't be told apart from their own popups or translucent screens, so their recents card is the plain green one.Important
On Android by design changes only apply to API levels of 33 or higher as discussed here
Fixed Issues
$ https://github.com/Expensify/Expensify/issues/633485
Tests
Note
When opening recents straight from a Plaid screen, its content stays visible while the screen animates into recents, but it's never written to disk, so the audit finding is still addressed. We can't do better because Android offers no reliable "leaving the app" signal for third-party activities: their focus loss looks the same as their own popups or translucent screens, so a cover would also flash over the country-code list and Plaid's next screens. Additionally, verify the splash isn't displayed when entering the flow, moving between Plaid screens or opening the country-code list.
Offline tests
N/A
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2026-10-16.at.12.16.28.mov
iOS: Native
Screen.Recording.2026-10-16.at.12.10.50.mov