CVE-2026-28650 AI-generated analysis
platform/frameworks/base, WindowManager (services/core/java/com/android/server/wm/WindowState.java)
WindowState.setHiddenWhileSuspended now checks the window's base type (getBaseType()) instead of its own mAttrs.type. As a result, sub-windows whose top parent is a system alert window or toast of a suspended app are hidden, and later shown again, like their parent.
Root cause
setHiddenWhileSuspended used mAttrs.type in its early-return test `!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST`. For a sub-window (for example TYPE_APPLICATION_PANEL), mAttrs.type is a sub-window type. That type is neither a system alert window type nor TYPE_TOAST, so the method returned early and never called hide()/show(). As a result, when the owning package was suspended, a sub-window whose top parent is a system alert window (such as TYPE_APPLICATION_OVERLAY) was not hidden, while its parent overlay was. The sibling method setForceHideNonSystemOverlayWindowIfNeeded in the same file already used getBaseType() for the equivalent check.
How the fix works
- services/core/java/com/android/server/wm/WindowState.java:setHiddenWhileSuspended: adds `final int baseType = getBaseType();` and replaces both uses of mAttrs.type in the early-return condition with baseType, giving `!isSystemAlertWindowType(baseType) && baseType != TYPE_TOAST`. According to the commit message, this means a sub-window whose top parent is a system alert window now passes the check and is hidden/shown. The mOwnerCanAddInternalSystemWindow bypass and the mHiddenWhileSuspended state tracking are unchanged.
- services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java: adds testSubWindowHiddenWhenSuspended. The test creates a TYPE_APPLICATION_OVERLAY parent with a TYPE_APPLICATION_PANEL sub-window. It then verifies that setHiddenWhileSuspended(true) calls hide(true, true) on the sub-window and setHiddenWhileSuspended(false) calls show(true, true).
Completeness
- The added test covers a direct sub-window of a TYPE_APPLICATION_OVERLAY parent.
- The changed condition applies to both system alert window types and TYPE_TOAST as base type. Only the overlay case is tested.
- The fix is limited to setHiddenWhileSuspended. In the shown code, the neighbouring setForceHideNonSystemOverlayWindowIfNeeded already uses getBaseType(), so the material shows no similar unfixed pattern.
- Windows whose owner has mOwnerCanAddInternalSystemWindow are still exempt, as before. The fix does not change that policy.
Behavior changes
- Sub-windows (e.g. TYPE_APPLICATION_PANEL) owned by a package without internal-system-window rights, whose base type is a system alert window or toast, are now hidden when RootWindowContainer.updateHiddenWhileSuspendedState marks the package as suspended. They are shown again when the package is unsuspended.
- No new error codes or exceptions. Only the hide()/show() visibility outcome for these sub-windows changes.
Per major
- Android 14: same fix: commit ce479a9a57bd in android-security-14.0.0_r29. The test uses the createWindow(parent, type, name) helper.
- Android 15: same fix: commit 8130b6057817 in android-security-15.0.0_r17. The WindowState.java change and the test (createWindow helper) are identical to 14; only line offsets differ.
- Android 16: same fix: commit b61562e1abe6 in android-security-16.0.0_r8. The WindowState.java change is identical; only the test is adapted to the newWindowBuilder(...).setParent(parent).build() helper.
- Android 17: same fix: commit 236258a3e304 in android-security-17.0.0_r1. The WindowState.java change is identical; the test uses newWindowBuilder and is placed before testOverlayWindowHiddenWhenLockedByAppLock.
Unknowns
- The material does not describe the concrete security impact beyond the commit message's 'security concerns' and the bulletin's High/EoP rating.
- The material does not show how getBaseType() is implemented, so behaviour for sub-windows nested more than one level deep is not shown.
- The per-major facts report 6/7 patched-region lines present on 14/15/16 versus 7/7 on 17, even though the fix commits are in those tags. The material does not show which line differs.
- Fixes for the 16-qpr2 and 17-next branches listed in the bulletin are not shown.