Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfcbc6ae authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Updated impl for adding/deleting custom shortcut to send appLauchData" into main

parents bd4fc429 51417ea4
Loading
Loading
Loading
Loading
+125 −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.data.repository

import android.hardware.input.AppLaunchData
import android.hardware.input.AppLaunchData.RoleData
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.fakeInputManager
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyboard.shortcut.appLaunchDataRepository
import com.android.systemui.keyboard.shortcut.shared.model.shortcutCommand
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
class AppLaunchDataRepositoryTest : SysuiTestCase() {
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val inputManager = kosmos.fakeInputManager.inputManager
    private val testHelper = kosmos.shortcutHelperTestHelper
    private val repo = kosmos.appLaunchDataRepository

    @Test
    fun appLaunchData_returnsDataRetrievedFromApiBasedOnShortcutCommand() =
        kosmos.runTest {
            val inputGesture = simpleInputGestureDataForAppLaunchShortcut()
            setApiAppLaunchBookmarks(listOf(inputGesture))

            testHelper.toggle(TEST_DEVICE_ID)

            val appLaunchData =
                repo.getAppLaunchDataForShortcutWithCommand(
                    shortcutCommand =
                        shortcutCommand {
                            key("Ctrl")
                            key("Alt")
                            key("A")
                        }
                )

            assertThat(appLaunchData).isEqualTo(inputGesture.action.appLaunchData())
        }

    @Test
    fun appLaunchData_returnsSameDataForAnyOrderOfShortcutCommandKeys() =
        kosmos.runTest {
            val inputGesture = simpleInputGestureDataForAppLaunchShortcut()
            setApiAppLaunchBookmarks(listOf(inputGesture))

            testHelper.toggle(TEST_DEVICE_ID)

            val shortcutCommandCtrlAltA = shortcutCommand {
                key("Ctrl")
                key("Alt")
                key("A")
            }

            val shortcutCommandCtrlAAlt = shortcutCommand {
                key("Ctrl")
                key("A")
                key("Alt")
            }

            val shortcutCommandAltCtrlA = shortcutCommand {
                key("Alt")
                key("Ctrl")
                key("A")
            }

            assertThat(repo.getAppLaunchDataForShortcutWithCommand(shortcutCommandCtrlAltA))
                .isEqualTo(inputGesture.action.appLaunchData())

            assertThat(repo.getAppLaunchDataForShortcutWithCommand(shortcutCommandCtrlAAlt))
                .isEqualTo(inputGesture.action.appLaunchData())

            assertThat(repo.getAppLaunchDataForShortcutWithCommand(shortcutCommandAltCtrlA))
                .isEqualTo(inputGesture.action.appLaunchData())
        }

    private fun setApiAppLaunchBookmarks(appLaunchBookmarks: List<InputGestureData>) {
        whenever(inputManager.appLaunchBookmarks).thenReturn(appLaunchBookmarks)
    }

    private fun simpleInputGestureDataForAppLaunchShortcut(
        keyCode: Int = KEYCODE_A,
        modifiers: Int = META_CTRL_ON or META_ALT_ON,
        appLaunchData: AppLaunchData = RoleData(TEST_ROLE),
    ): InputGestureData {
        return InputGestureData.Builder()
            .setTrigger(createKeyTrigger(keyCode, modifiers))
            .setAppLaunchData(appLaunchData)
            .build()
    }

    private companion object {
        private const val TEST_ROLE = "Test role"
        private const val TEST_DEVICE_ID = 123
    }
}
+56 −7
Original line number Diff line number Diff line
@@ -18,14 +18,21 @@ package com.android.systemui.keyboard.shortcut.data.repository

