Loading packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt +35 −10 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.UserHandle import android.view.KeyEvent import android.view.KeyEvent.KEYCODE_N import android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL import android.view.ViewConfiguration import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.dagger.qualifiers.Background Loading Loading @@ -128,15 +129,39 @@ constructor( controller.updateNoteTaskForCurrentUserAndManagedProfiles() } } } /** * Maps a [KeyEvent] to a [NoteTaskEntryPoint]. If the [KeyEvent] does not represent a * [NoteTaskEntryPoint], returns null. * Tracks a [KeyEvent], and determines if it should trigger an action to show the note task. * Returns a [NoteTaskEntryPoint] if an action should be taken, and null otherwise. */ private fun KeyEvent.toNoteTaskEntryPointOrNull(): NoteTaskEntryPoint? = when { keyCode == KEYCODE_STYLUS_BUTTON_TAIL && action == KeyEvent.ACTION_UP -> TAIL_BUTTON keyCode == KEYCODE_STYLUS_BUTTON_TAIL && isTailButtonNotesGesture() -> TAIL_BUTTON keyCode == KEYCODE_N && isMetaPressed && isCtrlPressed -> KEYBOARD_SHORTCUT else -> null } private var lastStylusButtonTailUpEventTime: Long = -MULTI_PRESS_TIMEOUT /** * Perform gesture detection for the stylus tail button to make sure we only show the note task * when there is a single press. Long presses and multi-presses are ignored for now. */ private fun KeyEvent.isTailButtonNotesGesture(): Boolean { if (keyCode != KEYCODE_STYLUS_BUTTON_TAIL || action != KeyEvent.ACTION_UP) { return false } val isMultiPress = (downTime - lastStylusButtonTailUpEventTime) < MULTI_PRESS_TIMEOUT val isLongPress = (eventTime - downTime) >= LONG_PRESS_TIMEOUT lastStylusButtonTailUpEventTime = eventTime // For now, trigger action immediately on UP of a single press, without waiting for // the multi-press timeout to expire. return !isMultiPress && !isLongPress } companion object { val MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout().toLong() val LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout().toLong() } } packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt +38 −0 Original line number Diff line number Diff line Loading @@ -235,4 +235,42 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { verify(controller).showNoteTask(any()) } @Test fun tailButtonGestureDetection_doublePress_shouldNotShowNoteTaskTwice() { val underTest = createUnderTest(isEnabled = true, bubbles = bubbles) underTest.initialize() val callback = withArgCaptor { verify(commandQueue).addCallback(capture()) } callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 0) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 50) ) callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 99, eventTime = 99) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 99, eventTime = 150) ) verify(controller, times(1)).showNoteTask(any()) } @Test fun tailButtonGestureDetection_longPress_shouldNotShowNoteTask() { val underTest = createUnderTest(isEnabled = true, bubbles = bubbles) underTest.initialize() val callback = withArgCaptor { verify(commandQueue).addCallback(capture()) } callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 0) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 1000) ) verify(controller, never()).showNoteTask(any()) } } Loading
packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt +35 −10 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.os.UserHandle import android.view.KeyEvent import android.view.KeyEvent.KEYCODE_N import android.view.KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL import android.view.ViewConfiguration import com.android.keyguard.KeyguardUpdateMonitor import com.android.keyguard.KeyguardUpdateMonitorCallback import com.android.systemui.dagger.qualifiers.Background Loading Loading @@ -128,15 +129,39 @@ constructor( controller.updateNoteTaskForCurrentUserAndManagedProfiles() } } } /** * Maps a [KeyEvent] to a [NoteTaskEntryPoint]. If the [KeyEvent] does not represent a * [NoteTaskEntryPoint], returns null. * Tracks a [KeyEvent], and determines if it should trigger an action to show the note task. * Returns a [NoteTaskEntryPoint] if an action should be taken, and null otherwise. */ private fun KeyEvent.toNoteTaskEntryPointOrNull(): NoteTaskEntryPoint? = when { keyCode == KEYCODE_STYLUS_BUTTON_TAIL && action == KeyEvent.ACTION_UP -> TAIL_BUTTON keyCode == KEYCODE_STYLUS_BUTTON_TAIL && isTailButtonNotesGesture() -> TAIL_BUTTON keyCode == KEYCODE_N && isMetaPressed && isCtrlPressed -> KEYBOARD_SHORTCUT else -> null } private var lastStylusButtonTailUpEventTime: Long = -MULTI_PRESS_TIMEOUT /** * Perform gesture detection for the stylus tail button to make sure we only show the note task * when there is a single press. Long presses and multi-presses are ignored for now. */ private fun KeyEvent.isTailButtonNotesGesture(): Boolean { if (keyCode != KEYCODE_STYLUS_BUTTON_TAIL || action != KeyEvent.ACTION_UP) { return false } val isMultiPress = (downTime - lastStylusButtonTailUpEventTime) < MULTI_PRESS_TIMEOUT val isLongPress = (eventTime - downTime) >= LONG_PRESS_TIMEOUT lastStylusButtonTailUpEventTime = eventTime // For now, trigger action immediately on UP of a single press, without waiting for // the multi-press timeout to expire. return !isMultiPress && !isLongPress } companion object { val MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout().toLong() val LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout().toLong() } }
packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt +38 −0 Original line number Diff line number Diff line Loading @@ -235,4 +235,42 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { verify(controller).showNoteTask(any()) } @Test fun tailButtonGestureDetection_doublePress_shouldNotShowNoteTaskTwice() { val underTest = createUnderTest(isEnabled = true, bubbles = bubbles) underTest.initialize() val callback = withArgCaptor { verify(commandQueue).addCallback(capture()) } callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 0) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 50) ) callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 99, eventTime = 99) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 99, eventTime = 150) ) verify(controller, times(1)).showNoteTask(any()) } @Test fun tailButtonGestureDetection_longPress_shouldNotShowNoteTask() { val underTest = createUnderTest(isEnabled = true, bubbles = bubbles) underTest.initialize() val callback = withArgCaptor { verify(commandQueue).addCallback(capture()) } callback.handleSystemKey( createKeyEvent(ACTION_DOWN, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 0) ) callback.handleSystemKey( createKeyEvent(ACTION_UP, KEYCODE_STYLUS_BUTTON_TAIL, downTime = 0, eventTime = 1000) ) verify(controller, never()).showNoteTask(any()) } }