am efd3266b: Input improvements and bug fixes.

* commit 'efd3266b719eed5f1b217021c0a9e76e4b274b06':
  Input improvements and bug fixes.
This commit is contained in:
Jeff Brown
2011-03-09 18:36:52 -08:00
committed by Android Git Automerger
10 changed files with 436 additions and 221 deletions

View File

@@ -211374,9 +211374,11 @@
deprecated="not deprecated"
visibility="public"
>
<parameter name="axis" type="int">
</parameter>
</method>
<method name="getMotionAxes"
return="int[]"
<method name="getMotionRange"
return="android.view.InputDevice.MotionRange"
abstract="false"
native="false"
synchronized="false"
@@ -211398,6 +211400,19 @@
>
<parameter name="axis" type="int">
</parameter>
<parameter name="source" type="int">
</parameter>
</method>
<method name="getMotionRanges"
return="java.util.List&lt;android.view.InputDevice.MotionRange&gt;"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getName"
return="java.lang.String"
@@ -211763,6 +211778,17 @@
deprecated="not deprecated"
visibility="public"
>
<method name="getAxis"
return="int"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getFlat"
return="float"
abstract="false"
@@ -211818,6 +211844,17 @@
visibility="public"
>
</method>
<method name="getSource"
return="int"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
</class>
<class name="InputEvent"
extends="java.lang.Object"

View File