import android.content.Context
import android.content.Context.INPUT_SERVICE
import android.hardware.input.AppLaunchData
import android.hardware.input.AppLaunchData.RoleData
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_ERROR_DOES_NOT_EXIST
import android.hardware.input.InputManager.CUSTOM_INPUT_GESTURE_RESULT_SUCCESS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION
import android.hardware.input.fakeInputManager
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.KEYCODE_SLASH
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CAPS_LOCK_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
@@ -44,14 +51,15 @@ import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.allCusto
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.customizableInputGestureWithUnknownKeyGestureType
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.expectedShortcutCategoriesWithSimpleShortcutCombination
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.goHomeInputGestureData
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.launchCalendarShortcutAddRequest
import com.android.systemui.keyboard.shortcut.data.source.TestShortcuts.standardKeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.KeyCombination
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo.Add
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo.Delete
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo.SingleShortcutCustomization
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.res.R
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.userTracker
@@ -72,7 +80,7 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {

    private val mockUserContext: Context = mock()
    private val kosmos =
        testKosmos().also {
        testKosmos().useUnconfinedTestDispatcher().also {
            it.userTracker = FakeUserTracker(onCreateCurrentUserContext = { mockUserContext })
        }

@@ -241,6 +249,32 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
        }
    }

    @Test
    fun buildInputGestureDataForAppLaunchShortcut_keyGestureTypeIsTypeLaunchApp() =
        testScope.runTest {
            setApiAppLaunchBookmarks(listOf(simpleInputGestureDataForAppLaunchShortcut()))
            helper.toggle(deviceId = 123)
            repo.onCustomizationRequested(launchCalendarShortcutAddRequest)
            repo.updateUserKeyCombination(standardKeyCombination)

            val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()

            assertThat(inputGestureData?.action?.keyGestureType())
                .isEqualTo(KEY_GESTURE_TYPE_LAUNCH_APPLICATION)
        }

    @Test
    fun buildInputGestureDataForAppLaunchShortcut_appLaunchDataIsAdded() =
        testScope.runTest {
            setApiAppLaunchBookmarks(listOf(simpleInputGestureDataForAppLaunchShortcut()))
            helper.toggle(deviceId = 123)
            repo.onCustomizationRequested(launchCalendarShortcutAddRequest)
            repo.updateUserKeyCombination(standardKeyCombination)

            val inputGestureData = repo.buildInputGestureDataForShortcutBeingCustomized()
            assertThat(inputGestureData?.action?.appLaunchData()).isNotNull()
        }

    @Test
    @EnableFlags(FLAG_ENABLE_CUSTOMIZABLE_INPUT_GESTURES, FLAG_USE_KEY_GESTURE_EVENT_HANDLER)
    fun deleteShortcut_successfullyRetrievesGestureDataAndDeletesShortcut() {
@@ -304,17 +338,17 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {

    private suspend fun customizeShortcut(
        customizationRequest: ShortcutCustomizationRequestInfo,
        keyCombination: KeyCombination? = null
        keyCombination: KeyCombination? = null,
    ): ShortcutCustomizationRequestResult {
        repo.onCustomizationRequested(customizationRequest)
        repo.updateUserKeyCombination(keyCombination)

        return when (customizationRequest) {
            is Add -> {
            is SingleShortcutCustomization.Add -> {
                repo.confirmAndSetShortcutCurrentlyBeingCustomized()
            }

            is Delete -> {
            is SingleShortcutCustomization.Delete -> {
                repo.deleteShortcutCurrentlyBeingCustomized()
            }

@@ -352,4 +386,19 @@ class CustomShortcutCategoriesRepositoryTest : SysuiTestCase() {
            assertThat(categories).isEmpty()
        }
    }

    private fun setApiAppLaunchBookmarks(appLaunchBookmarks: List<InputGestureData>) {
        whenever(inputManager.appLaunchBookmarks).thenReturn(appLaunchBookmarks)
    }

    private fun simpleInputGestureDataForAppLaunchShortcut(
        keyCode: Int = KEYCODE_A,
        modifiers: Int = META_CTRL_ON or META_ALT_ON,
        appLaunchData: AppLaunchData = RoleData("Test role"),
    ): InputGestureData {
        return InputGestureData.Builder()
            .setTrigger(createKeyTrigger(keyCode, modifiers))
            .setAppLaunchData(appLaunchData)
            .build()
    }
}
+38 −21
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.hardware.input.AppLaunchData
import android.hardware.input.AppLaunchData.RoleData
import android.hardware.input.InputGestureData
import android.hardware.input.InputGestureData.createKeyTrigger
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION
import android.view.KeyEvent.KEYCODE_A
import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
@@ -55,13 +56,14 @@ import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever


@SmallTest
@RunWith(AndroidJUnit4::class)
class InputGestureDataAdapterTest : SysuiTestCase() {

    private val kosmos = testKosmos().also { kosmos ->
        kosmos.userTracker = FakeUserTracker(onCreateCurrentUserContext = { kosmos.mockedContext })
    private val kosmos =
        testKosmos().also { kosmos ->
            kosmos.userTracker =
                FakeUserTracker(onCreateCurrentUserContext = { kosmos.mockedContext })
        }
    private val adapter = kosmos.inputGestureDataAdapter
    private val roleManager = kosmos.roleManager
@@ -139,24 +141,40 @@ class InputGestureDataAdapterTest : SysuiTestCase() {
            val inputGestureData = buildInputGestureDataForAppLaunchShortcut()
            val internalGroups = adapter.toInternalGroupSources(listOf(inputGestureData))

            assertThat(internalGroups).containsExactly(
            assertThat(internalGroups)
                .containsExactly(
                    InternalGroupsSource(
                        type = ShortcutCategoryType.AppCategories,
                    groups = listOf(
                        groups =
                            listOf(
                                InternalKeyboardShortcutGroup(
                                    label = APPLICATION_SHORTCUT_GROUP_LABEL,
                            items = listOf(
                                    items =
                                        listOf(
                                            InternalKeyboardShortcutInfo(
                                    label = expectedShortcutLabelForFirstAppMatchingIntent,
                                                label =
                                                    expectedShortcutLabelForFirstAppMatchingIntent,
                                                keycode = KEYCODE_A,
                                                modifiers = META_CTRL_ON or META_ALT_ON,
                                    isCustomShortcut = true
                                                isCustomShortcut = true,
                                            )
                                        ),
                                )
                            ),
                    )
                )
        }

    @Test
    fun keyGestureType_returnsTypeLaunchApplicationForAppLaunchShortcutCategory() =
        kosmos.runTest {
            assertThat(
                    adapter.getKeyGestureTypeForShortcut(
                        shortcutLabel = "Test Shortcut label",
                        shortcutCategoryType = ShortcutCategoryType.AppCategories,
                    )
                )
                .isEqualTo(KEY_GESTURE_TYPE_LAUNCH_APPLICATION)
        }

    private fun setApiToRetrieveResolverActivity() {
@@ -169,11 +187,10 @@ class InputGestureDataAdapterTest : SysuiTestCase() {
            .thenReturn(fakeActivityInfo)
    }


    private fun buildInputGestureDataForAppLaunchShortcut(
        keyCode: Int = KEYCODE_A,
        modifiers: Int = META_CTRL_ON or META_ALT_ON,
        appLaunchData: AppLaunchData = RoleData(TEST_ROLE)
        appLaunchData: AppLaunchData = RoleData(TEST_ROLE),
    ): InputGestureData {
        return InputGestureData.Builder()
            .setTrigger(createKeyTrigger(keyCode, modifiers))
+67 −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.data.repository

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyboard.shortcut.shortcutHelperInputDeviceRepository
import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runTest
import com.android.systemui.kosmos.useUnconfinedTestDispatcher
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class ShortcutHelperInputDeviceRepositoryTest : SysuiTestCase() {
    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
    private val testHelper = kosmos.shortcutHelperTestHelper
    private val repo = kosmos.shortcutHelperInputDeviceRepository

    @Test
    fun activeInputDevice_nullByDefault() =
        kosmos.runTest {
            val activeInputDevice by collectLastValue(repo.activeInputDevice)

            assertThat(activeInputDevice).isNull()
        }

    @Test
    fun activeInputDevice_nonNullWhenHelperIsShown() =
        kosmos.runTest {
            val activeInputDevice by collectLastValue(repo.activeInputDevice)

            testHelper.showFromActivity()

            assertThat(activeInputDevice).isNotNull()
        }

    @Test
    fun activeInputDevice_nullWhenHelperIsClosed() =
        kosmos.runTest {
            val activeInputDevice by collectLastValue(repo.activeInputDevice)

            testHelper.showFromActivity()
            testHelper.hideFromActivity()

            assertThat(activeInputDevice).isNull()
        }
}
+18 −4
Original line number Diff line number Diff line
@@ -43,11 +43,12 @@ import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MultiTasking
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.System
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCustomizationRequestInfo.SingleShortcutCustomization
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutKey
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import com.android.systemui.keyboard.shortcut.shared.model.shortcut
import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.shortcutCommand
import com.android.systemui.res.R

object TestShortcuts {
@@ -596,14 +597,27 @@ object TestShortcuts {
        )

    val allAppsShortcutAddRequest =
        ShortcutCustomizationRequestInfo.Add(
        SingleShortcutCustomization.Add(
            label = "Open apps list",
            categoryType = System,
            subCategoryLabel = "System controls",
        )

    val launchCalendarShortcutAddRequest =
        SingleShortcutCustomization.Add(
            label = "Calendar",
            categoryType = ShortcutCategoryType.AppCategories,
            subCategoryLabel = "Applications",
            shortcutCommand =
                shortcutCommand {
                    key("Ctrl")
                    key("Alt")
                    key("A")
                },
        )

    val allAppsShortcutDeleteRequest =
        ShortcutCustomizationRequestInfo.Delete(
        SingleShortcutCustomization.Delete(
            label = "Open apps list",
            categoryType = System,
            subCategoryLabel = "System controls",
@@ -698,7 +712,7 @@ object TestShortcuts {
        )

    val standardAddShortcutRequest =
        ShortcutCustomizationRequestInfo.Add(
        SingleShortcutCustomization.Add(
            label = "Standard shortcut",
            categoryType = System,
            subCategoryLabel = "Standard subcategory",
Loading