diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/service/wallpaper/WallpaperService.java | 8 | ||||
-rw-r--r-- | core/java/android/view/InputChannel.java | 8 | ||||
-rwxr-xr-x | core/java/android/view/InputDevice.java | 231 | ||||
-rwxr-xr-x | core/java/android/view/InputEvent.java | 63 | ||||
-rw-r--r-- | core/java/android/view/InputHandler.java | 14 | ||||
-rw-r--r-- | core/java/android/view/InputQueue.java | 41 | ||||
-rw-r--r-- | core/java/android/view/KeyCharacterMap.java | 8 | ||||
-rwxr-xr-x | core/java/android/view/KeyEvent.java | 77 | ||||
-rw-r--r-- | core/java/android/view/MotionEvent.java | 597 | ||||
-rw-r--r-- | core/java/android/view/ViewRoot.java | 62 | ||||
-rw-r--r-- | core/java/com/android/internal/view/BaseInputHandler.java | 6 |
11 files changed, 920 insertions, 195 deletions
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index e26a090..57a72bf 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -41,6 +41,7 @@ import android.util.LogPrinter; import android.view.Gravity; import android.view.IWindowSession; import android.view.InputChannel; +import android.view.InputDevice; import android.view.InputHandler; import android.view.InputQueue; import android.view.KeyEvent; @@ -214,9 +215,12 @@ public abstract class WallpaperService extends Service { final InputHandler mInputHandler = new BaseInputHandler() { @Override - public void handleTouch(MotionEvent event, Runnable finishedCallback) { + public void handleMotion(MotionEvent event, Runnable finishedCallback) { try { - dispatchPointer(event); + int source = event.getSource(); + if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) { + dispatchPointer(event); + } } finally { finishedCallback.run(); } 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); diff --git a/core/java/com/android/internal/view/BaseInputHandler.java b/core/java/com/android/internal/view/BaseInputHandler.java index 6fe5063..e943a7d 100644 --- a/core/java/com/android/internal/view/BaseInputHandler.java +++ b/core/java/com/android/internal/view/BaseInputHandler.java @@ -29,11 +29,7 @@ public abstract class BaseInputHandler implements InputHandler { finishedCallback.run(); } - public void handleTouch(MotionEvent event, Runnable finishedCallback) { - finishedCallback.run(); - } - - public void handleTrackball(MotionEvent event, Runnable finishedCallback) { + public void handleMotion(MotionEvent event, Runnable finishedCallback) { finishedCallback.run(); } } |