Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9a364e6 authored by Michael Mikhail's avatar Michael Mikhail
Browse files

Add media on lock screen setting

Add a new setting that controls whether media on lock screen is enabled,
disregarding the notifications status. The new setting is available
under media and privacy settings.

Bug: 229915240
Test: atest MediaHierarchyManagerTest
Test: atest KeyguardMediaControllerTest
Change-Id: I6adaa00ead1660488e4114d303c4394751ff87e8
parent d935aba9
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -10590,6 +10590,13 @@ public final class Settings {
        @Readable
        @Readable
        public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
        public static final String MEDIA_CONTROLS_RESUME = "qs_media_resumption";
        /**
         * Whether to enable media controls on lock screen.
         * When enabled, media controls will appear on lock screen.
         * @hide
         */
        public static final String MEDIA_CONTROLS_LOCK_SCREEN = "media_controls_lock_screen";
        /**
        /**
         * Controls whether contextual suggestions can be shown in the media controls.
         * Controls whether contextual suggestions can be shown in the media controls.
         * @hide
         * @hide
+1 −0
Original line number Original line Diff line number Diff line
@@ -182,6 +182,7 @@ public class SecureSettings {
        Settings.Secure.PEOPLE_STRIP,
        Settings.Secure.PEOPLE_STRIP,
        Settings.Secure.MEDIA_CONTROLS_RESUME,
        Settings.Secure.MEDIA_CONTROLS_RESUME,
        Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION,
        Settings.Secure.MEDIA_CONTROLS_RECOMMENDATION,
        Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
        Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
        Settings.Secure.ACCESSIBILITY_MAGNIFICATION_CAPABILITY,
+1 −0
Original line number Original line Diff line number Diff line
@@ -277,6 +277,7 @@ public class SecureSettingsValidators {
        VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.PEOPLE_STRIP, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MEDIA_CONTROLS_RESUME, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MEDIA_CONTROLS_RECOMMENDATION, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MEDIA_CONTROLS_RECOMMENDATION, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.MEDIA_CONTROLS_LOCK_SCREEN, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
        VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_MODE,
                new InclusiveIntegerRangeValidator(
                new InclusiveIntegerRangeValidator(
                        Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
                        Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
+36 −4
Original line number Original line Diff line number Diff line
@@ -18,19 +18,25 @@ package com.android.systemui.media


import android.content.Context
import android.content.Context
import android.content.res.Configuration
import android.content.res.Configuration
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
import android.provider.Settings
import android.view.View
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.dagger.MediaModule.KEYGUARD
import com.android.systemui.media.dagger.MediaModule.KEYGUARD
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.MediaContainerView
import com.android.systemui.statusbar.notification.stack.MediaContainerView
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.settings.SecureSettings
import javax.inject.Inject
import javax.inject.Inject
import javax.inject.Named
import javax.inject.Named


@@ -43,9 +49,10 @@ class KeyguardMediaController @Inject constructor(
    @param:Named(KEYGUARD) private val mediaHost: MediaHost,
    @param:Named(KEYGUARD) private val mediaHost: MediaHost,
    private val bypassController: KeyguardBypassController,
    private val bypassController: KeyguardBypassController,
    private val statusBarStateController: SysuiStatusBarStateController,
    private val statusBarStateController: SysuiStatusBarStateController,
    private val notifLockscreenUserManager: NotificationLockscreenUserManager,
    private val context: Context,
    private val context: Context,
    configurationController: ConfigurationController
    private val secureSettings: SecureSettings,
    @Main private val handler: Handler,
    configurationController: ConfigurationController,
) {
) {


    init {
    init {
@@ -60,6 +67,24 @@ class KeyguardMediaController @Inject constructor(
            }
            }
        })
        })


        val settingsObserver: ContentObserver = object : ContentObserver(handler) {
            override fun onChange(selfChange: Boolean, uri: Uri?) {
                if (uri == lockScreenMediaPlayerUri) {
                    allowMediaPlayerOnLockScreen =
                            secureSettings.getBoolForUser(
                                    Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
                                    true,
                                    UserHandle.USER_CURRENT
                            )
                    refreshMediaPosition()
                }
            }
        }
        secureSettings.registerContentObserverForUser(
                Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
                settingsObserver,
                UserHandle.USER_ALL)

        // First let's set the desired state that we want for this host
        // First let's set the desired state that we want for this host
        mediaHost.expansion = MediaHostState.EXPANDED
        mediaHost.expansion = MediaHostState.EXPANDED
        mediaHost.showsOnlyActiveMedia = true
        mediaHost.showsOnlyActiveMedia = true
@@ -100,6 +125,13 @@ class KeyguardMediaController @Inject constructor(
        private set
        private set
    private var splitShadeContainer: ViewGroup? = null
    private var splitShadeContainer: ViewGroup? = null


    /**
     * Track the media player setting status on lock screen.
     */
    private var allowMediaPlayerOnLockScreen: Boolean = true
    private val lockScreenMediaPlayerUri =
            secureSettings.getUriFor(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN)

    /**
    /**
     * Attaches media container in single pane mode, situated at the top of the notifications list
     * Attaches media container in single pane mode, situated at the top of the notifications list
     */
     */
@@ -164,7 +196,7 @@ class KeyguardMediaController @Inject constructor(
        visible = mediaHost.visible &&
        visible = mediaHost.visible &&
                !bypassController.bypassEnabled &&
                !bypassController.bypassEnabled &&
                keyguardOrUserSwitcher &&
                keyguardOrUserSwitcher &&
                notifLockscreenUserManager.shouldShowLockscreenNotifications()
                allowMediaPlayerOnLockScreen
        if (visible) {
        if (visible) {
            showMediaPlayer()
            showMediaPlayer()
        } else {
        } else {
+35 −5
Original line number Original line Diff line number Diff line
@@ -22,7 +22,12 @@ import android.animation.ValueAnimator
import android.annotation.IntDef
import android.annotation.IntDef
import android.content.Context
import android.content.Context
import android.content.res.Configuration
import android.content.res.Configuration
import android.database.ContentObserver
import android.graphics.Rect
import android.graphics.Rect
import android.net.Uri
import android.os.Handler
import android.os.UserHandle
import android.provider.Settings
import android.util.Log
import android.util.Log
import android.util.MathUtils
import android.util.MathUtils
import android.view.View
import android.view.View
@@ -33,12 +38,12 @@ import com.android.keyguard.KeyguardViewController
import com.android.systemui.R
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.dreams.DreamOverlayStateController
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.shade.NotifPanelEvents
import com.android.systemui.shade.NotifPanelEvents
import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.CrossFadeHelper
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
@@ -47,6 +52,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.LargeScreenUtils
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.animation.UniqueObjectHostView
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.traceSection
import com.android.systemui.util.traceSection
import javax.inject.Inject
import javax.inject.Inject


@@ -85,14 +91,22 @@ class MediaHierarchyManager @Inject constructor(
    private val keyguardStateController: KeyguardStateController,
    private val keyguardStateController: KeyguardStateController,
    private val bypassController: KeyguardBypassController,
    private val bypassController: KeyguardBypassController,
    private val mediaCarouselController: MediaCarouselController,
    private val mediaCarouselController: MediaCarouselController,
    private val notifLockscreenUserManager: NotificationLockscreenUserManager,
    private val keyguardViewController: KeyguardViewController,
    private val keyguardViewController: KeyguardViewController,
    private val dreamOverlayStateController: DreamOverlayStateController,
    private val dreamOverlayStateController: DreamOverlayStateController,
    configurationController: ConfigurationController,
    configurationController: ConfigurationController,
    wakefulnessLifecycle: WakefulnessLifecycle,
    wakefulnessLifecycle: WakefulnessLifecycle,
    panelEventsEvents: NotifPanelEvents,
    panelEventsEvents: NotifPanelEvents,
    private val secureSettings: SecureSettings,
    @Main private val handler: Handler,
) {
) {


    /**
     * Track the media player setting status on lock screen.
     */
    private var allowMediaPlayerOnLockScreen: Boolean = true
    private val lockScreenMediaPlayerUri =
            secureSettings.getUriFor(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN)

    /**
    /**
     * Whether we "skip" QQS during panel expansion.
     * Whether we "skip" QQS during panel expansion.
     *
     *
@@ -521,6 +535,23 @@ class MediaHierarchyManager @Inject constructor(
                updateDesiredLocation()
                updateDesiredLocation()
            }
            }
        })
        })

        val settingsObserver: ContentObserver = object : ContentObserver(handler) {
            override fun onChange(selfChange: Boolean, uri: Uri?) {
                if (uri == lockScreenMediaPlayerUri) {
                    allowMediaPlayerOnLockScreen =
                            secureSettings.getBoolForUser(
                                    Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
                                    true,
                                    UserHandle.USER_CURRENT
                            )
                }
            }
        }
        secureSettings.registerContentObserverForUser(
                Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN,
                settingsObserver,
                UserHandle.USER_ALL)
    }
    }


    private fun updateConfiguration() {
    private fun updateConfiguration() {
@@ -1036,7 +1067,6 @@ class MediaHierarchyManager @Inject constructor(
        }
        }
        val onLockscreen = (!bypassController.bypassEnabled &&
        val onLockscreen = (!bypassController.bypassEnabled &&
            (statusbarState == StatusBarState.KEYGUARD))
            (statusbarState == StatusBarState.KEYGUARD))
        val allowedOnLockscreen = notifLockscreenUserManager.shouldShowLockscreenNotifications()
        val location = when {
        val location = when {
            dreamOverlayActive -> LOCATION_DREAM_OVERLAY
            dreamOverlayActive -> LOCATION_DREAM_OVERLAY
            (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
            (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
@@ -1044,7 +1074,7 @@ class MediaHierarchyManager @Inject constructor(
            !hasActiveMedia -> LOCATION_QS
            !hasActiveMedia -> LOCATION_QS
            onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
            onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
            onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
            onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
            onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN
            onLockscreen && allowMediaPlayerOnLockScreen -> LOCATION_LOCKSCREEN
            else -> LOCATION_QQS
            else -> LOCATION_QQS
        }
        }
        // When we're on lock screen and the player is not active, we should keep it in QS.
        // When we're on lock screen and the player is not active, we should keep it in QS.
@@ -1116,7 +1146,7 @@ class MediaHierarchyManager @Inject constructor(
        return !statusBarStateController.isDozing &&
        return !statusBarStateController.isDozing &&
                !keyguardViewController.isBouncerShowing &&
                !keyguardViewController.isBouncerShowing &&
                statusBarStateController.state == StatusBarState.KEYGUARD &&
                statusBarStateController.state == StatusBarState.KEYGUARD &&
                notifLockscreenUserManager.shouldShowLockscreenNotifications() &&
                allowMediaPlayerOnLockScreen &&
                statusBarStateController.isExpanded &&
                statusBarStateController.isExpanded &&
                !qsExpanded
                !qsExpanded
    }
    }
Loading