Merge "Fix unlocked split shade jumping back into place after over expanding" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2429c98084
@@ -1915,7 +1915,6 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
// we want to perform an overshoot animation when flinging open
|
// we want to perform an overshoot animation when flinging open
|
||||||
final boolean addOverscroll =
|
final boolean addOverscroll =
|
||||||
expand
|
expand
|
||||||
&& !mSplitShadeEnabled // Split shade has its own overscroll logic
|
|
||||||
&& mStatusBarStateController.getState() != KEYGUARD
|
&& mStatusBarStateController.getState() != KEYGUARD
|
||||||
&& mOverExpansion == 0.0f
|
&& mOverExpansion == 0.0f
|
||||||
&& vel >= 0;
|
&& vel >= 0;
|
||||||
@@ -2591,9 +2590,14 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mOverExpansion = overExpansion;
|
mOverExpansion = overExpansion;
|
||||||
// Translating the quick settings by half the overexpansion to center it in the background
|
if (mSplitShadeEnabled) {
|
||||||
// frame
|
mQsController.setOverScrollAmount((int) overExpansion);
|
||||||
mQsController.updateQsFrameTranslation();
|
mScrimController.setNotificationsOverScrollAmount((int) overExpansion);
|
||||||
|
} else {
|
||||||
|
// Translating the quick settings by half the overexpansion to center it in the
|
||||||
|
// background frame
|
||||||
|
mQsController.updateQsFrameTranslation();
|
||||||
|
}
|
||||||
mNotificationStackScrollLayoutController.setOverExpansion(overExpansion);
|
mNotificationStackScrollLayoutController.setOverExpansion(overExpansion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3595,7 +3599,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
|
|
||||||
private void fling(float vel, boolean expand, float collapseSpeedUpFactor,
|
private void fling(float vel, boolean expand, float collapseSpeedUpFactor,
|
||||||
boolean expandBecauseOfFalsing) {
|
boolean expandBecauseOfFalsing) {
|
||||||
float target = expand ? getMaxPanelHeight() : 0;
|
float target = expand ? getMaxPanelTransitionDistance() : 0;
|
||||||
if (!expand) {
|
if (!expand) {
|
||||||
setClosing(true);
|
setClosing(true);
|
||||||
}
|
}
|
||||||
@@ -3680,7 +3684,7 @@ public final class NotificationPanelViewController implements Dumpable {
|
|||||||
float maxPanelHeight = getMaxPanelTransitionDistance();
|
float maxPanelHeight = getMaxPanelTransitionDistance();
|
||||||
if (mHeightAnimator == null) {
|
if (mHeightAnimator == null) {
|
||||||
// Split shade has its own overscroll logic
|
// Split shade has its own overscroll logic
|
||||||
if (mTracking && !mSplitShadeEnabled) {
|
if (mTracking) {
|
||||||
float overExpansionPixels = Math.max(0, h - maxPanelHeight);
|
float overExpansionPixels = Math.max(0, h - maxPanelHeight);
|
||||||
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
|
setOverExpansionInternal(overExpansionPixels, true /* isFromGesture */);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -803,6 +803,10 @@ public class QuickSettingsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setOverScrollAmount(int overExpansion) {
|
||||||
|
mQs.setOverScrollAmount(overExpansion);
|
||||||
|
}
|
||||||
|
|
||||||
private void setOverScrolling(boolean overscrolling) {
|
private void setOverScrolling(boolean overscrolling) {
|
||||||
mStackScrollerOverscrolling = overscrolling;
|
mStackScrollerOverscrolling = overscrolling;
|
||||||
if (mQs != null) {
|
if (mQs != null) {
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ constructor(
|
|||||||
shadeExpansionStateManager: ShadeExpansionStateManager,
|
shadeExpansionStateManager: ShadeExpansionStateManager,
|
||||||
dumpManager: DumpManager,
|
dumpManager: DumpManager,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val splitShadeOverScrollerFactory: SplitShadeOverScroller.Factory,
|
|
||||||
private val noOpOverScroller: NoOpOverScroller,
|
|
||||||
private val scrimShadeTransitionController: ScrimShadeTransitionController,
|
private val scrimShadeTransitionController: ScrimShadeTransitionController,
|
||||||
private val statusBarStateController: SysuiStatusBarStateController,
|
private val statusBarStateController: SysuiStatusBarStateController,
|
||||||
) {
|
) {
|
||||||
@@ -57,17 +55,6 @@ constructor(
|
|||||||
private var currentPanelState: Int? = null
|
private var currentPanelState: Int? = null
|
||||||
private var lastShadeExpansionChangeEvent: ShadeExpansionChangeEvent? = null
|
private var lastShadeExpansionChangeEvent: ShadeExpansionChangeEvent? = null
|
||||||
|
|
||||||
private val splitShadeOverScroller by lazy {
|
|
||||||
splitShadeOverScrollerFactory.create({ qs }, { notificationStackScrollLayoutController })
|
|
||||||
}
|
|
||||||
private val shadeOverScroller: ShadeOverScroller
|
|
||||||
get() =
|
|
||||||
if (inSplitShade && isScreenUnlocked() && propertiesInitialized()) {
|
|
||||||
splitShadeOverScroller
|
|
||||||
} else {
|
|
||||||
noOpOverScroller
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
updateResources()
|
updateResources()
|
||||||
configurationController.addCallback(
|
configurationController.addCallback(
|
||||||
@@ -89,21 +76,14 @@ constructor(
|
|||||||
|
|
||||||
private fun onPanelStateChanged(@PanelState state: Int) {
|
private fun onPanelStateChanged(@PanelState state: Int) {
|
||||||
currentPanelState = state
|
currentPanelState = state
|
||||||
shadeOverScroller.onPanelStateChanged(state)
|
|
||||||
scrimShadeTransitionController.onPanelStateChanged(state)
|
scrimShadeTransitionController.onPanelStateChanged(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
|
private fun onPanelExpansionChanged(event: ShadeExpansionChangeEvent) {
|
||||||
lastShadeExpansionChangeEvent = event
|
lastShadeExpansionChangeEvent = event
|
||||||
shadeOverScroller.onDragDownAmountChanged(event.dragDownPxAmount)
|
|
||||||
scrimShadeTransitionController.onPanelExpansionChanged(event)
|
scrimShadeTransitionController.onPanelExpansionChanged(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun propertiesInitialized() =
|
|
||||||
this::qs.isInitialized &&
|
|
||||||
this::notificationPanelViewController.isInitialized &&
|
|
||||||
this::notificationStackScrollLayoutController.isInitialized
|
|
||||||
|
|
||||||
private fun dump(pw: PrintWriter) {
|
private fun dump(pw: PrintWriter) {
|
||||||
pw.println(
|
pw.println(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2022 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.systemui.shade.transition
|
|
||||||
|
|
||||||
import android.animation.Animator
|
|
||||||
import android.animation.ValueAnimator
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.res.Configuration
|
|
||||||
import android.util.MathUtils
|
|
||||||
import com.android.internal.annotations.VisibleForTesting
|
|
||||||
import com.android.systemui.R
|
|
||||||
import com.android.systemui.animation.Interpolators
|
|
||||||
import com.android.systemui.dump.DumpManager
|
|
||||||
import com.android.systemui.plugins.qs.QS
|
|
||||||
import com.android.systemui.shade.PanelState
|
|
||||||
import com.android.systemui.shade.STATE_CLOSED
|
|
||||||
import com.android.systemui.shade.STATE_OPENING
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
|
|
||||||
import com.android.systemui.statusbar.phone.ScrimController
|
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
|
||||||
import dagger.assisted.Assisted
|
|
||||||
import dagger.assisted.AssistedFactory
|
|
||||||
import dagger.assisted.AssistedInject
|
|
||||||
import java.io.PrintWriter
|
|
||||||
|
|
||||||
class SplitShadeOverScroller
|
|
||||||
@AssistedInject
|
|
||||||
constructor(
|
|
||||||
configurationController: ConfigurationController,
|
|
||||||
dumpManager: DumpManager,
|
|
||||||
private val context: Context,
|
|
||||||
private val scrimController: ScrimController,
|
|
||||||
@Assisted private val qSProvider: () -> QS,
|
|
||||||
@Assisted private val nsslControllerProvider: () -> NotificationStackScrollLayoutController
|
|
||||||
) : ShadeOverScroller {
|
|
||||||
|
|
||||||
private var releaseOverScrollDuration = 0L
|
|
||||||
private var maxOverScrollAmount = 0
|
|
||||||
private var previousOverscrollAmount = 0
|
|
||||||
private var dragDownAmount: Float = 0f
|
|
||||||
@PanelState private var panelState: Int = STATE_CLOSED
|
|
||||||
|
|
||||||
private var releaseOverScrollAnimator: Animator? = null
|
|
||||||
|
|
||||||
private val qS: QS
|
|
||||||
get() = qSProvider()
|
|
||||||
|
|
||||||
private val nsslController: NotificationStackScrollLayoutController
|
|
||||||
get() = nsslControllerProvider()
|
|
||||||
|
|
||||||
init {
|
|
||||||
updateResources()
|
|
||||||
configurationController.addCallback(
|
|
||||||
object : ConfigurationController.ConfigurationListener {
|
|
||||||
override fun onConfigChanged(newConfig: Configuration?) {
|
|
||||||
updateResources()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
dumpManager.registerCriticalDumpable("SplitShadeOverScroller") { printWriter, _ ->
|
|
||||||
dump(printWriter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateResources() {
|
|
||||||
val resources = context.resources
|
|
||||||
maxOverScrollAmount = resources.getDimensionPixelSize(R.dimen.shade_max_over_scroll_amount)
|
|
||||||
releaseOverScrollDuration =
|
|
||||||
resources.getInteger(R.integer.lockscreen_shade_over_scroll_release_duration).toLong()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPanelStateChanged(@PanelState newPanelState: Int) {
|
|
||||||
if (shouldReleaseOverscroll(previousState = panelState, newState = newPanelState)) {
|
|
||||||
releaseOverScroll()
|
|
||||||
}
|
|
||||||
panelState = newPanelState
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDragDownAmountChanged(newDragDownAmount: Float) {
|
|
||||||
if (dragDownAmount == newDragDownAmount) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dragDownAmount = newDragDownAmount
|
|
||||||
if (shouldOverscroll()) {
|
|
||||||
overScroll(newDragDownAmount)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shouldOverscroll() = panelState == STATE_OPENING
|
|
||||||
|
|
||||||
private fun shouldReleaseOverscroll(@PanelState previousState: Int, @PanelState newState: Int) =
|
|
||||||
previousState == STATE_OPENING && newState != STATE_OPENING
|
|
||||||
|
|
||||||
private fun overScroll(dragDownAmount: Float) {
|
|
||||||
val overscrollAmount: Int = calculateOverscrollAmount(dragDownAmount)
|
|
||||||
applyOverscroll(overscrollAmount)
|
|
||||||
previousOverscrollAmount = overscrollAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun calculateOverscrollAmount(dragDownAmount: Float): Int {
|
|
||||||
val fullHeight: Int = nsslController.height
|
|
||||||
val fullHeightProgress: Float = MathUtils.saturate(dragDownAmount / fullHeight)
|
|
||||||
return (fullHeightProgress * maxOverScrollAmount).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyOverscroll(overscrollAmount: Int) {
|
|
||||||
qS.setOverScrollAmount(overscrollAmount)
|
|
||||||
scrimController.setNotificationsOverScrollAmount(overscrollAmount)
|
|
||||||
nsslController.setOverScrollAmount(overscrollAmount)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun releaseOverScroll() {
|
|
||||||
val animator = ValueAnimator.ofInt(previousOverscrollAmount, 0)
|
|
||||||
animator.addUpdateListener {
|
|
||||||
val overScrollAmount = it.animatedValue as Int
|
|
||||||
qS.setOverScrollAmount(overScrollAmount)
|
|
||||||
scrimController.setNotificationsOverScrollAmount(overScrollAmount)
|
|
||||||
nsslController.setOverScrollAmount(overScrollAmount)
|
|
||||||
}
|
|
||||||
animator.interpolator = Interpolators.STANDARD
|
|
||||||
animator.duration = releaseOverScrollDuration
|
|
||||||
animator.start()
|
|
||||||
releaseOverScrollAnimator = animator
|
|
||||||
previousOverscrollAmount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
internal fun finishAnimations() {
|
|
||||||
releaseOverScrollAnimator?.end()
|
|
||||||
releaseOverScrollAnimator = null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dump(pw: PrintWriter) {
|
|
||||||
pw.println(
|
|
||||||
"""
|
|
||||||
SplitShadeOverScroller:
|
|
||||||
Resources:
|
|
||||||
releaseOverScrollDuration: $releaseOverScrollDuration
|
|
||||||
maxOverScrollAmount: $maxOverScrollAmount
|
|
||||||
State:
|
|
||||||
previousOverscrollAmount: $previousOverscrollAmount
|
|
||||||
dragDownAmount: $dragDownAmount
|
|
||||||
panelState: $panelState
|
|
||||||
""".trimIndent())
|
|
||||||
}
|
|
||||||
|
|
||||||
@AssistedFactory
|
|
||||||
fun interface Factory {
|
|
||||||
fun create(
|
|
||||||
qSProvider: () -> QS,
|
|
||||||
nsslControllerProvider: () -> NotificationStackScrollLayoutController
|
|
||||||
): SplitShadeOverScroller
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,37 +2,24 @@ package com.android.systemui.shade.transition
|
|||||||
|
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.R
|
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.dump.DumpManager
|
import com.android.systemui.dump.DumpManager
|
||||||
import com.android.systemui.plugins.qs.QS
|
|
||||||
import com.android.systemui.shade.NotificationPanelViewController
|
|
||||||
import com.android.systemui.shade.STATE_OPENING
|
import com.android.systemui.shade.STATE_OPENING
|
||||||
import com.android.systemui.shade.ShadeExpansionChangeEvent
|
import com.android.systemui.shade.ShadeExpansionChangeEvent
|
||||||
import com.android.systemui.shade.ShadeExpansionStateManager
|
import com.android.systemui.shade.ShadeExpansionStateManager
|
||||||
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.NotificationStackScrollLayoutController
|
|
||||||
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.reset
|
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.verifyZeroInteractions
|
|
||||||
import org.mockito.Mockito.`when` as whenever
|
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
class ShadeTransitionControllerTest : SysuiTestCase() {
|
class ShadeTransitionControllerTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock private lateinit var npvc: NotificationPanelViewController
|
|
||||||
@Mock private lateinit var nsslController: NotificationStackScrollLayoutController
|
|
||||||
@Mock private lateinit var qs: QS
|
|
||||||
@Mock private lateinit var noOpOverScroller: NoOpOverScroller
|
|
||||||
@Mock private lateinit var splitShadeOverScroller: SplitShadeOverScroller
|
|
||||||
@Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
|
@Mock private lateinit var scrimShadeTransitionController: ScrimShadeTransitionController
|
||||||
@Mock private lateinit var dumpManager: DumpManager
|
@Mock private lateinit var dumpManager: DumpManager
|
||||||
@Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
|
@Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
|
||||||
@@ -52,119 +39,19 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
shadeExpansionStateManager,
|
shadeExpansionStateManager,
|
||||||
dumpManager,
|
dumpManager,
|
||||||
context,
|
context,
|
||||||
splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
|
|
||||||
noOpOverScroller,
|
|
||||||
scrimShadeTransitionController,
|
scrimShadeTransitionController,
|
||||||
statusBarStateController,
|
statusBarStateController,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resetting as they are notified upon initialization.
|
|
||||||
reset(noOpOverScroller, splitShadeOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelExpansionChanged_inSplitShade_forwardsToSplitShadeOverScroller() {
|
|
||||||
initLateProperties()
|
|
||||||
enableSplitShade()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(splitShadeOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(splitShadeOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(noOpOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_inSplitShade_propertiesNotInitialized_forwardsToNoOpOverScroller() {
|
|
||||||
enableSplitShade()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(splitShadeOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_inSplitShade_onKeyguard_forwardsToNoOpOverScroller() {
|
|
||||||
initLateProperties()
|
|
||||||
enableSplitShade()
|
|
||||||
setOnKeyguard()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(splitShadeOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_inSplitShade_onLockedShade_forwardsToNoOpOverScroller() {
|
|
||||||
initLateProperties()
|
|
||||||
enableSplitShade()
|
|
||||||
setOnLockedShade()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(splitShadeOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelExpansionChanged_inSplitShade_onUnlockedShade_forwardsToSplitShadeOverScroller() {
|
|
||||||
initLateProperties()
|
|
||||||
enableSplitShade()
|
|
||||||
setOnUnlockedShade()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(splitShadeOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(splitShadeOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(noOpOverScroller)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_notInSplitShade_forwardsToNoOpOverScroller() {
|
|
||||||
initLateProperties()
|
|
||||||
disableSplitShade()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
|
||||||
|
|
||||||
verify(noOpOverScroller).onPanelStateChanged(STATE_OPENING)
|
|
||||||
verify(noOpOverScroller).onDragDownAmountChanged(DEFAULT_DRAG_DOWN_AMOUNT)
|
|
||||||
verifyZeroInteractions(splitShadeOverScroller)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun onPanelStateChanged_forwardsToScrimTransitionController() {
|
fun onPanelStateChanged_forwardsToScrimTransitionController() {
|
||||||
initLateProperties()
|
|
||||||
|
|
||||||
startPanelExpansion()
|
startPanelExpansion()
|
||||||
|
|
||||||
verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING)
|
verify(scrimShadeTransitionController).onPanelStateChanged(STATE_OPENING)
|
||||||
verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
|
verify(scrimShadeTransitionController).onPanelExpansionChanged(DEFAULT_EXPANSION_EVENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initLateProperties() {
|
|
||||||
controller.qs = qs
|
|
||||||
controller.notificationStackScrollLayoutController = nsslController
|
|
||||||
controller.notificationPanelViewController = npvc
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun disableSplitShade() {
|
|
||||||
setSplitShadeEnabled(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun enableSplitShade() {
|
|
||||||
setSplitShadeEnabled(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setSplitShadeEnabled(enabled: Boolean) {
|
|
||||||
overrideResource(R.bool.config_use_split_notification_shade, enabled)
|
|
||||||
configurationController.notifyConfigurationChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startPanelExpansion() {
|
private fun startPanelExpansion() {
|
||||||
shadeExpansionStateManager.onPanelExpansionChanged(
|
shadeExpansionStateManager.onPanelExpansionChanged(
|
||||||
DEFAULT_EXPANSION_EVENT.fraction,
|
DEFAULT_EXPANSION_EVENT.fraction,
|
||||||
@@ -174,23 +61,6 @@ class ShadeTransitionControllerTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setOnKeyguard() {
|
|
||||||
setShadeState(StatusBarState.KEYGUARD)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setOnLockedShade() {
|
|
||||||
setShadeState(StatusBarState.SHADE_LOCKED)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setOnUnlockedShade() {
|
|
||||||
setShadeState(StatusBarState.SHADE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setShadeState(state: Int) {
|
|
||||||
whenever(statusBarStateController.state).thenReturn(state)
|
|
||||||
whenever(statusBarStateController.currentOrUpcomingState).thenReturn(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
|
private const val DEFAULT_DRAG_DOWN_AMOUNT = 123f
|
||||||
private val DEFAULT_EXPANSION_EVENT =
|
private val DEFAULT_EXPANSION_EVENT =
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
package com.android.systemui.shade.transition
|
|
||||||
|
|
||||||
import android.testing.AndroidTestingRunner
|
|
||||||
import android.testing.TestableLooper
|
|
||||||
import androidx.test.filters.SmallTest
|
|
||||||
import com.android.systemui.R
|
|
||||||
import com.android.systemui.SysuiTestCase
|
|
||||||
import com.android.systemui.dump.DumpManager
|
|
||||||
import com.android.systemui.plugins.qs.QS
|
|
||||||
import com.android.systemui.shade.STATE_CLOSED
|
|
||||||
import com.android.systemui.shade.STATE_OPEN
|
|
||||||
import com.android.systemui.shade.STATE_OPENING
|
|
||||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
|
|
||||||
import com.android.systemui.statusbar.phone.ScrimController
|
|
||||||
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.mockito.Mock
|
|
||||||
import org.mockito.Mockito.atLeastOnce
|
|
||||||
import org.mockito.Mockito.verify
|
|
||||||
import org.mockito.Mockito.verifyZeroInteractions
|
|
||||||
import org.mockito.Mockito.`when` as whenever
|
|
||||||
import org.mockito.MockitoAnnotations
|
|
||||||
|
|
||||||
@RunWith(AndroidTestingRunner::class)
|
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
|
||||||
@SmallTest
|
|
||||||
class SplitShadeOverScrollerTest : SysuiTestCase() {
|
|
||||||
|
|
||||||
@Mock private lateinit var dumpManager: DumpManager
|
|
||||||
@Mock private lateinit var scrimController: ScrimController
|
|
||||||
@Mock private lateinit var qs: QS
|
|
||||||
@Mock private lateinit var nsslController: NotificationStackScrollLayoutController
|
|
||||||
|
|
||||||
private val configurationController = FakeConfigurationController()
|
|
||||||
private lateinit var overScroller: SplitShadeOverScroller
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun setUp() {
|
|
||||||
MockitoAnnotations.initMocks(this)
|
|
||||||
|
|
||||||
whenever(nsslController.height).thenReturn(1000)
|
|
||||||
overScroller =
|
|
||||||
SplitShadeOverScroller(
|
|
||||||
configurationController,
|
|
||||||
dumpManager,
|
|
||||||
context,
|
|
||||||
scrimController,
|
|
||||||
{ qs },
|
|
||||||
{ nsslController })
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onDragDownAmountChanged_panelOpening_overScrolls_basedOnHeightAndMaxAmount() {
|
|
||||||
val maxOverScrollAmount = 50
|
|
||||||
val dragDownAmount = 100f
|
|
||||||
overrideResource(R.dimen.shade_max_over_scroll_amount, maxOverScrollAmount)
|
|
||||||
configurationController.notifyConfigurationChanged()
|
|
||||||
|
|
||||||
overScroller.onPanelStateChanged(STATE_OPENING)
|
|
||||||
overScroller.onDragDownAmountChanged(dragDownAmount)
|
|
||||||
|
|
||||||
val expectedOverScrollAmount =
|
|
||||||
(dragDownAmount / nsslController.height * maxOverScrollAmount).toInt()
|
|
||||||
verify(qs).setOverScrollAmount(expectedOverScrollAmount)
|
|
||||||
verify(nsslController).setOverScrollAmount(expectedOverScrollAmount)
|
|
||||||
verify(scrimController).setNotificationsOverScrollAmount(expectedOverScrollAmount)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onDragDownAmountChanged_panelClosed_doesNotOverScroll() {
|
|
||||||
overScroller.onPanelStateChanged(STATE_CLOSED)
|
|
||||||
overScroller.onDragDownAmountChanged(100f)
|
|
||||||
|
|
||||||
verifyZeroInteractions(qs, scrimController, nsslController)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onDragDownAmountChanged_panelOpen_doesNotOverScroll() {
|
|
||||||
overScroller.onPanelStateChanged(STATE_OPEN)
|
|
||||||
overScroller.onDragDownAmountChanged(100f)
|
|
||||||
|
|
||||||
verifyZeroInteractions(qs, scrimController, nsslController)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_opening_thenOpen_releasesOverScroll() {
|
|
||||||
overScroller.onPanelStateChanged(STATE_OPENING)
|
|
||||||
overScroller.onDragDownAmountChanged(100f)
|
|
||||||
|
|
||||||
overScroller.onPanelStateChanged(STATE_OPEN)
|
|
||||||
overScroller.finishAnimations()
|
|
||||||
|
|
||||||
verify(qs, atLeastOnce()).setOverScrollAmount(0)
|
|
||||||
verify(scrimController, atLeastOnce()).setNotificationsOverScrollAmount(0)
|
|
||||||
verify(nsslController, atLeastOnce()).setOverScrollAmount(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun onPanelStateChanged_opening_thenClosed_releasesOverScroll() {
|
|
||||||
overScroller.onPanelStateChanged(STATE_OPENING)
|
|
||||||
overScroller.onDragDownAmountChanged(100f)
|
|
||||||
|
|
||||||
overScroller.onPanelStateChanged(STATE_CLOSED)
|
|
||||||
overScroller.finishAnimations()
|
|
||||||
|
|
||||||
verify(qs, atLeastOnce()).setOverScrollAmount(0)
|
|
||||||
verify(scrimController, atLeastOnce()).setNotificationsOverScrollAmount(0)
|
|
||||||
verify(nsslController, atLeastOnce()).setOverScrollAmount(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user