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

Commit f46a363f authored by Christian Göllner's avatar Christian Göllner
Browse files

LockscreenShadeTransitionController: extract logic of keyguard and scrims

The file size was starting to grow for this class, so started extracting
some of it.

Also implemented dumpable for the new classes for better tracking of state
in bug reports.

Bug: 227604286
Test: LockscreenShadeTransitionControllerTest.kt
Test: adb shell dumpsys activity service SystemUIService
Test: Manually
Change-Id: Iebd36726ebffdb9b6a37e742f69d7e5a80f25e6e
parent 9519e3c9
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar

import android.content.Context
import android.content.res.Configuration
import android.util.IndentingPrintWriter
import com.android.systemui.Dumpable
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import java.io.FileDescriptor
import java.io.PrintWriter

/** An abstract implementation of a class that controls the lockscreen to shade transition. */
abstract class AbstractLockscreenShadeTransitionController(
    protected val context: Context,
    configurationController: ConfigurationController,
    dumpManager: DumpManager
) : Dumpable {

    protected var useSplitShade = false

    /**
     * The amount of pixels that the user has dragged down during the shade transition on
     * lockscreen.
     */
    var dragDownAmount = 0f
        set(value) {
            if (value == field) {
                return
            }
            field = value
            onDragDownAmountChanged(value)
        }

    init {
        updateResourcesInternal()
        configurationController.addCallback(
            object : ConfigurationController.ConfigurationListener {
                override fun onConfigChanged(newConfig: Configuration?) {
                    updateResourcesInternal()
                }
            })
        @Suppress("LeakingThis")
        dumpManager.registerDumpable(this)
    }

    private fun updateResourcesInternal() {
        useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
        updateResources()
    }

    protected abstract fun updateResources()

    protected abstract fun onDragDownAmountChanged(dragDownAmount: Float)

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        dump(IndentingPrintWriter(pw, /* singleIndent= */ "  "))
    }

    abstract fun dump(pw: IndentingPrintWriter)
}
+120 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar

import android.content.Context
import android.util.IndentingPrintWriter
import android.util.MathUtils
import com.android.systemui.R
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.MediaHierarchyManager
import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.policy.ConfigurationController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject

/** Controls the lockscreen to shade transition for the keyguard elements. */
class LockscreenShadeKeyguardTransitionController
@AssistedInject
constructor(
    private val mediaHierarchyManager: MediaHierarchyManager,
    @Assisted private val notificationPanelController: NotificationPanelViewController,
    context: Context,
    configurationController: ConfigurationController,
    dumpManager: DumpManager
) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {

    /**
     * Distance that the full shade transition takes in order for the keyguard content on
     * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
     */
    private var alphaTransitionDistance = 0

    /**
     * Distance that the full shade transition takes in order for the keyguard elements to fully
     * translate into their final position
     */
    private var keyguardTransitionDistance = 0

    /** The amount of vertical offset for the keyguard during the full shade transition. */
    private var keyguardTransitionOffset = 0

    /** The amount of alpha that was last set on the keyguard elements. */
    private var alpha = 0f

    /** The latest progress [0,1] of the alpha transition. */
    private var alphaProgress = 0f

    /** The amount of alpha that was last set on the keyguard status bar. */
    private var statusBarAlpha = 0f

    /** The amount of translationY that was last set on the keyguard elements. */
    private var translationY = 0

    /** The latest progress [0,1] of the translationY progress. */
    private var translationYProgress = 0f

    override fun updateResources() {
        alphaTransitionDistance =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
        keyguardTransitionDistance =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_keyguard_transition_distance)
        keyguardTransitionOffset =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
    }

    override fun onDragDownAmountChanged(dragDownAmount: Float) {
        alphaProgress = MathUtils.saturate(dragDownAmount / alphaTransitionDistance)
        alpha = 1f - alphaProgress
        translationY = calculateKeyguardTranslationY(dragDownAmount)
        notificationPanelController.setKeyguardTransitionProgress(alpha, translationY)

        statusBarAlpha = if (useSplitShade) alpha else -1f
        notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
    }

    private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
        if (!useSplitShade) {
            return 0
        }
        // On split-shade, the translationY of the keyguard should stay in sync with the
        // translation of media.
        if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
            return mediaHierarchyManager.getGuidedTransformationTranslationY()
        }
        // When media is not showing, apply the default distance
        translationYProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
        val translationY = translationYProgress * keyguardTransitionOffset
        return translationY.toInt()
    }

    override fun dump(indentingPrintWriter: IndentingPrintWriter) {
        indentingPrintWriter.let {
            it.println("LockscreenShadeKeyguardTransitionController:")
            it.increaseIndent()
            it.println("Resources:")
            it.increaseIndent()
            it.println("alphaTransitionDistance: $alphaTransitionDistance")
            it.println("keyguardTransitionDistance: $keyguardTransitionDistance")
            it.println("keyguardTransitionOffset: $keyguardTransitionOffset")
            it.decreaseIndent()
            it.println("State:")
            it.increaseIndent()
            it.println("dragDownAmount: $dragDownAmount")
            it.println("alpha: $alpha")
            it.println("alphaProgress: $alphaProgress")
            it.println("statusBarAlpha: $statusBarAlpha")
            it.println("translationProgress: $translationYProgress")
            it.println("translationY: $translationY")
        }
    }

    @AssistedFactory
    fun interface Factory {
        fun create(
            notificationPanelController: NotificationPanelViewController
        ): LockscreenShadeKeyguardTransitionController
    }
}
+86 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar

