summaryrefslogtreecommitdiffstats
path: root/core/java/android/view
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-07-14 18:48:53 -0700
committerJeff Brown <jeffbrown@google.com>2010-07-15 18:32:33 -0700
commitc5ed5910c9ef066cec6a13bbb404ec57b1e92637 (patch)
treeb06dfdac2d807dae78a2634007b6e627eefd0804 /core/java/android/view
parentd9452ecd0ce6c8e0518055929ba1fd0712146405 (diff)
downloadframeworks_base-c5ed5910c9ef066cec6a13bbb404ec57b1e92637.zip
frameworks_base-c5ed5910c9ef066cec6a13bbb404ec57b1e92637.tar.gz
frameworks_base-c5ed5910c9ef066cec6a13bbb404ec57b1e92637.tar.bz2
Add support for new input sources.
Added several new coordinate values to MotionEvents to capture touch major/minor area, tool major/minor area and orientation. Renamed NDK input constants per convention. Added InputDevice class in Java which will eventually provide useful information about available input devices. Added APIs for manufacturing new MotionEvent objects with multiple pointers and all necessary coordinate data. Fixed a bug in the input dispatcher where it could get stuck with a pointer down forever. Fixed a bug in the WindowManager where the input window list could end up containing stale removed windows. Fixed a bug in the WindowManager where the input channel was being removed only after the final animation transition had taken place which caused spurious WINDOW DIED log messages to be printed. Change-Id: Ie55084da319b20aad29b28a0499b8dd98bb5da68
Diffstat (limited to 'core/java/android/view')
-rw-r--r--core/java/android/view/InputChannel.java8
-rwxr-xr-xcore/java/android/view/InputDevice.java231
-rwxr-xr-xcore/java/android/view/InputEvent.java63
-rw-r--r--core/java/android/view/InputHandler.java14
-rw-r--r--core/java/android/view/InputQueue.java41
-rw-r--r--core/java/android/view/KeyCharacterMap.java8
-rwxr-xr-xcore/java/android/view/KeyEvent.java77
-rw-r--r--core/java/android/view/MotionEvent.java597
-rw-r--r--core/java/android/view/ViewRoot.java62
9 files changed, 913 insertions, 188 deletions
diff --git a/core/java/android/view/InputChannel.java b/core/java/android/view/InputChannel.java
index e24c3c9..f2cad2f 100644
--- a/core/java/android/view/InputChannel.java
+++ b/core/java/android/view/InputChannel.java
@@ -30,6 +30,8 @@ import android.util.Slog;
public final class InputChannel implements Parcelable {
private static final String TAG = "InputChannel";
+ private static final boolean DEBUG = false;
+
public static final Parcelable.Creator<InputChannel> CREATOR
= new Parcelable.Creator<InputChannel>() {
public InputChannel createFromParcel(Parcel source) {
@@ -84,8 +86,10 @@ public final class InputChannel implements Parcelable {
if (name == null) {
throw new IllegalArgumentException("name must not be null");
}
-
- Slog.d(TAG, "Opening input channel pair '" + name + "'");
+
+ if (DEBUG) {
+ Slog.d(TAG, "Opening input channel pair '" + name + "'");
+ }
return nativeOpenInputChannelPair(name);
}
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
new file mode 100755
index 0000000..568caa2
--- /dev/null
+++ b/core/java/android/view/InputDevice.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+/**
+ * Describes the capabilities of a particular input device.
+ * <p>
+ * Each input device may support multiple classes of input. For example, a multifunction
+ * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
+ * or other pointing device.
+ * </p><p>
+ * Some input devices present multiple distinguishable sources of input. For example, a
+ * game pad may have two analog joysticks, a directional pad and a full complement of buttons.
+ * Applications can query the framework about the characteristics of each distinct source.
+ * </p><p>
+ * As a further wrinkle, different kinds of input sources uses different coordinate systems
+ * to describe motion events. Refer to the comments on the input source constants for
+ * the appropriate interpretation.
+ */
+public final class InputDevice {
+ private int mId;
+ private String mName;
+ private int mSources;
+
+ /**
+ * A mask for input source classes.
+ *
+ * Each distinct input source constant has one or more input source class bits set to
+ * specify the desired interpretation for its input events.
+ */
+ public static final int SOURCE_CLASS_MASK = 0x000000ff;
+
+ /**
+ * The input source has buttons or keys.
+ * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_GAMEPAD}, {@link #SOURCE_DPAD}.
+ *
+ * A {@link KeyEvent} should be interpreted as a button or key press.
+ *
+ * Use {@link #hasKeyCode} to query whether the device supports a particular button or key.
+ */
+ public static final int SOURCE_CLASS_BUTTON = 0x00000001;
+
+ /**
+ * The input source is a pointing device associated with a display.
+ * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}.
+ *
+ * A {@link MotionEvent} should be interpreted as absolute coordinates in
+ * display units according to the {@link View} hierarchy. Pointer down/up indicated when
+ * the finger touches the display or when the selection button is pressed/released.
+ *
+ * Use {@link #getMotionRange} to query the range of the pointing device. Some devices permit
+ * touches outside the display area so the effective range may be somewhat smaller or larger
+ * than the actual display size.
+ */
+ public static final int SOURCE_CLASS_POINTER = 0x00000002;
+
+ /**
+ * The input source is a trackball navigation device.
+ * Examples: {@link #SOURCE_TRACKBALL}.
+ *
+ * A {@link MotionEvent} should be interpreted as relative movements in device-specific
+ * units used for navigation purposes. Pointer down/up indicates when the selection button
+ * is pressed/released.
+ *
+ * Use {@link #getMotionRange} to query the range of motion.
+ */
+ public static final int SOURCE_CLASS_TRACKBALL = 0x00000004;
+
+ /**
+ * The input source is an absolute positioning device not associated with a display
+ * (unlike {@link #SOURCE_CLASS_POINTER}).
+ *
+ * A {@link MotionEvent} should be interpreted as absolute coordinates in
+ * device-specific surface units.
+ *
+ * Use {@link #getMotionRange} to query the range of positions.
+ */
+ public static final int SOURCE_CLASS_POSITION = 0x00000008;
+
+ /**
+ * The input source is a joystick.
+ *
+ * A {@link KeyEvent} should be interpreted as a joystick button press.
+ *
+ * A {@link MotionEvent} should be interpreted in absolute coordinates as a joystick
+ * position in normalized device-specific units nominally between -1.0 and 1.0.
+ *
+ * Use {@link #getMotionRange} to query the range and precision of motion.
+ */
+ public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;
+
+ /**
+ * The input source is unknown.
+ */
+ public static final int SOURCE_UNKNOWN = 0x00000000;
+
+ /**
+ * The input source is a keyboard.
+ *
+ * @see #SOURCE_CLASS_BUTTON
+ */
+ public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
+
+ /**
+ * The input source is a DPad.
+ *
+ * @see #SOURCE_CLASS_BUTTON
+ */
+ public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON;
+
+ /**
+ * The input source is a gamepad.
+ *
+ * @see #SOURCE_CLASS_BUTTON
+ */
+ public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;
+
+ /**
+ * The input source is a touch screen pointing device.
+ *
+ * @see #SOURCE_CLASS_POINTER
+ */
+ public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;
+
+ /**
+ * The input source is a mouse pointing device.
+ * This code is also used for other mouse-like pointing devices such as trackpads
+ * and trackpoints.
+ *
+ * @see #SOURCE_CLASS_POINTER
+ */
+ public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER;
+
+ /**
+ * The input source is a trackball.
+ *
+ * @see #SOURCE_CLASS_TRACKBALL
+ */
+ public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL;
+
+ /**
+ * The input source is a touch pad or digitizer tablet that is not
+ * associated with a display (unlike {@link SOURCE_TOUCHSCREEN}).
+ *
+ * @see #SOURCE_CLASS_POSITION
+ */
+ public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;
+
+ /**
+ * The input source is a joystick mounted on the left or is a standalone joystick.
+ *
+ * @see #SOURCE_CLASS_JOYSTICK
+ */
+ public static final int SOURCE_JOYSTICK_LEFT = 0x01000000 | SOURCE_CLASS_JOYSTICK;
+
+ /**
+ * The input source is a joystick mounted on the right.
+ *
+ * @see #SOURCE_CLASS_JOYSTICK
+ */
+ public static final int SOURCE_JOYSTICK_RIGHT = 0x02000000 | SOURCE_CLASS_JOYSTICK;
+
+ /*
+ public static final int MOTION_RANGE_X = 0;
+ public static final int MOTION_RANGE_Y = 1;
+ public static final int MOTION_RANGE_PRESSURE = 2;
+ public static final int MOTION_RANGE_SIZE = 3;
+ public static final int MOTION_RANGE_TOUCH_MAJOR = 4;
+ public static final int MOTION_RANGE_TOUCH_MINOR = 5;
+ public static final int MOTION_RANGE_TOOL_MAJOR = 6;
+ public static final int MOTION_RANGE_TOOL_MINOR = 7;
+ public static final int MOTION_RANGE_ORIENTATION = 8;
+
+ public static InputDevice getDevice(int id) {
+ }
+ */
+
+ /**
+ * Gets the name of this input device.
+ * @return The input device name.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * Gets the input sources supported by this input device as a combined bitfield.
+ * @return The supported input sources.
+ */
+ public int getSources() {
+ return mSources;
+ }
+
+ /**
+ * Gets the key character map associated with this input device.
+ * @return The key character map.
+ */
+ public KeyCharacterMap getKeyCharacterMap() {
+ return KeyCharacterMap.load(mId);
+ }
+
+ /*
+
+ public MotionRange getMotionRange(int range) {
+ }
+
+ public boolean hasKeyCode(int keyCode) {
+ }
+
+ public static final class MotionRange {
+ public float min;
+ public float max;
+ public float range;
+ public float flat;
+ public float fuzz;
+ }*/
+}
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
new file mode 100755
index 0000000..445a980
--- /dev/null
+++ b/core/java/android/view/InputEvent.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.os.Parcelable;
+
+/**
+ * Common base class for input events.
+ */
+public abstract class InputEvent implements Parcelable {
+ protected int mDeviceId;
+ protected int mSource;
+
+ /*package*/ InputEvent() {
+ }
+
+ /**
+ * Gets the id for the device that this event came from. An id of
+ * zero indicates that the event didn't come from a physical device
+ * and maps to the default keymap. The other numbers are arbitrary and
+ * you shouldn't depend on the values.
+ *
+ * @return The device id.
+ * @see InputDevice#getDevice
+ */
+ public final int getDeviceId() {
+ return mDeviceId;
+ }
+
+ /**
+ * Gets the source of the event.
+ *
+ * @return The event source or {@link InputDevice.SOURCE_UNKNOWN} if unknown.
+ * @see InputDevice#getSourceInfo
+ */
+ public final int getSource() {
+ return mSource;
+ }
+
+ /**
+ * Modifies the source of the event.
+ * @param source The source.
+ *
+ * @hide
+ */
+ public final void setSource(int source) {
+ mSource = source;
+ }
+}
diff --git a/core/java/android/view/InputHandler.java b/core/java/android/view/InputHandler.java
index 816f622..41a152d 100644
--- a/core/java/android/view/InputHandler.java
+++ b/core/java/android/view/InputHandler.java
@@ -32,22 +32,12 @@ public interface InputHandler {
public void handleKey(KeyEvent event, Runnable finishedCallback);
/**
- * Handle a touch event.
+ * Handle a motion event.
* It is the responsibility of the callee to ensure that the finished callback is
* eventually invoked when the event processing is finished and the input system
* can send the next event.
* @param event The motion event data.
* @param finishedCallback The callback to invoke when event processing is finished.
*/
- public void handleTouch(MotionEvent event, Runnable finishedCallback);
-
- /**
- * Handle a trackball event.
- * It is the responsibility of the callee to ensure that the finished callback is
- * eventually invoked when the event processing is finished and the input system
- * can send the next event.
- * @param event The motion event data.
- * @param finishedCallback The callback to invoke when event processing is finished.
- */
- public void handleTrackball(MotionEvent event, Runnable finishedCallback);
+ public void handleMotion(MotionEvent event, Runnable finishedCallback);
}
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index 7feee38..997246f 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -26,6 +26,8 @@ import android.util.Slog;
public final class InputQueue {
private static final String TAG = "InputQueue";
+ private static final boolean DEBUG = false;
+
public static interface Callback {
void onInputQueueCreated(InputQueue queue);
void onInputQueueDestroyed(InputQueue queue);
@@ -33,15 +35,6 @@ public final class InputQueue {
final InputChannel mChannel;
- // Describes the interpretation of an event.
- // XXX This concept is tentative. See comments in android/input.h.
- /** @hide */
- public static final int INPUT_EVENT_NATURE_KEY = 1;
- /** @hide */
- public static final int INPUT_EVENT_NATURE_TOUCH = 2;
- /** @hide */
- public static final int INPUT_EVENT_NATURE_TRACKBALL = 3;
-
private static Object sLock = new Object();
private static native void nativeRegisterInputChannel(InputChannel inputChannel,
@@ -79,7 +72,10 @@ public final class InputQueue {
}
synchronized (sLock) {
- Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
+ if (DEBUG) {
+ Slog.d(TAG, "Registering input channel '" + inputChannel + "'");
+ }
+
nativeRegisterInputChannel(inputChannel, inputHandler, messageQueue);
}
}
@@ -96,35 +92,26 @@ public final class InputQueue {
}
synchronized (sLock) {
- Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
+ if (DEBUG) {
+ Slog.d(TAG, "Unregistering input channel '" + inputChannel + "'");
+ }
+
nativeUnregisterInputChannel(inputChannel);
}
}
@SuppressWarnings("unused")
private static void dispatchKeyEvent(InputHandler inputHandler,
- KeyEvent event, int nature, long finishedToken) {
+ KeyEvent event, long finishedToken) {
Runnable finishedCallback = new FinishedCallback(finishedToken);
-
- if (nature == INPUT_EVENT_NATURE_KEY) {
- inputHandler.handleKey(event, finishedCallback);
- } else {
- Slog.d(TAG, "Unsupported nature for key event: " + nature);
- }
+ inputHandler.handleKey(event, finishedCallback);
}
@SuppressWarnings("unused")
private static void dispatchMotionEvent(InputHandler inputHandler,
- MotionEvent event, int nature, long finishedToken) {
+ MotionEvent event, long finishedToken) {
Runnable finishedCallback = new FinishedCallback(finishedToken);
-
- if (nature == INPUT_EVENT_NATURE_TOUCH) {
- inputHandler.handleTouch(event, finishedCallback);
- } else if (nature == INPUT_EVENT_NATURE_TRACKBALL) {
- inputHandler.handleTrackball(event, finishedCallback);
- } else {
- Slog.d(TAG, "Unsupported nature for motion event: " + nature);
- }
+ inputHandler.handleMotion(event, finishedCallback);
}
// TODO consider recycling finished callbacks when done
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 25958aa..9981d87 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -26,6 +26,9 @@ import android.util.SparseArray;
import java.lang.Character;
import java.lang.ref.WeakReference;
+/**
+ * Describes the keys provided by a device and their associated labels.
+ */
public class KeyCharacterMap
{
/**
@@ -59,6 +62,11 @@ public class KeyCharacterMap
private static SparseArray<WeakReference<KeyCharacterMap>> sInstances
= new SparseArray<WeakReference<KeyCharacterMap>>();
+ /**
+ * Loads the key character maps for the keyboard with the specified device id.
+ * @param keyboard The device id of the keyboard.
+ * @return The associated key character map.
+ */
public static KeyCharacterMap load(int keyboard)
{
synchronized (sLock) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 9c05008..dd0d21a 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -26,7 +26,7 @@ import android.view.KeyCharacterMap.KeyData;
/**
* Contains constants for key events.
*/
-public class KeyEvent implements Parcelable {
+public class KeyEvent extends InputEvent implements Parcelable {
// key codes
public static final int KEYCODE_UNKNOWN = 0;
public static final int KEYCODE_SOFT_LEFT = 1;
@@ -349,7 +349,6 @@ public class KeyEvent implements Parcelable {
private int mKeyCode;
private int mScanCode;
private int mRepeatCount;
- private int mDeviceId;
private int mFlags;
private long mDownTime;
private long mEventTime;
@@ -484,19 +483,19 @@ public class KeyEvent implements Parcelable {
* @param repeat A repeat count for down events (> 0 if this is after the
* initial down) or event count for multiple events.
* @param metaState Flags indicating which meta keys are currently pressed.
- * @param device The device ID that generated the key event.
+ * @param deviceId The device ID that generated the key event.
* @param scancode Raw device scan code of the event.
*/
public KeyEvent(long downTime, long eventTime, int action,
int code, int repeat, int metaState,
- int device, int scancode) {
+ int deviceId, int scancode) {
mDownTime = downTime;
mEventTime = eventTime;
mAction = action;
mKeyCode = code;
mRepeatCount = repeat;
mMetaState = metaState;
- mDeviceId = device;
+ mDeviceId = deviceId;
mScanCode = scancode;
}
@@ -513,44 +512,79 @@ public class KeyEvent implements Parcelable {
* @param repeat A repeat count for down events (> 0 if this is after the
* initial down) or event count for multiple events.
* @param metaState Flags indicating which meta keys are currently pressed.
- * @param device The device ID that generated the key event.
+ * @param deviceId The device ID that generated the key event.
* @param scancode Raw device scan code of the event.
* @param flags The flags for this key event
*/
public KeyEvent(long downTime, long eventTime, int action,
int code, int repeat, int metaState,
- int device, int scancode, int flags) {
+ int deviceId, int scancode, int flags) {
mDownTime = downTime;
mEventTime = eventTime;
mAction = action;
mKeyCode = code;
mRepeatCount = repeat;
mMetaState = metaState;
- mDeviceId = device;
+ mDeviceId = deviceId;
mScanCode = scancode;
mFlags = flags;
}
/**
+ * Create a new key event.
+ *
+ * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
+ * at which this key code originally went down.
+ * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
+ * at which this event happened.
+ * @param action Action code: either {@link #ACTION_DOWN},
+ * {@link #ACTION_UP}, or {@link #ACTION_MULTIPLE}.
+ * @param code The key code.
+ * @param repeat A repeat count for down events (> 0 if this is after the
+ * initial down) or event count for multiple events.
+ * @param metaState Flags indicating which meta keys are currently pressed.
+ * @param deviceId The device ID that generated the key event.
+ * @param scancode Raw device scan code of the event.
+ * @param flags The flags for this key event
+ * @param source The input source such as {@link InputDevice#SOURCE_KEYBOARD}.
+ */
+ public KeyEvent(long downTime, long eventTime, int action,
+ int code, int repeat, int metaState,
+ int deviceId, int scancode, int flags, int source) {
+ mDownTime = downTime;
+ mEventTime = eventTime;
+ mAction = action;
+ mKeyCode = code;
+ mRepeatCount = repeat;
+ mMetaState = metaState;
+ mDeviceId = deviceId;
+ mScanCode = scancode;
+ mFlags = flags;
+ mSource = source;
+ }
+
+ /**
* Create a new key event for a string of characters. The key code,
- * action, and repeat could will automatically be set to
- * {@link #KEYCODE_UNKNOWN}, {@link #ACTION_MULTIPLE}, and 0 for you.
+ * action, repeat count and source will automatically be set to
+ * {@link #KEYCODE_UNKNOWN}, {@link #ACTION_MULTIPLE}, 0, and
+ * {@link InputDevice#SOURCE_KEYBOARD} for you.
*
* @param time The time (in {@link android.os.SystemClock#uptimeMillis})
* at which this event occured.
* @param characters The string of characters.
- * @param device The device ID that generated the key event.
+ * @param deviceId The device ID that generated the key event.
* @param flags The flags for this key event
*/
- public KeyEvent(long time, String characters, int device, int flags) {
+ public KeyEvent(long time, String characters, int deviceId, int flags) {
mDownTime = time;
mEventTime = time;
mCharacters = characters;
mAction = ACTION_MULTIPLE;
mKeyCode = KEYCODE_UNKNOWN;
mRepeatCount = 0;
- mDeviceId = device;
+ mDeviceId = deviceId;
mFlags = flags;
+ mSource = InputDevice.SOURCE_KEYBOARD;
}
/**
@@ -564,6 +598,7 @@ public class KeyEvent implements Parcelable {
mRepeatCount = origEvent.mRepeatCount;
mMetaState = origEvent.mMetaState;
mDeviceId = origEvent.mDeviceId;
+ mSource = origEvent.mSource;
mScanCode = origEvent.mScanCode;
mFlags = origEvent.mFlags;
mCharacters = origEvent.mCharacters;
@@ -589,6 +624,7 @@ public class KeyEvent implements Parcelable {
mRepeatCount = newRepeat;
mMetaState = origEvent.mMetaState;
mDeviceId = origEvent.mDeviceId;
+ mSource = origEvent.mSource;
mScanCode = origEvent.mScanCode;
mFlags = origEvent.mFlags;
mCharacters = origEvent.mCharacters;
@@ -642,6 +678,7 @@ public class KeyEvent implements Parcelable {
mRepeatCount = origEvent.mRepeatCount;
mMetaState = origEvent.mMetaState;
mDeviceId = origEvent.mDeviceId;
+ mSource = origEvent.mSource;
mScanCode = origEvent.mScanCode;
mFlags = origEvent.mFlags;
// Don't copy mCharacters, since one way or the other we'll lose it
@@ -897,18 +934,6 @@ public class KeyEvent implements Parcelable {
}
/**
- * Return the id for the keyboard that this event came from. A device
- * id of 0 indicates the event didn't come from a physical device and
- * maps to the default keymap. The other numbers are arbitrary and
- * you shouldn't depend on the values.
- *
- * @see KeyCharacterMap#load
- */
- public final int getDeviceId() {
- return mDeviceId;
- }
-
- /**
* Renamed to {@link #getDeviceId}.
*
* @hide
@@ -1204,6 +1229,7 @@ public class KeyEvent implements Parcelable {
out.writeInt(mRepeatCount);
out.writeInt(mMetaState);
out.writeInt(mDeviceId);
+ out.writeInt(mSource);
out.writeInt(mScanCode);
out.writeInt(mFlags);
out.writeLong(mDownTime);
@@ -1216,6 +1242,7 @@ public class KeyEvent implements Parcelable {
mRepeatCount = in.readInt();
mMetaState = in.readInt();
mDeviceId = in.readInt();
+ mSource = in.readInt();
mScanCode = in.readInt();
mFlags = in.readInt();
mDownTime = in.readLong();
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ae8c21d..0015db0 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -19,16 +19,17 @@ package android.view;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
-import android.util.Log;
/**
* Object used to report movement (mouse, pen, finger, trackball) events. This
* class may hold either absolute or relative movements, depending on what
* it is being used for.
+ *
+ * Refer to {@link InputDevice} for information about how different kinds of
+ * input devices and sources represent pointer coordinates.
*/
-public final class MotionEvent implements Parcelable {
+public final class MotionEvent extends InputEvent implements Parcelable {
private static final long MS_PER_NS = 1000000;
- static final boolean DEBUG_POINTERS = false;
/**
* Bit mask of the parts of the action code that are the action itself.
@@ -189,22 +190,52 @@ public final class MotionEvent implements Parcelable {
static public final int SAMPLE_Y = 1;
/**
- * Offset for the sample's X coordinate.
+ * Offset for the sample's pressure.
* @hide
*/
static public final int SAMPLE_PRESSURE = 2;
/**
- * Offset for the sample's X coordinate.
+ * Offset for the sample's size
* @hide
*/
static public final int SAMPLE_SIZE = 3;
/**
+ * Offset for the sample's touch major axis length.
+ * @hide
+ */
+ static public final int SAMPLE_TOUCH_MAJOR = 4;
+
+ /**
+ * Offset for the sample's touch minor axis length.
+ * @hide
+ */
+ static public final int SAMPLE_TOUCH_MINOR = 5;
+
+ /**
+ * Offset for the sample's tool major axis length.
+ * @hide
+ */
+ static public final int SAMPLE_TOOL_MAJOR = 6;
+
+ /**
+ * Offset for the sample's tool minor axis length.
+ * @hide
+ */
+ static public final int SAMPLE_TOOL_MINOR = 7;
+
+ /**
+ * Offset for the sample's orientation.
+ * @hide
+ */
+ static public final int SAMPLE_ORIENTATION = 8;
+
+ /**
* Number of data items for each sample.
* @hide
*/
- static public final int NUM_SAMPLE_DATA = 4;
+ static public final int NUM_SAMPLE_DATA = 9;
/**
* Number of possible pointers.
@@ -225,7 +256,6 @@ public final class MotionEvent implements Parcelable {
private float mYOffset;
private float mXPrecision;
private float mYPrecision;
- private int mDeviceId;
private int mEdgeFlags;
private int mMetaState;
@@ -298,18 +328,16 @@ public final class MotionEvent implements Parcelable {
*
* @param downTime The time (in ms) when the user originally pressed down to start
* a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param eventTime The the time (in ms) when this specific event was generated. This
+ * @param eventTime The the time (in ms) when this specific event was generated. This
* must be obtained from {@link SystemClock#uptimeMillis()}.
- * @param eventTimeNano The the time (in ns) when this specific event was generated. This
- * must be obtained from {@link System#nanoTime()}.
* @param action The kind of action being performed -- one of either
* {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
* {@link #ACTION_CANCEL}.
* @param pointers The number of points that will be in this event.
- * @param inPointerIds An array of <em>pointers</em> values providing
+ * @param pointerIds An array of <em>pointers</em> values providing
* an identifier for each pointer.
- * @param inData An array of <em>pointers*NUM_SAMPLE_DATA</em> of initial
- * data samples for the event.
+ * @param pointerCoords An array of <em>pointers</em> values providing
+ * a {@link PointerCoords} coordinate object for each pointer.
* @param metaState The state of any meta / modifier keys that were in effect when
* the event was generated.
* @param xPrecision The precision of the X coordinate being reported.
@@ -319,14 +347,15 @@ public final class MotionEvent implements Parcelable {
* numbers are arbitrary and you shouldn't depend on the values.
* @param edgeFlags A bitfield indicating which edges, if any, where touched by this
* MotionEvent.
- *
- * @hide
+ * @param source The source of this event.
*/
- static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano,
- int action, int pointers, int[] inPointerIds, float[] inData, int metaState,
- float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
+ static public MotionEvent obtain(long downTime, long eventTime,
+ int action, int pointers, int[] pointerIds, PointerCoords[] pointerCoords,
+ int metaState, float xPrecision, float yPrecision, int deviceId,
+ int edgeFlags, int source) {
MotionEvent ev = obtain(pointers, 1);
ev.mDeviceId = deviceId;
+ ev.mSource = source;
ev.mEdgeFlags = edgeFlags;
ev.mDownTimeNano = downTime * MS_PER_NS;
ev.mAction = action;
@@ -342,26 +371,11 @@ public final class MotionEvent implements Parcelable {
ev.mLastDataSampleIndex = 0;
ev.mLastEventTimeNanoSampleIndex = 0;
- System.arraycopy(inPointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
+ System.arraycopy(pointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
- ev.mEventTimeNanoSamples[0] = eventTimeNano;
+ ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
- System.arraycopy(inData, 0, ev.mDataSamples, 0, pointers * NUM_SAMPLE_DATA);
-
- if (DEBUG_POINTERS) {
- StringBuilder sb = new StringBuilder(128);
- sb.append("New:");
- for (int i = 0; i < pointers; i++) {
- sb.append(" #");
- sb.append(ev.getPointerId(i));
- sb.append("(");
- sb.append(ev.getX(i));
- sb.append(",");
- sb.append(ev.getY(i));
- sb.append(")");
- }
- Log.v("MotionEvent", sb.toString());
- }
+ ev.setPointerCoordsAtSampleIndex(0, pointerCoords);
return ev;
}
@@ -402,6 +416,7 @@ public final class MotionEvent implements Parcelable {
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
MotionEvent ev = obtain(1, 1);
ev.mDeviceId = deviceId;
+ ev.mSource = InputDevice.SOURCE_UNKNOWN;
ev.mEdgeFlags = edgeFlags;
ev.mDownTimeNano = downTime * MS_PER_NS;
ev.mAction = action;
@@ -421,11 +436,7 @@ public final class MotionEvent implements Parcelable {
ev.mEventTimeNanoSamples[0] = eventTime * MS_PER_NS;
- float[] dataSamples = ev.mDataSamples;
- dataSamples[SAMPLE_X] = x;
- dataSamples[SAMPLE_Y] = y;
- dataSamples[SAMPLE_PRESSURE] = pressure;
- dataSamples[SAMPLE_SIZE] = size;
+ ev.setPointerCoordsAtSampleIndex(0, x, y, pressure, size);
return ev;
}
@@ -501,6 +512,7 @@ public final class MotionEvent implements Parcelable {
static public MotionEvent obtain(MotionEvent o) {
MotionEvent ev = obtain(o.mNumPointers, o.mNumSamples);
ev.mDeviceId = o.mDeviceId;
+ ev.mSource = o.mSource;
ev.mEdgeFlags = o.mEdgeFlags;
ev.mDownTimeNano = o.mDownTimeNano;
ev.mAction = o.mAction;
@@ -531,6 +543,7 @@ public final class MotionEvent implements Parcelable {
static public MotionEvent obtainNoHistory(MotionEvent o) {
MotionEvent ev = obtain(o.mNumPointers, 1);
ev.mDeviceId = o.mDeviceId;
+ ev.mSource = o.mSource;
ev.mEdgeFlags = o.mEdgeFlags;
ev.mDownTimeNano = o.mDownTimeNano;
ev.mAction = o.mAction;
@@ -602,6 +615,10 @@ public final class MotionEvent implements Parcelable {
history[i + SAMPLE_Y] *= scale;
// no need to scale pressure
history[i + SAMPLE_SIZE] *= scale; // TODO: square this?
+ history[i + SAMPLE_TOUCH_MAJOR] *= scale;
+ history[i + SAMPLE_TOUCH_MINOR] *= scale;
+ history[i + SAMPLE_TOOL_MAJOR] *= scale;
+ history[i + SAMPLE_TOOL_MINOR] *= scale;
}
}
@@ -696,6 +713,46 @@ public final class MotionEvent implements Parcelable {
public final float getSize() {
return mDataSamples[mLastDataSampleIndex + SAMPLE_SIZE];
}
+
+ /**
+ * {@link #getTouchMajor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getTouchMajor() {
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_TOUCH_MAJOR];
+ }
+
+ /**
+ * {@link #getTouchMinor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getTouchMinor() {
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_TOUCH_MINOR];
+ }
+
+ /**
+ * {@link #getToolMajor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getToolMajor() {
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_TOOL_MAJOR];
+ }
+
+ /**
+ * {@link #getToolMinor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getToolMinor() {
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_TOOL_MINOR];
+ }
+
+ /**
+ * {@link #getOrientation(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getOrientation() {
+ return mDataSamples[mLastDataSampleIndex + SAMPLE_ORIENTATION];
+ }
/**
* The number of pointers of data contained in this event. Always
@@ -796,6 +853,93 @@ public final class MotionEvent implements Parcelable {
return mDataSamples[mLastDataSampleIndex
+ pointerIndex * NUM_SAMPLE_DATA + SAMPLE_SIZE];
}
+
+ /**
+ * Returns the length of the major axis of an ellipse that describes the touch
+ * area at the point of contact for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ */
+ public final float getTouchMajor(int pointerIndex) {
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ }
+
+ /**
+ * Returns the length of the minor axis of an ellipse that describes the touch
+ * area at the point of contact for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ */
+ public final float getTouchMinor(int pointerIndex) {
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ }
+
+ /**
+ * Returns the length of the major axis of an ellipse that describes the size of
+ * the approaching tool for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ */
+ public final float getToolMajor(int pointerIndex) {
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ }
+
+ /**
+ * Returns the length of the minor axis of an ellipse that describes the size of
+ * the approaching tool for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ */
+ public final float getToolMinor(int pointerIndex) {
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ }
+
+ /**
+ * Returns the orientation of the touch area and tool area in radians clockwise from vertical
+ * for the given pointer <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation. A positive angle
+ * indicates that the major axis of contact is oriented to the right. A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/4 radians (finger pointing fully left) to PI/4 radians
+ * (finger pointing fully right).
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ */
+ public final float getOrientation(int pointerIndex) {
+ return mDataSamples[mLastDataSampleIndex
+ + pointerIndex * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
+ }
+
+ /**
+ * Populates a {@link PointerCoords} object with pointer coordinate data for
+ * the specified pointer index.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param outPointerCoords The pointer coordinate object to populate.
+ */
+ public final void getPointerCoords(int pointerIndex, PointerCoords outPointerCoords) {
+ final int sampleIndex = mLastDataSampleIndex + pointerIndex * NUM_SAMPLE_DATA;
+ getPointerCoordsAtSampleIndex(sampleIndex, outPointerCoords);
+ }
/**
* Returns the state of any meta / modifier keys that were in effect when
@@ -820,7 +964,7 @@ public final class MotionEvent implements Parcelable {
public final float getRawX() {
return mDataSamples[mLastDataSampleIndex + SAMPLE_X];
}
-
+
/**
* Returns the original raw Y coordinate of this event. For touch
* events on the screen, this is the original location of the event
@@ -910,6 +1054,46 @@ public final class MotionEvent implements Parcelable {
}
/**
+ * {@link #getHistoricalTouchMajor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getHistoricalTouchMajor(int pos) {
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ }
+
+ /**
+ * {@link #getHistoricalTouchMinor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getHistoricalTouchMinor(int pos) {
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ }
+
+ /**
+ * {@link #getHistoricalToolMajor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getHistoricalToolMajor(int pos) {
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ }
+
+ /**
+ * {@link #getHistoricalToolMinor(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getHistoricalToolMinor(int pos) {
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ }
+
+ /**
+ * {@link #getHistoricalOrientation(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getHistoricalOrientation(int pos) {
+ return mDataSamples[pos * mNumPointers * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
+ }
+
+ /**
* Returns a historical X coordinate, as per {@link #getX(int)}, that
* occurred between this event and the previous event for the given pointer.
* Only applies to ACTION_MOVE events.
@@ -980,17 +1164,119 @@ public final class MotionEvent implements Parcelable {
return mDataSamples[(pos * mNumPointers + pointerIndex)
* NUM_SAMPLE_DATA + SAMPLE_SIZE];
}
+
+ /**
+ * Returns a historical touch major axis coordinate, as per {@link #getTouchMajor(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getTouchMajor
+ */
+ public final float getHistoricalTouchMajor(int pointerIndex, int pos) {
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MAJOR];
+ }
/**
- * Return the id for the device that this event came from. An id of
- * zero indicates that the event didn't come from a physical device; other
- * numbers are arbitrary and you shouldn't depend on the values.
+ * Returns a historical touch minor axis coordinate, as per {@link #getTouchMinor(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getTouchMinor
+ */
+ public final float getHistoricalTouchMinor(int pointerIndex, int pos) {
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_TOUCH_MINOR];
+ }
+
+ /**
+ * Returns a historical tool major axis coordinate, as per {@link #getToolMajor(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getToolMajor
+ */
+ public final float getHistoricalToolMajor(int pointerIndex, int pos) {
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_TOOL_MAJOR];
+ }
+
+ /**
+ * Returns a historical tool minor axis coordinate, as per {@link #getToolMinor(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getToolMinor
+ */
+ public final float getHistoricalToolMinor(int pointerIndex, int pos) {
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_TOOL_MINOR];
+ }
+
+ /**
+ * Returns a historical orientation coordinate, as per {@link #getOrientation(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ *
+ * @see #getHistorySize
+ * @see #getOrientation
*/
- public final int getDeviceId() {
- return mDeviceId;
+ public final float getHistoricalOrientation(int pointerIndex, int pos) {
+ return mDataSamples[(pos * mNumPointers + pointerIndex)
+ * NUM_SAMPLE_DATA + SAMPLE_ORIENTATION];
}
/**
+ * Populates a {@link PointerCoords} object with historical pointer coordinate data,
+ * as per {@link #getPointerCoords}, that occurred between this event and the previous
+ * event for the given pointer.
+ * Only applies to ACTION_MOVE events.
+ *
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * @param pos Which historical value to return; must be less than
+ * {@link #getHistorySize}
+ * @param outPointerCoords The pointer coordinate object to populate.
+ *
+ * @see #getHistorySize
+ * @see #getPointerCoords
+ */
+ public final void getHistoricalPointerCoords(int pointerIndex, int pos,
+ PointerCoords outPointerCoords) {
+ final int sampleIndex = (pos * mNumPointers + pointerIndex) * NUM_SAMPLE_DATA;
+ getPointerCoordsAtSampleIndex(sampleIndex, outPointerCoords);
+ }
+
+ /**
* Returns a bitfield indicating which edges, if any, were touched by this
* MotionEvent. For touch events, clients can use this to determine if the
* user's finger was touching the edge of the display.
@@ -1044,6 +1330,54 @@ public final class MotionEvent implements Parcelable {
mYOffset = y - mDataSamples[mLastDataSampleIndex + SAMPLE_Y];
}
+ private final void getPointerCoordsAtSampleIndex(int sampleIndex,
+ PointerCoords outPointerCoords) {
+ outPointerCoords.x = mDataSamples[sampleIndex + SAMPLE_X] + mXOffset;
+ outPointerCoords.y = mDataSamples[sampleIndex + SAMPLE_Y] + mYOffset;
+ outPointerCoords.pressure = mDataSamples[sampleIndex + SAMPLE_PRESSURE];
+ outPointerCoords.size = mDataSamples[sampleIndex + SAMPLE_SIZE];
+ outPointerCoords.touchMajor = mDataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR];
+ outPointerCoords.touchMinor = mDataSamples[sampleIndex + SAMPLE_TOUCH_MINOR];
+ outPointerCoords.toolMajor = mDataSamples[sampleIndex + SAMPLE_TOOL_MAJOR];
+ outPointerCoords.toolMinor = mDataSamples[sampleIndex + SAMPLE_TOOL_MINOR];
+ outPointerCoords.orientation = mDataSamples[sampleIndex + SAMPLE_ORIENTATION];
+ }
+
+ private final void setPointerCoordsAtSampleIndex(int sampleIndex,
+ PointerCoords[] pointerCoords) {
+ final int numPointers = mNumPointers;
+ for (int i = 0; i < numPointers; i++) {
+ setPointerCoordsAtSampleIndex(sampleIndex, pointerCoords[i]);
+ sampleIndex += NUM_SAMPLE_DATA;
+ }
+ }
+
+ private final void setPointerCoordsAtSampleIndex(int sampleIndex,
+ PointerCoords pointerCoords) {
+ mDataSamples[sampleIndex + SAMPLE_X] = pointerCoords.x - mXOffset;
+ mDataSamples[sampleIndex + SAMPLE_Y] = pointerCoords.y - mYOffset;
+ mDataSamples[sampleIndex + SAMPLE_PRESSURE] = pointerCoords.pressure;
+ mDataSamples[sampleIndex + SAMPLE_SIZE] = pointerCoords.size;
+ mDataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR] = pointerCoords.touchMajor;
+ mDataSamples[sampleIndex + SAMPLE_TOUCH_MINOR] = pointerCoords.touchMinor;
+ mDataSamples[sampleIndex + SAMPLE_TOOL_MAJOR] = pointerCoords.toolMajor;
+ mDataSamples[sampleIndex + SAMPLE_TOOL_MINOR] = pointerCoords.toolMinor;
+ mDataSamples[sampleIndex + SAMPLE_ORIENTATION] = pointerCoords.orientation;
+ }
+
+ private final void setPointerCoordsAtSampleIndex(int sampleIndex,
+ float x, float y, float pressure, float size) {
+ mDataSamples[sampleIndex + SAMPLE_X] = x - mXOffset;
+ mDataSamples[sampleIndex + SAMPLE_Y] = y - mYOffset;
+ mDataSamples[sampleIndex + SAMPLE_PRESSURE] = pressure;
+ mDataSamples[sampleIndex + SAMPLE_SIZE] = size;
+ mDataSamples[sampleIndex + SAMPLE_TOUCH_MAJOR] = pressure;
+ mDataSamples[sampleIndex + SAMPLE_TOUCH_MINOR] = pressure;
+ mDataSamples[sampleIndex + SAMPLE_TOOL_MAJOR] = size;
+ mDataSamples[sampleIndex + SAMPLE_TOOL_MINOR] = size;
+ mDataSamples[sampleIndex + SAMPLE_ORIENTATION] = 0;
+ }
+
private final void incrementNumSamplesAndReserveStorage(int dataSampleStride) {
if (mNumSamples == mEventTimeNanoSamples.length) {
long[] newEventTimeNanoSamples = new long[mNumSamples + BASE_AVAIL_SAMPLES];
@@ -1066,11 +1400,12 @@ public final class MotionEvent implements Parcelable {
/**
* Add a new movement to the batch of movements in this event. The event's
- * current location, position and size is updated to the new values. In
- * the future, the current values in the event will be added to a list of
- * historic values.
+ * current location, position and size is updated to the new values.
+ * The current values in the event are added to a list of historical values.
+ *
+ * Only applies to {@link ACTION_MOVE} events.
*
- * @param eventTime The time stamp for this data.
+ * @param eventTime The time stamp (in ms) for this data.
* @param x The new X position.
* @param y The new Y position.
* @param pressure The new pressure.
@@ -1082,62 +1417,30 @@ public final class MotionEvent implements Parcelable {
incrementNumSamplesAndReserveStorage(NUM_SAMPLE_DATA);
mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
-
- float[] dataSamples = mDataSamples;
- dataSamples[mLastDataSampleIndex + SAMPLE_X] = x - mXOffset;
- dataSamples[mLastDataSampleIndex + SAMPLE_Y] = y - mYOffset;
- dataSamples[mLastDataSampleIndex + SAMPLE_PRESSURE] = pressure;
- dataSamples[mLastDataSampleIndex + SAMPLE_SIZE] = size;
+ setPointerCoordsAtSampleIndex(mLastDataSampleIndex, x, y, pressure, size);
mMetaState |= metaState;
}
/**
- * Add a new movement to the batch of movements in this event. The
- * input data must contain (NUM_SAMPLE_DATA * {@link #getPointerCount()})
- * samples of data.
+ * Add a new movement to the batch of movements in this event. The event's
+ * current location, position and size is updated to the new values.
+ * The current values in the event are added to a list of historical values.
+ *
+ * Only applies to {@link ACTION_MOVE} events.
*
- * @param eventTime The time stamp for this data.
- * @param inData The actual data.
+ * @param eventTime The time stamp (in ms) for this data.
+ * @param pointerCoords The new pointer coordinates.
* @param metaState Meta key state.
- *
- * @hide
*/
- public final void addBatch(long eventTime, float[] inData, int metaState) {
- final int numPointers = mNumPointers;
- final int dataSampleStride = numPointers * NUM_SAMPLE_DATA;
+ public final void addBatch(long eventTime, PointerCoords[] pointerCoords, int metaState) {
+ final int dataSampleStride = mNumPointers * NUM_SAMPLE_DATA;
incrementNumSamplesAndReserveStorage(dataSampleStride);
mEventTimeNanoSamples[mLastEventTimeNanoSampleIndex] = eventTime * MS_PER_NS;
-
- float[] dataSamples = mDataSamples;
- System.arraycopy(inData, 0, dataSamples, mLastDataSampleIndex, dataSampleStride);
-
- if (mXOffset != 0 || mYOffset != 0) {
- int index = mLastEventTimeNanoSampleIndex;
- for (int i = 0; i < numPointers; i++) {
- dataSamples[index + SAMPLE_X] -= mXOffset;
- dataSamples[index + SAMPLE_Y] -= mYOffset;
- index += NUM_SAMPLE_DATA;
- }
- }
+ setPointerCoordsAtSampleIndex(mLastDataSampleIndex, pointerCoords);
mMetaState |= metaState;
-
- if (DEBUG_POINTERS) {
- StringBuilder sb = new StringBuilder(128);
- sb.append("Add:");
- for (int i = 0; i < mNumPointers; i++) {
- sb.append(" #");
- sb.append(getPointerId(i));
- sb.append("(");
- sb.append(getX(i));
- sb.append(",");
- sb.append(getY(i));
- sb.append(")");
- }
- Log.v("MotionEvent", sb.toString());
- }
}
@Override
@@ -1165,6 +1468,7 @@ public final class MotionEvent implements Parcelable {
ev.mXPrecision = in.readFloat();
ev.mYPrecision = in.readFloat();
ev.mDeviceId = in.readInt();
+ ev.mSource = in.readInt();
ev.mEdgeFlags = in.readInt();
ev.mMetaState = in.readInt();
@@ -1212,6 +1516,7 @@ public final class MotionEvent implements Parcelable {
out.writeFloat(mXPrecision);
out.writeFloat(mYPrecision);
out.writeInt(mDeviceId);
+ out.writeInt(mSource);
out.writeInt(mEdgeFlags);
out.writeInt(mMetaState);
@@ -1230,4 +1535,108 @@ public final class MotionEvent implements Parcelable {
out.writeFloat(dataSamples[i]);
}
}
+
+ /**
+ * Transfer object for pointer coordinates.
+ *
+ * Objects of this type can be used to manufacture new {@link MotionEvent} objects
+ * and to query pointer coordinate information in bulk.
+ *
+ * Refer to {@link InputDevice} for information about how different kinds of
+ * input devices and sources represent pointer coordinates.
+ */
+ public static final class PointerCoords {
+ /**
+ * The X coordinate of the pointer movement.
+ * The interpretation varies by input source and may represent the position of
+ * the center of the contact area, a relative displacement in device-specific units
+ * or something else.
+ */
+ public float x;
+
+ /**
+ * The Y coordinate of the pointer movement.
+ * The interpretation varies by input source and may represent the position of
+ * the center of the contact area, a relative displacement in device-specific units
+ * or something else.
+ */
+ public float y;
+
+ /**
+ * A scaled value that describes the pressure applied to the pointer.
+ * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
+ * however values higher than 1 may be generated depending on the calibration of
+ * the input device.
+ */
+ public float pressure;
+
+ /**
+ * A scaled value of the approximate size of the pointer touch area.
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
+ * touch is normalized with the device specific range of values
+ * and scaled to a value between 0 and 1. The value of size can be used to
+ * determine fat touch events.
+ */
+ public float size;
+
+ /**
+ * The length of the major axis of an ellipse that describes the touch area at
+ * the point of contact.
+ */
+ public float touchMajor;
+
+ /**
+ * The length of the minor axis of an ellipse that describes the touch area at
+ * the point of contact.
+ */
+ public float touchMinor;
+
+ /**
+ * The length of the major axis of an ellipse that describes the size of
+ * the approaching tool.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact.
+ */
+ public float toolMajor;
+
+ /**
+ * The length of the minor axis of an ellipse that describes the size of
+ * the approaching tool.
+ * The tool area represents the estimated size of the finger or pen that is
+ * touching the device independent of its actual touch area at the point of contact.
+ */
+ public float toolMinor;
+
+ /**
+ * The orientation of the touch area and tool area in radians clockwise from vertical.
+ * An angle of 0 degrees indicates that the major axis of contact is oriented
+ * upwards, is perfectly circular or is of unknown orientation. A positive angle
+ * indicates that the major axis of contact is oriented to the right. A negative angle
+ * indicates that the major axis of contact is oriented to the left.
+ * The full range is from -PI/4 radians (finger pointing fully left) to PI/4 radians
+ * (finger pointing fully right).
+ */
+ public float orientation;
+
+ /*
+ private static final float PI_8 = (float) (Math.PI / 8);
+
+ public float getTouchWidth() {
+ return Math.abs(orientation) > PI_8 ? touchMajor : touchMinor;
+ }
+
+ public float getTouchHeight() {
+ return Math.abs(orientation) > PI_8 ? touchMinor : touchMajor;
+ }
+
+ public float getToolWidth() {
+ return Math.abs(orientation) > PI_8 ? toolMajor : toolMinor;
+ }
+
+ public float getToolHeight() {
+ return Math.abs(orientation) > PI_8 ? toolMinor : toolMajor;
+ }
+ */
+ }
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 260bf7bc..7ce04cf 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -516,7 +516,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
mPendingContentInsets.set(mAttachInfo.mContentInsets);
mPendingVisibleInsets.set(0, 0, 0, 0);
- if (Config.LOGV) Log.v("ViewRoot", "Added window " + mWindow);
+ if (Config.LOGV) Log.v(TAG, "Added window " + mWindow);
if (res < WindowManagerImpl.ADD_OKAY) {
mView = null;
mAttachInfo.mRootView = null;
@@ -769,7 +769,7 @@ public final class ViewRoot extends Handler implements ViewParent,
desiredWindowWidth = frame.width();
desiredWindowHeight = frame.height();
if (desiredWindowWidth != mWidth || desiredWindowHeight != mHeight) {
- if (DEBUG_ORIENTATION) Log.v("ViewRoot",
+ if (DEBUG_ORIENTATION) Log.v(TAG,
"View " + host + " resized to: " + frame);
fullRedrawNeeded = true;
mLayoutRequested = true;
@@ -833,7 +833,7 @@ public final class ViewRoot extends Handler implements ViewParent,
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
// Ask host how big it wants to be
- if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v("ViewRoot",
+ if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(TAG,
"Measuring " + host + " in display " + desiredWindowWidth
+ "x" + desiredWindowHeight + "...");
host.measure(childWidthMeasureSpec, childHeightMeasureSpec);
@@ -1010,7 +1010,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
if (DEBUG_ORIENTATION) Log.v(
- "ViewRoot", "Relayout returned: frame=" + frame + ", surface=" + mSurface);
+ TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
attachInfo.mWindowLeft = frame.left;
attachInfo.mWindowTop = frame.top;
@@ -1131,7 +1131,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mLayoutRequested = false;
mScrollMayChange = true;
if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(
- "ViewRoot", "Laying out " + host + " to (" +
+ TAG, "Laying out " + host + " to (" +
host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")");
long startTime = 0L;
if (Config.DEBUG && ViewDebug.profileLayout) {
@@ -1260,7 +1260,7 @@ public final class ViewRoot extends Handler implements ViewParent,
if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0
|| mReportNextDraw) {
if (LOCAL_LOGV) {
- Log.v("ViewRoot", "FINISHED DRAWING: " + mWindowAttributes.getTitle());
+ Log.v(TAG, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
}
mReportNextDraw = false;
if (mSurfaceHolder != null && mSurface.isValid()) {
@@ -1437,7 +1437,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
- Log.v("ViewRoot", "Draw " + mView + "/"
+ Log.v(TAG, "Draw " + mView + "/"
+ mWindowAttributes.getTitle()
+ ": dirty={" + dirty.left + "," + dirty.top
+ "," + dirty.right + "," + dirty.bottom + "} surface="
@@ -1462,12 +1462,12 @@ public final class ViewRoot extends Handler implements ViewParent,
// TODO: Do this in native
canvas.setDensity(mDensity);
} catch (Surface.OutOfResourcesException e) {
- Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
+ Log.e(TAG, "OutOfResourcesException locking surface", e);
// TODO: we should ask the window manager to do something!
// for now we just do nothing
return;
} catch (IllegalArgumentException e) {
- Log.e("ViewRoot", "IllegalArgumentException locking surface", e);
+ Log.e(TAG, "IllegalArgumentException locking surface", e);
// TODO: we should ask the window manager to do something!
// for now we just do nothing
return;
@@ -1478,7 +1478,7 @@ public final class ViewRoot extends Handler implements ViewParent,
long startTime = 0L;
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
- Log.v("ViewRoot", "Surface " + surface + " drawing to bitmap w="
+ Log.v(TAG, "Surface " + surface + " drawing to bitmap w="
+ canvas.getWidth() + ", h=" + canvas.getHeight());
//canvas.drawARGB(255, 255, 0, 0);
}
@@ -1547,7 +1547,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
if (LOCAL_LOGV) {
- Log.v("ViewRoot", "Surface " + surface + " unlockCanvasAndPost");
+ Log.v(TAG, "Surface " + surface + " unlockCanvasAndPost");
}
if (scrolling) {
@@ -1739,7 +1739,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
void dispatchDetachedFromWindow() {
- if (Config.LOGV) Log.v("ViewRoot", "Detaching in " + this + " of " + mSurface);
+ if (Config.LOGV) Log.v(TAG, "Detaching in " + this + " of " + mSurface);
if (mView != null) {
mView.dispatchDetachedFromWindow();
@@ -1867,7 +1867,7 @@ public final class ViewRoot extends Handler implements ViewParent,
break;
case DISPATCH_KEY:
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "Dispatching key "
+ TAG, "Dispatching key "
+ msg.obj + " to " + mView);
deliverKeyEvent((KeyEvent)msg.obj, true);
break;
@@ -1989,7 +1989,7 @@ public final class ViewRoot extends Handler implements ViewParent,
break;
case DISPATCH_KEY_FROM_IME: {
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "Dispatching key "
+ TAG, "Dispatching key "
+ msg.obj + " from IME to " + mView);
KeyEvent event = (KeyEvent)msg.obj;
if ((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM) != 0) {
@@ -2484,7 +2484,7 @@ public final class ViewRoot extends Handler implements ViewParent,
if (handled) {
if (sendDone) {
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "Telling window manager key is finished");
+ TAG, "Telling window manager key is finished");
finishKeyEvent(event);
}
return;
@@ -2517,10 +2517,10 @@ public final class ViewRoot extends Handler implements ViewParent,
return;
} else if (sendDone) {
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "Telling window manager key is finished");
+ TAG, "Telling window manager key is finished");
finishKeyEvent(event);
} else {
- Log.w("ViewRoot", "handleFinishedEvent(seq=" + seq
+ Log.w(TAG, "handleFinishedEvent(seq=" + seq
+ " handled=" + handled + " ev=" + event
+ ") neither delivering nor finishing key");
}
@@ -2592,7 +2592,7 @@ public final class ViewRoot extends Handler implements ViewParent,
} finally {
if (sendDone) {
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "Telling window manager key is finished");
+ TAG, "Telling window manager key is finished");
finishKeyEvent(event);
}
// Let the exception fall through -- the looper will catch
@@ -2715,7 +2715,7 @@ public final class ViewRoot extends Handler implements ViewParent,
void doDie() {
checkThread();
- if (Config.LOGV) Log.v("ViewRoot", "DIE in " + this + " of " + mSurface);
+ if (Config.LOGV) Log.v(TAG, "DIE in " + this + " of " + mSurface);
synchronized (this) {
if (mAdded && !mFirst) {
int viewVisibility = mView.getVisibility();
@@ -2781,16 +2781,10 @@ public final class ViewRoot extends Handler implements ViewParent,
dispatchKey(event);
}
- public void handleTouch(MotionEvent event, Runnable finishedCallback) {
+ public void handleMotion(MotionEvent event, Runnable finishedCallback) {
finishedCallback.run();
- dispatchPointer(event);
- }
-
- public void handleTrackball(MotionEvent event, Runnable finishedCallback) {
- finishedCallback.run();
-
- dispatchTrackball(event);
+ dispatchMotion(event);
}
};
@@ -2812,10 +2806,22 @@ public final class ViewRoot extends Handler implements ViewParent,
msg.obj = event;
if (LOCAL_LOGV) Log.v(
- "ViewRoot", "sending key " + event + " to " + mView);
+ TAG, "sending key " + event + " to " + mView);
sendMessageAtTime(msg, event.getEventTime());
}
+
+ public void dispatchMotion(MotionEvent event) {
+ int source = event.getSource();
+ if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ dispatchPointer(event);
+ } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
+ dispatchTrackball(event);
+ } else {
+ // TODO
+ Log.v(TAG, "Dropping unsupported motion event (unimplemented): " + event);
+ }
+ }
public void dispatchPointer(MotionEvent event) {
Message msg = obtainMessage(DISPATCH_POINTER);