Generate and respect ACTION_CANCEL for joystick fallbacks. DO NOT MERGE

Also change MotionEvent.PointerCoords bit packing and unpacking
methods to be consistent with BitSets which are now used on the
native PointerCoords object.

Bug: 11480300
Change-Id: Ib18c99b94ac555104c69eac526860aa501e89e03
This commit is contained in:
Michael Wright
2014-03-19 11:51:26 -07:00
parent 1e3c93975e
commit 1b10869f39
3 changed files with 45 additions and 12 deletions

View File

@@ -3372,11 +3372,11 @@ public final class MotionEvent extends InputEvent implements Parcelable {
throw new IllegalArgumentException("Axis out of range.");
}
final long bits = mPackedAxisBits;
final long axisBit = 1L << axis;
final long axisBit = 0x8000000000000000L >>> axis;
if ((bits & axisBit) == 0) {
return 0;
}
final int index = Long.bitCount(bits & (axisBit - 1L));
final int index = Long.bitCount(bits & ~(0xFFFFFFFFFFFFFFFFL >>> axis));
return mPackedAxisValues[index];
}
}
@@ -3425,8 +3425,8 @@ public final class MotionEvent extends InputEvent implements Parcelable {
throw new IllegalArgumentException("Axis out of range.");
}
final long bits = mPackedAxisBits;
final long axisBit = 1L << axis;
final int index = Long.bitCount(bits & (axisBit - 1L));
final long axisBit = 0x8000000000000000L >>> axis;
final int index = Long.bitCount(bits & ~(0xFFFFFFFFFFFFFFFFL >>> axis));
float[] values = mPackedAxisValues;
if ((bits & axisBit) == 0) {
if (values == null) {

View File

@@ -4319,6 +4319,7 @@ public final class ViewRootImpl implements ViewParent,
* Creates dpad events from unhandled joystick movements.
*/
final class SyntheticJoystickHandler extends Handler {
private final static String TAG = "SyntheticJoystickHandler";
private final static int MSG_ENQUEUE_X_AXIS_KEY_REPEAT = 1;
private final static int MSG_ENQUEUE_Y_AXIS_KEY_REPEAT = 2;
@@ -4351,10 +4352,21 @@ public final class ViewRootImpl implements ViewParent,
}
public void process(MotionEvent event) {
update(event, true);
switch(event.getActionMasked()) {
case MotionEvent.ACTION_CANCEL:
cancel(event);
break;
case MotionEvent.ACTION_MOVE:
update(event, true);
break;
default:
Log.w(TAG, "Unexpected action: " + event.getActionMasked());
}
}
public void cancel(MotionEvent event) {
private void cancel(MotionEvent event) {
removeMessages(MSG_ENQUEUE_X_AXIS_KEY_REPEAT);
removeMessages(MSG_ENQUEUE_Y_AXIS_KEY_REPEAT);
update(event, false);
}

View File

@@ -4105,18 +4105,39 @@ bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
case AMOTION_EVENT_ACTION_POINTER_UP:
case AMOTION_EVENT_ACTION_POINTER_DOWN:
case AMOTION_EVENT_ACTION_MOVE: {
if (entry->source & AINPUT_SOURCE_CLASS_NAVIGATION) {
// Trackballs can send MOVE events with a corresponding DOWN or UP. There's no need to
// generate cancellation events for these since they're based in relative rather than
// absolute units.
return true;
}
ssize_t index = findMotionMemento(entry, false /*hovering*/);
if (entry->source & AINPUT_SOURCE_CLASS_JOYSTICK) {
// Joysticks can send MOVE events without a corresponding DOWN or UP. Since all
// joystick axes are normalized to [-1, 1] we can trust that 0 means it's neutral. Any
// other value and we need to track the motion so we can send cancellation events for
// anything generating fallback events (e.g. DPad keys for joystick movements).
if (index >= 0) {
if (entry->pointerCoords[0].isEmpty()) {
mMotionMementos.removeAt(index);
} else {
MotionMemento& memento = mMotionMementos.editItemAt(index);
memento.setPointers(entry);
}
} else if (!entry->pointerCoords[0].isEmpty()) {
addMotionMemento(entry, flags, false /*hovering*/);
}
// Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
return true;
}
if (index >= 0) {
MotionMemento& memento = mMotionMementos.editItemAt(index);
memento.setPointers(entry);
return true;
}
if (actionMasked == AMOTION_EVENT_ACTION_MOVE
&& (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
| AINPUT_SOURCE_CLASS_NAVIGATION))) {
// Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
return true;
}
#if DEBUG_OUTBOUND_EVENT_DETAILS
ALOGD("Dropping inconsistent motion pointer up/down or move event: "
"deviceId=%d, source=%08x, actionMasked=%d",