CVE-2026-0048 AI-generated analysis
platform/frameworks/base, WindowManager (services/core/java/com/android/server/wm/WindowState.java)
WindowState.hide() now hides a force-hidden window (non-system overlay, suspended owner, app-op hidden, or permanently hidden) immediately when that window is already playing an exit animation, and cancels any in-progress animation, instead of letting the hide wait for the previous exit animation to finish.
Root cause
In WindowState.hide(boolean doAnimation, boolean requestAnim), when doAnimation was true the code only cleared doAnimation if !mToken.okToAnimate(). Per the commit message, if the window was already playing an exit animation, WSA#applyAnimationLocked skipped the hide animation and the hide waited for the previous exit animation to finish, which could take a long time. As a result, a window that policy had decided to hide (the commit's test uses an activity launched with the hide-overlay flag) stayed on screen during that time.
How the fix works
- services/core/java/com/android/server/wm/WindowState.java:hide(): inside the existing `if (doAnimation)` block, after the okToAnimate check, a new block runs when any of mForceHideNonSystemOverlayWindow, mHiddenWhileSuspended, !mAppOpVisibility or mPermanentlyHidden is set.
- If isAnimating() is true and mAnimatingExit is true, doAnimation is set to false, so `current` is taken from isLegacyPolicyVisibility() and the window is hidden immediately rather than through a hide animation.
- Whenever isAnimating() is true (exit animation or not), cancelAnimation() is called; for non-exit animations doAnimation remains true.
- Single commit, one file, 10 added lines; identical diff on all branches.
Completeness
- Covers only WindowState.hide() and only when one of the four policy-hide flags is set; hide() calls for other reasons with an in-progress exit animation keep the old behavior (whether that matters is not shown).
- Immediate hide (doAnimation=false) is applied only when mAnimatingExit is true; for other running animations the fix only calls cancelAnimation() and keeps doAnimation.
- The new block is inside `if (doAnimation)`, so callers that already pass doAnimation=false are unaffected.
- show() is not changed; per the surrounding context it already returns early for all four flags, so the fix addresses the hide side only.
- No test file is changed in the commit; the Test: line describes a manual scenario.
Behavior changes
- A window that is being force-hidden while playing an exit animation is hidden immediately with no hide animation.
- Any running animation on a window being hidden for those four policy reasons is cancelled via cancelAnimation(), which may cut short an exit or other animation.
- No new error codes or API changes.
Per major
- Android 14: same fix: platform/frameworks/base 7c5437456c5d in android-security-14.0.0_r28 (cherry-pick, Merged-In I218fcb6eabe0033646f8a99e75a05409ed12c19f); 4/4 patched lines present at android-security-14.0.0_r29.
- Android 15: same fix: c9bc382318dd in android-security-15.0.0_r16, identical diff at a different line offset; 4/4 lines present at android-security-15.0.0_r17.
- Android 16: same fix: 36a774d72399 in android-security-16.0.0_r7, identical diff; 4/4 lines present at android-security-16.0.0_r8.
- Android 17: same fix: 6ca1d6b26237 in android-17.0.0_r1, identical diff; 4/4 lines present at android-security-17.0.0_r1.
Unknowns
- Which callers of hide() with doAnimation=true were involved in the reported issue (the material shows no callers).
- Whether, for non-exit animations, the hide animation is now applied after cancelAnimation(); not shown.
- Whether cancelAnimation() on an exit-animating window has further side effects (e.g. completing removal of the window); not shown in the material.
- Original bug report details (bug 463364410) and exact user-visible impact beyond the bulletin's EoP/High rating.