1 package com.android.systemui.qs 2 3 import android.content.res.Configuration 4 import android.test.suitebuilder.annotation.SmallTest 5 import android.testing.AndroidTestingRunner 6 import android.testing.TestableResources 7 import com.android.internal.logging.MetricsLogger 8 import com.android.internal.logging.UiEventLogger 9 import com.android.systemui.R 10 import com.android.systemui.SysuiTestCase 11 import com.android.systemui.dump.DumpManager 12 import com.android.systemui.media.controls.ui.MediaHost 13 import com.android.systemui.media.controls.ui.MediaHostState 14 import com.android.systemui.plugins.FalsingManager 15 import com.android.systemui.plugins.qs.QSTile 16 import com.android.systemui.qs.customize.QSCustomizerController 17 import com.android.systemui.qs.logging.QSLogger 18 import com.android.systemui.settings.brightness.BrightnessController 19 import com.android.systemui.settings.brightness.BrightnessSliderController 20 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager 21 import com.android.systemui.tuner.TunerService 22 import com.google.common.truth.Truth.assertThat 23 import org.junit.After 24 import org.junit.Before 25 import org.junit.Test 26 import org.junit.runner.RunWith 27 import org.mockito.ArgumentMatchers.anyBoolean 28 import org.mockito.Mock 29 import org.mockito.Mockito 30 import org.mockito.Mockito.any 31 import org.mockito.Mockito.never 32 import org.mockito.Mockito.reset 33 import org.mockito.Mockito.verify 34 import org.mockito.MockitoAnnotations 35 import org.mockito.Mockito.`when` as whenever 36 37 @SmallTest 38 @RunWith(AndroidTestingRunner::class) 39 class QSPanelControllerTest : SysuiTestCase() { 40 41 @Mock private lateinit var qsPanel: QSPanel 42 @Mock private lateinit var tunerService: TunerService 43 @Mock private lateinit var qsHost: QSHost 44 @Mock private lateinit var qsCustomizerController: QSCustomizerController 45 @Mock private lateinit var qsTileRevealControllerFactory: QSTileRevealController.Factory 46 @Mock private lateinit var dumpManager: DumpManager 47 @Mock private lateinit var metricsLogger: MetricsLogger 48 @Mock private lateinit var uiEventLogger: UiEventLogger 49 @Mock private lateinit var qsLogger: QSLogger 50 @Mock private lateinit var brightnessControllerFactory: BrightnessController.Factory 51 @Mock private lateinit var brightnessController: BrightnessController 52 @Mock private lateinit var brightnessSlider: BrightnessSliderController 53 @Mock private lateinit var brightnessSliderFactory: BrightnessSliderController.Factory 54 @Mock private lateinit var falsingManager: FalsingManager 55 @Mock private lateinit var mediaHost: MediaHost 56 @Mock private lateinit var tile: QSTile 57 @Mock private lateinit var otherTile: QSTile 58 @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager 59 @Mock private lateinit var configuration: Configuration 60 @Mock private lateinit var pagedTileLayout: PagedTileLayout 61 62 private lateinit var controller: QSPanelController 63 private val testableResources: TestableResources = mContext.orCreateTestableResources 64 65 @Before 66 fun setUp() { 67 MockitoAnnotations.initMocks(this) 68 69 whenever(brightnessSliderFactory.create(any(), any())).thenReturn(brightnessSlider) 70 whenever(brightnessControllerFactory.create(any())).thenReturn(brightnessController) 71 setShouldUseSplitShade(false) 72 whenever(qsPanel.resources).thenReturn(testableResources.resources) 73 whenever(qsPanel.getOrCreateTileLayout()).thenReturn(pagedTileLayout) 74 whenever(statusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false) 75 whenever(qsPanel.setListening(anyBoolean())).then { 76 whenever(qsPanel.isListening).thenReturn(it.getArgument(0)) 77 } 78 79 controller = QSPanelController( 80 qsPanel, 81 tunerService, 82 qsHost, 83 qsCustomizerController, 84 /* usingMediaPlayer= */ true, 85 mediaHost, 86 qsTileRevealControllerFactory, 87 dumpManager, 88 metricsLogger, 89 uiEventLogger, 90 qsLogger, 91 brightnessControllerFactory, 92 brightnessSliderFactory, 93 falsingManager, 94 statusBarKeyguardViewManager 95 ) 96 } 97 98 @After 99 fun tearDown() { 100 reset(mediaHost) 101 } 102 103 @Test 104 fun onInit_setsMediaAsExpanded() { 105 controller.onInit() 106 107 verify(mediaHost).expansion = MediaHostState.EXPANDED 108 } 109 110 @Test 111 fun testSetListeningDoesntRefreshListeningTiles() { 112 whenever(qsHost.getTiles()).thenReturn(listOf(tile, otherTile)) 113 controller.setTiles() 114 whenever(tile.isListening()).thenReturn(false) 115 whenever(otherTile.isListening()).thenReturn(true) 116 117 controller.setListening(true, true) 118 119 verify(tile).refreshState() 120 verify(otherTile, Mockito.never()).refreshState() 121 } 122 123 @Test 124 fun testIsBouncerInTransit() { 125 whenever(statusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(true) 126 assertThat(controller.isBouncerInTransit()).isEqualTo(true) 127 whenever(statusBarKeyguardViewManager.isPrimaryBouncerInTransit()).thenReturn(false) 128 assertThat(controller.isBouncerInTransit()).isEqualTo(false) 129 } 130 131 @Test 132 fun configurationChange_onlySplitShadeConfigChanges_tileAreRedistributed() { 133 setShouldUseSplitShade(false) 134 controller.mOnConfigurationChangedListener.onConfigurationChange(configuration) 135 verify(pagedTileLayout, never()).forceTilesRedistribution(any()) 136 137 setShouldUseSplitShade(true) 138 controller.mOnConfigurationChangedListener.onConfigurationChange(configuration) 139 verify(pagedTileLayout).forceTilesRedistribution("Split shade state changed") 140 } 141 142 @Test 143 fun configurationChange_onlySplitShadeConfigChanges_qsPanelCanBeCollapsed() { 144 setShouldUseSplitShade(false) 145 controller.mOnConfigurationChangedListener.onConfigurationChange(configuration) 146 verify(qsPanel, never()).setCanCollapse(anyBoolean()) 147 148 setShouldUseSplitShade(true) 149 controller.mOnConfigurationChangedListener.onConfigurationChange(configuration) 150 verify(qsPanel).setCanCollapse(false) 151 152 setShouldUseSplitShade(false) 153 controller.mOnConfigurationChangedListener.onConfigurationChange(configuration) 154 verify(qsPanel).setCanCollapse(true) 155 } 156 157 @Test 158 fun multipleListeningOnlyCallsBrightnessControllerOnce() { 159 controller.setListening(true, true) 160 controller.setListening(true, false) 161 controller.setListening(true, true) 162 163 verify(brightnessController).registerCallbacks() 164 165 controller.setListening(false, true) 166 controller.setListening(false, false) 167 controller.setListening(false, true) 168 169 verify(brightnessController).unregisterCallbacks() 170 } 171 172 private fun setShouldUseSplitShade(shouldUse: Boolean) { 173 testableResources.addOverride(R.bool.config_use_split_notification_shade, shouldUse) 174 } 175 } 176