CVE-2024-31312 AI-generated analysis
platform/frameworks/base, SystemUI media controls (packages/SystemUI/src/com/android/systemui/media/controls/ui)
Moves enforcement of the Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN user setting from the keyguard-only KeyguardMediaController into MediaHierarchyManager/MediaHost so that, when the setting is disabled, every media host hides the media carousel while the device is in the KEYGUARD or SHADE_LOCKED state.
Root cause
Before the fix, the MEDIA_CONTROLS_LOCK_SCREEN setting was read and observed inside KeyguardMediaController. Its allowMediaPlayerOnLockScreen flag was consulted only in KeyguardMediaController's visibility computation for the media container in the keyguard layout. MediaHierarchyManager kept its own allowMediaPlayerOnLockScreen field, hard-initialised to true and updated by a content observer, but MediaHost.updateViewVisibility did not consult it: a host's visibility depended only on whether active or any media (or a recommendation) existed. As a result, when the user disabled media controls on the lock screen, the carousel was hidden only in the keyguard layout and not everywhere while the device was on the lockscreen (per the commit message).
How the fix works
- MediaHierarchyManager.kt: allowMediaPlayerOnLockScreen is now initialised from a new private helper getMediaLockScreenSetting() (secureSettings.getBoolForUser(MEDIA_CONTROLS_LOCK_SCREEN, true, USER_CURRENT)) instead of a hard-coded true.
- MediaHierarchyManager.kt: a new public fun isLockedAndHidden() returns true when !allowMediaPlayerOnLockScreen and statusbarState is StatusBarState.SHADE_LOCKED or StatusBarState.KEYGUARD.
- MediaHost.kt:updateViewVisibility: state.visible is forced to false when mediaHierarchyManager.isLockedAndHidden() is true. This check runs before the existing showsOnlyActiveMedia / hasActiveMediaOrRecommendation / hasAnyMediaOrRecommendation logic. hostView.visibility then becomes GONE and visibleChangedListeners are notified if the visibility changed. This applies to every MediaHost, not only the keyguard one.
- MediaHierarchyManager.kt: in the status bar state callback, mediaCarouselController.updateHostVisibility() is now called after updateUserVisibility(), so all hosts recompute visibility on state changes. The tests exercise this through onStateChanged. The content observer for lockScreenMediaPlayerUri now updates allowMediaPlayerOnLockScreen via getMediaLockScreenSetting() and also calls mediaCarouselController.updateHostVisibility().
- KeyguardMediaController.kt: removes the setting read, the ContentObserver registration, the allowMediaPlayerOnLockScreen field, lockScreenMediaPlayerUri, and the SecureSettings and @Main Handler constructor parameters. Its visibility condition no longer checks allowMediaPlayerOnLockScreen and relies on mediaHost.visible, which now reflects isLockedAndHidden().
- Tests: KeyguardMediaControllerTest drops the two setting-based tests and the FakeSettings/FakeHandler constructor args. MediaHierarchyManagerTest adds keyguardState_allowedOnLockscreen_updateVisibility, keyguardState_notAllowedOnLockscreen_updateVisibility, keyguardGone_updateVisibility and lockscreenSettingChanged_updateVisibility, and stubs mediaCarouselController.updateHostVisibility.
Completeness
- The check is centralised in MediaHost.updateViewVisibility, so it covers every MediaHost whose visibility is refreshed through that method, including via the mediaCarouselController.updateHostVisibility lambda that iterates over all registered mediaHosts.
- isLockedAndHidden() treats only StatusBarState.KEYGUARD and StatusBarState.SHADE_LOCKED as locked, and it relies on MediaHierarchyManager.statusbarState being kept current. The material does not show whether other locked surfaces (for example the dream overlay) report one of these states.
- Host visibility is recomputed on status bar state changes and on setting changes. Any other trigger that calls updateViewVisibility also goes through the check.
- The KeyguardMediaController visibility condition still uses mediaHost.visible, which now includes the lock check indirectly.
Behavior changes
- When MEDIA_CONTROLS_LOCK_SCREEN is disabled and the device is in KEYGUARD or SHADE_LOCKED, all media host views become GONE, not only the keyguard layout container. Outside those states, visibility goes back to the existing media-availability logic.
- MediaHierarchyManager now reads the setting at construction instead of assuming true until the observer fires.
- mediaCarouselController.updateHostVisibility() is now invoked on status bar state changes and on every change of the MEDIA_CONTROLS_LOCK_SCREEN setting.
- The KeyguardMediaController constructor signature changed: the SecureSettings and @Main Handler parameters were removed. This affects Dagger injection and any code or tests that construct it directly.
Per major
- Android 14: same fix: commit 76d298d2e82c in android-security-14.0.0_r9 (cherry-pick of a441f4acd62c, Change-Id I4f618e4013db894291e6fca9d49bceb1cb7e4bd9); at android-security-14.0.0_r29, 8/8 lines of the patched region are present.
- Android 15: not affected per the bulletin; the three patched files are absent at these paths in android-security-15.0.0_r17.
- Android 16: not affected per the bulletin; the patched files are absent at these paths in android-security-16.0.0_r8.
- Android 17: not affected per the bulletin; the patched files are absent at these paths in android-security-17.0.0_r1.
Unknowns
- Which specific surface or host showed media content on the lockscreen in the original report (bug 314333719 is not described beyond the commit message), for example whether QS/QQS hosts in SHADE_LOCKED were involved.
- Whether and how the fix was applied to Android 12, 12L and 13, which the bulletin lists as affected; no commits for those branches are in the material.
- Where the equivalent logic lives in Android 15+ (if anywhere), and whether it carries the same check.