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

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

Merge "Shortcut Helper - Create KeyboardShortcutGroupsSource interface" into main

parents 0f480daa c25bf01b
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -20,6 +20,11 @@ import android.app.Activity
import com.android.systemui.CoreStartable
import com.android.systemui.Flags.keyboardShortcutHelperRewrite
import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperStateRepository
import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
import dagger.Binds
@@ -37,6 +42,14 @@ interface ShortcutHelperModule {
    @ClassKey(ShortcutHelperActivity::class)
    fun activity(impl: ShortcutHelperActivity): Activity

    @Binds
    @SystemShortcuts
    fun systemShortcutsSource(impl: SystemShortcutsSource): KeyboardShortcutGroupsSource

    @Binds
    @MultitaskingShortcuts
    fun multitaskingShortcutsSource(impl: MultitaskingShortcutsSource): KeyboardShortcutGroupsSource

    companion object {
        @Provides
        @IntoMap
+35 −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.model

import android.view.KeyboardShortcutInfo

class KeyboardShortcutInfoBuilder(val label: String) {

    private var modifiers = 0
    private var keyCode = 0

    fun command(modifiers: Int, keyCode: Int = 0) {
        this.modifiers = modifiers
        this.keyCode = keyCode
    }

    fun build() = KeyboardShortcutInfo(label, keyCode, modifiers)
}

fun shortcutInfo(label: String, block: KeyboardShortcutInfoBuilder.() -> Unit) =
    KeyboardShortcutInfoBuilder(label).apply(block).build()
+41 −14
Original line number Diff line number Diff line
@@ -22,14 +22,17 @@ import android.view.KeyboardShortcutInfo
import android.view.WindowManager
import android.view.WindowManager.KeyboardShortcutsReceiver
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyboard.shortcut.data.source.MultitaskingShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.SystemShortcutsSource
import com.android.systemui.keyboard.shortcut.data.source.KeyboardShortcutGroupsSource
import com.android.systemui.keyboard.shortcut.qualifiers.MultitaskingShortcuts
import com.android.systemui.keyboard.shortcut.qualifiers.SystemShortcuts
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.ShortcutCategoryType
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.IME
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCommand
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutSubCategory
import javax.inject.Inject
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -38,20 +41,31 @@ import kotlinx.coroutines.suspendCancellableCoroutine
class ShortcutHelperCategoriesRepository
@Inject
constructor(
    private val systemShortcutsSource: SystemShortcutsSource,
    private val multitaskingShortcutsSource: MultitaskingShortcutsSource,
    @SystemShortcuts private val systemShortcutsSource: KeyboardShortcutGroupsSource,
    @MultitaskingShortcuts private val multitaskingShortcutsSource: KeyboardShortcutGroupsSource,
    private val windowManager: WindowManager,
    shortcutHelperStateRepository: ShortcutHelperStateRepository
) {

    val systemShortcutsCategory =
        shortcutHelperStateRepository.state.map {
            if (it is Active) systemShortcutsSource.systemShortcutsCategory() else null
            if (it is Active) {
                toShortcutCategory(
                    systemShortcutsSource.shortcutGroups(),
                    ShortcutCategoryType.SYSTEM
                )
            } else {
                null
            }
        }

    val multitaskingShortcutsCategory =
        shortcutHelperStateRepository.state.map {
            if (it is Active) multitaskingShortcutsSource.multitaskingShortcutCategory() else null
            if (it is Active) {
                toShortcutCategory(multitaskingShortcutsSource.shortcutGroups(), MULTI_TASKING)
            } else {
                null
            }
        }

    val imeShortcutsCategory =
@@ -59,19 +73,32 @@ constructor(
            if (it is Active) retrieveImeShortcuts(it.deviceId) else null
        }

    private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory {
    private suspend fun retrieveImeShortcuts(deviceId: Int): ShortcutCategory? {
        return suspendCancellableCoroutine { continuation ->
            val shortcutsReceiver = KeyboardShortcutsReceiver { shortcutGroups ->
                continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups)))
                continuation.resumeWith(Result.success(toShortcutCategory(shortcutGroups, IME)))
            }
            windowManager.requestImeKeyboardShortcuts(shortcutsReceiver, deviceId)
        }
    }

    private fun toShortcutCategory(shortcutGroups: List<KeyboardShortcutGroup>) =
        shortcutCategory(ShortcutCategoryType.IME) {
            shortcutGroups.map { shortcutGroup ->
                subCategory(shortcutGroup.label.toString(), toShortcuts(shortcutGroup.items))
    private fun toShortcutCategory(
        shortcutGroups: List<KeyboardShortcutGroup>,
        type: ShortcutCategoryType,
    ): ShortcutCategory? {
        val subCategories =
            shortcutGroups
                .map { shortcutGroup ->
                    ShortcutSubCategory(
                        label = shortcutGroup.label.toString(),
                        shortcuts = toShortcuts(shortcutGroup.items)
                    )
                }
                .filter { it.shortcuts.isNotEmpty() }
        return if (subCategories.isEmpty()) {
            null
        } else {
            ShortcutCategory(type, subCategories)
        }
    }

+24 −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.source

import android.view.KeyboardShortcutGroup

interface KeyboardShortcutGroupsSource {

    fun shortcutGroups(): List<KeyboardShortcutGroup>
}
+23 −23
Original line number Diff line number Diff line
@@ -25,53 +25,53 @@ import android.view.KeyEvent.META_ALT_ON
import android.view.KeyEvent.META_CTRL_ON
import android.view.KeyEvent.META_META_ON
import android.view.KeyEvent.META_SHIFT_ON
import android.view.KeyboardShortcutGroup
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyboard.shortcut.shared.model.ShortcutCategoryType.MULTI_TASKING
import com.android.systemui.keyboard.shortcut.shared.model.shortcut
import com.android.systemui.keyboard.shortcut.shared.model.shortcutCategory
import com.android.systemui.keyboard.shortcut.data.model.shortcutInfo
import com.android.systemui.res.R
import javax.inject.Inject

class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) {
class MultitaskingShortcutsSource @Inject constructor(@Main private val resources: Resources) :
    KeyboardShortcutGroupsSource {

    fun multitaskingShortcutCategory() =
        shortcutCategory(MULTI_TASKING) {
            subCategory(
    override fun shortcutGroups() =
        listOf(
            KeyboardShortcutGroup(
                resources.getString(R.string.shortcutHelper_category_recent_apps),
                recentsShortcuts()
            )
            subCategory(
            ),
            KeyboardShortcutGroup(
                resources.getString(R.string.shortcutHelper_category_split_screen),
                splitScreenShortcuts()
            )
        }
        )

    private fun splitScreenShortcuts() =
        listOf(
            //  Enter Split screen with current app to RHS:
            //   - Meta + Ctrl + Right arrow
            shortcut(resources.getString(R.string.system_multitasking_rhs)) {
                command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_RIGHT)
            shortcutInfo(resources.getString(R.string.system_multitasking_rhs)) {
                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_RIGHT)
            },
            //  Enter Split screen with current app to LHS:
            //   - Meta + Ctrl + Left arrow
            shortcut(resources.getString(R.string.system_multitasking_lhs)) {
                command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_LEFT)
            shortcutInfo(resources.getString(R.string.system_multitasking_lhs)) {
                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_LEFT)
            },
            //  Switch from Split screen to full screen:
            //   - Meta + Ctrl + Up arrow
            shortcut(resources.getString(R.string.system_multitasking_full_screen)) {
                command(META_META_ON, META_CTRL_ON, KEYCODE_DPAD_UP)
            shortcutInfo(resources.getString(R.string.system_multitasking_full_screen)) {
                command(META_META_ON or META_CTRL_ON, KEYCODE_DPAD_UP)
            },
            //  Change split screen focus to RHS:
            //   - Meta + Alt + Right arrow
            shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
                command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_RIGHT)
            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_RIGHT)
            },
            //  Change split screen focus to LHS:
            //   - Meta + Alt + Left arrow
            shortcut(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
                command(META_META_ON, META_ALT_ON, KEYCODE_DPAD_LEFT)
            shortcutInfo(resources.getString(R.string.system_multitasking_splitscreen_focus_rhs)) {
                command(META_META_ON or META_ALT_ON, KEYCODE_DPAD_LEFT)
            },
        )

@@ -79,13 +79,13 @@ class MultitaskingShortcutsSource @Inject constructor(@Main private val resource
        listOf(
            // Cycle through recent apps (forward):
            //  - Alt + Tab
            shortcut(resources.getString(R.string.group_system_cycle_forward)) {
            shortcutInfo(resources.getString(R.string.group_system_cycle_forward)) {
                command(META_ALT_ON, KEYCODE_TAB)
            },
            // Cycle through recent apps (back):
            //  - Shift + Alt + Tab
            shortcut(resources.getString(R.string.group_system_cycle_back)) {
                command(META_SHIFT_ON, META_ALT_ON, KEYCODE_TAB)
            shortcutInfo(resources.getString(R.string.group_system_cycle_back)) {
                command(META_SHIFT_ON or META_ALT_ON, KEYCODE_TAB)
            },
        )
}
Loading