Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt +2 −2 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ constructor( Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null } if (info.keycode != 0) { if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null } if (keys.isEmpty()) { Loading @@ -253,7 +253,7 @@ constructor( return ShortcutKey.Icon(iconResId) } if (baseCharacter > Char.MIN_VALUE) { return ShortcutKey.Text(baseCharacter.toString()) return ShortcutKey.Text(baseCharacter.uppercase()) } val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode] if (specialKeyLabel != null) { Loading packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt +17 −80 Original line number Diff line number Diff line Loading @@ -16,92 +16,29 @@ package com.android.systemui.keyboard.shortcut.data.source import android.content.Intent import android.content.res.Resources import android.view.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.res.R import com.android.systemui.util.icons.AppCategoryIconProvider import android.view.WindowManager import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.extensions.copy import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext class AppCategoriesShortcutsSource @Inject constructor( private val appCategoryIconProvider: AppCategoryIconProvider, @Main private val resources: Resources, private val windowManager: WindowManager, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : KeyboardShortcutGroupsSource { override suspend fun shortcutGroups(deviceId: Int) = listOf( KeyboardShortcutGroup( /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications), /* items = */ shortcuts() ) ) private suspend fun shortcuts(): List<KeyboardShortcutInfo> = listOfNotNull( assistantAppShortcutInfo(), appCategoryShortcutInfo( Intent.CATEGORY_APP_BROWSER, R.string.keyboard_shortcut_group_applications_browser, KeyEvent.KEYCODE_B ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CONTACTS, R.string.keyboard_shortcut_group_applications_contacts, KeyEvent.KEYCODE_C ), appCategoryShortcutInfo( Intent.CATEGORY_APP_EMAIL, R.string.keyboard_shortcut_group_applications_email, KeyEvent.KEYCODE_E ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CALENDAR, R.string.keyboard_shortcut_group_applications_calendar, KeyEvent.KEYCODE_K ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MAPS, R.string.keyboard_shortcut_group_applications_maps, KeyEvent.KEYCODE_M ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MUSIC, R.string.keyboard_shortcut_group_applications_music, KeyEvent.KEYCODE_P ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MESSAGING, R.string.keyboard_shortcut_group_applications_sms, KeyEvent.KEYCODE_S ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CALCULATOR, R.string.keyboard_shortcut_group_applications_calculator, KeyEvent.KEYCODE_U ), ) .sortedBy { it.label!!.toString().lowercase() } private suspend fun assistantAppShortcutInfo(): KeyboardShortcutInfo? { val assistantIcon = appCategoryIconProvider.assistantAppIcon() ?: return null return KeyboardShortcutInfo( /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications_assist), /* icon = */ assistantIcon, /* keycode = */ KeyEvent.KEYCODE_A, /* modifiers = */ KeyEvent.META_META_ON, ) override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = withContext(backgroundDispatcher) { val group = windowManager.getApplicationLaunchKeyboardShortcuts(deviceId) return@withContext if (group == null) { emptyList() } else { val sortedShortcutItems = group.items.sortedBy { it.label!!.toString().lowercase() } listOf(group.copy(items = sortedShortcutItems)) } } private suspend fun appCategoryShortcutInfo(category: String, labelResId: Int, keycode: Int) = KeyboardShortcutInfo( /* label = */ resources.getString(labelResId), /* icon = */ appCategoryIconProvider.categoryAppIcon(category), /* keycode = */ keycode, /* modifiers = */ KeyEvent.META_META_ON, ) } packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * 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.keyboard.shortcut.extensions import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo fun KeyboardShortcutGroup.copy( label: CharSequence = getLabel(), items: List<KeyboardShortcutInfo> = getItems(), isSystemGroup: Boolean = isSystemGroup(), packageName: CharSequence? = getPackageName(), ) = KeyboardShortcutGroup(label, items, isSystemGroup).also { it.packageName = packageName } packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt +27 −173 Original line number Diff line number Diff line Loading @@ -16,21 +16,17 @@ package com.android.systemui.keyboard.shortcut.data.source import android.content.Intent.CATEGORY_APP_BROWSER import android.content.Intent.CATEGORY_APP_CALCULATOR import android.content.Intent.CATEGORY_APP_CALENDAR import android.content.Intent.CATEGORY_APP_CONTACTS import android.content.Intent.CATEGORY_APP_EMAIL import android.content.Intent.CATEGORY_APP_MAPS import android.content.Intent.CATEGORY_APP_MESSAGING import android.content.Intent.CATEGORY_APP_MUSIC import android.view.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import android.view.mockWindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.icons.fakeAppCategoryIconProvider import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before Loading @@ -43,185 +39,43 @@ class AppCategoriesShortcutsSourceTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val defaultAppIconsProvider = kosmos.fakeAppCategoryIconProvider private val source = kosmos.shortcutHelperAppCategoriesShortcutsSource private val mockWindowManager = kosmos.mockWindowManager private val source = AppCategoriesShortcutsSource(kosmos.mockWindowManager, kosmos.testDispatcher) private var appCategoriesGroup: KeyboardShortcutGroup? = null @Before fun setUp() { categoryApps.forEach { categoryAppIcon -> defaultAppIconsProvider.installCategoryApp( categoryAppIcon.category, categoryAppIcon.packageName, categoryAppIcon.iconResId ) } } @Test fun shortcutGroups_returnsSingleGroup() = testScope.runTest { assertThat(source.shortcutGroups(TEST_DEVICE_ID)).hasSize(1) } @Test fun shortcutGroups_hasAssistantIcon() = testScope.runTest { defaultAppIconsProvider.installAssistantApp(ASSISTANT_PACKAGE, ASSISTANT_ICON_RES_ID) val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Assistant" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(ASSISTANT_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(ASSISTANT_ICON_RES_ID) } @Test fun shortcutGroups_hasBrowserIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Browser" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(BROWSER_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(BROWSER_ICON_RES_ID) } @Test fun shortcutGroups_hasContactsIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Contacts" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CONTACTS_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CONTACTS_ICON_RES_ID) } @Test fun shortcutGroups_hasEmailIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Email" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(EMAIL_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(EMAIL_ICON_RES_ID) } @Test fun shortcutGroups_hasCalendarIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Calendar" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALENDAR_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALENDAR_ICON_RES_ID) } @Test fun shortcutGroups_hasMapsIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Maps" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MAPS_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MAPS_ICON_RES_ID) whenever(mockWindowManager.getApplicationLaunchKeyboardShortcuts(TEST_DEVICE_ID)) .thenAnswer { appCategoriesGroup } } @Test fun shortcutGroups_hasMessagingIcon() = fun shortcutGroups_nullResult_returnsEmptyList() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "SMS" } appCategoriesGroup = null assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MESSAGING_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MESSAGING_ICON_RES_ID) assertThat(source.shortcutGroups(TEST_DEVICE_ID)).isEmpty() } @Test fun shortcutGroups_hasMusicIcon() = fun shortcutGroups_returnsSortedList() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Music" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MUSIC_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MUSIC_ICON_RES_ID) } @Test fun shortcutGroups_hasCalculatorIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Calculator" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALCULATOR_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALCULATOR_ICON_RES_ID) } val testItems = listOf( KeyboardShortcutInfo("Info 2", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), KeyboardShortcutInfo("Info 1", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), KeyboardShortcutInfo("Info 3", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), ) appCategoriesGroup = KeyboardShortcutGroup("Test Group", testItems) @Test fun shortcutGroups_shortcutsSortedByLabelIgnoringCase() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutLabels = shortcuts.map { it.label!!.toString() } assertThat(shortcutLabels).isEqualTo(shortcutLabels.sortedBy { it.lowercase() }) val shortcutLabels = shortcuts.map { it.label.toString() } assertThat(shortcutLabels).containsExactly("Info 1", "Info 2", "Info 3").inOrder() } @Test fun shortcutGroups_noAssistantApp_excludesAssistantFromShortcuts() = testScope.runTest { val shortcutLabels = source.shortcutGroups(TEST_DEVICE_ID).first().items.map { it.label!!.toString() } assertThat(shortcutLabels).doesNotContain("Assistant") } private companion object { private const val ASSISTANT_PACKAGE = "the.assistant.app" private const val ASSISTANT_ICON_RES_ID = 123 private const val BROWSER_PACKAGE = "com.test.browser" private const val BROWSER_ICON_RES_ID = 1 private const val CONTACTS_PACKAGE = "app.test.contacts" private const val CONTACTS_ICON_RES_ID = 234 private const val EMAIL_PACKAGE = "email.app.test" private const val EMAIL_ICON_RES_ID = 351 private const val CALENDAR_PACKAGE = "app.test.calendar" private const val CALENDAR_ICON_RES_ID = 411 private const val MAPS_PACKAGE = "maps.app.package" private const val MAPS_ICON_RES_ID = 999 private const val MUSIC_PACKAGE = "com.android.music" private const val MUSIC_ICON_RES_ID = 101 private const val MESSAGING_PACKAGE = "my.sms.app" private const val MESSAGING_ICON_RES_ID = 9191 private const val CALCULATOR_PACKAGE = "that.calculator.app" private const val CALCULATOR_ICON_RES_ID = 314 private val categoryApps = listOf( CategoryApp(CATEGORY_APP_BROWSER, BROWSER_PACKAGE, BROWSER_ICON_RES_ID), CategoryApp(CATEGORY_APP_CONTACTS, CONTACTS_PACKAGE, CONTACTS_ICON_RES_ID), CategoryApp(CATEGORY_APP_EMAIL, EMAIL_PACKAGE, EMAIL_ICON_RES_ID), CategoryApp(CATEGORY_APP_CALENDAR, CALENDAR_PACKAGE, CALENDAR_ICON_RES_ID), CategoryApp(CATEGORY_APP_MAPS, MAPS_PACKAGE, MAPS_ICON_RES_ID), CategoryApp(CATEGORY_APP_MUSIC, MUSIC_PACKAGE, MUSIC_ICON_RES_ID), CategoryApp(CATEGORY_APP_MESSAGING, MESSAGING_PACKAGE, MESSAGING_ICON_RES_ID), CategoryApp(CATEGORY_APP_CALCULATOR, CALCULATOR_PACKAGE, CALCULATOR_ICON_RES_ID), ) companion object { private const val TEST_DEVICE_ID = 123 } private class CategoryApp(val category: String, val packageName: String, val iconResId: Int) } packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt +3 −1 Original line number Diff line number Diff line Loading @@ -19,4 +19,6 @@ package android.view import com.android.systemui.kosmos.Kosmos import org.mockito.Mockito.mock val Kosmos.windowManager by Kosmos.Fixture<WindowManager> { mock(WindowManager::class.java) } val Kosmos.mockWindowManager: WindowManager by Kosmos.Fixture { mock(WindowManager::class.java) } var Kosmos.windowManager: WindowManager by Kosmos.Fixture { mockWindowManager } Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperCategoriesRepository.kt +2 −2 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ constructor( Log.wtf(TAG, "Unsupported modifiers remaining: $remainingModifiers") return null } if (info.keycode != 0) { if (info.keycode != 0 || info.baseCharacter > Char.MIN_VALUE) { keys += toShortcutKey(keyCharacterMap, info.keycode, info.baseCharacter) ?: return null } if (keys.isEmpty()) { Loading @@ -253,7 +253,7 @@ constructor( return ShortcutKey.Icon(iconResId) } if (baseCharacter > Char.MIN_VALUE) { return ShortcutKey.Text(baseCharacter.toString()) return ShortcutKey.Text(baseCharacter.uppercase()) } val specialKeyLabel = ShortcutHelperKeys.specialKeyLabels[keyCode] if (specialKeyLabel != null) { Loading
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSource.kt +17 −80 Original line number Diff line number Diff line Loading @@ -16,92 +16,29 @@ package com.android.systemui.keyboard.shortcut.data.source import android.content.Intent import android.content.res.Resources import android.view.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.res.R import com.android.systemui.util.icons.AppCategoryIconProvider import android.view.WindowManager import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.keyboard.shortcut.extensions.copy import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext class AppCategoriesShortcutsSource @Inject constructor( private val appCategoryIconProvider: AppCategoryIconProvider, @Main private val resources: Resources, private val windowManager: WindowManager, @Background private val backgroundDispatcher: CoroutineDispatcher, ) : KeyboardShortcutGroupsSource { override suspend fun shortcutGroups(deviceId: Int) = listOf( KeyboardShortcutGroup( /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications), /* items = */ shortcuts() ) ) private suspend fun shortcuts(): List<KeyboardShortcutInfo> = listOfNotNull( assistantAppShortcutInfo(), appCategoryShortcutInfo( Intent.CATEGORY_APP_BROWSER, R.string.keyboard_shortcut_group_applications_browser, KeyEvent.KEYCODE_B ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CONTACTS, R.string.keyboard_shortcut_group_applications_contacts, KeyEvent.KEYCODE_C ), appCategoryShortcutInfo( Intent.CATEGORY_APP_EMAIL, R.string.keyboard_shortcut_group_applications_email, KeyEvent.KEYCODE_E ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CALENDAR, R.string.keyboard_shortcut_group_applications_calendar, KeyEvent.KEYCODE_K ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MAPS, R.string.keyboard_shortcut_group_applications_maps, KeyEvent.KEYCODE_M ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MUSIC, R.string.keyboard_shortcut_group_applications_music, KeyEvent.KEYCODE_P ), appCategoryShortcutInfo( Intent.CATEGORY_APP_MESSAGING, R.string.keyboard_shortcut_group_applications_sms, KeyEvent.KEYCODE_S ), appCategoryShortcutInfo( Intent.CATEGORY_APP_CALCULATOR, R.string.keyboard_shortcut_group_applications_calculator, KeyEvent.KEYCODE_U ), ) .sortedBy { it.label!!.toString().lowercase() } private suspend fun assistantAppShortcutInfo(): KeyboardShortcutInfo? { val assistantIcon = appCategoryIconProvider.assistantAppIcon() ?: return null return KeyboardShortcutInfo( /* label = */ resources.getString(R.string.keyboard_shortcut_group_applications_assist), /* icon = */ assistantIcon, /* keycode = */ KeyEvent.KEYCODE_A, /* modifiers = */ KeyEvent.META_META_ON, ) override suspend fun shortcutGroups(deviceId: Int): List<KeyboardShortcutGroup> = withContext(backgroundDispatcher) { val group = windowManager.getApplicationLaunchKeyboardShortcuts(deviceId) return@withContext if (group == null) { emptyList() } else { val sortedShortcutItems = group.items.sortedBy { it.label!!.toString().lowercase() } listOf(group.copy(items = sortedShortcutItems)) } } private suspend fun appCategoryShortcutInfo(category: String, labelResId: Int, keycode: Int) = KeyboardShortcutInfo( /* label = */ resources.getString(labelResId), /* icon = */ appCategoryIconProvider.categoryAppIcon(category), /* keycode = */ keycode, /* modifiers = */ KeyEvent.META_META_ON, ) }
packages/SystemUI/src/com/android/systemui/keyboard/shortcut/extensions/KeyboardShortcutGroupExtensions.kt 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * 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.keyboard.shortcut.extensions import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo fun KeyboardShortcutGroup.copy( label: CharSequence = getLabel(), items: List<KeyboardShortcutInfo> = getItems(), isSystemGroup: Boolean = isSystemGroup(), packageName: CharSequence? = getPackageName(), ) = KeyboardShortcutGroup(label, items, isSystemGroup).also { it.packageName = packageName }
packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/data/source/AppCategoriesShortcutsSourceTest.kt +27 −173 Original line number Diff line number Diff line Loading @@ -16,21 +16,17 @@ package com.android.systemui.keyboard.shortcut.data.source import android.content.Intent.CATEGORY_APP_BROWSER import android.content.Intent.CATEGORY_APP_CALCULATOR import android.content.Intent.CATEGORY_APP_CALENDAR import android.content.Intent.CATEGORY_APP_CONTACTS import android.content.Intent.CATEGORY_APP_EMAIL import android.content.Intent.CATEGORY_APP_MAPS import android.content.Intent.CATEGORY_APP_MESSAGING import android.content.Intent.CATEGORY_APP_MUSIC import android.view.KeyEvent import android.view.KeyboardShortcutGroup import android.view.KeyboardShortcutInfo import android.view.mockWindowManager import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.keyboard.shortcut.shortcutHelperAppCategoriesShortcutsSource import com.android.systemui.kosmos.testDispatcher import com.android.systemui.kosmos.testScope import com.android.systemui.testKosmos import com.android.systemui.util.icons.fakeAppCategoryIconProvider import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Before Loading @@ -43,185 +39,43 @@ class AppCategoriesShortcutsSourceTest : SysuiTestCase() { private val kosmos = testKosmos() private val testScope = kosmos.testScope private val defaultAppIconsProvider = kosmos.fakeAppCategoryIconProvider private val source = kosmos.shortcutHelperAppCategoriesShortcutsSource private val mockWindowManager = kosmos.mockWindowManager private val source = AppCategoriesShortcutsSource(kosmos.mockWindowManager, kosmos.testDispatcher) private var appCategoriesGroup: KeyboardShortcutGroup? = null @Before fun setUp() { categoryApps.forEach { categoryAppIcon -> defaultAppIconsProvider.installCategoryApp( categoryAppIcon.category, categoryAppIcon.packageName, categoryAppIcon.iconResId ) } } @Test fun shortcutGroups_returnsSingleGroup() = testScope.runTest { assertThat(source.shortcutGroups(TEST_DEVICE_ID)).hasSize(1) } @Test fun shortcutGroups_hasAssistantIcon() = testScope.runTest { defaultAppIconsProvider.installAssistantApp(ASSISTANT_PACKAGE, ASSISTANT_ICON_RES_ID) val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Assistant" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(ASSISTANT_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(ASSISTANT_ICON_RES_ID) } @Test fun shortcutGroups_hasBrowserIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Browser" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(BROWSER_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(BROWSER_ICON_RES_ID) } @Test fun shortcutGroups_hasContactsIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Contacts" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CONTACTS_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CONTACTS_ICON_RES_ID) } @Test fun shortcutGroups_hasEmailIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Email" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(EMAIL_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(EMAIL_ICON_RES_ID) } @Test fun shortcutGroups_hasCalendarIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Calendar" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALENDAR_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALENDAR_ICON_RES_ID) } @Test fun shortcutGroups_hasMapsIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Maps" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MAPS_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MAPS_ICON_RES_ID) whenever(mockWindowManager.getApplicationLaunchKeyboardShortcuts(TEST_DEVICE_ID)) .thenAnswer { appCategoriesGroup } } @Test fun shortcutGroups_hasMessagingIcon() = fun shortcutGroups_nullResult_returnsEmptyList() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "SMS" } appCategoriesGroup = null assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MESSAGING_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MESSAGING_ICON_RES_ID) assertThat(source.shortcutGroups(TEST_DEVICE_ID)).isEmpty() } @Test fun shortcutGroups_hasMusicIcon() = fun shortcutGroups_returnsSortedList() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Music" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(MUSIC_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(MUSIC_ICON_RES_ID) } @Test fun shortcutGroups_hasCalculatorIcon() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutInfo = shortcuts.first { it.label == "Calculator" } assertThat(shortcutInfo.icon!!.resPackage).isEqualTo(CALCULATOR_PACKAGE) assertThat(shortcutInfo.icon!!.resId).isEqualTo(CALCULATOR_ICON_RES_ID) } val testItems = listOf( KeyboardShortcutInfo("Info 2", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), KeyboardShortcutInfo("Info 1", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), KeyboardShortcutInfo("Info 3", KeyEvent.KEYCODE_E, KeyEvent.META_META_ON), ) appCategoriesGroup = KeyboardShortcutGroup("Test Group", testItems) @Test fun shortcutGroups_shortcutsSortedByLabelIgnoringCase() = testScope.runTest { val shortcuts = source.shortcutGroups(TEST_DEVICE_ID).first().items val shortcutLabels = shortcuts.map { it.label!!.toString() } assertThat(shortcutLabels).isEqualTo(shortcutLabels.sortedBy { it.lowercase() }) val shortcutLabels = shortcuts.map { it.label.toString() } assertThat(shortcutLabels).containsExactly("Info 1", "Info 2", "Info 3").inOrder() } @Test fun shortcutGroups_noAssistantApp_excludesAssistantFromShortcuts() = testScope.runTest { val shortcutLabels = source.shortcutGroups(TEST_DEVICE_ID).first().items.map { it.label!!.toString() } assertThat(shortcutLabels).doesNotContain("Assistant") } private companion object { private const val ASSISTANT_PACKAGE = "the.assistant.app" private const val ASSISTANT_ICON_RES_ID = 123 private const val BROWSER_PACKAGE = "com.test.browser" private const val BROWSER_ICON_RES_ID = 1 private const val CONTACTS_PACKAGE = "app.test.contacts" private const val CONTACTS_ICON_RES_ID = 234 private const val EMAIL_PACKAGE = "email.app.test" private const val EMAIL_ICON_RES_ID = 351 private const val CALENDAR_PACKAGE = "app.test.calendar" private const val CALENDAR_ICON_RES_ID = 411 private const val MAPS_PACKAGE = "maps.app.package" private const val MAPS_ICON_RES_ID = 999 private const val MUSIC_PACKAGE = "com.android.music" private const val MUSIC_ICON_RES_ID = 101 private const val MESSAGING_PACKAGE = "my.sms.app" private const val MESSAGING_ICON_RES_ID = 9191 private const val CALCULATOR_PACKAGE = "that.calculator.app" private const val CALCULATOR_ICON_RES_ID = 314 private val categoryApps = listOf( CategoryApp(CATEGORY_APP_BROWSER, BROWSER_PACKAGE, BROWSER_ICON_RES_ID), CategoryApp(CATEGORY_APP_CONTACTS, CONTACTS_PACKAGE, CONTACTS_ICON_RES_ID), CategoryApp(CATEGORY_APP_EMAIL, EMAIL_PACKAGE, EMAIL_ICON_RES_ID), CategoryApp(CATEGORY_APP_CALENDAR, CALENDAR_PACKAGE, CALENDAR_ICON_RES_ID), CategoryApp(CATEGORY_APP_MAPS, MAPS_PACKAGE, MAPS_ICON_RES_ID), CategoryApp(CATEGORY_APP_MUSIC, MUSIC_PACKAGE, MUSIC_ICON_RES_ID), CategoryApp(CATEGORY_APP_MESSAGING, MESSAGING_PACKAGE, MESSAGING_ICON_RES_ID), CategoryApp(CATEGORY_APP_CALCULATOR, CALCULATOR_PACKAGE, CALCULATOR_ICON_RES_ID), ) companion object { private const val TEST_DEVICE_ID = 123 } private class CategoryApp(val category: String, val packageName: String, val iconResId: Int) }
packages/SystemUI/tests/utils/src/android/view/WindowManagerKosmos.kt +3 −1 Original line number Diff line number Diff line Loading @@ -19,4 +19,6 @@ package android.view import com.android.systemui.kosmos.Kosmos import org.mockito.Mockito.mock val Kosmos.windowManager by Kosmos.Fixture<WindowManager> { mock(WindowManager::class.java) } val Kosmos.mockWindowManager: WindowManager by Kosmos.Fixture { mock(WindowManager::class.java) } var Kosmos.windowManager: WindowManager by Kosmos.Fixture { mockWindowManager }