diff options
6 files changed, 309 insertions, 108 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt new file mode 100644 index 000000000000..189f38422dcb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt @@ -0,0 +1,61 @@ +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) +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt new file mode 100644 index 000000000000..01eb4446ea8e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt @@ -0,0 +1,120 @@ +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 + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt new file mode 100644 index 000000000000..00d3701a0cc7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt @@ -0,0 +1,86 @@ +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") + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt index 63ab3de14d24..b7d82c3e8f89 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt @@ -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, @@ -112,22 +113,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. */ @@ -140,12 +125,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. */ @@ -164,17 +143,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, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt index e2d6ae07fe70..562c97017862 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt @@ -93,24 +93,34 @@ 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( - statusBarStateController = statusbarStateController, - logger = logger, - keyguardBypassController = keyguardBypassController, - lockScreenUserManager = lockScreenUserManager, - falsingCollector = falsingCollector, - ambientState = ambientState, - mediaHierarchyManager = mediaHierarchyManager, - scrimController = scrimController, - depthController = depthController, - wakefulnessLifecycle = wakefulnessLifecycle, - context = context, - configurationController = configurationController, - falsingManager = falsingManager, - dumpManager = dumpManager, - splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller }, - singleShadeOverScrollerFactory = { singleShadeOverScroller } - ) + transitionController = + LockscreenShadeTransitionController( + statusBarStateController = statusbarStateController, + logger = logger, + keyguardBypassController = keyguardBypassController, + lockScreenUserManager = lockScreenUserManager, + falsingCollector = falsingCollector, + ambientState = ambientState, + mediaHierarchyManager = mediaHierarchyManager, + depthController = depthController, + wakefulnessLifecycle = wakefulnessLifecycle, + context = context, + configurationController = configurationController, + falsingManager = falsingManager, + dumpManager = dumpManager, + splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller }, + 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 diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt index 3a5d9ee16b0a..146b56e49e65 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt @@ -5,22 +5,22 @@ import android.content.res.Configuration /** Fake implementation of [ConfigurationController] for tests. */ class FakeConfigurationController : ConfigurationController { - private var listener: ConfigurationController.ConfigurationListener? = null + private var listeners = mutableListOf<ConfigurationController.ConfigurationListener>() override fun addCallback(listener: ConfigurationController.ConfigurationListener) { - this.listener = listener + listeners += listener } override fun removeCallback(listener: ConfigurationController.ConfigurationListener) { - this.listener = null + listeners -= listener } override fun onConfigurationChanged(newConfiguration: Configuration?) { - listener?.onConfigChanged(newConfiguration) + listeners.forEach { it.onConfigChanged(newConfiguration) } } override fun notifyThemeChanged() { - listener?.onThemeChanged() + listeners.forEach { it.onThemeChanged() } } fun notifyConfigurationChanged() { |