Fix out of bounds in QuickQSPanelController

Make sure that we only select the correct number of tiles, therefore
there's no need to call subList. As we will always call setTiles if the
number of tiles in the resource changes. We'll always have enough tiles
to show.

Test: atest QuickQSControllerTest
Test: manual
Fixes: 173792244
Change-Id: I70a0e4903bb8e5a319dbbc8c321d8774f0dd3064
This commit is contained in:
Fabian Kozynski
2020-11-20 13:46:54 -05:00
parent f48a5e3d13
commit 152693dadf
2 changed files with 115 additions and 6 deletions

View File

@@ -40,8 +40,6 @@ import javax.inject.Named;
@QSScope
public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel> {
private List<QSTile> mAllTiles = new ArrayList<>();
private final QSPanel.OnConfigurationChangedListener mOnConfigurationChangedListener =
newConfig -> {
int newMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
@@ -92,14 +90,14 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
@Override
public void setTiles() {
mAllTiles.clear();
List<QSTile> tiles = new ArrayList();
for (QSTile tile : mHost.getTiles()) {
mAllTiles.add(tile);
if (mAllTiles.size() == QuickQSPanel.DEFAULT_MAX_TILES) {
tiles.add(tile);
if (tiles.size() == mView.getNumQuickTiles()) {
break;
}
}
super.setTiles(mAllTiles.subList(0, mView.getNumQuickTiles()), true);
super.setTiles(tiles, true);
}
/** */

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2020 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.qs
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.media.MediaHost
import com.android.systemui.plugins.qs.QSTile
import com.android.systemui.qs.customize.QSCustomizerController
import com.android.systemui.qs.logging.QSLogger
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
class QuickQSPanelControllerTest : SysuiTestCase() {
@Mock
private lateinit var quickQSPanel: QuickQSPanel
@Mock
private lateinit var qsTileHost: QSTileHost
@Mock
private lateinit var qsCustomizerController: QSCustomizerController
@Mock
private lateinit var mediaHost: MediaHost
@Mock
private lateinit var metricsLogger: MetricsLogger
private val uiEventLogger = UiEventLoggerFake()
@Mock
private lateinit var qsLogger: QSLogger
private val dumpManager = DumpManager()
@Mock
private lateinit var tile: QSTile
@Mock
private lateinit var tileLayout: TileLayout
private lateinit var controller: QuickQSPanelController
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
`when`(quickQSPanel.tileLayout).thenReturn(tileLayout)
`when`(quickQSPanel.dumpableTag).thenReturn("")
controller = QuickQSPanelController(
quickQSPanel,
qsTileHost,
qsCustomizerController,
false,
mediaHost,
metricsLogger,
uiEventLogger,
qsLogger,
dumpManager
)
controller.init()
}
@After
fun tearDown() {
controller.onViewDetached()
}
@Test
fun testTileSublistWithFewerTiles_noCrash() {
`when`(quickQSPanel.numQuickTiles).thenReturn(3)
`when`(qsTileHost.tiles).thenReturn(listOf(tile, tile))
controller.setTiles()
}
@Test
fun testTileSublistWithTooManyTiles() {
val limit = 3
`when`(quickQSPanel.numQuickTiles).thenReturn(limit)
`when`(qsTileHost.tiles).thenReturn(listOf(tile, tile, tile, tile))
controller.setTiles()
verify(quickQSPanel, times(limit)).addTile(any())
}
}