summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabian Kozynski <kozynski@google.com> 2024-12-09 14:10:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-12-09 14:10:30 +0000
commit96f4465669d8568b3bc0e030d104cfc692a7af03 (patch)
treee0e351f2c8a6aae0d45b7ca5d5c31d47a5e368e2
parente324c92e55271d7676760ad79cd02f7e00f7f635 (diff)
parent60d986c97761208b566ed8860032a465318fbd01 (diff)
Merge "Add edit mode events and QQS/QS open events" into main
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt164
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt18
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt95
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt19
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt4
8 files changed, 307 insertions, 16 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 583db722a759..bbfa7e7a81ee 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -21,6 +21,7 @@ import android.content.ComponentName
import android.graphics.drawable.TestStubDrawable
import android.platform.test.flag.junit.FlagsParameterization
import androidx.test.filters.SmallTest
+import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
@@ -29,9 +30,12 @@ import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.ui.compose.toAnnotatedString
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.FakeQSFactory
import com.android.systemui.qs.FakeQSTile
+import com.android.systemui.qs.QSEditEvent
import com.android.systemui.qs.panels.data.repository.stockTilesRepository
import com.android.systemui.qs.panels.domain.interactor.FakeTileAvailabilityInteractor
import com.android.systemui.qs.panels.domain.interactor.tileAvailabilityInteractorsMap
@@ -42,8 +46,10 @@ import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesReposi
import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesRepository
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
import com.android.systemui.qs.qsTileFactory
import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig
import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
@@ -86,6 +92,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
qsFlashlightTileConfig,
qsBatterySaverTileConfig,
qsAlarmTileConfig,
+ qsAirplaneModeTileConfig,
qsCameraSensorPrivacyToggleTileConfig,
qsMicrophoneSensorPrivacyToggleTileConfig,
)
@@ -116,7 +123,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
fakeInstalledTilesRepository.setInstalledServicesForUser(
userTracker.userId,
- listOf(serviceInfo1, serviceInfo2)
+ listOf(serviceInfo1, serviceInfo2),
)
with(fakeQSTileConfigProvider) { configs.forEach { putConfig(it.tileSpec, it) } }
@@ -424,10 +431,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
testScope.runTest {
val tiles by collectLastValue(underTest.tiles)
val currentTiles =
- mutableListOf(
- TileSpec.create("flashlight"),
- TileSpec.create("airplane"),
- )
+ mutableListOf(TileSpec.create("flashlight"), TileSpec.create("airplane"))
currentTilesInteractor.setTiles(currentTiles)
assertThat(currentTiles.size).isLessThan(minNumberOfTiles)
@@ -549,6 +553,156 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
}
}
+ // UI EVENT TESTS
+
+ @Test
+ fun startEditing_onlyOneEvent() =
+ kosmos.runTest {
+ underTest.startEditing()
+ underTest.startEditing()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+ assertThat(uiEventLoggerFake[0].eventId).isEqualTo(QSEditEvent.QS_EDIT_OPEN.id)
+ }
+
+ @Test
+ fun stopEditing_notEditing_noEvent() =
+ kosmos.runTest {
+ underTest.stopEditing()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(0)
+ }
+
+ @Test
+ fun stopEditing_whenEditing_correctEvent() =
+ kosmos.runTest {
+ underTest.startEditing()
+ underTest.stopEditing()
+
+ assertThat(uiEventLoggerFake[1].eventId).isEqualTo(QSEditEvent.QS_EDIT_CLOSED.id)
+ }
+
+ @Test
+ fun addTile_correctPackageAndPosition() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ val customTile = TileSpec.create(component2)
+ currentTilesInteractor.setTiles(listOf(flashlightTile))
+ runCurrent()
+
+ underTest.addTile(airplaneTile)
+ underTest.addTile(internetTile, position = 0)
+ underTest.addTile(customTile, position = 1)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+ assertThat(position).isEqualTo(-1)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ assertThat(position).isEqualTo(0)
+ }
+ with(uiEventLoggerFake[2]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(customTile.metricSpec)
+ assertThat(position).isEqualTo(1)
+ }
+ }
+
+ @Test
+ fun addTile_alreadyThere_usesMoveEvent() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ underTest.addTile(flashlightTile) // adding at the end, should use correct position
+ underTest.addTile(internetTile, 0)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(2)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+ // adding at the end, should use correct position
+ assertThat(position).isEqualTo(2)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ assertThat(position).isEqualTo(0)
+ }
+ }
+
+ @Test
+ fun removeTileEvent() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ underTest.removeTile(airplaneTile)
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+ assertThat(packageName).isEqualTo(airplaneTile.metricSpec)
+ }
+ }
+
+ @Test
+ fun setTiles_emitsCorrectOperation_individualOperations() =
+ kosmos.runTest {
+ val flashlightTile = TileSpec.create("flashlight")
+ val airplaneTile = TileSpec.create("airplane")
+ val internetTile = TileSpec.create("internet")
+ val alarmTile = TileSpec.create("alarm")
+
+ currentTilesInteractor.setTiles(listOf(flashlightTile, airplaneTile, internetTile))
+ runCurrent()
+
+ // 0. Move flashlightTile to position 2
+ underTest.setTiles(listOf(airplaneTile, internetTile, flashlightTile))
+ runCurrent()
+
+ // 1. Add alarm tile at position 1
+ underTest.setTiles(listOf(airplaneTile, alarmTile, internetTile, flashlightTile))
+ runCurrent()
+
+ // 2. Remove internetTile
+ underTest.setTiles(listOf(airplaneTile, alarmTile, flashlightTile))
+ runCurrent()
+
+ assertThat(uiEventLoggerFake.numLogs()).isEqualTo(3)
+
+ with(uiEventLoggerFake[0]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_MOVE.id)
+ assertThat(packageName).isEqualTo(flashlightTile.metricSpec)
+ assertThat(position).isEqualTo(2)
+ }
+ with(uiEventLoggerFake[1]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_ADD.id)
+ assertThat(packageName).isEqualTo(alarmTile.metricSpec)
+ assertThat(position).isEqualTo(1)
+ }
+ with(uiEventLoggerFake[2]) {
+ assertThat(eventId).isEqualTo(QSEditEvent.QS_EDIT_REMOVE.id)
+ assertThat(packageName).isEqualTo(internetTile.metricSpec)
+ }
+ }
+
companion object {
private val drawable1 = TestStubDrawable("drawable1")
private val appName1 = "App1"
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
index 869ab6c24fce..1fc1c0fd1e6b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
@@ -85,6 +85,24 @@ class TileSpecTest : SysuiTestCase() {
assertThat(TileSpec.create("")).isEqualTo(TileSpec.Invalid)
}
+ @Test
+ fun metricSpec_invalid() {
+ assertThat(TileSpec.Invalid.metricSpec).isEmpty()
+ }
+
+ @Test
+ fun metricSpec_platform_specName() {
+ val tile = "spec"
+ assertThat(TileSpec.create(tile).metricSpec).isEqualTo(tile)
+ }
+
+ @Test
+ fun metricSpec_custom_packageName() {
+ val componentName = ComponentName("test_pkg", "test_cls")
+
+ assertThat(TileSpec.create(componentName).metricSpec).isEqualTo(componentName.packageName)
+ }
+
companion object {
private const val CUSTOM_TILE_PREFIX = "custom("
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index 8d9f49e55cea..4cf6aab30596 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -325,9 +325,15 @@ constructor(
}
SceneTransitionLayout(state = sceneState, modifier = Modifier.fillMaxSize()) {
- scene(QuickSettings) { QuickSettingsElement() }
+ scene(QuickSettings) {
+ LaunchedEffect(Unit) { viewModel.onQSOpen() }
+ QuickSettingsElement()
+ }
- scene(QuickQuickSettings) { QuickQuickSettingsElement() }
+ scene(QuickQuickSettings) {
+ LaunchedEffect(Unit) { viewModel.onQQSOpen() }
+ QuickQuickSettingsElement()
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
index 3c725203a15f..07ceb6425574 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModel.kt
@@ -28,6 +28,7 @@ import androidx.compose.runtime.snapshotFlow
import androidx.lifecycle.LifecycleCoroutineScope
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launchTraced as launch
+import com.android.internal.logging.UiEventLogger
import com.android.keyguard.BouncerPanelExpansionCalculator
import com.android.systemui.Dumpable
import com.android.systemui.animation.ShadeInterpolation
@@ -51,6 +52,7 @@ import com.android.systemui.media.dagger.MediaModule.QS_PANEL
import com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.FooterActionsController
+import com.android.systemui.qs.QSEvent
import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeLog
import com.android.systemui.qs.composefragment.dagger.QSFragmentComposeModule
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
@@ -113,6 +115,7 @@ constructor(
@Named(QUICK_QS_PANEL) val qqsMediaHost: MediaHost,
@Named(QS_PANEL) val qsMediaHost: MediaHost,
@Named(QSFragmentComposeModule.QS_USING_MEDIA_PLAYER) private val usingMedia: Boolean,
+ private val uiEventLogger: UiEventLogger,
@Assisted private val lifecycleScope: LifecycleCoroutineScope,
) : Dumpable, ExclusiveActivatable() {
@@ -455,6 +458,14 @@ constructor(
falsingInteractor.isFalseTouch(Classifier.QS_SWIPE_NESTED)
}
+ fun onQQSOpen() {
+ uiEventLogger.log(QSEvent.QQS_PANEL_EXPANDED)
+ }
+
+ fun onQSOpen() {
+ uiEventLogger.log(QSEvent.QS_PANEL_EXPANDED)
+ }
+
override suspend fun onActivated(): Nothing {
initMediaHosts() // init regardless of using media (same as current QS).
coroutineScope {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
index faab6960a99c..f7ed1adecb34 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt
@@ -18,9 +18,14 @@ package com.android.systemui.qs.panels.ui.viewmodel
import android.content.Context
import androidx.compose.ui.util.fastMap
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListUpdateCallback
+import com.android.internal.logging.UiEventLogger
import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.QSEditEvent
import com.android.systemui.qs.panels.domain.interactor.EditTilesListInteractor
import com.android.systemui.qs.panels.domain.interactor.GridLayoutTypeInteractor
import com.android.systemui.qs.panels.domain.interactor.TilesAvailabilityInteractor
@@ -30,10 +35,12 @@ import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor.Companion.POSITION_AT_END
import com.android.systemui.qs.pipeline.domain.interactor.MinimumTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.pipeline.shared.metricSpec
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.util.kotlin.emitOnStart
import javax.inject.Inject
import javax.inject.Named
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
@@ -45,6 +52,7 @@ import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
@SysUISingleton
@OptIn(ExperimentalCoroutinesApi::class)
@@ -55,10 +63,12 @@ constructor(
private val currentTilesInteractor: CurrentTilesInteractor,
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
+ private val uiEventLogger: UiEventLogger,
@ShadeDisplayAware private val configurationInteractor: ConfigurationInteractor,
- @ShadeDisplayAware private val context: Context,
+ @ShadeDisplayAware private val context: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
+ @Background private val bgDispatcher: CoroutineDispatcher,
gridLayoutTypeInteractor: GridLayoutTypeInteractor,
gridLayoutMap: Map<GridLayoutType, @JvmSuppressWildcards GridLayout>,
) {
@@ -149,11 +159,17 @@ constructor(
/** @see isEditing */
fun startEditing() {
+ if (!isEditing.value) {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_OPEN)
+ }
_isEditing.value = true
}
/** @see isEditing */
fun stopEditing() {
+ if (isEditing.value) {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_CLOSED)
+ }
_isEditing.value = false
}
@@ -164,6 +180,7 @@ constructor(
fun addTile(tileSpec: TileSpec, position: Int = POSITION_AT_END) {
val specs = currentTilesInteractor.currentTilesSpecs.toMutableList()
val currentPosition = specs.indexOf(tileSpec)
+ val moved = currentPosition != -1
if (currentPosition != -1) {
// No operation needed if the element is already in the list at the right position
@@ -179,6 +196,12 @@ constructor(
} else {
specs.add(tileSpec)
}
+ uiEventLogger.logWithPosition(
+ if (moved) QSEditEvent.QS_EDIT_MOVE else QSEditEvent.QS_EDIT_ADD,
+ /* uid= */ 0,
+ /* packageName= */ tileSpec.metricSpec,
+ if (moved && position == POSITION_AT_END) specs.size - 1 else position,
+ )
// Setting the new tiles as one operation to avoid UI jank with tiles disappearing and
// reappearing
@@ -187,10 +210,80 @@ constructor(
/** Immediately removes [tileSpec] from the current tiles. */
fun removeTile(tileSpec: TileSpec) {
+ uiEventLogger.log(
+ QSEditEvent.QS_EDIT_REMOVE,
+ /* uid= */ 0,
+ /* packageName= */ tileSpec.metricSpec,
+ )
currentTilesInteractor.removeTiles(listOf(tileSpec))
}
fun setTiles(tileSpecs: List<TileSpec>) {
+ val currentTiles = currentTilesInteractor.currentTilesSpecs
currentTilesInteractor.setTiles(tileSpecs)
+ applicationScope.launch(bgDispatcher) {
+ calculateDiffsAndEmitUiEvents(currentTiles, tileSpecs)
+ }
+ }
+
+ private fun calculateDiffsAndEmitUiEvents(
+ currentTiles: List<TileSpec>,
+ newTiles: List<TileSpec>,
+ ) {
+ val listDiff = DiffUtil.calculateDiff(DiffCallback(currentTiles, newTiles))
+ listDiff.dispatchUpdatesTo(
+ object : ListUpdateCallback {
+ override fun onInserted(position: Int, count: Int) {
+ newTiles.getOrNull(position)?.let {
+ uiEventLogger.logWithPosition(
+ QSEditEvent.QS_EDIT_ADD,
+ /* uid= */ 0,
+ /* packageName= */ it.metricSpec,
+ position,
+ )
+ }
+ }
+
+ override fun onRemoved(position: Int, count: Int) {
+ currentTiles.getOrNull(position)?.let {
+ uiEventLogger.log(QSEditEvent.QS_EDIT_REMOVE, 0, it.metricSpec)
+ }
+ }
+
+ override fun onMoved(fromPosition: Int, toPosition: Int) {
+ currentTiles.getOrNull(fromPosition)?.let {
+ uiEventLogger.logWithPosition(
+ QSEditEvent.QS_EDIT_MOVE,
+ /* uid= */ 0,
+ /* packageName= */ it.metricSpec,
+ toPosition,
+ )
+ }
+ }
+
+ override fun onChanged(position: Int, count: Int, payload: Any?) {}
+ }
+ )
+ }
+}
+
+private class DiffCallback(
+ private val currentList: List<TileSpec>,
+ private val newList: List<TileSpec>,
+) : DiffUtil.Callback() {
+ override fun getOldListSize(): Int {
+ return currentList.size
+ }
+
+ override fun getNewListSize(): Int {
+ return newList.size
+ }
+
+ override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return currentList[oldItemPosition] == newList[newItemPosition]
+ }
+
+ override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return areItemsTheSame(oldItemPosition, newItemPosition)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
index 2e52845ceb80..16c27223a471 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/shared/TileSpec.kt
@@ -34,10 +34,7 @@ sealed class TileSpec private constructor(open val spec: String) {
data object Invalid : TileSpec("")
/** Container for the spec of a tile provided by SystemUI. */
- data class PlatformTileSpec
- internal constructor(
- override val spec: String,
- ) : TileSpec(spec) {
+ data class PlatformTileSpec internal constructor(override val spec: String) : TileSpec(spec) {
override fun toString(): String {
return "P($spec)"
}
@@ -49,10 +46,8 @@ sealed class TileSpec private constructor(open val spec: String) {
* [componentName] indicates the associated `TileService`.
*/
data class CustomTileSpec
- internal constructor(
- override val spec: String,
- val componentName: ComponentName,
- ) : TileSpec(spec) {
+ internal constructor(override val spec: String, val componentName: ComponentName) :
+ TileSpec(spec) {
override fun toString(): String {
return "C(${componentName.flattenToShortString()})"
}
@@ -92,3 +87,11 @@ sealed class TileSpec private constructor(open val spec: String) {
}
}
}
+
+val TileSpec.metricSpec
+ get() =
+ when (this) {
+ is TileSpec.Invalid -> ""
+ is TileSpec.PlatformTileSpec -> spec
+ is TileSpec.CustomTileSpec -> componentName.packageName
+ }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
index d71bc310b0ed..49957f0b43cc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/composefragment/viewmodel/QSFragmentComposeViewModelKosmos.kt
@@ -18,6 +18,7 @@ package com.android.systemui.qs.composefragment.viewmodel
import android.content.res.mainResources
import androidx.lifecycle.LifecycleCoroutineScope
+import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.classifier.domain.interactor.falsingInteractor
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
@@ -68,6 +69,7 @@ val Kosmos.qsFragmentComposeViewModelFactory by
qqsMediaHost,
qsMediaHost,
usingMediaInComposeFragment,
+ uiEventLoggerFake,
lifecycleScope,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
index 86c3add09577..71408f6adffd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt
@@ -17,9 +17,11 @@
package com.android.systemui.qs.panels.ui.viewmodel
import android.content.applicationContext
+import com.android.internal.logging.uiEventLoggerFake
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.qs.panels.domain.interactor.editTilesListInteractor
import com.android.systemui.qs.panels.domain.interactor.gridLayoutMap
import com.android.systemui.qs.panels.domain.interactor.gridLayoutTypeInteractor
@@ -35,10 +37,12 @@ val Kosmos.editModeViewModel by
currentTilesInteractor,
tilesAvailabilityInteractor,
minimumTilesInteractor,
+ uiEventLoggerFake,
configurationInteractor,
applicationContext,
infiniteGridLayout,
applicationCoroutineScope,
+ testDispatcher,
gridLayoutTypeInteractor,
gridLayoutMap,
)