import android.content.Context
import android.util.IndentingPrintWriter
import android.util.MathUtils
import com.android.systemui.R
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.ConfigurationController
import javax.inject.Inject

/** Controls the lockscreen to shade transition for scrims. */
class LockscreenShadeScrimTransitionController
@Inject
constructor(
    private val scrimController: ScrimController,
    context: Context,
    configurationController: ConfigurationController,
    dumpManager: DumpManager
) : AbstractLockscreenShadeTransitionController(context, configurationController, dumpManager) {

    /**
     * Distance that the full shade transition takes in order for scrim to fully transition to the
     * shade (in alpha)
     */
    private var scrimTransitionDistance = 0

    /** Distance it takes in order for the notifications scrim fade in to start. */
    private var notificationsScrimTransitionDelay = 0

    /** Distance it takes for the notifications scrim to fully fade if after it started. */
    private var notificationsScrimTransitionDistance = 0

    /** The latest progress [0,1] the scrims transition. */
    var scrimProgress = 0f

    /** The latest progress [0,1] specifically of the notifications scrim transition. */
    var notificationsScrimProgress = 0f

    /**
     * The last drag amount specifically for the notifications scrim. It is different to the normal
     * [dragDownAmount] as the notifications scrim transition starts relative to the other scrims'
     * progress.
     */
    var notificationsScrimDragAmount = 0f

    override fun updateResources() {
        scrimTransitionDistance =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_scrim_transition_distance)
        notificationsScrimTransitionDelay =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
        notificationsScrimTransitionDistance =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
    }

    override fun onDragDownAmountChanged(dragDownAmount: Float) {
        scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
        notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
        notificationsScrimProgress =
            MathUtils.saturate(notificationsScrimDragAmount / notificationsScrimTransitionDistance)
        scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
    }

    override fun dump(indentingPrintWriter: IndentingPrintWriter) {
        indentingPrintWriter.let {
            it.println("LockscreenShadeScrimTransitionController:")
            it.increaseIndent()
            it.println("Resources:")
            it.increaseIndent()
            it.println("scrimTransitionDistance: $scrimTransitionDistance")
            it.println("notificationsScrimTransitionDelay: $notificationsScrimTransitionDelay")
            it.println(
                "notificationsScrimTransitionDistance: $notificationsScrimTransitionDistance")
            it.decreaseIndent()
            it.println("State")
            it.increaseIndent()
            it.println("dragDownAmount: $dragDownAmount")
            it.println("scrimProgress: $scrimProgress")
            it.println("notificationsScrimProgress: $notificationsScrimProgress")
            it.println("notificationsScrimDragAmount: $notificationsScrimDragAmount")
        }
    }
}
+9 −85
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import java.io.FileDescriptor
@@ -61,7 +60,9 @@ class LockscreenShadeTransitionController @Inject constructor(
    private val falsingCollector: FalsingCollector,
    private val ambientState: AmbientState,
    private val mediaHierarchyManager: MediaHierarchyManager,
    private val scrimController: ScrimController,
    private val scrimTransitionController: LockscreenShadeScrimTransitionController,
    private val keyguardTransitionControllerFactory:
        LockscreenShadeKeyguardTransitionController.Factory,
    private val depthController: NotificationShadeDepthController,
    private val context: Context,
    private val splitShadeOverScrollerFactory: SplitShadeLockScreenOverScroller.Factory,
@@ -111,22 +112,6 @@ class LockscreenShadeTransitionController @Inject constructor(
     */
    private var fullTransitionDistanceByTap = 0

    /**
     * Distance that the full shade transition takes in order for scrim to fully transition to the
     * shade (in alpha)
     */
    private var scrimTransitionDistance = 0

    /**
     * Distance that it takes in order for the notifications scrim fade in to start.
     */
    private var notificationsScrimTransitionDelay = 0

    /**
     * Distance that it takes for the notifications scrim to fully fade if after it started.
     */
    private var notificationsScrimTransitionDistance = 0

    /**
     * Distance that the full shade transition takes in order for the notification shelf to fully
     * expand.
@@ -139,12 +124,6 @@ class LockscreenShadeTransitionController @Inject constructor(
     */
    private var qsTransitionDistance = 0

    /**
     * Distance that the full shade transition takes in order for the keyguard content on
     * NotificationPanelViewController to fully fade (e.g. Clock & Smartspace).
     */
    private var npvcKeyguardContentAlphaTransitionDistance = 0

    /**
     * Distance that the full shade transition takes in order for depth of the wallpaper to fully
     * change.
@@ -163,17 +142,6 @@ class LockscreenShadeTransitionController @Inject constructor(
     */
    private var statusBarTransitionDistance = 0

    /**
     * Distance that the full shade transition takes in order for the keyguard elements to fully
     * translate into their final position
     */
    private var keyguardTransitionDistance = 0

    /**
     * The amount of vertical offset for the keyguard during the full shade transition.
     */
    private var keyguardTransitionOffset = 0

    /**
     * Flag to make sure that the dragDownAmount is applied to the listeners even when in the
     * locked down shade.
@@ -215,6 +183,10 @@ class LockscreenShadeTransitionController @Inject constructor(
        singleShadeOverScrollerFactory.create(nsslController)
    }

    private val keyguardTransitionController by lazy {
        keyguardTransitionControllerFactory.create(notificationPanelController)
    }

    /**
     * [LockScreenShadeOverScroller] property that delegates to either
     * [SingleShadeLockScreenOverScroller] or [SplitShadeLockScreenOverScroller].
@@ -267,18 +239,10 @@ class LockscreenShadeTransitionController @Inject constructor(
                R.dimen.lockscreen_shade_full_transition_distance)
        fullTransitionDistanceByTap = context.resources.getDimensionPixelSize(
            R.dimen.lockscreen_shade_transition_by_tap_distance)
        scrimTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_scrim_transition_distance)
        notificationsScrimTransitionDelay = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_notifications_scrim_transition_delay)
        notificationsScrimTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_notifications_scrim_transition_distance)
        notificationShelfTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_notif_shelf_transition_distance)
        qsTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_qs_transition_distance)
        npvcKeyguardContentAlphaTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
        depthControllerTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_depth_controller_transition_distance)
        udfpsTransitionDistance = context.resources.getDimensionPixelSize(
@@ -286,10 +250,6 @@ class LockscreenShadeTransitionController @Inject constructor(
        statusBarTransitionDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_status_bar_transition_distance)
        useSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(context.resources)
        keyguardTransitionDistance = context.resources.getDimensionPixelSize(
            R.dimen.lockscreen_shade_keyguard_transition_distance)
        keyguardTransitionOffset = context.resources.getDimensionPixelSize(
            R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
    }

    fun setStackScroller(nsslController: NotificationStackScrollLayoutController) {
@@ -457,9 +417,9 @@ class LockscreenShadeTransitionController @Inject constructor(
                            false /* animate */, 0 /* delay */)

                    mediaHierarchyManager.setTransitionToFullShadeAmount(field)
                    transitionToShadeAmountScrim(field)
                    scrimTransitionController.dragDownAmount = value
                    transitionToShadeAmountCommon(field)
                    transitionToShadeAmountKeyguard(field)
                    keyguardTransitionController.dragDownAmount = value
                    shadeOverScroller.expansionDragDownAmount = dragDownAmount
                }
            }
