summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chaohui Wang <chaohuiw@google.com> 2022-11-16 02:16:50 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2022-11-16 02:16:50 +0000
commitc0d2dfe2d659af39f90d03a118ba3de3272bc148 (patch)
treeac9a430b70e69a88762387da87d74a443c507e6f
parent027397129047edbd330f5fc49f0d53261c6b452a (diff)
parenta907c9d949f406fe5e69e5c3f6b491dad003b476 (diff)
Merge "Support grouping in the New App List"
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListModel.kt8
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt19
-rw-r--r--packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt60
3 files changed, 74 insertions, 13 deletions
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListModel.kt
index 373b57f73ef0..a7122d0eb03a 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListModel.kt
@@ -54,6 +54,14 @@ interface AppListModel<T : AppRecord> {
)
/**
+ * Gets the group title of this item.
+ *
+ * Note: Items should be sorted by group in [getComparator] first, this [getGroupTitle] will not
+ * change the list order.
+ */
+ fun getGroupTitle(option: Int, record: T): String? = null
+
+ /**
* Gets the summary for the given app record.
*
* @return null if no summary should be displayed.
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
index 7f5fe9f75d51..681eb1c3508e 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/AppList.kt
@@ -34,9 +34,11 @@ import com.android.settingslib.spa.framework.compose.LogCompositions
import com.android.settingslib.spa.framework.compose.TimeMeasurer.Companion.rememberTimeMeasurer
import com.android.settingslib.spa.framework.compose.rememberLazyListStateAndHideKeyboardWhenStartScroll
import com.android.settingslib.spa.framework.compose.toState
+import com.android.settingslib.spa.widget.ui.CategoryTitle
import com.android.settingslib.spa.widget.ui.PlaceholderTitle
import com.android.settingslib.spaprivileged.R
import com.android.settingslib.spaprivileged.framework.compose.DisposableBroadcastReceiverAsUser
+import com.android.settingslib.spaprivileged.model.app.AppEntry
import com.android.settingslib.spaprivileged.model.app.AppListConfig
import com.android.settingslib.spaprivileged.model.app.AppListData
import com.android.settingslib.spaprivileged.model.app.AppListModel
@@ -100,17 +102,28 @@ private fun <T : AppRecord> AppListWidget(
}
items(count = list.size, key = { option to list[it].record.app.packageName }) {
+ remember(list) { listModel.getGroupTitleIfFirst(option, list, it) }
+ ?.let { group -> CategoryTitle(title = group) }
+
val appEntry = list[it]
val summary = listModel.getSummary(option, appEntry.record) ?: "".toState()
- val itemModel = remember(appEntry) {
+ appItem(remember(appEntry) {
AppListItemModel(appEntry.record, appEntry.label, summary)
- }
- appItem(itemModel)
+ })
}
}
}
}
+/** Returns group title if this is the first item of the group. */
+private fun <T : AppRecord> AppListModel<T>.getGroupTitleIfFirst(
+ option: Int,
+ list: List<AppEntry<T>>,
+ index: Int,
+): String? = getGroupTitle(option, list[index].record)?.takeIf {
+ index == 0 || it != getGroupTitle(option, list[index - 1].record)
+}
+
@Composable
private fun <T : AppRecord> loadAppListData(
config: AppListConfig,
diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
index 80c4eac9b98f..9f20c78485a8 100644
--- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
+++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/app/AppListTest.kt
@@ -58,26 +58,43 @@ class AppListTest {
@Test
fun couldShowAppItem() {
- setContent(appEntries = listOf(APP_ENTRY))
+ setContent(appEntries = listOf(APP_ENTRY_A))
- composeTestRule.onNodeWithText(APP_ENTRY.label).assertIsDisplayed()
+ composeTestRule.onNodeWithText(APP_ENTRY_A.label).assertIsDisplayed()
}
@Test
fun couldShowHeader() {
- setContent(header = { Text(HEADER) }, appEntries = listOf(APP_ENTRY))
+ setContent(appEntries = listOf(APP_ENTRY_A), header = { Text(HEADER) })
composeTestRule.onNodeWithText(HEADER).assertIsDisplayed()
}
+ @Test
+ fun whenNotGrouped_groupTitleDoesNotExist() {
+ setContent(appEntries = listOf(APP_ENTRY_A, APP_ENTRY_B), enableGrouping = false)
+
+ composeTestRule.onNodeWithText(GROUP_A).assertDoesNotExist()
+ composeTestRule.onNodeWithText(GROUP_B).assertDoesNotExist()
+ }
+
+ @Test
+ fun whenGrouped_groupTitleDisplayed() {
+ setContent(appEntries = listOf(APP_ENTRY_A, APP_ENTRY_B), enableGrouping = true)
+
+ composeTestRule.onNodeWithText(GROUP_A).assertIsDisplayed()
+ composeTestRule.onNodeWithText(GROUP_B).assertIsDisplayed()
+ }
+
private fun setContent(
- header: @Composable () -> Unit = {},
appEntries: List<AppEntry<TestAppRecord>>,
+ header: @Composable () -> Unit = {},
+ enableGrouping: Boolean = false,
) {
composeTestRule.setContent {
AppList(
config = AppListConfig(userId = USER_ID, showInstantApps = false),
- listModel = TestAppListModel(),
+ listModel = TestAppListModel(enableGrouping),
state = AppListState(
showSystem = false.toState(),
option = 0.toState(),
@@ -96,17 +113,37 @@ class AppListTest {
private companion object {
const val USER_ID = 0
const val HEADER = "Header"
- val APP_ENTRY = AppEntry(
- record = TestAppRecord(ApplicationInfo()),
- label = "AAA",
+ const val GROUP_A = "Group A"
+ const val GROUP_B = "Group B"
+ val APP_ENTRY_A = AppEntry(
+ record = TestAppRecord(
+ app = ApplicationInfo().apply {
+ packageName = "package.name.a"
+ },
+ group = GROUP_A,
+ ),
+ label = "Label A",
+ labelCollationKey = CollationKey("", byteArrayOf()),
+ )
+ val APP_ENTRY_B = AppEntry(
+ record = TestAppRecord(
+ app = ApplicationInfo().apply {
+ packageName = "package.name.b"
+ },
+ group = GROUP_B,
+ ),
+ label = "Label B",
labelCollationKey = CollationKey("", byteArrayOf()),
)
}
}
-private data class TestAppRecord(override val app: ApplicationInfo) : AppRecord
+private data class TestAppRecord(
+ override val app: ApplicationInfo,
+ val group: String? = null,
+) : AppRecord
-private class TestAppListModel : AppListModel<TestAppRecord> {
+private class TestAppListModel(val enableGrouping: Boolean) : AppListModel<TestAppRecord> {
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
appListFlow.asyncMapItem { TestAppRecord(it) }
@@ -118,4 +155,7 @@ private class TestAppListModel : AppListModel<TestAppRecord> {
option: Int,
recordListFlow: Flow<List<TestAppRecord>>,
) = recordListFlow
+
+ override fun getGroupTitle(option: Int, record: TestAppRecord) =
+ if (enableGrouping) record.group else null
}