Merge "Fix media staying too long during shade "immediate" expansion/collapsing" into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c7359149cd
@@ -36,6 +36,7 @@ import com.android.systemui.dagger.SysUISingleton
|
|||||||
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.statusbar.CrossFadeHelper
|
import com.android.systemui.statusbar.CrossFadeHelper
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
||||||
import com.android.systemui.statusbar.StatusBarState
|
import com.android.systemui.statusbar.StatusBarState
|
||||||
@@ -85,12 +86,21 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
private val bypassController: KeyguardBypassController,
|
private val bypassController: KeyguardBypassController,
|
||||||
private val mediaCarouselController: MediaCarouselController,
|
private val mediaCarouselController: MediaCarouselController,
|
||||||
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
|
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
|
||||||
|
private val keyguardViewController: KeyguardViewController,
|
||||||
|
private val dreamOverlayStateController: DreamOverlayStateController,
|
||||||
configurationController: ConfigurationController,
|
configurationController: ConfigurationController,
|
||||||
wakefulnessLifecycle: WakefulnessLifecycle,
|
wakefulnessLifecycle: WakefulnessLifecycle,
|
||||||
private val keyguardViewController: KeyguardViewController,
|
panelEventsEvents: NotifPanelEvents,
|
||||||
private val dreamOverlayStateController: DreamOverlayStateController
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we "skip" QQS during panel expansion.
|
||||||
|
*
|
||||||
|
* This means that when expanding the panel we go directly to QS. Also when we are on QS and
|
||||||
|
* start closing the panel, it fully collapses instead of going to QQS.
|
||||||
|
*/
|
||||||
|
private var skipQqsOnExpansion: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The root overlay of the hierarchy. This is where the media notification is attached to
|
* The root overlay of the hierarchy. This is where the media notification is attached to
|
||||||
* whenever the view is transitioning from one host to another. It also make sure that the
|
* whenever the view is transitioning from one host to another. It also make sure that the
|
||||||
@@ -504,6 +514,13 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
mediaCarouselController.updateUserVisibility = {
|
mediaCarouselController.updateUserVisibility = {
|
||||||
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panelEventsEvents.registerListener(object : NotifPanelEvents.Listener {
|
||||||
|
override fun onExpandImmediateChanged(isExpandImmediateEnabled: Boolean) {
|
||||||
|
skipQqsOnExpansion = isExpandImmediateEnabled
|
||||||
|
updateDesiredLocation()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateConfiguration() {
|
private fun updateConfiguration() {
|
||||||
@@ -701,6 +718,9 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
if (isCurrentlyInGuidedTransformation()) {
|
if (isCurrentlyInGuidedTransformation()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if (skipQqsOnExpansion) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// This is an invalid transition, and can happen when using the camera gesture from the
|
// This is an invalid transition, and can happen when using the camera gesture from the
|
||||||
// lock screen. Disallow.
|
// lock screen. Disallow.
|
||||||
if (previousLocation == LOCATION_LOCKSCREEN &&
|
if (previousLocation == LOCATION_LOCKSCREEN &&
|
||||||
@@ -852,6 +872,9 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
* otherwise
|
* otherwise
|
||||||
*/
|
*/
|
||||||
private fun getTransformationProgress(): Float {
|
private fun getTransformationProgress(): Float {
|
||||||
|
if (skipQqsOnExpansion) {
|
||||||
|
return -1.0f
|
||||||
|
}
|
||||||
val progress = getQSTransformationProgress()
|
val progress = getQSTransformationProgress()
|
||||||
if (statusbarState != StatusBarState.KEYGUARD && progress >= 0) {
|
if (statusbarState != StatusBarState.KEYGUARD && progress >= 0) {
|
||||||
return progress
|
return progress
|
||||||
@@ -1042,6 +1065,10 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
// reattach it without an animation
|
// reattach it without an animation
|
||||||
return LOCATION_LOCKSCREEN
|
return LOCATION_LOCKSCREEN
|
||||||
}
|
}
|
||||||
|
if (skipQqsOnExpansion) {
|
||||||
|
// When doing an immediate expand or collapse, we want to keep it in QS.
|
||||||
|
return LOCATION_QS
|
||||||
|
}
|
||||||
return location
|
return location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,25 @@ interface NotifPanelEvents {
|
|||||||
interface Listener {
|
interface Listener {
|
||||||
|
|
||||||
/** Invoked when the notification panel starts or stops collapsing. */
|
/** Invoked when the notification panel starts or stops collapsing. */
|
||||||
fun onPanelCollapsingChanged(isCollapsing: Boolean)
|
@JvmDefault
|
||||||
|
fun onPanelCollapsingChanged(isCollapsing: Boolean) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked when the notification panel starts or stops launching an [android.app.Activity].
|
* Invoked when the notification panel starts or stops launching an [android.app.Activity].
|
||||||
*/
|
*/
|
||||||
fun onLaunchingActivityChanged(isLaunchingActivity: Boolean)
|
@JvmDefault
|
||||||
|
fun onLaunchingActivityChanged(isLaunchingActivity: Boolean) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when the "expand immediate" attribute changes.
|
||||||
|
*
|
||||||
|
* An example of expanding immediately is when swiping down from the top with two fingers.
|
||||||
|
* Instead of going to QQS, we immediately expand to full QS.
|
||||||
|
*
|
||||||
|
* Another example is when full QS is showing, and we swipe up from the bottom. Instead of
|
||||||
|
* going to QQS, the panel fully collapses.
|
||||||
|
*/
|
||||||
|
@JvmDefault
|
||||||
|
fun onExpandImmediateChanged(isExpandImmediateEnabled: Boolean) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1745,12 +1745,17 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mQsExpanded) {
|
if (mQsExpanded) {
|
||||||
mQsExpandImmediate = true;
|
setQsExpandImmediate(true);
|
||||||
setShowShelfOnly(true);
|
setShowShelfOnly(true);
|
||||||
}
|
}
|
||||||
super.collapse(delayed, speedUpFactor);
|
super.collapse(delayed, speedUpFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setQsExpandImmediate(boolean expandImmediate) {
|
||||||
|
mQsExpandImmediate = expandImmediate;
|
||||||
|
mPanelEventsEmitter.notifyExpandImmediateChange(expandImmediate);
|
||||||
|
}
|
||||||
|
|
||||||
private void setShowShelfOnly(boolean shelfOnly) {
|
private void setShowShelfOnly(boolean shelfOnly) {
|
||||||
mNotificationStackScrollLayoutController.setShouldShowShelfOnly(
|
mNotificationStackScrollLayoutController.setShouldShowShelfOnly(
|
||||||
shelfOnly && !mSplitShadeEnabled);
|
shelfOnly && !mSplitShadeEnabled);
|
||||||
@@ -1803,7 +1808,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
|
|
||||||
public void expandWithQs() {
|
public void expandWithQs() {
|
||||||
if (isQsExpansionEnabled()) {
|
if (isQsExpansionEnabled()) {
|
||||||
mQsExpandImmediate = true;
|
setQsExpandImmediate(true);
|
||||||
setShowShelfOnly(true);
|
setShowShelfOnly(true);
|
||||||
}
|
}
|
||||||
if (mSplitShadeEnabled && isOnKeyguard()) {
|
if (mSplitShadeEnabled && isOnKeyguard()) {
|
||||||
@@ -2132,7 +2137,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex())
|
if (mTwoFingerQsExpandPossible && isOpenQsEvent(event) && event.getY(event.getActionIndex())
|
||||||
< mStatusBarMinHeight) {
|
< mStatusBarMinHeight) {
|
||||||
mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
|
mMetricsLogger.count(COUNTER_PANEL_OPEN_QS, 1);
|
||||||
mQsExpandImmediate = true;
|
setQsExpandImmediate(true);
|
||||||
setShowShelfOnly(true);
|
setShowShelfOnly(true);
|
||||||
requestPanelHeightUpdate();
|
requestPanelHeightUpdate();
|
||||||
|
|
||||||
@@ -3334,7 +3339,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
} else {
|
} else {
|
||||||
setListening(true);
|
setListening(true);
|
||||||
}
|
}
|
||||||
mQsExpandImmediate = false;
|
setQsExpandImmediate(false);
|
||||||
setShowShelfOnly(false);
|
setShowShelfOnly(false);
|
||||||
mTwoFingerQsExpandPossible = false;
|
mTwoFingerQsExpandPossible = false;
|
||||||
updateTrackingHeadsUp(null);
|
updateTrackingHeadsUp(null);
|
||||||
@@ -3392,7 +3397,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
super.onTrackingStarted();
|
super.onTrackingStarted();
|
||||||
mScrimController.onTrackingStarted();
|
mScrimController.onTrackingStarted();
|
||||||
if (mQsFullyExpanded) {
|
if (mQsFullyExpanded) {
|
||||||
mQsExpandImmediate = true;
|
setQsExpandImmediate(true);
|
||||||
setShowShelfOnly(true);
|
setShowShelfOnly(true);
|
||||||
}
|
}
|
||||||
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
|
mNotificationStackScrollLayoutController.onPanelTrackingStarted();
|
||||||
@@ -4959,7 +4964,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
// to locked will trigger this event and we're not actually in the process of opening
|
// to locked will trigger this event and we're not actually in the process of opening
|
||||||
// the shade, lockscreen is just always expanded
|
// the shade, lockscreen is just always expanded
|
||||||
if (mSplitShadeEnabled && !isOnKeyguard()) {
|
if (mSplitShadeEnabled && !isOnKeyguard()) {
|
||||||
mQsExpandImmediate = true;
|
setQsExpandImmediate(true);
|
||||||
}
|
}
|
||||||
mCentralSurfaces.makeExpandedVisible(false);
|
mCentralSurfaces.makeExpandedVisible(false);
|
||||||
}
|
}
|
||||||
@@ -5026,5 +5031,11 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
cb.onPanelCollapsingChanged(isCollapsing);
|
cb.onPanelCollapsingChanged(isCollapsing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyExpandImmediateChange(boolean expandImmediateEnabled) {
|
||||||
|
for (NotifPanelEvents.Listener cb : mListeners) {
|
||||||
|
cb.onExpandImmediateChanged(expandImmediateEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.media
|
package com.android.systemui.media
|
||||||
|
|
||||||
import org.mockito.Mockito.`when` as whenever
|
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.testing.AndroidTestingRunner
|
import android.testing.AndroidTestingRunner
|
||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
@@ -30,6 +29,7 @@ import com.android.systemui.controls.controller.ControlsControllerImplTest.Compa
|
|||||||
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.testing.FakeNotifPanelEvents
|
||||||
import com.android.systemui.statusbar.NotificationLockscreenUserManager
|
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
|
||||||
@@ -50,10 +50,11 @@ import org.mockito.ArgumentMatchers.anyBoolean
|
|||||||
import org.mockito.ArgumentMatchers.anyLong
|
import org.mockito.ArgumentMatchers.anyLong
|
||||||
import org.mockito.Captor
|
import org.mockito.Captor
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.`when`
|
|
||||||
import org.mockito.Mockito.clearInvocations
|
import org.mockito.Mockito.clearInvocations
|
||||||
import org.mockito.Mockito.times
|
import org.mockito.Mockito.times
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
|
import org.mockito.Mockito.`when`
|
||||||
|
import org.mockito.Mockito.`when` as whenever
|
||||||
import org.mockito.junit.MockitoJUnit
|
import org.mockito.junit.MockitoJUnit
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@@ -61,32 +62,19 @@ import org.mockito.junit.MockitoJUnit
|
|||||||
@TestableLooper.RunWithLooper
|
@TestableLooper.RunWithLooper
|
||||||
class MediaHierarchyManagerTest : SysuiTestCase() {
|
class MediaHierarchyManagerTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock
|
@Mock private lateinit var lockHost: MediaHost
|
||||||
private lateinit var lockHost: MediaHost
|
@Mock private lateinit var qsHost: MediaHost
|
||||||
@Mock
|
@Mock private lateinit var qqsHost: MediaHost
|
||||||
private lateinit var qsHost: MediaHost
|
@Mock private lateinit var bypassController: KeyguardBypassController
|
||||||
@Mock
|
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||||
private lateinit var qqsHost: MediaHost
|
@Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
|
||||||
@Mock
|
@Mock private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
|
||||||
private lateinit var bypassController: KeyguardBypassController
|
@Mock private lateinit var mediaCarouselController: MediaCarouselController
|
||||||
@Mock
|
@Mock private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
|
||||||
private lateinit var keyguardStateController: KeyguardStateController
|
@Mock private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
|
||||||
@Mock
|
@Mock private lateinit var keyguardViewController: KeyguardViewController
|
||||||
private lateinit var statusBarStateController: SysuiStatusBarStateController
|
@Mock private lateinit var uniqueObjectHostView: UniqueObjectHostView
|
||||||
@Mock
|
@Mock private lateinit var dreamOverlayStateController: DreamOverlayStateController
|
||||||
private lateinit var notificationLockscreenUserManager: NotificationLockscreenUserManager
|
|
||||||
@Mock
|
|
||||||
private lateinit var mediaCarouselController: MediaCarouselController
|
|
||||||
@Mock
|
|
||||||
private lateinit var mediaCarouselScrollHandler: MediaCarouselScrollHandler
|
|
||||||
@Mock
|
|
||||||
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
|
|
||||||
@Mock
|
|
||||||
private lateinit var keyguardViewController: KeyguardViewController
|
|
||||||
@Mock
|
|
||||||
private lateinit var uniqueObjectHostView: UniqueObjectHostView
|
|
||||||
@Mock
|
|
||||||
private lateinit var dreamOverlayStateController: DreamOverlayStateController
|
|
||||||
@Captor
|
@Captor
|
||||||
private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)>
|
private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)>
|
||||||
@Captor
|
@Captor
|
||||||
@@ -97,6 +85,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
|
|||||||
private lateinit var mediaHiearchyManager: MediaHierarchyManager
|
private lateinit var mediaHiearchyManager: MediaHierarchyManager
|
||||||
private lateinit var mediaFrame: ViewGroup
|
private lateinit var mediaFrame: ViewGroup
|
||||||
private val configurationController = FakeConfigurationController()
|
private val configurationController = FakeConfigurationController()
|
||||||
|
private val notifPanelEvents = FakeNotifPanelEvents()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
@@ -111,10 +100,12 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
|
|||||||
bypassController,
|
bypassController,
|
||||||
mediaCarouselController,
|
mediaCarouselController,
|
||||||
notificationLockscreenUserManager,
|
notificationLockscreenUserManager,
|
||||||
|
keyguardViewController,
|
||||||
|
dreamOverlayStateController,
|
||||||
configurationController,
|
configurationController,
|
||||||
wakefulnessLifecycle,
|
wakefulnessLifecycle,
|
||||||
keyguardViewController,
|
notifPanelEvents,
|
||||||
dreamOverlayStateController)
|
)
|
||||||
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
|
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
|
||||||
verify(statusBarStateController).addCallback(statusBarCallback.capture())
|
verify(statusBarStateController).addCallback(statusBarCallback.capture())
|
||||||
setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN, LOCKSCREEN_TOP)
|
setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN, LOCKSCREEN_TOP)
|
||||||
@@ -211,6 +202,25 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
|
|||||||
assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
|
assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun calculateTransformationType_notOnLockscreen_returnsTransition() {
|
||||||
|
expandQS()
|
||||||
|
|
||||||
|
val transformType = mediaHiearchyManager.calculateTransformationType()
|
||||||
|
|
||||||
|
assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_TRANSITION)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun calculateTransformationType_onLockscreen_returnsTransition() {
|
||||||
|
goToLockscreen()
|
||||||
|
expandQS()
|
||||||
|
|
||||||
|
val transformType = mediaHiearchyManager.calculateTransformationType()
|
||||||
|
|
||||||
|
assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun calculateTransformationType_onLockShade_inSplitShade_goingToFullShade_returnsTransition() {
|
fun calculateTransformationType_onLockShade_inSplitShade_goingToFullShade_returnsTransition() {
|
||||||
enableSplitShade()
|
enableSplitShade()
|
||||||
@@ -294,6 +304,18 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
|
|||||||
assertThat(mediaHiearchyManager.isCurrentlyInGuidedTransformation()).isTrue()
|
assertThat(mediaHiearchyManager.isCurrentlyInGuidedTransformation()).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isCurrentlyInGuidedTransformation_hostsVisible_expandImmediateEnabled_returnsFalse() {
|
||||||
|
notifPanelEvents.changeExpandImmediate(expandImmediate = true)
|
||||||
|
goToLockscreen()
|
||||||
|
enterGuidedTransformation()
|
||||||
|
whenever(lockHost.visible).thenReturn(true)
|
||||||
|
whenever(qsHost.visible).thenReturn(true)
|
||||||
|
whenever(qqsHost.visible).thenReturn(true)
|
||||||
|
|
||||||
|
assertThat(mediaHiearchyManager.isCurrentlyInGuidedTransformation()).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() {
|
fun isCurrentlyInGuidedTransformation_hostNotVisible_returnsTrue() {
|
||||||
goToLockscreen()
|
goToLockscreen()
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.testing
|
||||||
|
|
||||||
|
import com.android.systemui.shade.NotifPanelEvents
|
||||||
|
|
||||||
|
/** Fake implementation of [NotifPanelEvents] for testing. */
|
||||||
|
class FakeNotifPanelEvents : NotifPanelEvents {
|
||||||
|
|
||||||
|
private val listeners = mutableListOf<NotifPanelEvents.Listener>()
|
||||||
|
|
||||||
|
override fun registerListener(listener: NotifPanelEvents.Listener) {
|
||||||
|
listeners.add(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterListener(listener: NotifPanelEvents.Listener) {
|
||||||
|
listeners.remove(listener)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changeExpandImmediate(expandImmediate: Boolean) {
|
||||||
|
listeners.forEach { it.onExpandImmediateChanged(expandImmediate) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user