summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt5
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java (renamed from packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java)100
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java31
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java (renamed from packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java)52
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt14
13 files changed, 242 insertions, 62 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 357eca37ba37..d2caefd3b552 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -398,6 +398,7 @@ public class BrightLineFalsingManager implements FalsingManager {
|| mAccessibilityManager.isTouchExplorationEnabled()
|| mDataProvider.isA11yAction()
|| mDataProvider.isFromTrackpad()
+ || mDataProvider.isFromKeyboard()
|| (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
&& mDataProvider.isUnfolded());
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
index a79a654aedc2..76b228d4726a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
@@ -16,6 +16,7 @@
package com.android.systemui.classifier;
+import android.view.KeyEvent;
import android.view.MotionEvent;
/**
@@ -50,6 +51,14 @@ public interface FalsingCollector {
void onBouncerHidden();
/**
+ * Call this to record a KeyEvent in the {@link com.android.systemui.plugins.FalsingManager}.
+ *
+ * This may decide to only collect certain KeyEvents and ignore others. Do not assume all
+ * KeyEvents are collected.
+ */
+ void onKeyEvent(KeyEvent ev);
+
+ /**
* Call this to record a MotionEvent in the {@link com.android.systemui.plugins.FalsingManager}.
*
* Be sure to call {@link #onMotionEventComplete()} after the rest of SystemUI is done with the
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
index d6b9a119e31c..dcd419512498 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
@@ -16,6 +16,7 @@
package com.android.systemui.classifier;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import javax.inject.Inject;
@@ -23,6 +24,8 @@ import javax.inject.Inject;
/** */
public class FalsingCollectorFake implements FalsingCollector {
+ public KeyEvent lastKeyEvent = null;
+
@Override
public void init() {
}
@@ -70,6 +73,11 @@ public class FalsingCollectorFake implements FalsingCollector {
}
@Override
+ public void onKeyEvent(KeyEvent ev) {
+ lastKeyEvent = ev;
+ }
+
+ @Override
public void onTouchEvent(MotionEvent ev) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 4f4f3d0324b3..beaa170943fd 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -21,6 +21,7 @@ import static com.android.systemui.dock.DockManager.DockEventListener;
import android.hardware.SensorManager;
import android.hardware.biometrics.BiometricSourceType;
import android.util.Log;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.annotation.VisibleForTesting;
@@ -49,7 +50,10 @@ import com.android.systemui.util.time.SystemClock;
import dagger.Lazy;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
import javax.inject.Inject;
@@ -61,6 +65,14 @@ class FalsingCollectorImpl implements FalsingCollector {
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final long GESTURE_PROCESSING_DELAY_MS = 100;
+ private final Set<Integer> mAcceptedKeycodes = new HashSet<>(Arrays.asList(
+ KeyEvent.KEYCODE_ENTER,
+ KeyEvent.KEYCODE_ESCAPE,
+ KeyEvent.KEYCODE_SHIFT_LEFT,
+ KeyEvent.KEYCODE_SHIFT_RIGHT,
+ KeyEvent.KEYCODE_SPACE
+ ));
+
private final FalsingDataProvider mFalsingDataProvider;
private final FalsingManager mFalsingManager;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -279,6 +291,14 @@ class FalsingCollectorImpl implements FalsingCollector {
}
@Override
+ public void onKeyEvent(KeyEvent ev) {
+ // Only collect if it is an ACTION_UP action and is allow-listed
+ if (ev.getAction() == KeyEvent.ACTION_UP && mAcceptedKeycodes.contains(ev.getKeyCode())) {
+ mFalsingDataProvider.onKeyEvent(ev);
+ }
+ }
+
+ @Override
public void onTouchEvent(MotionEvent ev) {
logDebug("REAL: onTouchEvent(" + ev.getActionMasked() + ")");
if (!mKeyguardStateController.isShowing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
index c5d8c795853d..b289fa49d06c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
@@ -16,6 +16,7 @@
package com.android.systemui.classifier
+import android.view.KeyEvent
import android.view.MotionEvent
import com.android.systemui.classifier.FalsingCollectorImpl.logDebug
import com.android.systemui.dagger.SysUISingleton
@@ -59,6 +60,10 @@ class FalsingCollectorNoOp @Inject constructor() : FalsingCollector {
logDebug("NOOP: onBouncerHidden")
}
+ override fun onKeyEvent(ev: KeyEvent) {
+ logDebug("NOOP: onKeyEvent(${ev.action}")
+ }
+
override fun onTouchEvent(ev: MotionEvent) {
logDebug("NOOP: onTouchEvent(${ev.actionMasked})")
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 809d5b289cab..15017011134b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -20,6 +20,7 @@ import static com.android.systemui.classifier.FalsingModule.IS_FOLDABLE_DEVICE;
import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.util.DisplayMetrics;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
@@ -41,6 +42,7 @@ import javax.inject.Named;
public class FalsingDataProvider {
private static final long MOTION_EVENT_AGE_MS = 1000;
+ private static final long KEY_EVENT_AGE_MS = 500;
private static final long DROP_EVENT_THRESHOLD_MS = 50;
private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
@@ -56,8 +58,10 @@ public class FalsingDataProvider {
private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
private final List<GestureFinalizedListener> mGestureFinalizedListeners = new ArrayList<>();
- private TimeLimitedMotionEventBuffer mRecentMotionEvents =
- new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+ private TimeLimitedInputEventBuffer<MotionEvent> mRecentMotionEvents =
+ new TimeLimitedInputEventBuffer<>(MOTION_EVENT_AGE_MS);
+ private final TimeLimitedInputEventBuffer<KeyEvent> mRecentKeyEvents =
+ new TimeLimitedInputEventBuffer<>(KEY_EVENT_AGE_MS);
private List<MotionEvent> mPriorMotionEvents = new ArrayList<>();
private boolean mDirty = true;
@@ -89,6 +93,10 @@ public class FalsingDataProvider {
FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
}
+ void onKeyEvent(KeyEvent keyEvent) {
+ mRecentKeyEvents.add(keyEvent);
+ }
+
void onMotionEvent(MotionEvent motionEvent) {
List<MotionEvent> motionEvents = unpackMotionEvent(motionEvent);
FalsingClassifier.logVerbose("Unpacked into: " + motionEvents.size());
@@ -109,6 +117,10 @@ public class FalsingDataProvider {
// previous ACTION_MOVE event and when it happens, it makes some classifiers fail.
mDropLastEvent = shouldDropEvent(motionEvent);
+ if (!motionEvents.isEmpty() && !mRecentKeyEvents.isEmpty()) {
+ recycleAndClearRecentKeyEvents();
+ }
+
mRecentMotionEvents.addAll(motionEvents);
FalsingClassifier.logVerbose("Size: " + mRecentMotionEvents.size());
@@ -141,7 +153,7 @@ public class FalsingDataProvider {
mRecentMotionEvents.get(mRecentMotionEvents.size() - 1).getEventTime()));
mPriorMotionEvents = mRecentMotionEvents;
- mRecentMotionEvents = new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+ mRecentMotionEvents = new TimeLimitedInputEventBuffer<>(MOTION_EVENT_AGE_MS);
}
mDropLastEvent = false;
mA11YAction = false;
@@ -261,6 +273,13 @@ public class FalsingDataProvider {
return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY();
}
+ /**
+ * If it's a specific set of keys as collected from {@link FalsingCollector}
+ */
+ public boolean isFromKeyboard() {
+ return !mRecentKeyEvents.isEmpty();
+ }
+
public boolean isFromTrackpad() {
if (mRecentMotionEvents.isEmpty()) {
return false;
@@ -318,6 +337,14 @@ public class FalsingDataProvider {
}
}
+ private void recycleAndClearRecentKeyEvents() {
+ for (KeyEvent ev : mRecentKeyEvents) {
+ ev.recycle();
+ }
+
+ mRecentKeyEvents.clear();
+ }
+
private List<MotionEvent> unpackMotionEvent(MotionEvent motionEvent) {
List<MotionEvent> motionEvents = new ArrayList<>();
List<PointerProperties> pointerPropertiesList = new ArrayList<>();
@@ -416,6 +443,8 @@ public class FalsingDataProvider {
mRecentMotionEvents.clear();
+ recycleAndClearRecentKeyEvents();
+
mDirty = true;
mSessionListeners.forEach(SessionListener::onSessionEnded);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java
index 51aede79b581..7627ad19f650 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java
@@ -16,7 +16,7 @@
package com.android.systemui.classifier;
-import android.view.MotionEvent;
+import android.view.InputEvent;
import java.util.ArrayList;
import java.util.Collection;
@@ -25,31 +25,31 @@ import java.util.List;
import java.util.ListIterator;
/**
- * Maintains an ordered list of the last N milliseconds of MotionEvents.
+ * Maintains an ordered list of the last N milliseconds of InputEvents.
*
* This class is simply a convenience class designed to look like a simple list, but that
- * automatically discards old MotionEvents. It functions much like a queue - first in first out -
+ * automatically discards old InputEvents. It functions much like a queue - first in first out -
* but does not have a fixed size like a circular buffer.
*/
-public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
+public class TimeLimitedInputEventBuffer<T extends InputEvent> implements List<T> {
- private final List<MotionEvent> mMotionEvents;
+ private final List<T> mInputEvents;
private final long mMaxAgeMs;
- public TimeLimitedMotionEventBuffer(long maxAgeMs) {
+ public TimeLimitedInputEventBuffer(long maxAgeMs) {
super();
mMaxAgeMs = maxAgeMs;
- mMotionEvents = new ArrayList<>();
+ mInputEvents = new ArrayList<>();
}
private void ejectOldEvents() {
- if (mMotionEvents.isEmpty()) {
+ if (mInputEvents.isEmpty()) {
return;
}
- Iterator<MotionEvent> iter = listIterator();
- long mostRecentMs = mMotionEvents.get(mMotionEvents.size() - 1).getEventTime();
+ Iterator<T> iter = listIterator();
+ long mostRecentMs = mInputEvents.get(mInputEvents.size() - 1).getEventTime();
while (iter.hasNext()) {
- MotionEvent ev = iter.next();
+ T ev = iter.next();
if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
iter.remove();
ev.recycle();
@@ -58,140 +58,140 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
}
@Override
- public void add(int index, MotionEvent element) {
+ public void add(int index, T element) {
throw new UnsupportedOperationException();
}
@Override
- public MotionEvent remove(int index) {
- return mMotionEvents.remove(index);
+ public T remove(int index) {
+ return mInputEvents.remove(index);
}
@Override
public int indexOf(Object o) {
- return mMotionEvents.indexOf(o);
+ return mInputEvents.indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
- return mMotionEvents.lastIndexOf(o);
+ return mInputEvents.lastIndexOf(o);
}
@Override
public int size() {
- return mMotionEvents.size();
+ return mInputEvents.size();
}
@Override
public boolean isEmpty() {
- return mMotionEvents.isEmpty();
+ return mInputEvents.isEmpty();
}
@Override
public boolean contains(Object o) {
- return mMotionEvents.contains(o);
+ return mInputEvents.contains(o);
}
@Override
- public Iterator<MotionEvent> iterator() {
- return mMotionEvents.iterator();
+ public Iterator<T> iterator() {
+ return mInputEvents.iterator();
}
@Override
public Object[] toArray() {
- return mMotionEvents.toArray();
+ return mInputEvents.toArray();
}
@Override
- public <T> T[] toArray(T[] a) {
- return mMotionEvents.toArray(a);
+ public <T2> T2[] toArray(T2[] a) {
+ return mInputEvents.toArray(a);
}
@Override
- public boolean add(MotionEvent element) {
- boolean result = mMotionEvents.add(element);
+ public boolean add(T element) {
+ boolean result = mInputEvents.add(element);
ejectOldEvents();
return result;
}
@Override
public boolean remove(Object o) {
- return mMotionEvents.remove(o);
+ return mInputEvents.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
- return mMotionEvents.containsAll(c);
+ return mInputEvents.containsAll(c);
}
@Override
- public boolean addAll(Collection<? extends MotionEvent> collection) {
- boolean result = mMotionEvents.addAll(collection);
+ public boolean addAll(Collection<? extends T> collection) {
+ boolean result = mInputEvents.addAll(collection);
ejectOldEvents();
return result;
}
@Override
- public boolean addAll(int index, Collection<? extends MotionEvent> elements) {
+ public boolean addAll(int index, Collection<? extends T> elements) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
- return mMotionEvents.removeAll(c);
+ return mInputEvents.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
- return mMotionEvents.retainAll(c);
+ return mInputEvents.retainAll(c);
}
@Override
public void clear() {
- mMotionEvents.clear();
+ mInputEvents.clear();
}
@Override
public boolean equals(Object o) {
- return mMotionEvents.equals(o);
+ return mInputEvents.equals(o);
}
@Override
public int hashCode() {
- return mMotionEvents.hashCode();
+ return mInputEvents.hashCode();
}
@Override
- public MotionEvent get(int index) {
- return mMotionEvents.get(index);
+ public T get(int index) {
+ return mInputEvents.get(index);
}
@Override
- public MotionEvent set(int index, MotionEvent element) {
+ public T set(int index, T element) {
throw new UnsupportedOperationException();
}
@Override
- public ListIterator<MotionEvent> listIterator() {
+ public ListIterator<T> listIterator() {
return new Iter(0);
}
@Override
- public ListIterator<MotionEvent> listIterator(int index) {
+ public ListIterator<T> listIterator(int index) {
return new Iter(index);
}
@Override
- public List<MotionEvent> subList(int fromIndex, int toIndex) {
- return mMotionEvents.subList(fromIndex, toIndex);
+ public List<T> subList(int fromIndex, int toIndex) {
+ return mInputEvents.subList(fromIndex, toIndex);
}
- class Iter implements ListIterator<MotionEvent> {
+ class Iter implements ListIterator<T> {
- private final ListIterator<MotionEvent> mIterator;
+ private final ListIterator<T> mIterator;
Iter(int index) {
- this.mIterator = mMotionEvents.listIterator(index);
+ this.mIterator = mInputEvents.listIterator(index);
}
@Override
@@ -200,7 +200,7 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
}
@Override
- public MotionEvent next() {
+ public T next() {
return mIterator.next();
}
@@ -210,7 +210,7 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
}
@Override
- public MotionEvent previous() {
+ public T previous() {
return mIterator.previous();
}
@@ -230,12 +230,12 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
}
@Override
- public void set(MotionEvent motionEvent) {
+ public void set(T inputEvent) {
throw new UnsupportedOperationException();
}
@Override
- public void add(MotionEvent element) {
+ public void add(T element) {
throw new UnsupportedOperationException();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index f9b4e671f373..903af61f2202 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -81,6 +81,8 @@ public class NotificationShadeWindowView extends WindowRootView {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
+ mInteractionEventHandler.collectKeyEvent(event);
+
if (mInteractionEventHandler.interceptMediaKey(event)) {
return true;
}
@@ -301,6 +303,11 @@ public class NotificationShadeWindowView extends WindowRootView {
boolean dispatchKeyEvent(KeyEvent event);
boolean dispatchKeyEventPreIme(KeyEvent event);
+
+ /**
+ * Collects the KeyEvent without intercepting it
+ */
+ void collectKeyEvent(KeyEvent event);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 324dfdf32a3f..6ac81d226eee 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -563,6 +563,11 @@ public class NotificationShadeWindowViewController implements Dumpable {
public boolean dispatchKeyEvent(KeyEvent event) {
return mSysUIKeyEventHandler.dispatchKeyEvent(event);
}
+
+ @Override
+ public void collectKeyEvent(KeyEvent event) {
+ mFalsingCollector.onKeyEvent(event);
+ }
});
mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index 45d20dcd9d11..8e5ddc79976f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
@@ -202,6 +203,36 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
}
@Test
+ public void testPassThroughEnterKeyEvent() {
+ KeyEvent enterDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER,
+ 0, 0, 0, 0, 0, 0, 0, "");
+ KeyEvent enterUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0,
+ 0, 0, 0, 0, 0, 0, "");
+
+ mFalsingCollector.onKeyEvent(enterDown);
+ verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+
+ mFalsingCollector.onKeyEvent(enterUp);
+ verify(mFalsingDataProvider, times(1)).onKeyEvent(enterUp);
+ }
+
+ @Test
+ public void testAvoidAKeyEvent() {
+ // Arbitrarily chose the "A" key, as it is not currently allowlisted. If this key is
+ // allowlisted in the future, please choose another key that will not be collected.
+ KeyEvent aKeyDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A,
+ 0, 0, 0, 0, 0, 0, 0, "");
+ KeyEvent aKeyUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0,
+ 0, 0, 0, 0, 0, 0, "");
+
+ mFalsingCollector.onKeyEvent(aKeyDown);
+ verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+
+ mFalsingCollector.onKeyEvent(aKeyUp);
+ verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+ }
+
+ @Test
public void testPassThroughGesture() {
MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 0353f87ae9b4..057b0a158cab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
import android.testing.AndroidTestingRunner;
import android.util.DisplayMetrics;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
@@ -282,6 +283,22 @@ public class FalsingDataProviderTest extends ClassifierTest {
}
@Test
+ public void test_isFromKeyboard_disallowedKey_false() {
+ KeyEvent eventDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0,
+ 0, 0, 0, 0, 0, 0, "");
+ KeyEvent eventUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+ 0, 0, 0, 0, 0, "");
+
+ //events have not come in yet
+ assertThat(mDataProvider.isFromKeyboard()).isFalse();
+
+ mDataProvider.onKeyEvent(eventDown);
+ mDataProvider.onKeyEvent(eventUp);
+ assertThat(mDataProvider.isFromKeyboard()).isTrue();
+ mDataProvider.onSessionEnd();
+ }
+
+ @Test
public void test_IsFromTrackpad() {
MotionEvent motionEventOrigin = appendTrackpadDownEvent(0, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
index 901196f8bbba..ad7afa3c593f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
@@ -20,6 +20,8 @@ import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import android.testing.AndroidTestingRunner;
+import android.view.InputEvent;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
@@ -34,28 +36,28 @@ import org.mockito.MockitoAnnotations;
@SmallTest
@RunWith(AndroidTestingRunner.class)
-public class TimeLimitedMotionEventBufferTest extends SysuiTestCase {
+public class TimeLimitedInputEventBufferTest extends SysuiTestCase {
private static final long MAX_AGE_MS = 100;
- private TimeLimitedMotionEventBuffer mBuffer;
+ private TimeLimitedInputEventBuffer<InputEvent> mBuffer;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mBuffer = new TimeLimitedMotionEventBuffer(MAX_AGE_MS);
+ mBuffer = new TimeLimitedInputEventBuffer<>(MAX_AGE_MS);
}
@After
public void tearDown() {
- for (MotionEvent motionEvent : mBuffer) {
- motionEvent.recycle();
+ for (InputEvent inputEvent : mBuffer) {
+ inputEvent.recycle();
}
mBuffer.clear();
}
@Test
- public void testAllEventsRetained() {
+ public void testMotionEventAllEventsRetained() {
MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
MotionEvent eventC = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 0, 0, 0);
@@ -70,7 +72,7 @@ public class TimeLimitedMotionEventBufferTest extends SysuiTestCase {
}
@Test
- public void testOlderEventsRemoved() {
+ public void testMotionEventOlderEventsRemoved() {
MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
MotionEvent eventC = MotionEvent.obtain(
@@ -89,4 +91,40 @@ public class TimeLimitedMotionEventBufferTest extends SysuiTestCase {
assertThat(mBuffer.get(0), is(eventC));
assertThat(mBuffer.get(1), is(eventD));
}
+
+ @Test
+ public void testKeyEventAllEventsRetained() {
+ KeyEvent eventA = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+ 0, 0, 0, 0, 0, "");
+ KeyEvent eventB = KeyEvent.obtain(0, 3, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, 0, 0, 0,
+ 0, 0, 0, "");
+
+ mBuffer.add(eventA);
+ mBuffer.add(eventB);
+
+ assertThat(mBuffer.size(), is(2));
+ }
+
+ @Test
+ public void testKeyEventOlderEventsRemoved() {
+ KeyEvent eventA = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+ 0, 0, 0, 0, 0, "");
+ KeyEvent eventB = KeyEvent.obtain(0, 1, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, 0, 0, 0,
+ 0, 0, 0, "");
+ KeyEvent eventC = KeyEvent.obtain(0, MAX_AGE_MS + 1, MotionEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_A, 0, 0, 0, 0, 0, 0, 0, "");
+ KeyEvent eventD = KeyEvent.obtain(0, MAX_AGE_MS + 2, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A,
+ 0, 0, 0, 0, 0, 0, 0, "");
+
+ mBuffer.add(eventA);
+ mBuffer.add(eventB);
+ assertThat(mBuffer.size(), is(2));
+
+ mBuffer.add(eventC);
+ mBuffer.add(eventD);
+ assertThat(mBuffer.size(), is(2));
+
+ assertThat(mBuffer.get(0), is(eventC));
+ assertThat(mBuffer.get(1), is(eventD));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index dfbb699ed915..2c0a15dd4e5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -69,7 +69,6 @@ import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
@@ -87,6 +86,8 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
+import kotlin.test.assertEquals
+import java.util.Optional
import org.mockito.Mockito.`when` as whenever
@OptIn(ExperimentalCoroutinesApi::class)
@@ -138,6 +139,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
private val notificationLaunchAnimationInteractor =
NotificationLaunchAnimationInteractor(notificationLaunchAnimationRepository)
+ private lateinit var falsingCollector: FalsingCollectorFake
private lateinit var fakeClock: FakeSystemClock
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
private lateinit var interactionEventHandler: InteractionEventHandler
@@ -170,11 +172,12 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
mSetFlagsRule.enableFlags(Flags.FLAG_REVAMPED_BOUNCER_MESSAGES)
testScope = TestScope()
+ falsingCollector = FalsingCollectorFake()
fakeClock = FakeSystemClock()
underTest =
NotificationShadeWindowViewController(
lockscreenShadeTransitionController,
- FalsingCollectorFake(),
+ falsingCollector,
sysuiStatusBarStateController,
dockManager,
notificationShadeDepthController,
@@ -566,6 +569,13 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
verify(sysUIKeyEventHandler).interceptMediaKey(keyEvent)
}
+ @Test
+ fun forwardsCollectKeyEvent() {
+ val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)
+ interactionEventHandler.collectKeyEvent(keyEvent)
+ assertEquals(keyEvent, falsingCollector.lastKeyEvent)
+ }
+
companion object {
private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)