CVE-2025-48626 AI-generated analysis
platform/packages/apps/Launcher3 (quickstep OverviewCommandHelper / SystemUiProxy) and platform/frameworks/base (SystemUI OverviewProxyService, ISystemUiProxy AIDL)
Launcher3's OverviewCommandHelper no longer launches the home activity directly via startActivity for the TYPE_HOME command; it asks SystemUI (new ISystemUiProxy.onKeyEvent) to send a KEYCODE_HOME key event so the press goes through the system's key handling.
Root cause
In quickstep/src/com/android/quickstep/OverviewCommandHelper.java, executeCommand handled cmd.type == TYPE_HOME by calling mService.startActivity(mOverviewComponentObserver.getHomeIntent()) on TouchInteractionService (the launcher process). This launched the home intent directly from Launcher3 instead of delivering a home key press to the system. Back, by contrast, was already routed through SystemUI: ISystemUiProxy.onBackPressed in OverviewProxyService calls sendEvent for ACTION_DOWN and ACTION_UP of KEYCODE_BACK. The fix suggests that the system's KEYCODE_HOME handling was meant to apply to home presses from the launcher-handled home button and was skipped.
How the fix works
- Commit 1 (frameworks/base a8a441b0eb62, A14): packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl adds `oneway void onKeyEvent(int keycode) = 60;` (Next id = 61) and rewords the onBackPressed doc to say it sends KEYCODE_BACK ACTION_DOWN followed by ACTION_UP.
- Commit 1: packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java implements onKeyEvent(int keycode). It wraps the work in verifyCallerAndClearCallingIdentityPostMain("onKeyEvent " + keyCodeToString(keycode), ...) and calls the existing sendEvent(KeyEvent.ACTION_DOWN, keycode) and then sendEvent(KeyEvent.ACTION_UP, keycode). onBackPressed() now just calls onKeyEvent(KEYCODE_BACK), so back and home share one path.
- Commit 2 (Launcher3 9f5688403e25, A14): quickstep/src/com/android/quickstep/SystemUiProxy.java adds a client-side onKeyEvent(int keycode) wrapper. When the SystemUI binder is non-null, it forwards to mSystemUiProxy.onKeyEvent(keycode) and logs any RemoteException.
- Commit 2: quickstep/src/com/android/quickstep/OverviewCommandHelper.java gains a SystemUiProxy constructor parameter and field (mSystemUiProxy). In executeCommand, the TYPE_HOME branch changes from mService.startActivity(mOverviewComponentObserver.getHomeIntent()) to mSystemUiProxy.onKeyEvent(KeyEvent.KEYCODE_HOME).
- Commit 2: quickstep/src/com/android/quickstep/TouchInteractionService.java onUserUnlocked passes SystemUiProxy.INSTANCE.get(this) to the new OverviewCommandHelper constructor.
- Net effect: a launcher-side home press becomes a KEYCODE_HOME down/up pair sent by SystemUI's sendEvent, instead of Launcher3 starting the home activity itself.
Completeness
- Covers only the TYPE_HOME command in OverviewCommandHelper.executeCommand, the single startActivity(getHomeIntent()) site touched by the diff. The material does not show whether other Launcher3 call sites start the home intent directly.
- The SystemUI-side onKeyEvent accepts any keycode from the proxy client, not just KEYCODE_HOME or KEYCODE_BACK. It is wrapped in the same verifyCallerAndClearCallingIdentityPostMain call as onBackPressed. What that check verifies is not shown.
- The A14 onKeyEvent has no displayId parameter. The displayId mentioned in the commit message exists only in the A16 variant: onKeyEvent(int keycode, int displayId), onBackEvent(KeyEvent, int displayId) and sendEvent(action, code, displayId).
- The commit message cites flag com.android.launcher3.home_button_uses_keycode_home, but the A14 and A15 Launcher3 diffs apply the change unconditionally, with no flag check in the patched code.
Behavior changes
- Home presses routed through OverviewCommandHelper TYPE_HOME are now delivered as a KEYCODE_HOME down/up pair via SystemUI instead of a direct startActivity of the home intent.
- SystemUI gets a new ISystemUiProxy binder method, onKeyEvent (transaction id 60). On A14, ids 52 to 59 are skipped. Id 60 matches the A16 variant.
- If the SystemUI proxy is not connected (mSystemUiProxy == null in Launcher3 SystemUiProxy), the TYPE_HOME command now does nothing instead of launching home. A RemoteException is logged and swallowed.
- onBackPressed in SystemUI now goes through the shared onKeyEvent path, with the log label "onKeyEvent KEYCODE_BACK". Its sendEvent calls are unchanged.
Per major
- Android 14: same fix (two commits): frameworks/base a8a441b0eb62 adds ISystemUiProxy.onKeyEvent(int keycode)=60 and OverviewProxyService.onKeyEvent; Launcher3 9f5688403e25 switches TYPE_HOME to mSystemUiProxy.onKeyEvent(KEYCODE_HOME). Landed in android-security-14.0.0_r24; 8/8 lines of the patched region present at android-security-14.0.0_r29.
- Android 15: adapted fix: Launcher3 db8146473259 in android-security-15.0.0_r12 makes the same TYPE_HOME change inside a switch statement (with ActiveGestureLog logging), plus SystemUiProxy.onKeyEvent and the TouchInteractionService constructor change. 8/8 lines present at android-security-15.0.0_r17. The frameworks/base counterpart for 15 is not shown in the material.
- Android 16: adapted fix: frameworks/base 9fb37191609f in android-security-16.0.0_r3 adds onKeyEvent(int keycode, int displayId)=60 and adds displayId to onBackEvent(KeyEvent, int) and to sendEvent in LauncherProxyService. Only 5/8 lines of the patched region are present at android-security-16.0.0_r8. The Launcher3 commit for 16 is not shown.
- Android 17: not affected (not listed by the bulletin); 6/8 lines of the patched region present at android-security-17.0.0_r1.
Unknowns
- Which system-level restriction on KEYCODE_HOME the direct startActivity bypassed (the material does not show the privilege gained).
- Where TYPE_HOME commands are produced (the home-button caller is not in the diff or the index results).
- The body of sendEvent and of verifyCallerAndClearCallingIdentityPostMain on A14 (which display the event targets, how it is injected, what the caller check enforces).
- The Android 13 fix commits, the frameworks/base commit for Android 15, and the Launcher3 commit for Android 16.
- Why only 5/8 (A16) and 6/8 (A17) lines of the patched region are present in the latest tags.