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

Commit a93c8e82 authored by Steven Ng's avatar Steven Ng Committed by Android (Google) Code Review
Browse files

Merge "Register notification panel key gesture handler in SysUi" into main

parents 8fa17c0d aee50c35
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1165,6 +1165,13 @@ flag {
    bug: "406452076"
}

flag {
    name: "enable_key_gesture_handler_for_sysui"
    namespace: "lse_desktop_experience"
    description: "Enables the key gesture handler for listening to SysUi interested key events."
    bug: "406740557"
}

flag {
    name: "enable_desktop_first_based_default_to_desktop_bugfix"
    namespace: "lse_desktop_experience"
+111 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.keyevent

import android.hardware.input.InputManager
import android.hardware.input.InputManager.KeyGestureEventHandler
import android.hardware.input.KeyGestureEvent
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_ALL_APPS
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.CommandQueue
import com.android.window.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.any
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoInteractions

@SmallTest
@RunWith(AndroidJUnit4::class)
class SysUIKeyGestureEventInitializerTest : SysuiTestCase() {
    @JvmField @Rule var mockitoRule = MockitoJUnit.rule()
    @Mock private lateinit var inputManager: InputManager
    @Mock private lateinit var commandQueue: CommandQueue
    @Captor private lateinit var keyGestureEventsCaptor: ArgumentCaptor<List<Int>>
    @Captor
    private lateinit var keyGestureEventHandlerCaptor: ArgumentCaptor<KeyGestureEventHandler>

    private lateinit var underTest: SysUIKeyGestureEventInitializer

    @Before
    fun setup() {
        underTest = SysUIKeyGestureEventInitializer(inputManager, commandQueue)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_SYSUI)
    fun start_flagEnabled_registerKeyGestureEvents() {
        underTest.start()

        verify(inputManager).registerKeyGestureEventHandler(keyGestureEventsCaptor.capture(), any())
        keyGestureEventsCaptor.value.let { keyGestureEvents ->
            assertThat(keyGestureEvents).containsExactly(KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL)
        }
    }

    @Test
    @DisableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_SYSUI)
    fun start_flagDisabled_noRegisterKeyGestureEvents() {
        underTest.start()

        verifyNoInteractions(inputManager)
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_SYSUI)
    fun handleKeyGestureEvent_eventTypeToggleNotificationPanel_toggleNotificationPanel() {
        underTest.start()
        verify(inputManager)
            .registerKeyGestureEventHandler(any(), keyGestureEventHandlerCaptor.capture())

        keyGestureEventHandlerCaptor.value.handleKeyGestureEvent(
            KeyGestureEvent.Builder()
                .setKeyGestureType(KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL)
                .build(),
            /* focusedToken= */ null,
        )

        verify(commandQueue).toggleNotificationsPanel()
    }

    @Test
    @EnableFlags(Flags.FLAG_ENABLE_KEY_GESTURE_HANDLER_FOR_SYSUI)
    fun handleKeyGestureEvent_otherEventTypeToggleNotificationPanel_noInteraction() {
        underTest.start()
        verify(inputManager)
            .registerKeyGestureEventHandler(any(), keyGestureEventHandlerCaptor.capture())

        keyGestureEventHandlerCaptor.value.handleKeyGestureEvent(
            KeyGestureEvent.Builder().setKeyGestureType(KEY_GESTURE_TYPE_ALL_APPS).build(),
            /* focusedToken= */ null,
        )

        verifyNoInteractions(commandQueue)
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.haptics.msdl.MSDLCoreStartable
import com.android.systemui.keyboard.KeyboardUI
import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable
import com.android.systemui.keyevent.SysUIKeyGestureEventInitializer
import com.android.systemui.keyguard.KeyguardViewConfigurator
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable
@@ -346,4 +347,11 @@ abstract class SystemUICoreStartableModule {
    @IntoMap
    @ClassKey(ComplicationTypesUpdater::class)
    abstract fun bindComplicationTypesUpdater(updater: ComplicationTypesUpdater): CoreStartable

    @Binds
    @IntoMap
    @ClassKey(SysUIKeyGestureEventInitializer::class)
    abstract fun bindSysUIKeyGestureEventInitializer(
        keyGestureEventInitializer: SysUIKeyGestureEventInitializer
    ): CoreStartable
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.keyevent

import android.hardware.input.InputManager
import android.hardware.input.KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL
import android.util.Slog
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.CommandQueue
import com.android.window.flags.Flags
import javax.inject.Inject

/**
 * Registers system UI interested keyboard shortcut events and dispatches events to the correct
 * handlers.
 */
@SysUISingleton
class SysUIKeyGestureEventInitializer
@Inject
constructor(private val inputManager: InputManager, private val commandQueue: CommandQueue) :
    CoreStartable {
    override fun start() {
        if (!Flags.enableKeyGestureHandlerForSysui()) {
            return
        }
        inputManager.registerKeyGestureEventHandler(
            listOf(KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL)
        ) { event, _ ->
            when (event.keyGestureType) {
                KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL ->
                    commandQueue.toggleNotificationsPanel()

                else -> Slog.w(TAG, "Unsupported key gesture event: ${event.keyGestureType}")
            }
        }
    }

    private companion object {
        const val TAG = "KeyGestureEventInitializer"
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -3381,7 +3381,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                KeyGestureEvent.KEY_GESTURE_TYPE_HOME,
                KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_SYSTEM_SETTINGS,
                KeyGestureEvent.KEY_GESTURE_TYPE_LOCK_SCREEN,
                KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL,
                KeyGestureEvent.KEY_GESTURE_TYPE_TAKE_SCREENSHOT,
                KeyGestureEvent.KEY_GESTURE_TYPE_TRIGGER_BUG_REPORT,
                KeyGestureEvent.KEY_GESTURE_TYPE_MULTI_WINDOW_NAVIGATION,
@@ -3414,6 +3413,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS);
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_RECENT_APPS_SWITCHER);
        }
        if (!com.android.window.flags.Flags.enableKeyGestureHandlerForSysui()) {
            supportedGestures.add(KeyGestureEvent.KEY_GESTURE_TYPE_TOGGLE_NOTIFICATION_PANEL);
        }
        mInputManager.registerKeyGestureEventHandler(supportedGestures,
                PhoneWindowManager.this::handleKeyGestureEvent);
    }
Loading