summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Fabián Kozynski <kozynski@google.com> 2024-09-03 14:52:30 -0400
committer Fabián Kozynski <kozynski@google.com> 2024-09-09 14:02:01 -0400
commit29e397412d87de8ed7ed724a9ed9407f600a58fa (patch)
treed591ed921cc59ceb9c166ebeac191592c056658a
parent366dbf89935270dc68b2a98346c875191db01ce7 (diff)
Add categories to tiles for edit mode
This CL adds categories to the QSTileConfig. These are used for grouping and sorting the tiles that can be added into groups, making them easier to parse. Test: manual Test: atest GroupAndSortCategoryAndNameTest Bug: 364329418 Flag: com.android.systemui.qs_ui_refactor_compose_fragment Change-Id: I2ef086502d68f4d2ea484411e2d1d6101d02075a
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt7
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt5
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt6
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt20
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt87
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt4
-rw-r--r--packages/SystemUI/res/values/strings.xml29
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt8
-rw-r--r--packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt39
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModel.kt72
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt37
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt6
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelKosmos.kt4
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt2
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt3
33 files changed, 401 insertions, 97 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
index e1f73e304b9e..4e8121f14e4b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/common/ui/compose/TextExt.kt
@@ -17,9 +17,12 @@
package com.android.systemui.common.ui.compose
+import android.content.Context
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.AnnotatedString
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.shared.model.Text.Companion.loadText
/** Returns the loaded [String] or `null` if there isn't one. */
@Composable
@@ -29,3 +32,7 @@ fun Text.load(): String? {
is Text.Resource -> stringResource(res)
}
}
+
+fun Text.toAnnotatedString(context: Context): AnnotatedString? {
+ return loadText(context)?.let { AnnotatedString(it) }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
index 1e5599bfe1d5..93ba26517e37 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepositoryTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.qs.panels.data.repository
import android.content.ComponentName
import android.content.packageManager
import android.content.pm.PackageManager
-import android.content.pm.ServiceInfo
import android.content.pm.UserInfo
import android.graphics.drawable.TestStubDrawable
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -35,6 +34,7 @@ import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesCompon
import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository
import com.android.systemui.qs.pipeline.data.repository.installedTilesRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.fakeUserTracker
import com.android.systemui.testKosmos
@@ -100,6 +100,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)),
Text.Loaded(tileService1),
Text.Loaded(appName1),
+ TileCategory.PROVIDED_BY_APP,
)
val expectedData2 =
EditTileData(
@@ -107,6 +108,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable2, ContentDescription.Loaded(tileService2)),
Text.Loaded(tileService2),
Text.Loaded(appName2),
+ TileCategory.PROVIDED_BY_APP,
)
assertThat(editTileDataList).containsExactly(expectedData1, expectedData2)
@@ -144,6 +146,7 @@ class IconAndNameCustomRepositoryTest : SysuiTestCase() {
Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)),
Text.Loaded(tileService1),
Text.Loaded(appName1),
+ TileCategory.PROVIDED_BY_APP,
)
val editTileDataList = underTest.getCustomTileData()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
index deefbf585ba9..053a59aa533a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
@@ -31,6 +31,7 @@ import com.android.systemui.qs.panels.shared.model.EditTileData
import com.android.systemui.qs.pipeline.data.repository.FakeInstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig
@@ -132,6 +133,7 @@ class EditTilesListInteractorTest : SysuiTestCase() {
icon = Icon.Loaded(icon, ContentDescription.Loaded(tileName)),
label = Text.Loaded(tileName),
appName = Text.Loaded(appName),
+ category = TileCategory.PROVIDED_BY_APP,
)
assertThat(editTiles.customTiles).hasSize(1)
@@ -181,7 +183,8 @@ class EditTilesListInteractorTest : SysuiTestCase() {
tileSpec = this,
icon = Icon.Resource(android.R.drawable.star_on, ContentDescription.Loaded(spec)),
label = Text.Loaded(spec),
- appName = null
+ appName = null,
+ category = TileCategory.UNKNOWN,
)
}
@@ -192,6 +195,7 @@ class EditTilesListInteractorTest : SysuiTestCase() {
Icon.Resource(uiConfig.iconRes, ContentDescription.Resource(uiConfig.labelRes)),
label = Text.Resource(uiConfig.labelRes),
appName = null,
+ category = category,
)
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
index 7f01fad1ce55..484a8ff973c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/compose/EditTileListStateTest.kt
@@ -16,11 +16,11 @@
package com.android.systemui.qs.panels.ui.compose
+import androidx.compose.ui.text.AnnotatedString
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.model.GridCell
@@ -28,6 +28,7 @@ import com.android.systemui.qs.panels.ui.model.SpacerGridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@@ -141,10 +142,11 @@ class EditTileListStateTest : SysuiTestCase() {
EditTileViewModel(
tileSpec = TileSpec.create(tileSpec),
icon = Icon.Resource(0, null),
- label = Text.Loaded("unused"),
+ label = AnnotatedString("unused"),
appName = null,
isCurrent = true,
availableEditActions = emptySet(),
+ category = TileCategory.UNKNOWN,
),
width,
)
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 601779f8fb02..583db722a759 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
@@ -26,6 +26,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
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.testScope
@@ -42,6 +43,7 @@ import com.android.systemui.qs.pipeline.data.repository.fakeMinimumTilesReposito
import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.qsTileFactory
+import com.android.systemui.qs.shared.model.TileCategory
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
@@ -190,7 +192,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
.forEach {
val data = getEditTileData(it.tileSpec)
- assertThat(it.label).isEqualTo(data.label)
+ assertThat(it.label).isEqualTo(data.label.toAnnotatedString(context))
assertThat(it.icon).isEqualTo(data.icon)
assertThat(it.appName).isNull()
}
@@ -224,15 +226,19 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
// service1
val model1 = tiles!!.first { it.tileSpec == TileSpec.create(component1) }
- assertThat(model1.label).isEqualTo(Text.Loaded(tileService1))
- assertThat(model1.appName).isEqualTo(Text.Loaded(appName1))
+ assertThat(model1.label)
+ .isEqualTo(Text.Loaded(tileService1).toAnnotatedString(context))
+ assertThat(model1.appName)
+ .isEqualTo(Text.Loaded(appName1).toAnnotatedString(context))
assertThat(model1.icon)
.isEqualTo(Icon.Loaded(drawable1, ContentDescription.Loaded(tileService1)))
// service2
val model2 = tiles!!.first { it.tileSpec == TileSpec.create(component2) }
- assertThat(model2.label).isEqualTo(Text.Loaded(tileService2))
- assertThat(model2.appName).isEqualTo(Text.Loaded(appName2))
+ assertThat(model2.label)
+ .isEqualTo(Text.Loaded(tileService2).toAnnotatedString(context))
+ assertThat(model2.appName)
+ .isEqualTo(Text.Loaded(appName2).toAnnotatedString(context))
assertThat(model2.icon)
.isEqualTo(Icon.Loaded(drawable2, ContentDescription.Loaded(tileService2)))
}
@@ -559,7 +565,8 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
tileSpec = this,
icon = Icon.Resource(R.drawable.star_on, ContentDescription.Loaded(spec)),
label = Text.Loaded(spec),
- appName = null
+ appName = null,
+ category = TileCategory.UNKNOWN,
)
}
@@ -570,6 +577,7 @@ class EditModeViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
Icon.Resource(uiConfig.iconRes, ContentDescription.Resource(uiConfig.labelRes)),
label = Text.Resource(uiConfig.labelRes),
appName = null,
+ category = category,
)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt
new file mode 100644
index 000000000000..7f90e3b6f5e0
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/shared/model/GroupAndSortCategoryAndNameTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 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.shared.model
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class GroupAndSortCategoryAndNameTest : SysuiTestCase() {
+
+ private val elements =
+ listOf(
+ CategoryAndName(TileCategory.DISPLAY, "B"),
+ CategoryAndName(TileCategory.PRIVACY, "A"),
+ CategoryAndName(TileCategory.DISPLAY, "C"),
+ CategoryAndName(TileCategory.UTILITIES, "B"),
+ CategoryAndName(TileCategory.CONNECTIVITY, "A"),
+ CategoryAndName(TileCategory.PROVIDED_BY_APP, "B"),
+ CategoryAndName(TileCategory.CONNECTIVITY, "C"),
+ CategoryAndName(TileCategory.ACCESSIBILITY, "A")
+ )
+
+ @Test
+ fun allElementsInResult() {
+ val grouped = groupAndSort(elements)
+ val allValues = grouped.values.reduce { acc, el -> acc + el }
+ assertThat(allValues).containsExactlyElementsIn(elements)
+ }
+
+ @Test
+ fun groupedByCategory() {
+ val grouped = groupAndSort(elements)
+ grouped.forEach { tileCategory, categoryAndNames ->
+ categoryAndNames.forEach { element ->
+ assertThat(element.category).isEqualTo(tileCategory)
+ }
+ }
+ }
+
+ @Test
+ fun sortedAlphabeticallyInEachCategory() {
+ val grouped = groupAndSort(elements)
+ grouped.values.forEach { elements ->
+ assertThat(elements.map(CategoryAndName::name)).isInOrder()
+ }
+ }
+
+ @Test
+ fun categoriesSortedInNaturalOrder() {
+ val grouped = groupAndSort(elements)
+ assertThat(grouped.keys).isInOrder()
+ }
+
+ @Test
+ fun missingCategoriesAreNotInResult() {
+ val grouped = groupAndSort(elements.filterNot { it.category == TileCategory.CONNECTIVITY })
+ assertThat(grouped.keys).doesNotContain(TileCategory.CONNECTIVITY)
+ }
+
+ companion object {
+ private fun CategoryAndName(category: TileCategory, name: String): CategoryAndName {
+ return object : CategoryAndName {
+ override val category = category
+ override val name = name
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
index 244422943309..fa6d8bf4a317 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
@@ -24,6 +24,7 @@ import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testCase
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.qs.qsEventLogger
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
@@ -43,7 +44,8 @@ class IssueRecordingMapperTest : SysuiTestCase() {
QSTileConfig(
TileSpec.create(RecordIssueModule.TILE_SPEC),
uiConfig,
- kosmos.qsEventLogger.getNewInstanceId()
+ kosmos.qsEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
)
private val resources = kosmos.mainResources
private val theme = resources.newTheme()
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e6cc6cf766c6..5ffa07d48b75 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -3787,4 +3787,33 @@ Action + ESC for this.</string>
<!-- Toast message for notifying users to use regular brightness bar to lower the brightness. [CHAR LIMIT=NONE] -->
<string name="accessibility_deprecate_extra_dim_dialog_toast">
Extra dim shortcut removed. To lower your brightness, use the regular brightness bar.</string>
+
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to connectivity, e.g. Internet. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_connectivity">
+ Connectivity
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to accessibility functions, e.g. Hearing devices. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_accessibility">
+ Accessibility
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to general utilities, e.g. Flashlight. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_utilities">
+ Utilities
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to privacy, e.g. Mic access. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_privacy">
+ Privacy
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are provided by an app, e.g. Calculator. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_providedByApps">
+ Provided by apps
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles that are related to the display, e.g. Dark theme. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_display">
+ Display
+ </string>
+ <!-- Label for category in QS Edit mode list of tiles, for tiles with an unknown category. [CHAR LIMIT=NONE] -->
+ <string name="qs_edit_mode_category_unknown">
+ Unknown
+ </string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
index bb80396c70fb..cd9efaf6e6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.accessibility.qs
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.ColorCorrectionTile
import com.android.systemui.qs.tiles.ColorInversionTile
@@ -179,6 +180,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_color_correction_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject ColorCorrectionTile into tileViewModelMap in QSModule */
@@ -210,6 +212,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_inversion_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject ColorInversionTile into tileViewModelMap in QSModule */
@@ -241,6 +244,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_font_scaling_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject FontScaling Tile into tileViewModelMap in QSModule */
@@ -272,6 +276,7 @@ interface QSAccessibilityModule {
labelRes = com.android.internal.R.string.reduce_bright_colors_feature_name,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
@Provides
@@ -286,6 +291,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_hearing_devices_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/**
@@ -322,6 +328,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_onehanded_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.ACCESSIBILITY,
)
/** Inject One Handed Mode Tile into tileViewModelMap in QSModule. */
@@ -355,6 +362,7 @@ interface QSAccessibilityModule {
labelRes = R.string.quick_settings_night_display_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/**
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
index 8a9a322ff100..831bc1da5a79 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
@@ -2,6 +2,7 @@ package com.android.systemui.battery
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.BatterySaverTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -33,7 +34,7 @@ interface BatterySaverModule {
@IntoMap
@StringKey(BATTERY_SAVER_TILE_SPEC)
fun provideBatterySaverAvailabilityInteractor(
- impl: BatterySaverTileDataInteractor
+ impl: BatterySaverTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -51,6 +52,7 @@ interface BatterySaverModule {
labelRes = R.string.battery_detail_switch_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject BatterySaverTile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index db7ffc1bef79..037b6facc50d 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -48,6 +48,7 @@ import com.android.systemui.controls.ui.ControlsUiControllerImpl
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.DeviceControlsTile
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
@@ -86,15 +87,16 @@ abstract class ControlsModule {
@IntoMap
@StringKey(DEVICE_CONTROLS_SPEC)
fun provideDeviceControlsTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
- QSTileConfig(
- tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
- uiConfig =
- QSTileUIConfig.Resource(
- iconRes = com.android.systemui.res.R.drawable.controls_icon,
- labelRes = com.android.systemui.res.R.string.quick_controls_title
- ),
- instanceId = uiEventLogger.getNewInstanceId(),
- )
+ QSTileConfig(
+ tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
+ uiConfig =
+ QSTileUIConfig.Resource(
+ iconRes = com.android.systemui.res.R.drawable.controls_icon,
+ labelRes = com.android.systemui.res.R.string.quick_controls_title
+ ),
+ instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
+ )
}
@Binds
@@ -115,12 +117,12 @@ abstract class ControlsModule {
@Binds
abstract fun provideSettingsManager(
- manager: ControlsSettingsRepositoryImpl
+ manager: ControlsSettingsRepositoryImpl
): ControlsSettingsRepository
@Binds
abstract fun provideDialogManager(
- manager: ControlsSettingsDialogManagerImpl
+ manager: ControlsSettingsDialogManagerImpl
): ControlsSettingsDialogManager
@Binds
@@ -141,8 +143,7 @@ abstract class ControlsModule {
repository: SelectedComponentRepositoryImpl
): SelectedComponentRepository
- @BindsOptionalOf
- abstract fun optionalPersistenceWrapper(): ControlsFavoritePersistenceWrapper
+ @BindsOptionalOf abstract fun optionalPersistenceWrapper(): ControlsFavoritePersistenceWrapper
@BindsOptionalOf
abstract fun provideControlsTileResourceConfiguration(): ControlsTileResourceConfiguration
@@ -157,23 +158,17 @@ abstract class ControlsModule {
@Binds
@IntoMap
@ClassKey(ControlsFavoritingActivity::class)
- abstract fun provideControlsFavoritingActivity(
- activity: ControlsFavoritingActivity
- ): Activity
+ abstract fun provideControlsFavoritingActivity(activity: ControlsFavoritingActivity): Activity
@Binds
@IntoMap
@ClassKey(ControlsEditingActivity::class)
- abstract fun provideControlsEditingActivity(
- activity: ControlsEditingActivity
- ): Activity
+ abstract fun provideControlsEditingActivity(activity: ControlsEditingActivity): Activity
@Binds
@IntoMap
@ClassKey(ControlsRequestDialog::class)
- abstract fun provideControlsRequestDialog(
- activity: ControlsRequestDialog
- ): Activity
+ abstract fun provideControlsRequestDialog(activity: ControlsRequestDialog): Activity
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index f6ac7a579140..a45ad157837b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -38,6 +38,7 @@ import com.android.systemui.dreams.homecontrols.DreamServiceDelegateImpl;
import com.android.systemui.dreams.homecontrols.HomeControlsDreamService;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.shared.model.TileCategory;
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
@@ -196,6 +197,7 @@ public interface DreamModule {
R.drawable.ic_qs_screen_saver,
R.string.quick_settings_screensaver_label),
uiEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
tileSpec.getSpec(),
QSTilePolicy.NoRestrictions.INSTANCE
);
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
index 3a8fe7198ebd..ef1f8341cb15 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.qrcodescanner.dagger
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.QRCodeScannerTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -51,7 +52,7 @@ interface QRCodeScannerModule {
@IntoMap
@StringKey(QR_CODE_SCANNER_TILE_SPEC)
fun provideQrCodeScannerAvailabilityInteractor(
- impl: QRCodeScannerTileDataInteractor
+ impl: QRCodeScannerTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -69,6 +70,7 @@ interface QRCodeScannerModule {
labelRes = R.string.qr_code_scanner_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject QR Code Scanner Tile into tileViewModelMap in QSModule. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
index 28c1fbf2007d..2f054b0a82c0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/data/repository/IconAndNameCustomRepository.kt
@@ -24,10 +24,10 @@ import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.qs.panels.shared.model.EditTileData
import com.android.systemui.qs.pipeline.data.repository.InstalledTilesComponentRepository
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.settings.UserTracker
import javax.inject.Inject
import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
@SysUISingleton
@@ -60,6 +60,7 @@ constructor(
Icon.Loaded(icon, ContentDescription.Loaded(label.toString())),
Text.Loaded(label.toString()),
Text.Loaded(appName.toString()),
+ TileCategory.PROVIDED_BY_APP,
)
} else {
null
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
index 3b29422ccfc3..a2cee3b68d49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
@@ -24,6 +24,7 @@ import com.android.systemui.qs.panels.data.repository.IconAndNameCustomRepositor
import com.android.systemui.qs.panels.data.repository.StockTilesRepository
import com.android.systemui.qs.panels.domain.model.EditTilesModel
import com.android.systemui.qs.panels.shared.model.EditTileData
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
import javax.inject.Inject
@@ -53,6 +54,7 @@ constructor(
),
Text.Resource(config.uiConfig.labelRes),
null,
+ category = config.category,
)
} else {
EditTileData(
@@ -62,7 +64,8 @@ constructor(
ContentDescription.Loaded(it.spec)
),
Text.Loaded(it.spec),
- null
+ null,
+ category = TileCategory.UNKNOWN,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
index 8b70bb9f9e23..b153ef7e8a62 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/shared/model/EditTileData.kt
@@ -19,12 +19,14 @@ package com.android.systemui.qs.panels.shared.model
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
data class EditTileData(
val tileSpec: TileSpec,
val icon: Icon,
val label: Text,
val appName: Text?,
+ val category: TileCategory,
) {
init {
check(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
index 79c2eb90af20..6d96f5c13238 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/Tile.kt
@@ -34,6 +34,7 @@ import androidx.compose.animation.graphics.vector.AnimatedImageVector
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.LocalOverscrollConfiguration
+import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable
@@ -96,6 +97,8 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.util.fastMap
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.android.compose.animation.Expandable
import com.android.compose.modifiers.background
@@ -116,6 +119,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toUiState
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.groupAndSort
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.res.R
import java.util.function.Supplier
@@ -473,31 +477,39 @@ private fun AvailableTileGrid(
onClick: (TileSpec) -> Unit,
dragAndDropState: DragAndDropState,
) {
- // Available tiles aren't visible during drag and drop, so the row isn't needed
- val (otherTilesStock, otherTilesCustom) =
- tiles.map { TileGridCell(it, 0) }.partition { it.tile.appName == null }
val availableTileHeight = tileHeight(true)
val availableGridHeight = gridHeight(tiles.size, availableTileHeight, columns, tilePadding)
+ // Available tiles aren't visible during drag and drop, so the row isn't needed
+ val groupedTiles =
+ remember(tiles.fastMap { it.tile.category }, tiles.fastMap { it.tile.label }) {
+ groupAndSort(tiles.fastMap { TileGridCell(it, 0) })
+ }
+ val labelColors = TileDefaults.inactiveTileColors()
// Available tiles
TileLazyGrid(
modifier = Modifier.height(availableGridHeight).testTag(AVAILABLE_TILES_GRID_TEST_TAG),
columns = GridCells.Fixed(columns)
) {
- editTiles(
- otherTilesStock,
- ClickAction.ADD,
- onClick,
- dragAndDropState = dragAndDropState,
- showLabels = true,
- )
- editTiles(
- otherTilesCustom,
- ClickAction.ADD,
- onClick,
- dragAndDropState = dragAndDropState,
- showLabels = true,
- )
+ groupedTiles.forEach { category, tiles ->
+ stickyHeader {
+ Text(
+ text = category.label.load() ?: "",
+ fontSize = 20.sp,
+ color = labelColors.label,
+ modifier =
+ Modifier.background(Color.Black)
+ .padding(start = 16.dp, bottom = 8.dp, top = 8.dp)
+ )
+ }
+ editTiles(
+ tiles,
+ ClickAction.ADD,
+ onClick,
+ dragAndDropState = dragAndDropState,
+ showLabels = true,
+ )
+ }
}
}
@@ -619,7 +631,7 @@ fun EditTile(
showLabels: Boolean,
modifier: Modifier = Modifier,
) {
- val label = tileViewModel.label.load() ?: tileViewModel.tileSpec.spec
+ val label = tileViewModel.label.text
val colors = TileDefaults.inactiveTileColors()
TileContainer(
@@ -639,7 +651,7 @@ fun EditTile(
} else {
LargeTileContent(
label = label,
- secondaryLabel = tileViewModel.appName?.load(),
+ secondaryLabel = tileViewModel.appName?.text,
icon = tileViewModel.icon,
colors = colors,
iconShape = RoundedCornerShape(TileDefaults.InactiveCornerRadius),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
index 8ca8de762772..08ee856a0ec6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/model/TileGridCell.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.Immutable
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.splitInRowsSequence
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
+import com.android.systemui.qs.shared.model.CategoryAndName
/** Represents an item from a grid associated with a row and a span */
interface GridCell {
@@ -38,7 +39,7 @@ data class TileGridCell(
override val row: Int,
override val width: Int,
override val span: GridItemSpan = GridItemSpan(width)
-) : GridCell, SizedTile<EditTileViewModel> {
+) : GridCell, SizedTile<EditTileViewModel>, CategoryAndName by tile {
val key: String = "${tile.tileSpec.spec}-$row"
constructor(
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 42715be6f6c0..4a8aa83e7d4e 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
@@ -16,6 +16,9 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.Context
+import androidx.compose.ui.util.fastMap
+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.qs.panels.domain.interactor.EditTilesListInteractor
@@ -27,6 +30,7 @@ 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.util.kotlin.emitOnStart
import javax.inject.Inject
import javax.inject.Named
import kotlinx.coroutines.CoroutineScope
@@ -35,6 +39,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
@@ -49,6 +54,8 @@ constructor(
private val currentTilesInteractor: CurrentTilesInteractor,
private val tilesAvailabilityInteractor: TilesAvailabilityInteractor,
private val minTilesInteractor: MinimumTilesInteractor,
+ private val configurationInteractor: ConfigurationInteractor,
+ @Application private val applicationContext: Context,
@Named("Default") private val defaultGridLayout: GridLayout,
@Application private val applicationScope: CoroutineScope,
gridLayoutTypeInteractor: GridLayoutTypeInteractor,
@@ -99,38 +106,45 @@ constructor(
.map { it.tileSpec }
.minus(currentTilesInteractor.currentTilesSpecs.toSet())
)
- currentTilesInteractor.currentTiles.map { tiles ->
- val currentSpecs = tiles.map { it.spec }
- val canRemoveTiles = currentSpecs.size > minimumTiles
- val allTiles = editTilesData.stockTiles + editTilesData.customTiles
- val allTilesMap = allTiles.associate { it.tileSpec to it }
- val currentTiles = currentSpecs.map { allTilesMap.get(it) }.filterNotNull()
- val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
-
- (currentTiles + nonCurrentTiles)
- .filterNot { it.tileSpec in unavailable }
- .map {
- val current = it.tileSpec in currentSpecs
- val availableActions = buildSet {
- if (current) {
- add(AvailableEditActions.MOVE)
- if (canRemoveTiles) {
- add(AvailableEditActions.REMOVE)
+ currentTilesInteractor.currentTiles
+ .map { tiles ->
+ val currentSpecs = tiles.map { it.spec }
+ val canRemoveTiles = currentSpecs.size > minimumTiles
+ val allTiles = editTilesData.stockTiles + editTilesData.customTiles
+ val allTilesMap = allTiles.associate { it.tileSpec to it }
+ val currentTiles = currentSpecs.map { allTilesMap.get(it) }.filterNotNull()
+ val nonCurrentTiles = allTiles.filter { it.tileSpec !in currentSpecs }
+
+ (currentTiles + nonCurrentTiles)
+ .filterNot { it.tileSpec in unavailable }
+ .map {
+ val current = it.tileSpec in currentSpecs
+ val availableActions = buildSet {
+ if (current) {
+ add(AvailableEditActions.MOVE)
+ if (canRemoveTiles) {
+ add(AvailableEditActions.REMOVE)
+ }
+ } else {
+ add(AvailableEditActions.ADD)
}
- } else {
- add(AvailableEditActions.ADD)
}
+ UnloadedEditTileViewModel(
+ it.tileSpec,
+ it.icon,
+ it.label,
+ it.appName,
+ current,
+ availableActions,
+ it.category,
+ )
}
- EditTileViewModel(
- it.tileSpec,
- it.icon,
- it.label,
- it.appName,
- current,
- availableActions
- )
- }
- }
+ }
+ .combine(configurationInteractor.onAnyConfigurationChange.emitOnStart()) {
+ tiles,
+ _ ->
+ tiles.fastMap { it.load(applicationContext) }
+ }
} else {
emptyFlow()
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
index a4c86381b785..ee12736f6db4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/EditTileViewModel.kt
@@ -16,9 +16,15 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.Context
+import androidx.compose.runtime.Immutable
+import androidx.compose.ui.text.AnnotatedString
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.ui.compose.toAnnotatedString
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.CategoryAndName
+import com.android.systemui.qs.shared.model.TileCategory
/**
* View model for each tile that is available to be added/removed/moved in Edit mode.
@@ -26,14 +32,41 @@ import com.android.systemui.qs.pipeline.shared.TileSpec
* [isCurrent] indicates whether this tile is part of the current set of tiles that the user sees in
* Quick Settings.
*/
-data class EditTileViewModel(
+data class UnloadedEditTileViewModel(
val tileSpec: TileSpec,
val icon: Icon,
val label: Text,
val appName: Text?,
val isCurrent: Boolean,
val availableEditActions: Set<AvailableEditActions>,
-)
+ val category: TileCategory,
+) {
+ fun load(context: Context): EditTileViewModel {
+ return EditTileViewModel(
+ tileSpec,
+ icon,
+ label.toAnnotatedString(context) ?: AnnotatedString(tileSpec.spec),
+ appName?.toAnnotatedString(context),
+ isCurrent,
+ availableEditActions,
+ category,
+ )
+ }
+}
+
+@Immutable
+data class EditTileViewModel(
+ val tileSpec: TileSpec,
+ val icon: Icon,
+ val label: AnnotatedString,
+ val appName: AnnotatedString?,
+ val isCurrent: Boolean,
+ val availableEditActions: Set<AvailableEditActions>,
+ override val category: TileCategory,
+) : CategoryAndName {
+ override val name
+ get() = label.text
+}
enum class AvailableEditActions {
ADD,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt b/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt
new file mode 100644
index 000000000000..59cb7d3d5345
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/shared/model/TileCategory.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 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.shared.model
+
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.res.R
+
+/** Categories for tiles. This can be used to sort tiles in edit mode. */
+enum class TileCategory(val label: Text) {
+ CONNECTIVITY(Text.Resource(R.string.qs_edit_mode_category_connectivity)),
+ UTILITIES(Text.Resource(R.string.qs_edit_mode_category_utilities)),
+ DISPLAY(Text.Resource(R.string.qs_edit_mode_category_display)),
+ PRIVACY(Text.Resource(R.string.qs_edit_mode_category_privacy)),
+ ACCESSIBILITY(Text.Resource(R.string.qs_edit_mode_category_accessibility)),
+ PROVIDED_BY_APP(Text.Resource(R.string.qs_edit_mode_category_providedByApps)),
+ UNKNOWN(Text.Resource(R.string.qs_edit_mode_category_unknown)),
+}
+
+interface CategoryAndName {
+ val category: TileCategory
+ val name: String
+}
+
+/**
+ * Groups the elements of the list by [CategoryAndName.category] (with the keys sorted in the
+ * natural order of [TileCategory]), and sorts the elements of each group based on the
+ * [CategoryAndName.name].
+ */
+fun <T : CategoryAndName> groupAndSort(list: List<T>): Map<TileCategory, List<T>> {
+ val groupedByCategory = list.groupBy { it.category }.toSortedMap()
+ return groupedByCategory.mapValues { it.value.sortedBy { it.name } }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
index cdcefdb50b0f..3a9cb170040c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -21,6 +21,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.android.internal.logging.InstanceId
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
data class QSTileConfig
@JvmOverloads
@@ -28,6 +29,7 @@ constructor(
val tileSpec: TileSpec,
val uiConfig: QSTileUIConfig,
val instanceId: InstanceId,
+ val category: TileCategory,
val metricsSpec: String = tileSpec.spec,
val policy: QSTilePolicy = QSTilePolicy.NoRestrictions,
val autoRemoveOnUnavailable: Boolean = true,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
index 0609e797d53b..4dbddd91092a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
@@ -20,6 +20,7 @@ import com.android.internal.util.Preconditions
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import javax.inject.Inject
interface QSTileConfigProvider {
@@ -73,6 +74,7 @@ constructor(
spec,
QSTileUIConfig.Empty,
qsEventLogger.getNewInstanceId(),
+ category = TileCategory.PROVIDED_BY_APP,
)
is TileSpec.Invalid ->
throw IllegalArgumentException("TileSpec.Invalid doesn't support configs")
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index 907b92ce4c9b..c092c2f86799 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.recordissue
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.RecordIssueTile
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
@@ -61,6 +62,7 @@ interface RecordIssueModule {
labelRes = R.string.qs_record_issue_label
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject FlashlightTile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
index 0589e6c63931..c9712fcdaa27 100644
--- a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
@@ -19,6 +19,7 @@ package com.android.systemui.rotationlock
import com.android.systemui.camera.CameraRotationModule
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileDataInteractor
@@ -42,8 +43,9 @@ interface RotationLockNewModule {
@IntoMap
@StringKey(ROTATION_TILE_SPEC)
fun provideRotationAvailabilityInteractor(
- impl: RotationLockTileDataInteractor
+ impl: RotationLockTileDataInteractor
): QSTileAvailabilityInteractor
+
companion object {
private const val ROTATION_TILE_SPEC = "rotation"
@@ -60,6 +62,7 @@ interface RotationLockNewModule {
labelRes = R.string.quick_settings_rotation_unlocked_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject Rotation tile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
index a830e1bbfe72..9a9c576c5af6 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
@@ -21,6 +21,7 @@ import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.ScreenRecordTile
import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
@@ -74,6 +75,7 @@ interface ScreenRecordModule {
labelRes = R.string.quick_settings_screen_record_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject ScreenRecord Tile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index 400f8af99e07..dac01028ef64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -21,6 +21,7 @@ import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.SIGNAL_CALLBACK_DEPRECATION
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.AirplaneModeTile
import com.android.systemui.qs.tiles.BluetoothTile
@@ -95,21 +96,21 @@ interface ConnectivityModule {
@IntoMap
@StringKey(AIRPLANE_MODE_TILE_SPEC)
fun provideAirplaneModeAvailabilityInteractor(
- impl: AirplaneModeTileDataInteractor
+ impl: AirplaneModeTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(DATA_SAVER_TILE_SPEC)
fun provideDataSaverAvailabilityInteractor(
- impl: DataSaverTileDataInteractor
+ impl: DataSaverTileDataInteractor
): QSTileAvailabilityInteractor
@Binds
@IntoMap
@StringKey(INTERNET_TILE_SPEC)
fun provideInternetAvailabilityInteractor(
- impl: InternetTileDataInteractor
+ impl: InternetTileDataInteractor
): QSTileAvailabilityInteractor
companion object {
@@ -149,6 +150,7 @@ interface ConnectivityModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(UserManager.DISALLOW_AIRPLANE_MODE)),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject AirplaneModeTile into tileViewModelMap in QSModule */
@@ -180,6 +182,7 @@ interface ConnectivityModule {
labelRes = R.string.data_saver,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject DataSaverTile into tileViewModelMap in QSModule */
@@ -211,6 +214,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_internet_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
/** Inject InternetTile into tileViewModelMap in QSModule */
@@ -242,6 +246,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_hotspot_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
@Provides
@@ -256,6 +261,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_cast_title,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
@Provides
@@ -270,6 +276,7 @@ interface ConnectivityModule {
labelRes = R.string.quick_settings_bluetooth_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index 21ec14fc7f03..5ff77e7ab24f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -23,6 +23,7 @@ import android.os.UserManager.DISALLOW_SHARE_LOCATION
import com.android.systemui.Flags
import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.qs.tiles.AlarmTile
import com.android.systemui.qs.tiles.CameraToggleTile
@@ -157,6 +158,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_flashlight_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject FlashlightTile into tileViewModelMap in QSModule */
@@ -192,7 +194,8 @@ interface PolicyModule {
policy =
QSTilePolicy.Restricted(
listOf(DISALLOW_SHARE_LOCATION, DISALLOW_CONFIG_LOCATION)
- )
+ ),
+ category = TileCategory.PRIVACY,
)
/** Inject LocationTile into tileViewModelMap in QSModule */
@@ -225,6 +228,7 @@ interface PolicyModule {
labelRes = R.string.status_bar_alarm,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.UTILITIES,
)
/** Inject AlarmTile into tileViewModelMap in QSModule */
@@ -257,6 +261,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_ui_mode_night_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.DISPLAY,
)
/** Inject uimodenight into tileViewModelMap in QSModule */
@@ -290,6 +295,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
autoRemoveOnUnavailable = false,
+ category = TileCategory.PRIVACY,
)
/** Inject work mode into tileViewModelMap in QSModule */
@@ -323,6 +329,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(DISALLOW_CAMERA_TOGGLE)),
+ category = TileCategory.PRIVACY,
)
/** Inject camera toggle tile into tileViewModelMap in QSModule */
@@ -365,6 +372,7 @@ interface PolicyModule {
),
instanceId = uiEventLogger.getNewInstanceId(),
policy = QSTilePolicy.Restricted(listOf(DISALLOW_MICROPHONE_TOGGLE)),
+ category = TileCategory.PRIVACY,
)
/** Inject microphone toggle tile into tileViewModelMap in QSModule */
@@ -407,6 +415,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_modes_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
} else {
QSTileConfig(
@@ -417,6 +426,7 @@ interface PolicyModule {
labelRes = R.string.quick_settings_dnd_label,
),
instanceId = uiEventLogger.getNewInstanceId(),
+ category = TileCategory.CONNECTIVITY,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
index ea213cba9567..dd1c11d11d1e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
@@ -25,6 +25,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.qs.QsEventLogger;
import com.android.systemui.qs.pipeline.shared.TileSpec;
+import com.android.systemui.qs.shared.model.TileCategory;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.qs.tiles.QuickAccessWalletTile;
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
@@ -34,8 +35,6 @@ import com.android.systemui.res.R;
import com.android.systemui.wallet.controller.WalletContextualLocationsService;
import com.android.systemui.wallet.ui.WalletActivity;
-import java.util.concurrent.Executor;
-
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -43,6 +42,8 @@ import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
import dagger.multibindings.StringKey;
+import java.util.concurrent.Executor;
+
/**
* Module for injecting classes in Wallet.
*/
@@ -90,6 +91,7 @@ public abstract class WalletModule {
R.string.wallet_title
),
uiEventLogger.getNewInstanceId(),
+ TileCategory.UTILITIES,
tileSpec.getSpec(),
QSTilePolicy.NoRestrictions.INSTANCE
);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index d9faa30cb072..70af5e75105d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -31,17 +31,18 @@ import androidx.compose.ui.test.onChildren
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.text.AnnotatedString
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.FlakyTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.common.shared.model.Text
import com.android.systemui.qs.panels.shared.model.SizedTile
import com.android.systemui.qs.panels.shared.model.SizedTileImpl
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -199,10 +200,11 @@ class DragAndDropTest : SysuiTestCase() {
android.R.drawable.star_on,
ContentDescription.Loaded(tileSpec)
),
- label = Text.Loaded(tileSpec),
+ label = AnnotatedString(tileSpec),
appName = null,
isCurrent = true,
availableEditActions = emptySet(),
+ category = TileCategory.UNKNOWN,
),
getWidth(tileSpec),
)
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 b03542cb569e..33227a4fcc62 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
@@ -16,6 +16,8 @@
package com.android.systemui.qs.panels.ui.viewmodel
+import android.content.applicationContext
+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.qs.panels.domain.interactor.editTilesListInteractor
@@ -33,6 +35,8 @@ val Kosmos.editModeViewModel by
currentTilesInteractor,
tilesAvailabilityInteractor,
minimumTilesInteractor,
+ configurationInteractor,
+ applicationContext,
infiniteGridLayout,
applicationCoroutineScope,
gridLayoutTypeInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
index dceb8bff0ae7..f66125a6087e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
@@ -20,6 +20,7 @@ import android.os.UserHandle
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.qs.instanceIdSequenceFake
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
import com.android.systemui.qs.tiles.viewmodel.QSTileState
@@ -47,6 +48,7 @@ val Kosmos.customTileViewModelFactory: QSTileViewModelFactory.Component by
tileSpec,
QSTileUIConfig.Empty,
instanceIdSequenceFake.newInstanceId(),
+ category = TileCategory.PROVIDED_BY_APP,
)
object : QSTileViewModel {
override val state: StateFlow<QSTileState?> =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
index 2a0ee888db35..73d9b3233375 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
@@ -18,6 +18,7 @@ package com.android.systemui.qs.tiles.viewmodel
import com.android.internal.logging.InstanceId
import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.shared.model.TileCategory
object QSTileConfigTestBuilder {
@@ -30,12 +31,14 @@ object QSTileConfigTestBuilder {
var instanceId: InstanceId = InstanceId.fakeInstanceId(0)
var metricsSpec: String = tileSpec.spec
var policy: QSTilePolicy = QSTilePolicy.NoRestrictions
+ var category: TileCategory = TileCategory.UNKNOWN
fun build() =
QSTileConfig(
tileSpec,
uiConfig,
instanceId,
+ category,
metricsSpec,
policy,
)