Fix a11y key event handling from multiple devices.
For M, we ignored device type entirely, but with ag/760625 we started paying attention to it, which rejects events when keys from different devices are pressed simultaneously. Since the volume keys show up as different devices, the new behavior disrupted the event stream when both volume keys were pressed. Now tracking each device separately, which restores the old behavior but still takes the device id into account. Holding down two keys when enabling an accessibility service, however, always has and still can produce an invalid event stream. It doesn't seem worth the overhead, however, to track each key separately. Bug: 28091773 Change-Id: I8d30de1f5e05f779b6fe305856d42f209ff8b038
This commit is contained in:
@@ -20,6 +20,7 @@ import android.content.Context;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Pools.SimplePool;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.Choreographer;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
@@ -637,10 +638,10 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps state of stream of events from a keyboard device.
|
||||
* Keeps state of streams of events from all keyboard devices.
|
||||
*/
|
||||
private static class KeyboardEventStreamState extends EventStreamState {
|
||||
private boolean mEventSequenceStarted;
|
||||
private SparseBooleanArray mEventSequenceStartedMap = new SparseBooleanArray();
|
||||
|
||||
public KeyboardEventStreamState() {
|
||||
reset();
|
||||
@@ -649,17 +650,35 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
|
||||
@Override
|
||||
final public void reset() {
|
||||
super.reset();
|
||||
mEventSequenceStarted = false;
|
||||
mEventSequenceStartedMap.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* Key events from different devices may be interleaved. For example, the volume up and
|
||||
* down keys can come from different device IDs.
|
||||
*/
|
||||
@Override
|
||||
public boolean updateDeviceId(int deviceId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We manage all device ids simultaneously; there is no concept of validity.
|
||||
@Override
|
||||
public boolean deviceIdValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
final public boolean shouldProcessKeyEvent(KeyEvent event) {
|
||||
// Wait for a down key event to start processing.
|
||||
if (mEventSequenceStarted) {
|
||||
// For each keyboard device, wait for a down event from a device to start processing
|
||||
int deviceId = event.getDeviceId();
|
||||
if (mEventSequenceStartedMap.get(deviceId, false)) {
|
||||
return true;
|
||||
}
|
||||
mEventSequenceStarted = event.getAction() == KeyEvent.ACTION_DOWN;
|
||||
return mEventSequenceStarted;
|
||||
boolean shouldProcess = event.getAction() == KeyEvent.ACTION_DOWN;
|
||||
mEventSequenceStartedMap.put(deviceId, shouldProcess);
|
||||
return shouldProcess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user