[Split shade][Motion] Fix scrim not being fully opaque after shade expansion

When using fling to expand the shade, the scrim was not at full opacity
at the end of the shade expansion.

This is because we are using a custom expansion fraction for split shade,
instead of reading the fraction provided by PanelViewController.

The fix is to only use the custom fraction during the expansion transition,
and when a completed transition is detected, use the default fraction.

Test: Manually
Test: ShadeTransitionControllerTest.kt
Test: ScrimShadeTransitionControllerTest.kt
Fixes: 237101056
Change-Id: Ifa87309347d501aeb293d6e2f01d537943996b4b
This commit is contained in:
Christian Göllner
2022-06-28 17:50:09 +02:00
parent 7341405aa1
commit 39d63e5197
5 changed files with 105 additions and 36 deletions

View File

@@ -20,6 +20,7 @@ import android.annotation.IntDef
import android.util.Log
import androidx.annotation.FloatRange
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.util.Compile
import javax.inject.Inject
/**
@@ -109,8 +110,8 @@ class PanelExpansionStateManager @Inject constructor() {
debugLog(
"panelExpansionChanged:" +
"start state=${oldState.stateToString()} " +
"end state=${state.stateToString()} " +
"start state=${oldState.panelStateToString()} " +
"end state=${state.panelStateToString()} " +
"f=$fraction " +
"expanded=$expanded " +
"tracking=$tracking" +
@@ -126,14 +127,15 @@ class PanelExpansionStateManager @Inject constructor() {
/** Updates the panel state if necessary. */
fun updateState(@PanelState state: Int) {
debugLog("update state: ${this.state.stateToString()} -> ${state.stateToString()}")
debugLog(
"update state: ${this.state.panelStateToString()} -> ${state.panelStateToString()}")
if (this.state != state) {
updateStateInternal(state)
}
}
private fun updateStateInternal(@PanelState state: Int) {
debugLog("go state: ${this.state.stateToString()} -> ${state.stateToString()}")
debugLog("go state: ${this.state.panelStateToString()} -> ${state.panelStateToString()}")
this.state = state
stateListeners.forEach { it.onPanelStateChanged(state) }
}
@@ -154,7 +156,7 @@ const val STATE_OPENING = 1
const val STATE_OPEN = 2
@PanelState
private fun Int.stateToString(): String {
fun Int.panelStateToString(): String {
return when (this) {
STATE_CLOSED -> "CLOSED"
STATE_OPENING -> "OPENING"
@@ -163,5 +165,5 @@ private fun Int.stateToString(): String {
}
}
private const val DEBUG = false
private val TAG = PanelExpansionStateManager::class.simpleName
private val DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG)

View File

@@ -11,6 +11,8 @@ import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.PanelState
import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.LargeScreenUtils
import java.io.PrintWriter
@@ -30,8 +32,9 @@ constructor(
private var inSplitShade = false
private var splitShadeScrimTransitionDistance = 0
private var lastExpansionFraction: Float = 0f
private var lastExpansionFraction: Float? = null
private var lastExpansionEvent: PanelExpansionChangeEvent? = null
private var currentPanelState: Int? = null
init {
updateResources()
@@ -41,8 +44,8 @@ constructor(
updateResources()
}
})
dumpManager
.registerDumpable(ScrimShadeTransitionController::class.java.simpleName, this::dump)
dumpManager.registerDumpable(
ScrimShadeTransitionController::class.java.simpleName, this::dump)
}
private fun updateResources() {
@@ -51,21 +54,38 @@ constructor(
resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
}
fun onPanelExpansionChanged(panelExpansionChangeEvent: PanelExpansionChangeEvent) {
val expansionFraction = calculateScrimExpansionFraction(panelExpansionChangeEvent)
scrimController.setRawPanelExpansionFraction(expansionFraction)
lastExpansionFraction = expansionFraction
lastExpansionEvent = panelExpansionChangeEvent
fun onPanelStateChanged(@PanelState state: Int) {
currentPanelState = state
onStateChanged()
}
private fun calculateScrimExpansionFraction(expansionEvent: PanelExpansionChangeEvent): Float {
return if (inSplitShade && isScreenUnlocked()) {
fun onPanelExpansionChanged(panelExpansionChangeEvent: PanelExpansionChangeEvent) {
lastExpansionEvent = panelExpansionChangeEvent
onStateChanged()
}
private fun onStateChanged() {
val expansionEvent = lastExpansionEvent ?: return
val panelState = currentPanelState
val expansionFraction = calculateScrimExpansionFraction(expansionEvent, panelState)
scrimController.setRawPanelExpansionFraction(expansionFraction)
lastExpansionFraction = expansionFraction
}
private fun calculateScrimExpansionFraction(
expansionEvent: PanelExpansionChangeEvent,
@PanelState panelState: Int?
): Float {
return if (canUseCustomFraction(panelState)) {
constrain(expansionEvent.dragDownPxAmount / splitShadeScrimTransitionDistance, 0f, 1f)
} else {
expansionEvent.fraction
}
}
private fun canUseCustomFraction(panelState: Int?) =
inSplitShade && isScreenUnlocked() && panelState == STATE_OPENING
private fun isScreenUnlocked() =
statusBarStateController.currentOrUpcomingState == StatusBarState.SHADE
@@ -78,9 +98,9 @@ constructor(
isScreenUnlocked: ${isScreenUnlocked()}
splitShadeScrimTransitionDistance: $splitShadeScrimTransitionDistance
State:
currentPanelState: $currentPanelState
lastExpansionFraction: $lastExpansionFraction
lastExpansionEvent: $lastExpansionEvent
""".trimIndent()
)
""".trimIndent())
}
}

View File

@@ -11,6 +11,7 @@ import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
import com.android.systemui.statusbar.phone.panelstate.PanelState
import com.android.systemui.statusbar.phone.panelstate.panelStateToString
import com.android.systemui.statusbar.policy.ConfigurationController
import java.io.PrintWriter
import javax.inject.Inject
@@ -34,6 +35,8 @@ constructor(
lateinit var qs: QS
private var inSplitShade = false
private var currentPanelState: Int? = null
private var lastPanelExpansionChangeEvent: PanelExpansionChangeEvent? = null
private val splitShadeOverScroller by lazy {
splitShadeOverScrollerFactory.create({ qs }, { notificationStackScrollLayoutController })
@@ -66,10 +69,13 @@ constructor(
}
private fun onPanelStateChanged(@PanelState state: Int) {
currentPanelState = state
shadeOverScroller.onPanelStateChanged(state)
scrimShadeTransitionController.onPanelStateChanged(state)
}
private fun onPanelExpansionChanged(event: PanelExpansionChangeEvent) {
lastPanelExpansionChangeEvent = event
shadeOverScroller.onDragDownAmountChanged(event.dragDownPxAmount)
scrimShadeTransitionController.onPanelExpansionChanged(event)
}
@@ -84,6 +90,8 @@ constructor(
"""
ShadeTransitionController:
inSplitShade: $inSplitShade
currentPanelState: ${currentPanelState?.panelStateToString()}
lastPanelExpansionChangeEvent: $lastPanelExpansionChangeEvent
qs.isInitialized: ${this::qs.isInitialized}
npvc.isInitialized: ${this::notificationPanelViewController.isInitialized}
nssl.isInitialized: ${this::notificationStackScrollLayoutController.isInitialized}

View File

@@ -9,6 +9,9 @@ import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.STATE_CLOSED
import com.android.systemui.statusbar.phone.panelstate.STATE_OPEN
import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING
import com.android.systemui.statusbar.policy.FakeConfigurationController
import org.junit.Before
import org.junit.Test
@@ -39,8 +42,9 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() {
dumpManager,
scrimController,
context.resources,
statusBarStateController
)
statusBarStateController)
controller.onPanelStateChanged(STATE_OPENING)
}
@Test
@@ -54,8 +58,7 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() {
@Test
fun onPanelExpansionChanged_inSplitShade_unlockedShade_setsFractionBasedOnDragDownAmount() {
whenever(statusBarStateController.currentOrUpcomingState)
.thenReturn(StatusBarState.SHADE)
whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE)
val scrimShadeTransitionDistance =
context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
setSplitShadeEnabled(true)
@@ -68,23 +71,20 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() {
@Test
fun onPanelExpansionChanged_inSplitShade_largeDragDownAmount_fractionIsNotGreaterThan1() {
whenever(statusBarStateController.currentOrUpcomingState)
.thenReturn(StatusBarState.SHADE)
whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE)
val scrimShadeTransitionDistance =
context.resources.getDimensionPixelSize(R.dimen.split_shade_scrim_transition_distance)
setSplitShadeEnabled(true)
controller.onPanelExpansionChanged(
EXPANSION_EVENT.copy(dragDownPxAmount = 100f * scrimShadeTransitionDistance)
)
EXPANSION_EVENT.copy(dragDownPxAmount = 100f * scrimShadeTransitionDistance))
verify(scrimController).setRawPanelExpansionFraction(1f)
}
@Test
fun onPanelExpansionChanged_inSplitShade_negativeDragDownAmount_fractionIsNotLessThan0() {
whenever(statusBarStateController.currentOrUpcomingState)
.thenReturn(StatusBarState.SHADE)
whenever(statusBarStateController.currentOrUpcomingState).thenReturn(StatusBarState.SHADE)
setSplitShadeEnabled(true)
controller.onPanelExpansionChanged(EXPANSION_EVENT.copy(dragDownPxAmount = -100f))
@@ -114,6 +114,30 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() {
verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
}
@Test
fun onPanelExpansionChanged_inSplitShade_panelOpen_setsFractionEqualToEventFraction() {
controller.onPanelStateChanged(STATE_OPEN)
whenever(statusBarStateController.currentOrUpcomingState)
.thenReturn(StatusBarState.KEYGUARD)
setSplitShadeEnabled(true)
controller.onPanelExpansionChanged(EXPANSION_EVENT)
verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
}
@Test
fun onPanelExpansionChanged_inSplitShade_panelClosed_setsFractionEqualToEventFraction() {
controller.onPanelStateChanged(STATE_CLOSED)
whenever(statusBarStateController.currentOrUpcomingState)
.thenReturn(StatusBarState.KEYGUARD)
setSplitShadeEnabled(true)
controller.onPanelExpansionChanged(EXPANSION_EVENT)
verify(scrimController).setRawPanelExpansionFraction(EXPANSION_EVENT.fraction)
}
private fun setSplitShadeEnabled(enabled: Boolean) {
overrideResource(R.bool.config_use_split_notification_shade, enabled)
configurationController.notifyConfigurationChanged()
@@ -122,7 +146,6 @@ class ScrimShadeTransitionControllerTest : SysuiTestCase() {
companion object {
val EXPANSION_EVENT =
PanelExpansionChangeEvent(
fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 10f
)
fraction = 0.5f, expanded = true, tracking = true, dragDownPxAmount = 10f)
}
}

View File

@@ -8,6 +8,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.NotificationPanelViewController
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
import com.android.systemui.statusbar.phone.panelstate.STATE_OPENING
import com.android.systemui.statusbar.policy.FakeConfigurationController
@@ -49,8 +50,7 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
context,
splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
noOpOverScroller,
scrimShadeTransitionController
)
scrimShadeTransitionController)
// Resetting as they are notified upon initialization.
reset(noOpOverScroller, splitShadeOverScroller)
@@ -91,6 +91,16 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
verifyZeroInteractions(splitShadeOverScroller)
}
@Test
fun onPanelStateChanged_forwardsToScrimTransitionController() {
initLateProperties()
startPanelExpansion()
verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING)
verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
}
private fun initLateProperties() {
controller.qs = qs
controller.notificationStackScrollLayoutController = nsslController
@@ -112,14 +122,20 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
private fun startPanelExpansion() {
panelExpansionStateManager.onPanelExpansionChanged(
fraction = 0.5f,
expanded = true,
tracking = true,
dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT
DEFAULT_EXPANSION_EVENT.fraction,
DEFAULT_EXPANSION_EVENT.expanded,
DEFAULT_EXPANSION_EVENT.tracking,
DEFAULT_EXPANSION_EVENT.dragDownPxAmount,
)
}
companion object {
private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
private val DEFAULT_EXPANSION_EVENT =
PanelExpansionChangeEvent(
fraction = 0.5f,
expanded = true,
tracking = true,
dragDownPxAmount = DEFAULT_DRAG_DOWN_AMOUNT)
}
}