CVE-2026-0005 AI-generated analysis
platform/frameworks/base, WindowManager lock task (LockTaskController / ActivityTaskManagerService) plus keyguard (SystemUI KeyguardViewMediator, system_server KeyguardServiceDelegate)
Adds IActivityTaskManager.rebuildSystemLockTaskPinnedMode() (gated by enforceTaskPermission) that re-applies the recents, task-change-listener, status bar and keyguard state of app pinned mode for the existing locked task, has SystemUI's KeyguardViewMediator call it when ATMS reports LOCK_TASK_MODE_PINNED, and makes KeyguardServiceDelegate keep the keyguard enabled flag across a keyguard service disconnect, so that the device stays in app pinned mode upon a SystemUI crash.
Root cause
In app pinned mode, LockTaskController keeps mLockTaskModeState == LOCK_TASK_MODE_PINNED and the task in mLockTaskModeTasks, and the restrictions (status bar via setStatusBarState, keyguard via setKeyguardState, recents and task-change notifications) are applied when the mode is entered (the tests show each called once by startLockTaskMode). Before the fix nothing re-applied them after a SystemUI crash while system_server still considered the device pinned. In addition, KeyguardServiceDelegate.onServiceDisconnected called mKeyguardState.reset() without preserving the enabled flag; the fix's save/restore implies the reset could lose a disabled keyguard state that onServiceConnected replays via `if (!mKeyguardState.enabled) setKeyguardEnabled(...)`.
How the fix works
- core/java/android/app/IActivityTaskManager.aidl: adds `void rebuildSystemLockTaskPinnedMode();` next to startSystemLockTaskMode/stopSystemLockTaskMode.
- services/core/java/com/android/server/wm/ActivityTaskManagerService.java:rebuildSystemLockTaskPinnedMode(): calls enforceTaskPermission("rebuildSystemLockTaskPinnedMode") (same gate as startSystemLockTaskMode/stopSystemLockTaskMode), clears the calling identity, and under mGlobalLock calls getLockTaskController().rebuildSystemLockTaskPinnedMode().
- services/core/java/com/android/server/wm/LockTaskController.java:rebuildSystemLockTaskPinnedMode(): returns (Slog.e) if mLockTaskModeState != LOCK_TASK_MODE_PINNED; returns (Slog.i) if mLockTaskModeTasks is empty; otherwise takes the first locked task, calls mSupervisor.mRecentTasks.onLockTaskModeStateChanged(LOCK_TASK_MODE_PINNED, task.mUserId) synchronously, then on mHandler calls IStatusBarService.showPinningEnterExitToast(true), mTaskChangeNotificationController.notifyLockTaskModeChanged(state), setStatusBarState(state, userId) and setKeyguardState(state, userId), reusing the existing locked task rather than starting a new lock task.
- packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java: right after the mBootSendUserPresent / sendUserPresentBroadcast() check, posts a runnable that queries getLockTaskModeState() and, if it equals LOCK_TASK_MODE_PINNED, calls rebuildSystemLockTaskPinnedMode(); RemoteException is logged.
- services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java:onServiceDisconnected(): saves mKeyguardState.enabled before mKeyguardState.reset() and restores it afterwards, so the flag is available to the existing `if (!mKeyguardState.enabled) mKeyguardService.setKeyguardEnabled(...)` replay in onServiceConnected.
- services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java: four new tests: empty task list, DONT_LOCK task and non-pinned mode are no-ops; pinned mode re-issues notifyLockTaskModeChanged, disableKeyguard, status bar disable/disable2 and RecentTasks.onLockTaskModeStateChanged a second time.
Completeness
- Covers only LOCK_TASK_MODE_PINNED: rebuildSystemLockTaskPinnedMode() returns for any other state, and KeyguardViewMediator only triggers it when getLockTaskModeState() == LOCK_TASK_MODE_PINNED. Full lock task mode (LOCK_TASK_MODE_LOCKED) is not rebuilt; whether it has the same exposure is not shown by the material.
- Only the first entry of mLockTaskModeTasks is used for the user id.
- The rebuild is triggered from one place only, the SystemUI KeyguardViewMediator call site; system_server's KeyguardServiceDelegate.onServiceDisconnected only preserves the enabled flag and re-asserts setLockScreenShown, it does not trigger the rebuild itself.
- The restrictions are re-applied asynchronously (SystemUI handler post, then LockTaskController mHandler post); the material does not quantify the window.
- The new handler runnable wraps a RemoteException in RuntimeException.
- The new binder method uses the same enforceTaskPermission gate as the existing system lock task entry points.
Behavior changes
- New hidden binder method IActivityTaskManager.rebuildSystemLockTaskPinnedMode(), guarded by enforceTaskPermission.
- When the rebuild runs while pinned, the screen pinning 'entering' toast is shown again, status bar / keyguard / recents state is re-applied, and task stack listeners receive another lock task mode change notification.
- KeyguardServiceDelegate preserves the keyguard enabled flag across a keyguard service disconnect.
- New log lines: Slog.e when rebuild is requested outside pinned mode, Slog.i when there are no locked tasks, Log.e in SystemUI if the rebuild binder call fails.
Per major
- Android 14: Same fix: 9ff1c081e9f7 in android-security-14.0.0_r25 (RESTRICT AUTOMERGE cherry-pick of 575845147cb4). KeyguardViewMediator uses ActivityTaskManager.getService(), LockTaskController uses mLockTaskModeTasks.get(0), tests use verifyNoInteractions(mSupervisor). Region fully present (8/8) at android-security-14.0.0_r29.
- Android 15: Adapted fix 08abd0bc0451 in android-security-15.0.0_r13: same production logic, but KeyguardViewMediator calls the mActivityTaskManagerService field (and adds an android.app.ActivityTaskManager import), LockTaskController uses mLockTaskModeTasks.getFirst(), and no-op tests use verify(mSupervisor, never()).mRecentTasks.onLockTaskModeStateChanged(...). Region fully present (8/8) at android-security-15.0.0_r17.
- Android 16: Adapted fix 92b109b60414 in android-security-16.0.0_r4, same shape as the Android 15 variant (mActivityTaskManagerService field, getFirst()). Region fully present (8/8) at android-security-16.0.0_r8.
- Android 17: Not affected per the bulletin (not listed); the patched region is present (8/8 lines) at android-security-17.0.0_r1.
Unknowns
- The enclosing method of the KeyguardViewMediator hunk and when it runs relative to a SystemUI restart are not shown.
- What KeyguardState.reset() sets `enabled` to is not shown.
- Whether full lock task mode (LOCK_TASK_MODE_LOCKED) loses restrictions after a SystemUI crash is not shown; the fix excludes it.
- Whether mLockTaskModeTasks can hold more than one task in pinned mode is not shown.
- The precise consequence the bulletin classifies as Information Disclosure is not described in the material.