@@ -471,14 +431,6 @@ class LockscreenShadeTransitionController @Inject constructor(
    var qSDragProgress = 0f
        private set

    private fun transitionToShadeAmountScrim(dragDownAmount: Float) {
        val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
        val notificationsScrimDragAmount = dragDownAmount - notificationsScrimTransitionDelay
        val notificationsScrimProgress = MathUtils.saturate(
                notificationsScrimDragAmount / notificationsScrimTransitionDistance)
        scrimController.setTransitionToFullShadeProgress(scrimProgress, notificationsScrimProgress)
    }

    private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
        if (depthControllerTransitionDistance == 0) { // split shade
            depthController.transitionToFullShadeProgress = 0f
@@ -495,34 +447,6 @@ class LockscreenShadeTransitionController @Inject constructor(
        centralSurfaces.setTransitionToFullShadeProgress(statusBarProgress)
    }

    private fun transitionToShadeAmountKeyguard(dragDownAmount: Float) {
        // Fade out all content only visible on the lockscreen
        val keyguardAlphaProgress =
            MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
        val keyguardAlpha = 1f - keyguardAlphaProgress
        val keyguardTranslationY = calculateKeyguardTranslationY(dragDownAmount)
        notificationPanelController
            .setKeyguardTransitionProgress(keyguardAlpha, keyguardTranslationY)

        val statusBarAlpha = if (useSplitShade) keyguardAlpha else -1f
        notificationPanelController.setKeyguardStatusBarAlpha(statusBarAlpha)
    }

    private fun calculateKeyguardTranslationY(dragDownAmount: Float): Int {
        if (!useSplitShade) {
            return 0
        }
        // On split-shade, the translationY of the keyguard should stay in sync with the
        // translation of media.
        if (mediaHierarchyManager.isCurrentlyInGuidedTransformation()) {
            return mediaHierarchyManager.getGuidedTransformationTranslationY()
        }
        // When media is not showing, apply the default distance
        val translationProgress = MathUtils.saturate(dragDownAmount / keyguardTransitionDistance)
        val translationY = translationProgress * keyguardTransitionOffset
        return translationY.toInt()
    }

    private fun setDragDownAmountAnimated(
        target: Float,
        delay: Long = 0,
+28 −18
Original line number Diff line number Diff line
@@ -93,7 +93,8 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
                .addOverride(R.bool.config_use_split_notification_shade, false)
        context.getOrCreateTestableResources()
            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
        transitionController = LockscreenShadeTransitionController(
        transitionController =
            LockscreenShadeTransitionController(
                statusBarStateController = statusbarStateController,
                logger = logger,
                keyguardBypassController = keyguardBypassController,
@@ -101,7 +102,6 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
                falsingCollector = falsingCollector,
                ambientState = ambientState,
                mediaHierarchyManager = mediaHierarchyManager,
            scrimController = scrimController,
                depthController = depthController,
                wakefulnessLifecycle = wakefulnessLifecycle,
                context = context,
@@ -109,8 +109,18 @@ class LockscreenShadeTransitionControllerTest : SysuiTestCase() {
                falsingManager = falsingManager,
                dumpManager = dumpManager,
                splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
            singleShadeOverScrollerFactory = { singleShadeOverScroller }
        )
                singleShadeOverScrollerFactory = { singleShadeOverScroller },
                scrimTransitionController =
                LockscreenShadeScrimTransitionController(
                    scrimController, context, configurationController, dumpManager),
                keyguardTransitionControllerFactory = { notificationPanelController ->
                    LockscreenShadeKeyguardTransitionController(
                        mediaHierarchyManager,
                        notificationPanelController,
                        context,
                        configurationController,
                        dumpManager)
                })
        whenever(nsslController.view).thenReturn(stackscroller)
        whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
        transitionController.notificationPanelController = notificationPanelController
Loading