@@ -20,7 +20,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.SparseArray;
import java.util.ArrayList;
import java.util.List;
/**
* Describes the capabilities of a particular input device.
@@ -43,8 +45,7 @@ public final class InputDevice implements Parcelable {
private int mSources;
private int mKeyboardType;
private final SparseArray<MotionRange> mMotionRanges = new SparseArray<MotionRange>();
private int[] mMotionAxes;
private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
/**
* A mask for input source classes.
@@ -354,6 +355,11 @@ public final class InputDevice implements Parcelable {
/**
* Gets information about the range of values for a particular {@link MotionEvent} axis.
* If the device supports multiple sources, the same axis may have different meanings
* for each source. Returns information about the first axis found for any source.
* To obtain information about the axis for a specific source, use
* {@link #getMotionRange(int, int)}.
*
* @param axis The axis constant.
* @return The range of values, or null if the requested axis is not
* supported by the device.
@@ -363,30 +369,55 @@ public final class InputDevice implements Parcelable {
* @see #getSupportedAxes()
*/
public MotionRange getMotionRange(int axis) {
return mMotionRanges.get(axis);
final int numRanges = mMotionRanges.size();
for (int i = 0; i < numRanges; i++) {
final MotionRange range = mMotionRanges.get(i);
if (range.mAxis == axis) {
return range;
}
}
return null;
}
/**
* Gets the axis ids of all motion axes supported by this device.
* @return The axis ids of all motion axes supported by this device.
* Gets information about the range of values for a particular {@link MotionEvent} axis
* used by a particular source on the device.
* If the device supports multiple sources, the same axis may have different meanings
* for each source.
*
* @see #getMotionRange(int)
* @param axis The axis constant.
* @param source The source for which to return information.
* @return The range of values, or null if the requested axis is not
* supported by the device.
*
* @see MotionEvent#AXIS_X
* @see MotionEvent#AXIS_Y
* @see #getSupportedAxes()
*/
public int[] getMotionAxes() {
synchronized (this) {
if (mMotionAxes == null) {
final int count = mMotionRanges.size();
mMotionAxes = new int[count];
for (int i = 0; i < count; i++) {
mMotionAxes[i] = mMotionRanges.keyAt(i);
}
public MotionRange getMotionRange(int axis, int source) {
final int numRanges = mMotionRanges.size();
for (int i = 0; i < numRanges; i++) {
final MotionRange range = mMotionRanges.get(i);
if (range.mAxis == axis && range.mSource == source) {
return range;
}
return mMotionAxes;
}
return null;
}
private void addMotionRange(int axis, float min, float max, float flat, float fuzz) {
mMotionRanges.append(axis, new MotionRange(min, max, flat, fuzz));
/**
* Gets the ranges for all axes supported by the device.
* @return The motion ranges for the device.
*
* @see #getMotionRange(int, int)
*/
public List<MotionRange> getMotionRanges() {
return mMotionRanges;
}
private void addMotionRange(int axis, int source,
float min, float max, float flat, float fuzz) {
mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz));
}
/**
@@ -395,18 +426,38 @@ public final class InputDevice implements Parcelable {
* @see InputDevice#getMotionRange(int)
*/
public static final class MotionRange {
private int mAxis;
private int mSource;
private float mMin;
private float mMax;
private float mFlat;
private float mFuzz;
private MotionRange(float min, float max, float flat, float fuzz) {
private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) {
mAxis = axis;
mSource = source;
mMin = min;
mMax = max;
mFlat = flat;
mFuzz = fuzz;
}
/**
* Gets the axis id.
* @return The axis id.
*/
public int getAxis() {
return mAxis;
}
/**
* Gets the source for which the axis is defined.
* @return The source.
*/
public int getSource() {
return mSource;
}
/**
* Gets the inclusive minimum value for the axis.
* @return The inclusive minimum value.
@@ -480,7 +531,8 @@ public final class InputDevice implements Parcelable {
if (axis < 0) {
break;
}
addMotionRange(axis, in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
addMotionRange(axis, in.readInt(),
in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
}
}
@@ -491,11 +543,11 @@ public final class InputDevice implements Parcelable {
out.writeInt(mSources);
out.writeInt(mKeyboardType);
final int numAxes = mMotionRanges.size();
for (int i = 0; i < numAxes; i++) {
int axis = mMotionRanges.keyAt(i);
MotionRange range = mMotionRanges.valueAt(i);
out.writeInt(axis);
final int numRanges = mMotionRanges.size();
for (int i = 0; i < numRanges; i++) {
MotionRange range = mMotionRanges.get(i);
out.writeInt(range.mAxis);
out.writeInt(range.mSource);
out.writeFloat(range.mMin);
out.writeFloat(range.mMax);
out.writeFloat(range.mFlat);
@@ -528,7 +580,7 @@ public final class InputDevice implements Parcelable {
}
description.append("\n");
description.append(" Sources: ").append(Integer.toHexString(mSources)).append(" (");
description.append(" Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
@@ -541,10 +593,10 @@ public final class InputDevice implements Parcelable {
final int numAxes = mMotionRanges.size();
for (int i = 0; i < numAxes; i++) {
int axis = mMotionRanges.keyAt(i);
MotionRange range = mMotionRanges.valueAt(i);
description.append(" ").append(MotionEvent.axisToString(axis));
description.append(": min=").append(range.mMin);
MotionRange range = mMotionRanges.get(i);
description.append(" ").append(MotionEvent.axisToString(range.mAxis));
description.append(": source=0x").append(Integer.toHexString(range.mSource));
description.append(" min=").append(range.mMin);
description.append(" max=").append(range.mMax);
description.append(" flat=").append(range.mFlat);
description.append(" fuzz=").append(range.mFuzz);

View File

@@ -143,6 +143,14 @@ enum {
POLICY_FLAG_PASS_TO_USER = 0x40000000,
};
/*
* Button state.
*/
enum {
// Primary button pressed (left mouse button).
BUTTON_STATE_PRIMARY = 1 << 0,
};
/*
* Describes the basic configuration of input devices that are present.
*/
@@ -544,6 +552,8 @@ public:
~InputDeviceInfo();
struct MotionRange {
int32_t axis;
uint32_t source;
float min;
float max;
float flat;
@@ -556,16 +566,17 @@ public:
inline const String8 getName() const { return mName; }
inline uint32_t getSources() const { return mSources; }
const MotionRange* getMotionRange(int32_t axis) const;
const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
void addSource(uint32_t source);
void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
void addMotionRange(int32_t axis, const MotionRange& range);
void addMotionRange(int32_t axis, uint32_t source,
float min, float max, float flat, float fuzz);
void addMotionRange(const MotionRange& range);
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
inline int32_t getKeyboardType() const { return mKeyboardType; }
inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
inline const Vector<MotionRange>& getMotionRanges() const {
return mMotionRanges;
}
@@ -575,7 +586,7 @@ private:
uint32_t mSources;
int32_t mKeyboardType;
KeyedVector<int32_t, MotionRange> mMotionRanges;
Vector<MotionRange> mMotionRanges;
};
/*

View File

@@ -657,23 +657,30 @@ void InputDeviceInfo::initialize(int32_t id, const String8& name) {
mMotionRanges.clear();
}
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
ssize_t index = mMotionRanges.indexOfKey(axis);
return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
int32_t axis, uint32_t source) const {
size_t numRanges = mMotionRanges.size();
for (size_t i = 0; i < numRanges; i++) {
const MotionRange& range = mMotionRanges.itemAt(i);
if (range.axis == axis && range.source == source) {
return &range;
}
}
return NULL;
}
void InputDeviceInfo::addSource(uint32_t source) {
mSources |= source;
}
void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
float flat, float fuzz) {
MotionRange range = { min, max, flat, fuzz };
addMotionRange(axis, range);
MotionRange range = { axis, source, min, max, flat, fuzz };
mMotionRanges.add(range);
}
void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
mMotionRanges.add(axis, range);
void InputDeviceInfo::addMotionRange(const MotionRange& range) {
mMotionRanges.add(range);
}
} // namespace android

View File

@@ -2343,17 +2343,17 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
}
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
if (motionEntry->deviceId != deviceId) {
// Keep looking for this device.
if (motionEntry->deviceId != deviceId
|| motionEntry->source != source) {
// Keep looking for this device and source.
continue;
}
if (motionEntry->action != action
|| motionEntry->source != source
|| motionEntry->pointerCount != pointerCount
|| motionEntry->isInjected()) {
// Last motion event in the queue for this device is not compatible for
// appending new samples. Stop here.
// Last motion event in the queue for this device and source is
// not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}

View File

@@ -33,6 +33,7 @@
// Log debug messages about pointer assignment calculations.
#define DEBUG_POINTER_ASSIGNMENT 0
#include "InputReader.h"
#include <cutils/log.h>
@@ -140,6 +141,48 @@ static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
}
static uint32_t getButtonStateForScanCode(int32_t scanCode) {
// Currently all buttons are mapped to the primary button.
switch (scanCode) {
case BTN_LEFT:
case BTN_RIGHT:
case BTN_MIDDLE:
case BTN_SIDE:
case BTN_EXTRA:
case BTN_FORWARD:
case BTN_BACK:
case BTN_TASK:
return BUTTON_STATE_PRIMARY;
default:
return 0;
}
}
// Returns true if the pointer should be reported as being down given the specified
// button states.
static bool isPointerDown(uint32_t buttonState) {
return buttonState & BUTTON_STATE_PRIMARY;
}
static int32_t calculateEdgeFlagsUsingPointerBounds(
const sp<PointerControllerInterface>& pointerController, float x, float y) {
int32_t edgeFlags = 0;
float minX, minY, maxX, maxY;
if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
if (x <= minX) {
edgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
} else if (x >= maxX) {
edgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
}
if (y <= minY) {
edgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
} else if (y >= maxY) {
edgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
}
}
return edgeFlags;
}
// --- InputReader ---
@@ -270,23 +313,23 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui
}
// Keyboard-like devices.
uint32_t keyboardSources = 0;
uint32_t keyboardSource = 0;
int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
keyboardSources |= AINPUT_SOURCE_KEYBOARD;
keyboardSource |= AINPUT_SOURCE_KEYBOARD;
}
if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
}
if (classes & INPUT_DEVICE_CLASS_DPAD) {
keyboardSources |= AINPUT_SOURCE_DPAD;
keyboardSource |= AINPUT_SOURCE_DPAD;
}
if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
keyboardSources |= AINPUT_SOURCE_GAMEPAD;
keyboardSource |= AINPUT_SOURCE_GAMEPAD;
}
if (keyboardSources != 0) {
device->addMapper(new KeyboardInputMapper(device, keyboardSources, keyboardType));
if (keyboardSource != 0) {
device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
}
// Cursor-like devices.
@@ -617,22 +660,22 @@ void InputDevice::dump(String8& dump) {
dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
const KeyedVector<int32_t, InputDeviceInfo::MotionRange> ranges = deviceInfo.getMotionRanges();
const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
if (!ranges.isEmpty()) {
dump.append(INDENT2 "Motion Ranges:\n");
for (size_t i = 0; i < ranges.size(); i++) {
int32_t axis = ranges.keyAt(i);
const char* label = getAxisLabel(axis);
const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
const char* label = getAxisLabel(range.axis);
char name[32];
if (label) {
strncpy(name, label, sizeof(name));
name[sizeof(name) - 1] = '\0';
} else {
snprintf(name, sizeof(name), "%d", axis);
snprintf(name, sizeof(name), "%d", range.axis);
}
const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
name, range.min, range.max, range.flat, range.fuzz);
dump.appendFormat(INDENT3 "%s: source=0x%08x, "
"min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
name, range.source, range.min, range.max, range.flat, range.fuzz);
}
}
@@ -837,8 +880,8 @@ int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCod
// --- KeyboardInputMapper ---
KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
uint32_t sources, int32_t keyboardType) :
InputMapper(device), mSources(sources),
uint32_t source, int32_t keyboardType) :
InputMapper(device), mSource(source),
mKeyboardType(keyboardType) {
initializeLocked();
}
@@ -852,7 +895,7 @@ void KeyboardInputMapper::initializeLocked() {
}
uint32_t KeyboardInputMapper::getSources() {
return mSources;
return mSource;
}
void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1036,7 +1079,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
getContext()->fadePointer();
}
getDispatcher()->notifyKey(when, getDeviceId(), mSources, policyFlags,
getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
}
@@ -1116,7 +1159,7 @@ CursorInputMapper::~CursorInputMapper() {
}
uint32_t CursorInputMapper::getSources() {
return mSources;
return mSource;
}
void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1125,20 +1168,20 @@ void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
if (mParameters.mode == Parameters::MODE_POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
info->addMotionRange(AMOTION_EVENT_AXIS_X, minX, maxX, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_Y, minY, maxY, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f);
}
} else {
info->addMotionRange(AMOTION_EVENT_AXIS_X, -1.0f, 1.0f, 0.0f, mXScale);
info->addMotionRange(AMOTION_EVENT_AXIS_Y, -1.0f, 1.0f, 0.0f, mYScale);
info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale);
info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale);
}
info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 0.0f, 1.0f, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f);
if (mHaveVWheel) {
info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
}
if (mHaveHWheel) {
info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, -1.0f, 1.0f, 0.0f, 0.0f);
info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
}
}
@@ -1155,7 +1198,8 @@ void CursorInputMapper::dump(String8& dump) {
dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel));
dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState);
dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState)));
dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
} // release lock
}
@@ -1169,7 +1213,7 @@ void CursorInputMapper::configure() {
// Configure device mode.
switch (mParameters.mode) {
case Parameters::MODE_POINTER:
mSources = AINPUT_SOURCE_MOUSE;
mSource = AINPUT_SOURCE_MOUSE;
mXPrecision = 1.0f;
mYPrecision = 1.0f;
mXScale = 1.0f;
@@ -1177,7 +1221,7 @@ void CursorInputMapper::configure() {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
break;
case Parameters::MODE_NAVIGATION:
mSources = AINPUT_SOURCE_TRACKBALL;
mSource = AINPUT_SOURCE_TRACKBALL;
mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
@@ -1234,16 +1278,18 @@ void CursorInputMapper::dumpParameters(String8& dump) {
void CursorInputMapper::initializeLocked() {
mAccumulator.clear();
mLocked.down = false;
mLocked.buttonState = 0;
mLocked.downTime = 0;
}
void CursorInputMapper::reset() {
for (;;) {
uint32_t buttonState;
{ // acquire lock
AutoMutex _l(mLock);
if (! mLocked.down) {
buttonState = mLocked.buttonState;
if (!buttonState) {
initializeLocked();
break; // done
}
@@ -1251,8 +1297,10 @@ void CursorInputMapper::reset() {
// Synthesize button up event on reset.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = false;
mAccumulator.clear();
mAccumulator.buttonDown = 0;
mAccumulator.buttonUp = buttonState;
mAccumulator.fields = Accumulator::FIELD_BUTTONS;
sync(when);
}
@@ -1261,24 +1309,25 @@ void CursorInputMapper::reset() {
void CursorInputMapper::process(const RawEvent* rawEvent) {
switch (rawEvent->type) {
case EV_KEY:
switch (rawEvent->scanCode) {
case BTN_LEFT:
case BTN_RIGHT:
case BTN_MIDDLE:
case BTN_SIDE:
case BTN_EXTRA:
case BTN_FORWARD:
case BTN_BACK:
case BTN_TASK:
mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = rawEvent->value != 0;
case EV_KEY: {
uint32_t buttonState = getButtonStateForScanCode(rawEvent->scanCode);
if (buttonState) {
if (rawEvent->value) {
mAccumulator.buttonDown = buttonState;
mAccumulator.buttonUp = 0;
} else {
mAccumulator.buttonDown = 0;
mAccumulator.buttonUp = buttonState;
}
mAccumulator.fields |= Accumulator::FIELD_BUTTONS;
// Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
// we need to ensure that we report the up/down promptly.
sync(rawEvent->when);
break;
}
break;
}
case EV_REL:
switch (rawEvent->scanCode) {
@@ -1325,23 +1374,26 @@ void CursorInputMapper::sync(nsecs_t when) {
{ // acquire lock
AutoMutex _l(mLock);
bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
bool down, downChanged;
bool wasDown = isPointerDown(mLocked.buttonState);
bool buttonsChanged = fields & Accumulator::FIELD_BUTTONS;
if (buttonsChanged) {
mLocked.buttonState = (mLocked.buttonState | mAccumulator.buttonDown)
& ~mAccumulator.buttonUp;
if (downChanged) {
if (mAccumulator.btnMouse) {
if (!mLocked.down) {
mLocked.down = true;
mLocked.downTime = when;
} else {
downChanged = false;
}
down = isPointerDown(mLocked.buttonState);
if (!wasDown && down) {
mLocked.downTime = when;
downChanged = true;
} else if (wasDown && !down) {
downChanged = true;
} else {
if (mLocked.down) {
mLocked.down = false;
} else {
downChanged = false;
}
downChanged = false;
}
} else {
down = wasDown;
downChanged = false;
}
downTime = mLocked.downTime;
@@ -1349,8 +1401,8 @@ void CursorInputMapper::sync(nsecs_t when) {
float deltaY = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
if (downChanged) {
motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
} else if (mLocked.down || mPointerController == NULL) {
motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
} else if (down || mPointerController == NULL) {
motionEventAction = AMOTION_EVENT_ACTION_MOVE;
} else {
motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
@@ -1393,35 +1445,25 @@ void CursorInputMapper::sync(nsecs_t when) {
if (mPointerController != NULL) {
mPointerController->move(deltaX, deltaY);
if (downChanged) {
mPointerController->setButtonState(mLocked.down ? POINTER_BUTTON_1 : 0);
if (buttonsChanged) {
mPointerController->setButtonState(mLocked.buttonState);
}
float x, y;
mPointerController->getPosition(&x, &y);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
if (x <= minX) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
} else if (x >= maxX) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
}
if (y <= minY) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
} else if (y >= maxY) {
motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
}
}
motionEventEdgeFlags = calculateEdgeFlagsUsingPointerBounds(
mPointerController, x, y);
}
} else {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
}
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) {
vscroll = mAccumulator.relWheel;
@@ -1449,7 +1491,7 @@ void CursorInputMapper::sync(nsecs_t when) {
int32_t metaState = mContext->getGlobalMetaState();
int32_t pointerId = 0;
getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
motionEventAction, 0, metaState, motionEventEdgeFlags,
1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
@@ -1459,7 +1501,7 @@ void CursorInputMapper::sync(nsecs_t when) {
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
}
@@ -1476,7 +1518,9 @@ int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCod
void CursorInputMapper::fadePointer() {
{ // acquire lock
AutoMutex _l(mLock);
mPointerController->fade();
if (mPointerController != NULL) {
mPointerController->fade();
}
} // release lock
}
@@ -1496,7 +1540,7 @@ TouchInputMapper::~TouchInputMapper() {
}
uint32_t TouchInputMapper::getSources() {
return mSources;
return mTouchSource;
}
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
@@ -1507,38 +1551,33 @@ void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
// Ensure surface information is up to date so that orientation changes are
// noticed immediately.
configureSurfaceLocked();
if (!configureSurfaceLocked()) {
return;
}
info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x);
info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y);
info->addMotionRange(mLocked.orientedRanges.x);
info->addMotionRange(mLocked.orientedRanges.y);
if (mLocked.orientedRanges.havePressure) {
info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
mLocked.orientedRanges.pressure);
info->addMotionRange(mLocked.orientedRanges.pressure);
}
if (mLocked.orientedRanges.haveSize) {
info->addMotionRange(AMOTION_EVENT_AXIS_SIZE,
mLocked.orientedRanges.size);
info->addMotionRange(mLocked.orientedRanges.size);
}
if (mLocked.orientedRanges.haveTouchSize) {
info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR,
mLocked.orientedRanges.touchMajor);
info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR,
mLocked.orientedRanges.touchMinor);
info->addMotionRange(mLocked.orientedRanges.touchMajor);
info->addMotionRange(mLocked.orientedRanges.touchMinor);
}
if (mLocked.orientedRanges.haveToolSize) {
info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR,
mLocked.orientedRanges.toolMajor);
info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR,
mLocked.orientedRanges.toolMinor);
info->addMotionRange(mLocked.orientedRanges.toolMajor);
info->addMotionRange(mLocked.orientedRanges.toolMinor);
}
if (mLocked.orientedRanges.haveOrientation) {
info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION,
mLocked.orientedRanges.orientation);
info->addMotionRange(mLocked.orientedRanges.orientation);
}
} // release lock
}
@@ -1552,6 +1591,7 @@ void TouchInputMapper::dump(String8& dump) {
dumpRawAxes(dump);
dumpCalibration(dump);
dumpSurfaceLocked(dump);
dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
@@ -1564,7 +1604,10 @@ void TouchInputMapper::dump(String8& dump) {
dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale);
dump.appendFormat(INDENT3 "Last Touch:\n");
dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount);
} // release lock
}
@@ -1598,10 +1641,10 @@ void TouchInputMapper::configure() {
// Configure sources.
switch (mParameters.deviceType) {
case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
mSources = AINPUT_SOURCE_TOUCHSCREEN;
mTouchSource = AINPUT_SOURCE_TOUCHSCREEN;
break;
case Parameters::DEVICE_TYPE_TOUCH_PAD:
mSources = AINPUT_SOURCE_TOUCHPAD;
mTouchSource = AINPUT_SOURCE_TOUCHPAD;
break;
default:
assert(false);
@@ -1634,17 +1677,20 @@ void TouchInputMapper::configureParameters() {
deviceTypeString)) {
if (deviceTypeString == "touchScreen") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
} else if (deviceTypeString != "touchPad") {
} else if (deviceTypeString == "touchPad") {
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
} else {
LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
}
}
bool isTouchScreen = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
mParameters.orientationAware = isTouchScreen;
mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
mParameters.orientationAware);
mParameters.associatedDisplayId = mParameters.orientationAware || isTouchScreen ? 0 : -1;
mParameters.associatedDisplayId = mParameters.orientationAware
|| mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
? 0 : -1;
}
void TouchInputMapper::dumpParameters(String8& dump) {
@@ -1711,15 +1757,23 @@ bool TouchInputMapper::configureSurfaceLocked() {
int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
if (mParameters.associatedDisplayId >= 0) {
bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
bool wantOrientation = mParameters.orientationAware;
// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
wantSize ? &width : NULL, wantSize ? &height : NULL,
wantOrientation ? &orientation : NULL)) {
&mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight,
&mLocked.associatedDisplayOrientation)) {
return false;
}
// A touch screen inherits the dimensions of the display.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
width = mLocked.associatedDisplayWidth;
height = mLocked.associatedDisplayHeight;
}
// The device inherits the orientation of the display if it is orientation aware.
if (mParameters.orientationAware) {
orientation = mLocked.associatedDisplayOrientation;
}
}
bool orientationChanged = mLocked.surfaceOrientation != orientation;
@@ -1729,7 +1783,7 @@ bool TouchInputMapper::configureSurfaceLocked() {
bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
if (sizeChanged) {
LOGI("Device reconfigured: id=%d, name='%s', display size is now %dx%d",
LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d",
getDeviceId(), getDeviceName().string(), width, height);
mLocked.surfaceWidth = width;
@@ -1741,6 +1795,11 @@ bool TouchInputMapper::configureSurfaceLocked() {
mLocked.xPrecision = 1.0f / mLocked.xScale;
mLocked.yPrecision = 1.0f / mLocked.yScale;
mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
mLocked.orientedRanges.x.source = mTouchSource;
mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
mLocked.orientedRanges.y.source = mTouchSource;
configureVirtualKeysLocked();
// Scale factor for terms that are not oriented in a particular axis.
@@ -1754,11 +1813,16 @@ bool TouchInputMapper::configureSurfaceLocked() {
// TouchMajor and TouchMinor factors.
if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
mLocked.orientedRanges.haveTouchSize = true;
mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
mLocked.orientedRanges.touchMajor.source = mTouchSource;
mLocked.orientedRanges.touchMajor.min = 0;
mLocked.orientedRanges.touchMajor.max = diagonalSize;
mLocked.orientedRanges.touchMajor.flat = 0;
mLocked.orientedRanges.touchMajor.fuzz = 0;
mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
}
// ToolMajor and ToolMinor factors.
@@ -1802,11 +1866,16 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
mLocked.orientedRanges.haveToolSize = true;
mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
mLocked.orientedRanges.toolMajor.source = mTouchSource;
mLocked.orientedRanges.toolMajor.min = 0;
mLocked.orientedRanges.toolMajor.max = diagonalSize;
mLocked.orientedRanges.toolMajor.flat = 0;
mLocked.orientedRanges.toolMajor.fuzz = 0;
mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
}
// Pressure factors.
@@ -1835,6 +1904,9 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
mLocked.orientedRanges.havePressure = true;
mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
mLocked.orientedRanges.pressure.source = mTouchSource;
mLocked.orientedRanges.pressure.min = 0;
mLocked.orientedRanges.pressure.max = 1.0;
mLocked.orientedRanges.pressure.flat = 0;
@@ -1851,6 +1923,9 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
mLocked.orientedRanges.haveSize = true;
mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
mLocked.orientedRanges.size.source = mTouchSource;
mLocked.orientedRanges.size.min = 0;
mLocked.orientedRanges.size.max = 1.0;
mLocked.orientedRanges.size.flat = 0;
@@ -1867,6 +1942,8 @@ bool TouchInputMapper::configureSurfaceLocked() {
}
}
mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
mLocked.orientedRanges.orientation.source = mTouchSource;
mLocked.orientedRanges.orientation.min = - M_PI_2;
mLocked.orientedRanges.orientation.max = M_PI_2;
mLocked.orientedRanges.orientation.flat = 0;
@@ -2381,8 +2458,10 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
uint32_t policyFlags = 0;
if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
// Hide the pointer on an initial down.
getContext()->fadePointer();
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
// If this is a touch screen, hide the pointer on an initial down.
getContext()->fadePointer();
}
// Initial downs on external touch devices should wake the device.
// We don't do this for internal touch screens to prevent them from waking
@@ -2396,7 +2475,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
// Process touches and virtual keys.
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
detectGestures(when);
suppressSwipeOntoVirtualKeys(when);
dispatchTouches(when, policyFlags);
}
@@ -2523,7 +2602,7 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
return touchResult;
}
void TouchInputMapper::detectGestures(nsecs_t when) {
void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
// Disable all virtual key touches that happen within a short time interval of the
// most recent touch. The idea is to filter out stray virtual key presses when
// interacting with the touch screen.
@@ -2648,7 +2727,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
AutoMutex _l(mLock);
// Walk through the the active pointers and map touch screen coordinates (TouchData) into
// display coordinates (PointerCoords) and adjust for display orientation.
// display or surface coordinates (PointerCoords) and adjust for display orientation.
for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
uint32_t id = idBits.firstMarkedBit();
idBits.clearBit(id);
@@ -2869,7 +2948,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
yPrecision = mLocked.orientedYPrecision;
} // release lock
getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags,
getDispatcher()->notifyMotion(when, getDeviceId(), mTouchSource, policyFlags,
motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
pointerCount, pointerIds, pointerCoords,
xPrecision, yPrecision, mDownTime);
@@ -3860,9 +3939,11 @@ void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
for (size_t i = 0; i < mAxes.size(); i++) {
const Axis& axis = mAxes.valueAt(i);
info->addMotionRange(axis.axisInfo.axis, axis.min, axis.max, axis.flat, axis.fuzz);
info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK,
axis.min, axis.max, axis.flat, axis.fuzz);
if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
info->addMotionRange(axis.axisInfo.highAxis, axis.min, axis.max, axis.flat, axis.fuzz);
info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK,
axis.min, axis.max, axis.flat, axis.fuzz);
}
}
}

View File

@@ -389,7 +389,7 @@ private:
class KeyboardInputMapper : public InputMapper {
public:
KeyboardInputMapper(InputDevice* device, uint32_t sources, int32_t keyboardType);
KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
virtual ~KeyboardInputMapper();
virtual uint32_t getSources();
@@ -414,7 +414,7 @@ private:
int32_t scanCode;
};
uint32_t mSources;
uint32_t mSource;
int32_t mKeyboardType;
// Immutable configuration parameters.
@@ -493,7 +493,7 @@ private:
struct Accumulator {
enum {
FIELD_BTN_MOUSE = 1,
FIELD_BUTTONS = 1,
FIELD_REL_X = 2,
FIELD_REL_Y = 4,
FIELD_REL_WHEEL = 8,
@@ -502,7 +502,9 @@ private:
uint32_t fields;
bool btnMouse;
uint32_t buttonDown;
uint32_t buttonUp;
int32_t relX;
int32_t relY;
int32_t relWheel;
@@ -513,7 +515,7 @@ private:
}
} mAccumulator;
int32_t mSources;
int32_t mSource;
float mXScale;
float mYScale;
float mXPrecision;
@@ -527,7 +529,7 @@ private:
sp<PointerControllerInterface> mPointerController;
struct LockedState {
bool down;
uint32_t buttonState;
nsecs_t downTime;
} mLocked;
@@ -629,7 +631,7 @@ protected:
};
// Input sources supported by the device.
int32_t mSources;
uint32_t mTouchSource; // sources when reporting touch data
// Immutable configuration parameters.
struct Parameters {
@@ -745,6 +747,10 @@ protected:
int32_t surfaceOrientation;
int32_t surfaceWidth, surfaceHeight;
// The associated display orientation and width and height set by configureSurfaceLocked().
int32_t associatedDisplayOrientation;
int32_t associatedDisplayWidth, associatedDisplayHeight;
// Translation and scaling factors, orientation-independent.
float xScale;
float xPrecision;
@@ -870,7 +876,7 @@ private:
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
int32_t motionEventAction);
void detectGestures(nsecs_t when);
void suppressSwipeOntoVirtualKeys(nsecs_t when);
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
@@ -900,7 +906,7 @@ private:
FIELD_ABS_X = 2,
FIELD_ABS_Y = 4,
FIELD_ABS_PRESSURE = 8,
FIELD_ABS_TOOL_WIDTH = 16
FIELD_ABS_TOOL_WIDTH = 16,
};
uint32_t fields;

View File

@@ -31,10 +31,6 @@
namespace android {
enum {
POINTER_BUTTON_1 = 1 << 0,
};
/**
* Interface for tracking a single (mouse) pointer.
*

View File

@@ -405,7 +405,8 @@ class FakeEventHub : public EventHubInterface {
String8 name;
uint32_t classes;
PropertyMap configuration;
KeyedVector<int, RawAbsoluteAxisInfo> axes;
KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
KeyedVector<int, bool> relativeAxes;
KeyedVector<int32_t, int32_t> keyCodeStates;
KeyedVector<int32_t, int32_t> scanCodeStates;
KeyedVector<int32_t, int32_t> switchStates;
@@ -460,7 +461,7 @@ public:
device->configuration.addAll(configuration);
}
void addAxis(int32_t deviceId, int axis,
void addAbsoluteAxis(int32_t deviceId, int axis,
int32_t minValue, int32_t maxValue, int flat, int fuzz) {
Device* device = getDevice(deviceId);
@@ -470,7 +471,12 @@ public:
info.maxValue = maxValue;
info.flat = flat;
info.fuzz = fuzz;
device->axes.add(axis, info);
device->absoluteAxes.add(axis, info);
}
void addRelativeAxis(int32_t deviceId, int32_t axis) {
Device* device = getDevice(deviceId);
device->relativeAxes.add(axis, true);
}
void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
@@ -560,9 +566,9 @@ private:
RawAbsoluteAxisInfo* outAxisInfo) const {
Device* device = getDevice(deviceId);
if (device) {
ssize_t index = device->axes.indexOfKey(axis);
ssize_t index = device->absoluteAxes.indexOfKey(axis);
if (index >= 0) {
*outAxisInfo = device->axes.valueAt(index);
*outAxisInfo = device->absoluteAxes.valueAt(index);
return OK;
}
}
@@ -570,6 +576,10 @@ private:
}
virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
Device* device = getDevice(deviceId);
if (device) {
return device->relativeAxes.indexOfKey(axis) >= 0;
}
return false;
}
@@ -1487,13 +1497,15 @@ protected:
}
static void assertMotionRange(const InputDeviceInfo& info,
int32_t rangeType, float min, float max, float flat, float fuzz) {
const InputDeviceInfo::MotionRange* range = info.getMotionRange(rangeType);
ASSERT_TRUE(range != NULL) << "Range: " << rangeType;
ASSERT_NEAR(min, range->min, EPSILON) << "Range: " << rangeType;
ASSERT_NEAR(max, range->max, EPSILON) << "Range: " << rangeType;
ASSERT_NEAR(flat, range->flat, EPSILON) << "Range: " << rangeType;
ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Range: " << rangeType;
int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source;
ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
}
static void assertPointerCoords(const PointerCoords& coords,
@@ -2001,10 +2013,10 @@ TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeF
mapper->populateDeviceInfo(&info);
// Initially there may not be a valid motion range.
ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X));
ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE,
0.0f, 1.0f, 0.0f, 0.0f));
ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
// When the bounds are set, then there should be a valid motion range.
mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
@@ -2012,11 +2024,14 @@ TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeF
InputDeviceInfo info2;
mapper->populateDeviceInfo(&info2);
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_X,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
1, 800 - 1, 0.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_Y,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
2, 480 - 1, 0.0f, 0.0f));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2, AINPUT_MOTION_RANGE_PRESSURE,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
0.0f, 1.0f, 0.0f, 0.0f));
}
@@ -2028,11 +2043,14 @@ TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsSca
InputDeviceInfo info;
mapper->populateDeviceInfo(&info);
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_X,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
-1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_Y,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
-1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_PRESSURE,
ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
0.0f, 1.0f, 0.0f, 0.0f));
}
@@ -2385,14 +2403,18 @@ protected:
void SingleTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
mFakeEventHub->addAxis(DEVICE_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
RAW_X_MIN, RAW_X_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & PRESSURE) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_PRESSURE, RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
if (axes & TOOL) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
}
}
@@ -3040,33 +3062,37 @@ protected:
void MultiTouchInputMapperTest::prepareAxes(int axes) {
if (axes & POSITION) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
RAW_X_MIN, RAW_X_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
RAW_Y_MIN, RAW_Y_MAX, 0, 0);
}
if (axes & TOUCH) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
if (axes & MINOR) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
}
}
if (axes & TOOL) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
if (axes & MINOR) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
}
}
if (axes & ORIENTATION) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_ORIENTATION,
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
}
if (axes & PRESSURE) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_PRESSURE,
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
if (axes & ID) {
mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
RAW_ID_MIN, RAW_ID_MAX, 0, 0);
}
}

View File

@@ -1103,12 +1103,11 @@ static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
for (size_t i = 0; i < ranges.size(); i++) {
int rangeType = ranges.keyAt(i);
const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
rangeType, range.min, range.max, range.flat, range.fuzz);
range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
if (env->ExceptionCheck()) {
return NULL;
}
@@ -1321,7 +1320,7 @@ int register_android_server_InputManager(JNIEnv* env) {
"<init>", "()V");
GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
"addMotionRange", "(IFFFF)V");
"addMotionRange", "(IIFFFF)V");
GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
"mId", "I");