diff options
36 files changed, 2434 insertions, 612 deletions
@@ -167794,6 +167794,38 @@ </parameter> </constructor> </class> +<class name="InputEvent" + extends="java.lang.Object" + abstract="true" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.os.Parcelable"> +</implements> +<method name="getDeviceId" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<field name="mDeviceId" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +</field> +</class> <class name="KeyCharacterMap" extends="java.lang.Object" abstract="false" @@ -168130,7 +168162,7 @@ </field> </class> <class name="KeyEvent" - extends="java.lang.Object" + extends="android.view.InputEvent" abstract="false" static="false" final="false" @@ -168423,17 +168455,6 @@ <parameter name="c" type="int"> </parameter> </method> -<method name="getDeviceId" - return="int" - abstract="false" - native="false" - synchronized="false" - static="false" - final="true" - deprecated="not deprecated" - visibility="public" -> -</method> <method name="getDisplayLabel" return="char" abstract="false" @@ -171308,7 +171329,7 @@ </method> </interface> <class name="MotionEvent" - extends="java.lang.Object" + extends="android.view.InputEvent" abstract="false" static="false" final="true" @@ -171397,17 +171418,6 @@ visibility="public" > </method> -<method name="getDeviceId" - return="int" - abstract="false" - native="false" - synchronized="false" - static="false" - final="true" - deprecated="not deprecated" - visibility="public" -> -</method> <method name="getDownTime" return="long" abstract="false" diff --git a/api/current.xml b/api/current.xml index 1ced890..94acae4 100644 --- a/api/current.xml +++ b/api/current.xml @@ -173022,6 +173022,285 @@ </parameter> </constructor> </class> +<class name="InputDevice" + extends="java.lang.Object" + abstract="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<constructor name="InputDevice" + type="android.view.InputDevice" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<method name="getKeyCharacterMap" + return="android.view.KeyCharacterMap" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getName" + return="java.lang.String" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getSources" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<field name="SOURCE_CLASS_BUTTON" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_CLASS_JOYSTICK" + type="int" + transient="false" + volatile="false" + value="16" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_CLASS_MASK" + type="int" + transient="false" + volatile="false" + value="255" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_CLASS_POINTER" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_CLASS_POSITION" + type="int" + transient="false" + volatile="false" + value="8" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_CLASS_TRACKBALL" + type="int" + transient="false" + volatile="false" + value="4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_DPAD" + type="int" + transient="false" + volatile="false" + value="513" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_GAMEPAD" + type="int" + transient="false" + volatile="false" + value="1025" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_JOYSTICK_LEFT" + type="int" + transient="false" + volatile="false" + value="16777232" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_JOYSTICK_RIGHT" + type="int" + transient="false" + volatile="false" + value="33554448" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_KEYBOARD" + type="int" + transient="false" + volatile="false" + value="257" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_MOUSE" + type="int" + transient="false" + volatile="false" + value="8194" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_TOUCHPAD" + type="int" + transient="false" + volatile="false" + value="1048584" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_TOUCHSCREEN" + type="int" + transient="false" + volatile="false" + value="4098" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_TRACKBALL" + type="int" + transient="false" + volatile="false" + value="65540" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SOURCE_UNKNOWN" + type="int" + transient="false" + volatile="false" + value="0" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +</class> +<class name="InputEvent" + extends="java.lang.Object" + abstract="true" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<implements name="android.os.Parcelable"> +</implements> +<method name="getDeviceId" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getSource" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<field name="mDeviceId" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +</field> +<field name="mSource" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="protected" +> +</field> +</class> <class name="InputQueue" extends="java.lang.Object" abstract="false" @@ -173401,7 +173680,7 @@ </field> </class> <class name="KeyEvent" - extends="java.lang.Object" + extends="android.view.InputEvent" abstract="false" static="false" final="false" @@ -173479,10 +173758,36 @@ </parameter> <parameter name="metaState" type="int"> </parameter> -<parameter name="device" type="int"> +<parameter name="deviceId" type="int"> +</parameter> +<parameter name="scancode" type="int"> +</parameter> +</constructor> +<constructor name="KeyEvent" + type="android.view.KeyEvent" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="downTime" type="long"> +</parameter> +<parameter name="eventTime" type="long"> +</parameter> +<parameter name="action" type="int"> +</parameter> +<parameter name="code" type="int"> +</parameter> +<parameter name="repeat" type="int"> +</parameter> +<parameter name="metaState" type="int"> +</parameter> +<parameter name="deviceId" type="int"> </parameter> <parameter name="scancode" type="int"> </parameter> +<parameter name="flags" type="int"> +</parameter> </constructor> <constructor name="KeyEvent" type="android.view.KeyEvent" @@ -173503,12 +173808,14 @@ </parameter> <parameter name="metaState" type="int"> </parameter> -<parameter name="device" type="int"> +<parameter name="deviceId" type="int"> </parameter> <parameter name="scancode" type="int"> </parameter> <parameter name="flags" type="int"> </parameter> +<parameter name="source" type="int"> +</parameter> </constructor> <constructor name="KeyEvent" type="android.view.KeyEvent" @@ -173521,7 +173828,7 @@ </parameter> <parameter name="characters" type="java.lang.String"> </parameter> -<parameter name="device" type="int"> +<parameter name="deviceId" type="int"> </parameter> <parameter name="flags" type="int"> </parameter> @@ -173694,17 +174001,6 @@ <parameter name="c" type="int"> </parameter> </method> -<method name="getDeviceId" - return="int" - abstract="false" - native="false" - synchronized="false" - static="false" - final="true" - deprecated="not deprecated" - visibility="public" -> -</method> <method name="getDisplayLabel" return="char" abstract="false" @@ -176788,7 +177084,7 @@ </method> </interface> <class name="MotionEvent" - extends="java.lang.Object" + extends="android.view.InputEvent" abstract="false" static="false" final="true" @@ -176820,6 +177116,23 @@ <parameter name="metaState" type="int"> </parameter> </method> +<method name="addBatch" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="eventTime" type="long"> +</parameter> +<parameter name="pointerCoords" type="android.view.MotionEvent.PointerCoords[]"> +</parameter> +<parameter name="metaState" type="int"> +</parameter> +</method> <method name="describeContents" return="int" abstract="false" @@ -176877,7 +177190,18 @@ visibility="public" > </method> -<method name="getDeviceId" +<method name="getDownTime" + return="long" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getEdgeFlags" return="int" abstract="false" native="false" @@ -176888,7 +177212,7 @@ visibility="public" > </method> -<method name="getDownTime" +<method name="getEventTime" return="long" abstract="false" native="false" @@ -176899,8 +177223,8 @@ visibility="public" > </method> -<method name="getEdgeFlags" - return="int" +<method name="getHistoricalEventTime" + return="long" abstract="false" native="false" synchronized="false" @@ -176909,9 +177233,11 @@ deprecated="not deprecated" visibility="public" > +<parameter name="pos" type="int"> +</parameter> </method> -<method name="getEventTime" - return="long" +<method name="getHistoricalOrientation" + return="float" abstract="false" native="false" synchronized="false" @@ -176920,9 +177246,26 @@ deprecated="not deprecated" visibility="public" > +<parameter name="pos" type="int"> +</parameter> </method> -<method name="getHistoricalEventTime" - return="long" +<method name="getHistoricalOrientation" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalPointerCoords" + return="void" abstract="false" native="false" synchronized="false" @@ -176931,8 +177274,12 @@ deprecated="not deprecated" visibility="public" > +<parameter name="pointerIndex" type="int"> +</parameter> <parameter name="pos" type="int"> </parameter> +<parameter name="outPointerCoords" type="android.view.MotionEvent.PointerCoords"> +</parameter> </method> <method name="getHistoricalPressure" return="float" @@ -176990,6 +177337,118 @@ <parameter name="pos" type="int"> </parameter> </method> +<method name="getHistoricalToolMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalToolMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalToolMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalToolMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalTouchMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalTouchMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalTouchMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pos" type="int"> +</parameter> +</method> +<method name="getHistoricalTouchMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="pos" type="int"> +</parameter> +</method> <method name="getHistoricalX" return="float" abstract="false" @@ -177068,6 +177527,45 @@ visibility="public" > </method> +<method name="getOrientation" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getOrientation" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +</method> +<method name="getPointerCoords" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +<parameter name="outPointerCoords" type="android.view.MotionEvent.PointerCoords"> +</parameter> +</method> <method name="getPointerCount" return="int" abstract="false" @@ -177162,6 +177660,102 @@ <parameter name="pointerIndex" type="int"> </parameter> </method> +<method name="getToolMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getToolMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +</method> +<method name="getToolMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getToolMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +</method> +<method name="getTouchMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getTouchMajor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +</method> +<method name="getTouchMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="getTouchMinor" + return="float" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +<parameter name="pointerIndex" type="int"> +</parameter> +</method> <method name="getX" return="float" abstract="false" @@ -177248,6 +177842,41 @@ </parameter> <parameter name="action" type="int"> </parameter> +<parameter name="pointers" type="int"> +</parameter> +<parameter name="pointerIds" type="int[]"> +</parameter> +<parameter name="pointerCoords" type="android.view.MotionEvent.PointerCoords[]"> +</parameter> +<parameter name="metaState" type="int"> +</parameter> +<parameter name="xPrecision" type="float"> +</parameter> +<parameter name="yPrecision" type="float"> +</parameter> +<parameter name="deviceId" type="int"> +</parameter> +<parameter name="edgeFlags" type="int"> +</parameter> +<parameter name="source" type="int"> +</parameter> +</method> +<method name="obtain" + return="android.view.MotionEvent" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="downTime" type="long"> +</parameter> +<parameter name="eventTime" type="long"> +</parameter> +<parameter name="action" type="int"> +</parameter> <parameter name="x" type="float"> </parameter> <parameter name="y" type="float"> @@ -177688,6 +178317,113 @@ > </field> </class> +<class name="MotionEvent.PointerCoords" + extends="java.lang.Object" + abstract="false" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +<constructor name="MotionEvent.PointerCoords" + type="android.view.MotionEvent.PointerCoords" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</constructor> +<field name="orientation" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="pressure" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="size" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="toolMajor" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="toolMinor" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="touchMajor" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="touchMinor" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="x" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="y" + type="float" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> +</class> <class name="OrientationEventListener" extends="java.lang.Object" abstract="true" 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(); } } diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index 9f042c2..c17b504 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -196,7 +196,7 @@ int32_t AInputQueue::getEvent(AInputEvent** outEvent) { void AInputQueue::finishEvent(AInputEvent* event, bool handled) { bool needFinished = true; - if (!handled && ((InputEvent*)event)->getType() == INPUT_EVENT_TYPE_KEY + if (!handled && ((InputEvent*)event)->getType() == AINPUT_EVENT_TYPE_KEY && ((KeyEvent*)event)->hasDefaultAction()) { // The app didn't handle this, but it may have a default action // associated with it. We need to hand this back to Java to be @@ -767,7 +767,7 @@ dispatchKeyEvent_native(JNIEnv* env, jobject clazz, jint handle, jobject eventOb NativeCode* code = (NativeCode*)handle; if (code->nativeInputQueue != NULL) { KeyEvent* event = new KeyEvent(); - android_view_KeyEvent_toNative(env, eventObj, INPUT_EVENT_NATURE_KEY, event); + android_view_KeyEvent_toNative(env, eventObj, event); code->nativeInputQueue->dispatchEvent(event); } } diff --git a/core/jni/android_view_InputQueue.cpp b/core/jni/android_view_InputQueue.cpp index 6fb3cf7..226c797 100644 --- a/core/jni/android_view_InputQueue.cpp +++ b/core/jni/android_view_InputQueue.cpp @@ -326,12 +326,11 @@ bool NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* da // the input handler object itself for the same reason. int32_t inputEventType = inputEvent->getType(); - int32_t inputEventNature = inputEvent->getNature(); jobject inputEventObj; jmethodID dispatchMethodId; switch (inputEventType) { - case INPUT_EVENT_TYPE_KEY: + case AINPUT_EVENT_TYPE_KEY: #if DEBUG_DISPATCH_CYCLE LOGD("channel '%s' ~ Received key event.", connection->getInputChannelName()); #endif @@ -340,7 +339,7 @@ bool NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* da dispatchMethodId = gInputQueueClassInfo.dispatchKeyEvent; break; - case INPUT_EVENT_TYPE_MOTION: + case AINPUT_EVENT_TYPE_MOTION: #if DEBUG_DISPATCH_CYCLE LOGD("channel '%s' ~ Received motion event.", connection->getInputChannelName()); #endif @@ -367,7 +366,7 @@ bool NativeInputQueue::handleReceiveCallback(int receiveFd, int events, void* da #endif env->CallStaticVoidMethod(gInputQueueClassInfo.clazz, dispatchMethodId, inputHandlerObjLocal, inputEventObj, - jint(inputEventNature), jlong(finishedToken)); + jlong(finishedToken)); #if DEBUG_DISPATCH_CYCLE LOGD("Returned from input handler."); #endif @@ -471,11 +470,11 @@ int register_android_view_InputQueue(JNIEnv* env) { GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchKeyEvent, gInputQueueClassInfo.clazz, "dispatchKeyEvent", - "(Landroid/view/InputHandler;Landroid/view/KeyEvent;IJ)V"); + "(Landroid/view/InputHandler;Landroid/view/KeyEvent;J)V"); GET_STATIC_METHOD_ID(gInputQueueClassInfo.dispatchMotionEvent, gInputQueueClassInfo.clazz, "dispatchMotionEvent", - "(Landroid/view/InputHandler;Landroid/view/MotionEvent;IJ)V"); + "(Landroid/view/InputHandler;Landroid/view/MotionEvent;J)V"); return 0; } diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp index 8f648f4..7e7583c 100644 --- a/core/jni/android_view_KeyEvent.cpp +++ b/core/jni/android_view_KeyEvent.cpp @@ -32,12 +32,13 @@ static struct { jmethodID ctor; + jfieldID mDeviceId; + jfieldID mSource; jfieldID mMetaState; jfieldID mAction; jfieldID mKeyCode; jfieldID mScanCode; jfieldID mRepeatCount; - jfieldID mDeviceId; jfieldID mFlags; jfieldID mDownTime; jfieldID mEventTime; @@ -56,22 +57,24 @@ jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { event->getMetaState(), event->getDeviceId(), event->getScanCode(), - event->getFlags()); + event->getFlags(), + event->getSource()); } -void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature, +void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, KeyEvent* event) { + jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); + jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode); jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount); - jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags); jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); - event->initialize(deviceId, nature, action, flags, keyCode, scanCode, metaState, repeatCount, + event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, milliseconds_to_nanoseconds(downTime), milliseconds_to_nanoseconds(eventTime)); } @@ -91,8 +94,6 @@ static const JNINativeMethod g_methods[] = { { "native_hasDefaultAction", "(I)Z", (void*)native_hasDefaultAction }, }; -static const char* const kKeyEventPathName = "android/view/KeyEvent"; - #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); \ @@ -107,11 +108,15 @@ static const char* const kKeyEventPathName = "android/view/KeyEvent"; LOG_FATAL_IF(! var, "Unable to find field " fieldName); int register_android_view_KeyEvent(JNIEnv* env) { - FIND_CLASS(gKeyEventClassInfo.clazz, kKeyEventPathName); + FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent"); GET_METHOD_ID(gKeyEventClassInfo.ctor, gKeyEventClassInfo.clazz, - "<init>", "(JJIIIIIII)V"); + "<init>", "(JJIIIIIIII)V"); + GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz, + "mDeviceId", "I"); + GET_FIELD_ID(gKeyEventClassInfo.mSource, gKeyEventClassInfo.clazz, + "mSource", "I"); GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz, "mMetaState", "I"); GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz, @@ -122,8 +127,6 @@ int register_android_view_KeyEvent(JNIEnv* env) { "mScanCode", "I"); GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz, "mRepeatCount", "I"); - GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz, - "mDeviceId", "I"); GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz, "mFlags", "I"); GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz, @@ -134,8 +137,7 @@ int register_android_view_KeyEvent(JNIEnv* env) { "mCharacters", "Ljava/lang/String;"); return AndroidRuntime::registerNativeMethods( - env, kKeyEventPathName, - g_methods, NELEM(g_methods)); + env, "android/view/KeyEvent", g_methods, NELEM(g_methods)); } } // namespace android diff --git a/core/jni/android_view_KeyEvent.h b/core/jni/android_view_KeyEvent.h index 3c71b1a..0bd410c 100644 --- a/core/jni/android_view_KeyEvent.h +++ b/core/jni/android_view_KeyEvent.h @@ -27,7 +27,7 @@ class KeyEvent; extern jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event); /* Copies the contents of a DVM KeyEvent object to a native KeyEvent instance. */ -extern void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature, +extern void android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, KeyEvent* event); } // namespace android diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 78137e2..fe247e8 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -24,7 +24,7 @@ #include "android_view_MotionEvent.h" // Number of float items per entry in a DVM sample data array -#define NUM_SAMPLE_DATA 4 +#define NUM_SAMPLE_DATA 9 namespace android { @@ -36,13 +36,14 @@ static struct { jmethodID obtain; jmethodID recycle; + jfieldID mDeviceId; + jfieldID mSource; jfieldID mDownTimeNano; jfieldID mAction; jfieldID mXOffset; jfieldID mYOffset; jfieldID mXPrecision; jfieldID mYPrecision; - jfieldID mDeviceId; jfieldID mEdgeFlags; jfieldID mMetaState; jfieldID mNumPointers; @@ -70,6 +71,10 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even return NULL; } + env->SetIntField(eventObj, gMotionEventClassInfo.mDeviceId, + event->getDeviceId()); + env->SetIntField(eventObj, gMotionEventClassInfo.mSource, + event->getSource()); env->SetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano, event->getDownTime()); env->SetIntField(eventObj, gMotionEventClassInfo.mAction, @@ -82,8 +87,6 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even event->getXPrecision()); env->SetFloatField(eventObj, gMotionEventClassInfo.mYPrecision, event->getYPrecision()); - env->SetIntField(eventObj, gMotionEventClassInfo.mDeviceId, - event->getDeviceId()); env->SetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags, event->getEdgeFlags()); env->SetIntField(eventObj, gMotionEventClassInfo.mMetaState, @@ -129,6 +132,11 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even *(destDataSamples++) = srcSamplePointerCoords->y; *(destDataSamples++) = srcSamplePointerCoords->pressure; *(destDataSamples++) = srcSamplePointerCoords->size; + *(destDataSamples++) = srcSamplePointerCoords->touchMajor; + *(destDataSamples++) = srcSamplePointerCoords->touchMinor; + *(destDataSamples++) = srcSamplePointerCoords->toolMajor; + *(destDataSamples++) = srcSamplePointerCoords->toolMinor; + *(destDataSamples++) = srcSamplePointerCoords->orientation; srcSamplePointerCoords += 1; } @@ -142,15 +150,16 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even return eventObj; } -void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature, +void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, MotionEvent* event) { + jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId); + jint source = env->GetIntField(eventObj, gMotionEventClassInfo.mSource); jlong downTimeNano = env->GetLongField(eventObj, gMotionEventClassInfo.mDownTimeNano); jint action = env->GetIntField(eventObj, gMotionEventClassInfo.mAction); jfloat xOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mXOffset); jfloat yOffset = env->GetFloatField(eventObj, gMotionEventClassInfo.mYOffset); jfloat xPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mXPrecision); jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision); - jint deviceId = env->GetIntField(eventObj, gMotionEventClassInfo.mDeviceId); jint edgeFlags = env->GetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags); jint metaState = env->GetIntField(eventObj, gMotionEventClassInfo.mMetaState); jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers); @@ -180,9 +189,14 @@ void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t na samplePointerCoords[j].y = *(srcDataSamples++); samplePointerCoords[j].pressure = *(srcDataSamples++); samplePointerCoords[j].size = *(srcDataSamples++); + samplePointerCoords[j].touchMajor = *(srcDataSamples++); + samplePointerCoords[j].touchMinor = *(srcDataSamples++); + samplePointerCoords[j].toolMajor = *(srcDataSamples++); + samplePointerCoords[j].toolMinor = *(srcDataSamples++); + samplePointerCoords[j].orientation = *(srcDataSamples++); } - event->initialize(deviceId, nature, action, edgeFlags, metaState, + event->initialize(deviceId, source, action, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTimeNano, sampleEventTime, numPointers, pointerIdentifiers, samplePointerCoords); @@ -193,6 +207,11 @@ void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t na samplePointerCoords[j].y = *(srcDataSamples++); samplePointerCoords[j].pressure = *(srcDataSamples++); samplePointerCoords[j].size = *(srcDataSamples++); + samplePointerCoords[j].touchMajor = *(srcDataSamples++); + samplePointerCoords[j].touchMinor = *(srcDataSamples++); + samplePointerCoords[j].toolMajor = *(srcDataSamples++); + samplePointerCoords[j].toolMinor = *(srcDataSamples++); + samplePointerCoords[j].orientation = *(srcDataSamples++); } event->addSample(sampleEventTime, samplePointerCoords); } @@ -242,6 +261,10 @@ int register_android_view_MotionEvent(JNIEnv* env) { GET_METHOD_ID(gMotionEventClassInfo.recycle, gMotionEventClassInfo.clazz, "recycle", "()V"); + GET_FIELD_ID(gMotionEventClassInfo.mDeviceId, gMotionEventClassInfo.clazz, + "mDeviceId", "I"); + GET_FIELD_ID(gMotionEventClassInfo.mSource, gMotionEventClassInfo.clazz, + "mSource", "I"); GET_FIELD_ID(gMotionEventClassInfo.mDownTimeNano, gMotionEventClassInfo.clazz, "mDownTimeNano", "J"); GET_FIELD_ID(gMotionEventClassInfo.mAction, gMotionEventClassInfo.clazz, @@ -254,8 +277,6 @@ int register_android_view_MotionEvent(JNIEnv* env) { "mXPrecision", "F"); GET_FIELD_ID(gMotionEventClassInfo.mYPrecision, gMotionEventClassInfo.clazz, "mYPrecision", "F"); - GET_FIELD_ID(gMotionEventClassInfo.mDeviceId, gMotionEventClassInfo.clazz, - "mDeviceId", "I"); GET_FIELD_ID(gMotionEventClassInfo.mEdgeFlags, gMotionEventClassInfo.clazz, "mEdgeFlags", "I"); GET_FIELD_ID(gMotionEventClassInfo.mMetaState, gMotionEventClassInfo.clazz, diff --git a/core/jni/android_view_MotionEvent.h b/core/jni/android_view_MotionEvent.h index 03ee32f..86e4bde 100644 --- a/core/jni/android_view_MotionEvent.h +++ b/core/jni/android_view_MotionEvent.h @@ -27,7 +27,7 @@ class MotionEvent; extern jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* event); /* Copies the contents of a DVM MotionEvent object to a native MotionEvent instance. */ -extern void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, int32_t nature, +extern void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, MotionEvent* event); /* Recycles a DVM MotionEvent object. */ diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h index d322a34..5be17d3 100644 --- a/include/ui/EventHub.h +++ b/include/ui/EventHub.h @@ -60,6 +60,32 @@ namespace android { class KeyLayoutMap; /* + * Input device classes. + */ +enum { + /* The input device is a keyboard. */ + INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001, + + /* The input device is an alpha-numeric keyboard (not just a dial pad). */ + INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002, + + /* The input device is a touchscreen (either single-touch or multi-touch). */ + INPUT_DEVICE_CLASS_TOUCHSCREEN = 0x00000004, + + /* The input device is a trackball. */ + INPUT_DEVICE_CLASS_TRACKBALL = 0x00000008, + + /* The input device is a multi-touch touchscreen. */ + INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010, + + /* The input device is a directional pad. */ + INPUT_DEVICE_CLASS_DPAD = 0x00000020, + + /* The input device is a gamepad (implies keyboard). */ + INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040 +}; + +/* * Grand Central Station for events. * * The event hub aggregates input events received across all known input diff --git a/include/ui/Input.h b/include/ui/Input.h index a7d23d4..f069888 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -32,7 +32,7 @@ enum { /* * Private control to determine when an app is tracking a key sequence. */ - KEY_EVENT_FLAG_START_TRACKING = 0x40000000 + AKEY_EVENT_FLAG_START_TRACKING = 0x40000000 }; /* @@ -130,6 +130,11 @@ struct PointerCoords { float y; float pressure; float size; + float touchMajor; + float touchMinor; + float toolMajor; + float toolMinor; + float orientation; }; /* @@ -143,14 +148,14 @@ public: inline int32_t getDeviceId() const { return mDeviceId; } - inline int32_t getNature() const { return mNature; } + inline int32_t getSource() const { return mSource; } protected: - void initialize(int32_t deviceId, int32_t nature); + void initialize(int32_t deviceId, int32_t source); private: int32_t mDeviceId; - int32_t mNature; + int32_t mSource; }; /* @@ -160,7 +165,7 @@ class KeyEvent : public InputEvent { public: virtual ~KeyEvent() { } - virtual int32_t getType() const { return INPUT_EVENT_TYPE_KEY; } + virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; } inline int32_t getAction() const { return mAction; } @@ -188,7 +193,7 @@ public: void initialize( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t flags, int32_t keyCode, @@ -216,7 +221,7 @@ class MotionEvent : public InputEvent { public: virtual ~MotionEvent() { } - virtual int32_t getType() const { return INPUT_EVENT_TYPE_MOTION; } + virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; } inline int32_t getAction() const { return mAction; } @@ -264,6 +269,26 @@ public: return getCurrentPointerCoords(pointerIndex).size; } + inline float getTouchMajor(size_t pointerIndex) const { + return getCurrentPointerCoords(pointerIndex).touchMajor; + } + + inline float getTouchMinor(size_t pointerIndex) const { + return getCurrentPointerCoords(pointerIndex).touchMinor; + } + + inline float getToolMajor(size_t pointerIndex) const { + return getCurrentPointerCoords(pointerIndex).toolMajor; + } + + inline float getToolMinor(size_t pointerIndex) const { + return getCurrentPointerCoords(pointerIndex).toolMinor; + } + + inline float getOrientation(size_t pointerIndex) const { + return getCurrentPointerCoords(pointerIndex).orientation; + } + inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; } inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const { @@ -294,9 +319,29 @@ public: return getHistoricalPointerCoords(pointerIndex, historicalIndex).size; } + inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor; + } + + inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor; + } + + inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor; + } + + inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor; + } + + inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const { + return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation; + } + void initialize( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t edgeFlags, int32_t metaState, diff --git a/include/ui/InputDevice.h b/include/ui/InputDevice.h index 4420600..3b9c70e 100644 --- a/include/ui/InputDevice.h +++ b/include/ui/InputDevice.h @@ -42,6 +42,7 @@ namespace android { extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); extern int32_t rotateKeyCode(int32_t keyCode, int32_t orientation); + /* * An input device structure tracks the state of a single input device. * @@ -168,8 +169,11 @@ struct InputDevice { FIELD_ABS_MT_POSITION_X = 1, FIELD_ABS_MT_POSITION_Y = 2, FIELD_ABS_MT_TOUCH_MAJOR = 4, - FIELD_ABS_MT_WIDTH_MAJOR = 8, - FIELD_ABS_MT_TRACKING_ID = 16 + FIELD_ABS_MT_TOUCH_MINOR = 8, + FIELD_ABS_MT_WIDTH_MAJOR = 16, + FIELD_ABS_MT_WIDTH_MINOR = 32, + FIELD_ABS_MT_ORIENTATION = 64, + FIELD_ABS_MT_TRACKING_ID = 128 }; uint32_t pointerCount; @@ -179,7 +183,10 @@ struct InputDevice { int32_t absMTPositionX; int32_t absMTPositionY; int32_t absMTTouchMajor; + int32_t absMTTouchMinor; int32_t absMTWidthMajor; + int32_t absMTWidthMinor; + int32_t absMTOrientation; int32_t absMTTrackingId; inline void clear() { @@ -206,6 +213,11 @@ struct InputDevice { int32_t y; int32_t pressure; int32_t size; + int32_t touchMajor; + int32_t touchMinor; + int32_t toolMajor; + int32_t toolMinor; + int32_t orientation; }; struct TouchData { @@ -236,6 +248,7 @@ struct InputDevice { AbsoluteAxisInfo yAxis; AbsoluteAxisInfo pressureAxis; AbsoluteAxisInfo sizeAxis; + AbsoluteAxisInfo orientationAxis; } parameters; // The touch data of the current sample being processed. @@ -290,6 +303,8 @@ struct InputDevice { int32_t sizeOrigin; float sizeScale; + + float orientationScale; } precalculated; void reset(); diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h index eb8f820..674852a 100644 --- a/include/ui/InputDispatcher.h +++ b/include/ui/InputDispatcher.h @@ -167,10 +167,10 @@ public: */ virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0; virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0; - virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature, + virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0; - virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature, + virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime) = 0; @@ -232,10 +232,10 @@ public: virtual void notifyConfigurationChanged(nsecs_t eventTime); virtual void notifyAppSwitchComing(nsecs_t eventTime); - virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature, + virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime); - virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature, + virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime); @@ -281,7 +281,7 @@ private: struct KeyEntry : EventEntry { int32_t deviceId; - int32_t nature; + int32_t source; uint32_t policyFlags; int32_t action; int32_t flags; @@ -301,7 +301,7 @@ private: struct MotionEntry : EventEntry { int32_t deviceId; - int32_t nature; + int32_t source; uint32_t policyFlags; int32_t action; int32_t metaState; @@ -424,11 +424,11 @@ private: ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime); KeyEntry* obtainKeyEntry(nsecs_t eventTime, - int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action, + int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime); MotionEntry* obtainMotionEntry(nsecs_t eventTime, - int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action, + int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords); diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h index 226d1d5..31ec701 100644 --- a/include/ui/InputTransport.h +++ b/include/ui/InputTransport.h @@ -119,7 +119,7 @@ struct InputMessage { }; int32_t deviceId; - int32_t nature; + int32_t source; union { struct { @@ -198,7 +198,7 @@ public: */ status_t publishKeyEvent( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t flags, int32_t keyCode, @@ -216,7 +216,7 @@ public: */ status_t publishMotionEvent( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t edgeFlags, int32_t metaState, @@ -233,7 +233,7 @@ public: /* Appends a motion sample to a motion event unless already consumed. * * Returns OK on success. - * Returns INVALID_OPERATION if the current event is not a MOTION_EVENT_ACTION_MOVE event. + * Returns INVALID_OPERATION if the current event is not a AMOTION_EVENT_ACTION_MOVE event. * Returns FAILED_TRANSACTION if the current event has already been consumed. * Returns NO_MEMORY if the buffer is full and no additional samples can be added. */ @@ -272,7 +272,7 @@ private: status_t publishInputEvent( int32_t type, int32_t deviceId, - int32_t nature); + int32_t source); }; /* diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index 768b04e..33dd373 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -168,12 +168,12 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t deviceClasses, device_t* device = mDevicesById[i].device; if (device != NULL && (device->classes & deviceClasses) != 0) { int32_t result = getScanCodeStateLocked(device, scanCode); - if (result >= KEY_STATE_DOWN) { + if (result >= AKEY_STATE_DOWN) { return result; } } } - return KEY_STATE_UP; + return AKEY_STATE_UP; } else { device_t* device = getDevice(deviceId); if (device != NULL) { @@ -181,7 +181,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t deviceClasses, } } } - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const { @@ -189,9 +189,9 @@ int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) con memset(key_bitmask, 0, sizeof(key_bitmask)); if (ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) { - return test_bit(scanCode, key_bitmask) ? KEY_STATE_DOWN : KEY_STATE_UP; + return test_bit(scanCode, key_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP; } - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t deviceClasses, @@ -202,19 +202,19 @@ int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t deviceClasses, device_t* device = mDevicesById[i].device; if (device != NULL && (device->classes & deviceClasses) != 0) { int32_t result = getKeyCodeStateLocked(device, keyCode); - if (result >= KEY_STATE_DOWN) { + if (result >= AKEY_STATE_DOWN) { return result; } } } - return KEY_STATE_UP; + return AKEY_STATE_UP; } else { device_t* device = getDevice(deviceId); if (device != NULL) { return getKeyCodeStateLocked(device, keyCode); } } - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const { @@ -235,12 +235,12 @@ int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const int32_t sc = scanCodes.itemAt(i); //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask)); if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) { - return KEY_STATE_DOWN; + return AKEY_STATE_DOWN; } } - return KEY_STATE_UP; + return AKEY_STATE_UP; } - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } int32_t EventHub::getSwitchState(int32_t deviceId, int32_t deviceClasses, int32_t sw) const { @@ -251,19 +251,19 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t deviceClasses, int32_ if (deviceId == -1) { deviceId = mSwitches[sw]; if (deviceId == 0) { - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } } device_t* device = getDevice(deviceId); if (device == NULL) { - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } return getSwitchStateLocked(device, sw); } #endif - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const { @@ -271,9 +271,9 @@ int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const { memset(sw_bitmask, 0, sizeof(sw_bitmask)); if (ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) { - return test_bit(sw, sw_bitmask) ? KEY_STATE_DOWN : KEY_STATE_UP; + return test_bit(sw, sw_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP; } - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode, diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp index 1f19c2c..e5f014f 100644 --- a/libs/ui/Input.cpp +++ b/libs/ui/Input.cpp @@ -13,9 +13,9 @@ namespace android { // class InputEvent -void InputEvent::initialize(int32_t deviceId, int32_t nature) { +void InputEvent::initialize(int32_t deviceId, int32_t source) { mDeviceId = deviceId; - mNature = nature; + mSource = source; } // class KeyEvent @@ -86,7 +86,7 @@ bool KeyEvent::isSystemKey() const { void KeyEvent::initialize( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t flags, int32_t keyCode, @@ -95,7 +95,7 @@ void KeyEvent::initialize( int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime) { - InputEvent::initialize(deviceId, nature); + InputEvent::initialize(deviceId, source); mAction = action; mFlags = flags; mKeyCode = keyCode; @@ -110,7 +110,7 @@ void KeyEvent::initialize( void MotionEvent::initialize( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t edgeFlags, int32_t metaState, @@ -123,7 +123,7 @@ void MotionEvent::initialize( size_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords) { - InputEvent::initialize(deviceId, nature); + InputEvent::initialize(deviceId, source); mAction = action; mEdgeFlags = edgeFlags; mMetaState = metaState; diff --git a/libs/ui/InputDevice.cpp b/libs/ui/InputDevice.cpp index 6014017..b2a4d6c 100644 --- a/libs/ui/InputDevice.cpp +++ b/libs/ui/InputDevice.cpp @@ -108,7 +108,7 @@ void InputDevice::TouchData::copyFrom(const TouchData& other) { // --- InputDevice::KeyboardState --- void InputDevice::KeyboardState::reset() { - current.metaState = META_NONE; + current.metaState = AMETA_NONE; current.downTime = 0; } diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index c4ffce1..a438c69 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -245,14 +245,14 @@ void InputDispatcher::processConfigurationChangedLockedInterruptible( void InputDispatcher::processKeyLockedInterruptible( nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout) { #if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("processKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, " + LOGD("processKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, " "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld", - entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action, + entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState, entry->downTime); #endif - if (entry->action == KEY_EVENT_ACTION_DOWN && ! entry->isInjected()) { + if (entry->action == AKEY_EVENT_ACTION_DOWN && ! entry->isInjected()) { if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) { // We have seen two identical key downs in a row which indicates that the device @@ -287,7 +287,7 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( if (queuedEntry->type == EventEntry::TYPE_KEY) { KeyEntry* queuedKeyEntry = static_cast<KeyEntry*>(queuedEntry); if (queuedKeyEntry->deviceId == entry->deviceId - && entry->action == KEY_EVENT_ACTION_UP) { + && entry->action == AKEY_EVENT_ACTION_UP) { resetKeyRepeatLocked(); return; } @@ -303,7 +303,7 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( entry->repeatCount += 1; } else { KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime, - entry->deviceId, entry->nature, policyFlags, + entry->deviceId, entry->source, policyFlags, entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount + 1, entry->downTime); @@ -314,16 +314,16 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( } if (entry->repeatCount == 1) { - entry->flags |= KEY_EVENT_FLAG_LONG_PRESS; + entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS; } mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout; #if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, " + LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, " "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, " "repeatCount=%d, downTime=%lld", - entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, + entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount, entry->downTime); #endif @@ -334,9 +334,9 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( void InputDispatcher::processMotionLockedInterruptible( nsecs_t currentTime, MotionEntry* entry) { #if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("processMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, " + LOGD("processMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, " "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld", - entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action, + entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action, entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision, entry->downTime); @@ -357,7 +357,7 @@ void InputDispatcher::processMotionLockedInterruptible( // Keep in mind that due to batching, it is possible for the number of samples actually // dispatched to change before the application finally consumed them. - if (entry->action == MOTION_EVENT_ACTION_MOVE) { + if (entry->action == AMOTION_EVENT_ACTION_MOVE) { LOGD(" ... Total movement samples currently batched %d ...", sampleCount); } #endif @@ -375,7 +375,7 @@ void InputDispatcher::identifyInputTargetsAndDispatchKeyLockedInterruptible( mCurrentInputTargetsValid = false; mLock.unlock(); - mReusableKeyEvent.initialize(entry->deviceId, entry->nature, entry->action, entry->flags, + mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount, entry->downTime, entry->eventTime); @@ -404,7 +404,7 @@ void InputDispatcher::identifyInputTargetsAndDispatchMotionLockedInterruptible( mCurrentInputTargetsValid = false; mLock.unlock(); - mReusableMotionEvent.initialize(entry->deviceId, entry->nature, entry->action, + mReusableMotionEvent.initialize(entry->deviceId, entry->source, entry->action, entry->edgeFlags, entry->metaState, 0, 0, entry->xPrecision, entry->yPrecision, entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds, @@ -611,11 +611,11 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, int32_t action = keyEntry->action; int32_t flags = keyEntry->flags; if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) { - flags |= KEY_EVENT_FLAG_CANCELED; + flags |= AKEY_EVENT_FLAG_CANCELED; } // Publish the key event. - status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->nature, + status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source, action, flags, keyEntry->keyCode, keyEntry->scanCode, keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime, keyEntry->eventTime); @@ -635,10 +635,10 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, // Apply target flags. int32_t action = motionEntry->action; if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) { - action = MOTION_EVENT_ACTION_OUTSIDE; + action = AMOTION_EVENT_ACTION_OUTSIDE; } if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) { - action = MOTION_EVENT_ACTION_CANCEL; + action = AMOTION_EVENT_ACTION_CANCEL; } // If headMotionSample is non-NULL, then it points to the first new sample that we @@ -652,7 +652,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, // Publish the motion event and the first motion sample. status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId, - motionEntry->nature, action, motionEntry->edgeFlags, motionEntry->metaState, + motionEntry->source, action, motionEntry->edgeFlags, motionEntry->metaState, dispatchEntry->xOffset, dispatchEntry->yOffset, motionEntry->xPrecision, motionEntry->yPrecision, motionEntry->downTime, firstMotionSample->eventTime, @@ -964,13 +964,13 @@ void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) { } // release lock } -void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature, +void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) { #if DEBUG_INBOUND_EVENT_DETAILS - LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, " + LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, " "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld", - eventTime, deviceId, nature, policyFlags, action, flags, + eventTime, deviceId, source, policyFlags, action, flags, keyCode, scanCode, metaState, downTime); #endif @@ -980,7 +980,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nat int32_t repeatCount = 0; KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime, - deviceId, nature, policyFlags, action, flags, keyCode, scanCode, + deviceId, source, policyFlags, action, flags, keyCode, scanCode, metaState, repeatCount, downTime); wasEmpty = mInboundQueue.isEmpty(); @@ -992,15 +992,15 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nat } } -void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature, +void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime) { #if DEBUG_INBOUND_EVENT_DETAILS - LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, " + LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, " "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, " "downTime=%lld", - eventTime, deviceId, nature, policyFlags, action, metaState, edgeFlags, + eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags, xPrecision, yPrecision, downTime); for (uint32_t i = 0; i < pointerCount; i++) { LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f", @@ -1014,7 +1014,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t AutoMutex _l(mLock); // Attempt batching and streaming of move events. - if (action == MOTION_EVENT_ACTION_MOVE) { + if (action == AMOTION_EVENT_ACTION_MOVE) { // BATCHING CASE // // Try to append a move sample to the tail of the inbound queue for this device. @@ -1033,7 +1033,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t continue; } - if (motionEntry->action != MOTION_EVENT_ACTION_MOVE + if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE || motionEntry->pointerCount != pointerCount || motionEntry->isInjected()) { // Last motion event in the queue for this device is not compatible for @@ -1094,7 +1094,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>( dispatchEntry->eventEntry); - if (syncedMotionEntry->action != MOTION_EVENT_ACTION_MOVE + if (syncedMotionEntry->action != AMOTION_EVENT_ACTION_MOVE || syncedMotionEntry->deviceId != deviceId || syncedMotionEntry->pointerCount != pointerCount || syncedMotionEntry->isInjected()) { @@ -1124,7 +1124,7 @@ NoBatchingOrStreaming:; // Just enqueue a new motion event. MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime, - deviceId, nature, policyFlags, action, metaState, edgeFlags, + deviceId, source, policyFlags, action, metaState, edgeFlags, xPrecision, yPrecision, downTime, pointerCount, pointerIds, pointerCoords); @@ -1224,19 +1224,19 @@ bool InputDispatcher::isFullySynchronizedLocked() { InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked( const InputEvent* event) { switch (event->getType()) { - case INPUT_EVENT_TYPE_KEY: { + case AINPUT_EVENT_TYPE_KEY: { const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event); uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(), - keyEvent->getDeviceId(), keyEvent->getNature(), policyFlags, + keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags, keyEvent->getAction(), keyEvent->getFlags(), keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(), keyEvent->getRepeatCount(), keyEvent->getDownTime()); return keyEntry; } - case INPUT_EVENT_TYPE_MOTION: { + case AINPUT_EVENT_TYPE_MOTION: { const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events @@ -1245,7 +1245,7 @@ InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked( size_t pointerCount = motionEvent->getPointerCount(); MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes, - motionEvent->getDeviceId(), motionEvent->getNature(), policyFlags, + motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags, motionEvent->getAction(), motionEvent->getMetaState(), motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), uint32_t(pointerCount), @@ -1500,14 +1500,14 @@ InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) { } InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime, - int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action, + int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime) { KeyEntry* entry = mKeyEntryPool.alloc(); initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime); entry->deviceId = deviceId; - entry->nature = nature; + entry->source = source; entry->policyFlags = policyFlags; entry->action = action; entry->flags = flags; @@ -1520,7 +1520,7 @@ InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t ev } InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime, - int32_t deviceId, int32_t nature, uint32_t policyFlags, int32_t action, + int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords) { @@ -1529,7 +1529,7 @@ InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsec entry->eventTime = eventTime; entry->deviceId = deviceId; - entry->nature = nature; + entry->source = source; entry->policyFlags = policyFlags; entry->action = action; entry->metaState = metaState; diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 0a21db7..cd4654a 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -29,6 +29,7 @@ #include <unistd.h> #include <errno.h> #include <limits.h> +#include <math.h> /** Amount that trackball needs to move in order to generate a key event. */ #define TRACKBALL_MOVEMENT_THRESHOLD 6 @@ -60,33 +61,33 @@ int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) { int32_t mask; switch (keyCode) { case AKEYCODE_ALT_LEFT: - mask = META_ALT_LEFT_ON; + mask = AMETA_ALT_LEFT_ON; break; case AKEYCODE_ALT_RIGHT: - mask = META_ALT_RIGHT_ON; + mask = AMETA_ALT_RIGHT_ON; break; case AKEYCODE_SHIFT_LEFT: - mask = META_SHIFT_LEFT_ON; + mask = AMETA_SHIFT_LEFT_ON; break; case AKEYCODE_SHIFT_RIGHT: - mask = META_SHIFT_RIGHT_ON; + mask = AMETA_SHIFT_RIGHT_ON; break; case AKEYCODE_SYM: - mask = META_SYM_ON; + mask = AMETA_SYM_ON; break; default: return oldMetaState; } int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask - & ~ (META_ALT_ON | META_SHIFT_ON); + & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON); - if (newMetaState & (META_ALT_LEFT_ON | META_ALT_RIGHT_ON)) { - newMetaState |= META_ALT_ON; + if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { + newMetaState |= AMETA_ALT_ON; } - if (newMetaState & (META_SHIFT_LEFT_ON | META_SHIFT_RIGHT_ON)) { - newMetaState |= META_SHIFT_ON; + if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { + newMetaState |= AMETA_SHIFT_ON; } return newMetaState; @@ -324,11 +325,26 @@ void InputReader::handleAbsoluteMotion(const RawEvent* rawEvent) { InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MAJOR; pointer->absMTTouchMajor = rawEvent->value; break; + case ABS_MT_TOUCH_MINOR: + pointer->fields |= + InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MINOR; + pointer->absMTTouchMinor = rawEvent->value; + break; case ABS_MT_WIDTH_MAJOR: pointer->fields |= InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MAJOR; pointer->absMTWidthMajor = rawEvent->value; break; + case ABS_MT_WIDTH_MINOR: + pointer->fields |= + InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MINOR; + pointer->absMTWidthMinor = rawEvent->value; + break; + case ABS_MT_ORIENTATION: + pointer->fields |= + InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_ORIENTATION; + pointer->absMTOrientation = rawEvent->value; + break; case ABS_MT_TRACKING_ID: pointer->fields |= InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TRACKING_ID; @@ -408,17 +424,17 @@ void InputReader::onKey(nsecs_t when, InputDevice* device, int32_t keyEventAction; if (down) { device->keyboard.current.downTime = when; - keyEventAction = KEY_EVENT_ACTION_DOWN; + keyEventAction = AKEY_EVENT_ACTION_DOWN; } else { - keyEventAction = KEY_EVENT_ACTION_UP; + keyEventAction = AKEY_EVENT_ACTION_UP; } - int32_t keyEventFlags = KEY_EVENT_FLAG_FROM_SYSTEM; + int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM; if (policyActions & InputReaderPolicyInterface::ACTION_WOKE_HERE) { - keyEventFlags = keyEventFlags | KEY_EVENT_FLAG_WOKE_HERE; + keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE; } - mDispatcher->notifyKey(when, device->id, INPUT_EVENT_NATURE_KEY, policyFlags, + mDispatcher->notifyKey(when, device->id, AINPUT_SOURCE_KEYBOARD, policyFlags, keyEventAction, keyEventFlags, keyCode, scanCode, device->keyboard.current.metaState, device->keyboard.current.downTime); @@ -473,11 +489,29 @@ void InputReader::onMultiTouchScreenStateChanged(nsecs_t when, continue; } + out->pointers[outCount].x = in->accumulator.pointers[inIndex].absMTPositionX; + out->pointers[outCount].y = in->accumulator.pointers[inIndex].absMTPositionY; + + out->pointers[outCount].touchMajor = in->accumulator.pointers[inIndex].absMTTouchMajor; + out->pointers[outCount].touchMinor = (fields + & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_TOUCH_MINOR) != 0 + ? in->accumulator.pointers[inIndex].absMTTouchMinor + : in->accumulator.pointers[inIndex].absMTTouchMajor; + + out->pointers[outCount].toolMajor = in->accumulator.pointers[inIndex].absMTWidthMajor; + out->pointers[outCount].toolMinor = (fields + & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_WIDTH_MINOR) != 0 + ? in->accumulator.pointers[inIndex].absMTWidthMinor + : in->accumulator.pointers[inIndex].absMTWidthMajor; + + out->pointers[outCount].orientation = (fields + & InputDevice::MultiTouchScreenState::Accumulator::FIELD_ABS_MT_ORIENTATION) != 0 + ? in->accumulator.pointers[inIndex].absMTOrientation : 0; + + // Derive an approximation of pressure and size. // FIXME assignment of pressure may be incorrect, probably better to let // pressure = touch / width. Later on we pass width to MotionEvent as a size, which // isn't quite right either. Should be using touch for that. - out->pointers[outCount].x = in->accumulator.pointers[inIndex].absMTPositionX; - out->pointers[outCount].y = in->accumulator.pointers[inIndex].absMTPositionY; out->pointers[outCount].pressure = in->accumulator.pointers[inIndex].absMTTouchMajor; out->pointers[outCount].size = in->accumulator.pointers[inIndex].absMTWidthMajor; @@ -556,6 +590,11 @@ void InputReader::onSingleTouchScreenStateChanged(nsecs_t when, out->pointers[0].y = in->current.y; out->pointers[0].pressure = in->current.pressure; out->pointers[0].size = in->current.size; + out->pointers[0].touchMajor = in->current.pressure; + out->pointers[0].touchMinor = in->current.pressure; + out->pointers[0].toolMajor = in->current.size; + out->pointers[0].toolMinor = in->current.size; + out->pointers[0].orientation = 0; out->idToIndex[0] = 0; out->idBits.markBit(0); } @@ -635,8 +674,8 @@ bool InputReader::consumeVirtualKeyTouches(nsecs_t when, device->touchScreen.currentVirtualKey.keyCode, device->touchScreen.currentVirtualKey.scanCode); #endif - dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP, - KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY); + dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY); return true; // consumed } @@ -658,9 +697,9 @@ bool InputReader::consumeVirtualKeyTouches(nsecs_t when, device->touchScreen.currentVirtualKey.keyCode, device->touchScreen.currentVirtualKey.scanCode); #endif - dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_UP, - KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY - | KEY_EVENT_FLAG_CANCELED); + dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_UP, + AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY + | AKEY_EVENT_FLAG_CANCELED); return true; // consumed default: @@ -679,8 +718,8 @@ bool InputReader::consumeVirtualKeyTouches(nsecs_t when, device->touchScreen.currentVirtualKey.keyCode, device->touchScreen.currentVirtualKey.scanCode); #endif - dispatchVirtualKey(when, device, policyFlags, KEY_EVENT_ACTION_DOWN, - KEY_EVENT_FLAG_FROM_SYSTEM | KEY_EVENT_FLAG_VIRTUAL_HARD_KEY); + dispatchVirtualKey(when, device, policyFlags, AKEY_EVENT_ACTION_DOWN, + AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY); return true; // consumed } } @@ -698,15 +737,15 @@ void InputReader::dispatchVirtualKey(nsecs_t when, nsecs_t downTime = device->touchScreen.currentVirtualKey.downTime; int32_t metaState = globalMetaState(); - if (keyEventAction == KEY_EVENT_ACTION_DOWN) { + if (keyEventAction == AKEY_EVENT_ACTION_DOWN) { mPolicy->virtualKeyDownFeedback(); } int32_t policyActions = mPolicy->interceptKey(when, device->id, - keyEventAction == KEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags); + keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags); if (applyStandardInputDispatchPolicyActions(when, policyActions, & policyFlags)) { - mDispatcher->notifyKey(when, device->id, INPUT_EVENT_NATURE_KEY, policyFlags, + mDispatcher->notifyKey(when, device->id, AINPUT_SOURCE_KEYBOARD, policyFlags, keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime); } } @@ -725,7 +764,7 @@ void InputReader::dispatchTouches(nsecs_t when, if (currentIdBits == lastIdBits) { // No pointer id changes so this is a move event. // The dispatcher takes care of batching moves so we don't have to deal with that here. - int32_t motionEventAction = MOTION_EVENT_ACTION_MOVE; + int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE; dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch, currentIdBits, motionEventAction); } else { @@ -743,10 +782,10 @@ void InputReader::dispatchTouches(nsecs_t when, int32_t motionEventAction; if (activeIdBits.isEmpty()) { - motionEventAction = MOTION_EVENT_ACTION_UP; + motionEventAction = AMOTION_EVENT_ACTION_UP; } else { - motionEventAction = MOTION_EVENT_ACTION_POINTER_UP - | (upId << MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP + | (upId << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); } dispatchTouch(when, device, policyFlags, & device->touchScreen.lastTouch, @@ -761,11 +800,11 @@ void InputReader::dispatchTouches(nsecs_t when, int32_t motionEventAction; if (oldActiveIdBits.isEmpty()) { - motionEventAction = MOTION_EVENT_ACTION_DOWN; + motionEventAction = AMOTION_EVENT_ACTION_DOWN; device->touchScreen.downTime = when; } else { - motionEventAction = MOTION_EVENT_ACTION_POINTER_DOWN - | (downId << MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); + motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN + | (downId << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); } dispatchTouch(when, device, policyFlags, & device->touchScreen.currentTouch, @@ -813,11 +852,17 @@ void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t poli float size = float(touch->pointers[index].size - precalculated.sizeOrigin) * precalculated.sizeScale; + float orientation = float(touch->pointers[index].orientation) + * precalculated.orientationScale; + + bool vertical = abs(orientation) <= M_PI / 8; + switch (mDisplayOrientation) { case InputReaderPolicyInterface::ROTATION_90: { float xTemp = x; x = y; y = mDisplayWidth - xTemp; + vertical = ! vertical; break; } case InputReaderPolicyInterface::ROTATION_180: { @@ -829,16 +874,35 @@ void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t poli float xTemp = x; x = mDisplayHeight - y; y = xTemp; + vertical = ! vertical; break; } } + float touchMajor, touchMinor, toolMajor, toolMinor; + if (vertical) { + touchMajor = float(touch->pointers[index].touchMajor) * precalculated.yScale; + touchMinor = float(touch->pointers[index].touchMinor) * precalculated.xScale; + toolMajor = float(touch->pointers[index].toolMajor) * precalculated.yScale; + toolMinor = float(touch->pointers[index].toolMinor) * precalculated.xScale; + } else { + touchMajor = float(touch->pointers[index].touchMajor) * precalculated.xScale; + touchMinor = float(touch->pointers[index].touchMinor) * precalculated.yScale; + toolMajor = float(touch->pointers[index].toolMajor) * precalculated.xScale; + toolMinor = float(touch->pointers[index].toolMinor) * precalculated.yScale; + } + pointerIds[pointerCount] = int32_t(id); pointerCoords[pointerCount].x = x; pointerCoords[pointerCount].y = y; pointerCoords[pointerCount].pressure = pressure; pointerCoords[pointerCount].size = size; + pointerCoords[pointerCount].touchMajor = touchMajor; + pointerCoords[pointerCount].touchMinor = touchMinor; + pointerCoords[pointerCount].toolMajor = toolMajor; + pointerCoords[pointerCount].toolMinor = toolMinor; + pointerCoords[pointerCount].orientation = orientation; pointerCount += 1; } @@ -847,21 +911,21 @@ void InputReader::dispatchTouch(nsecs_t when, InputDevice* device, uint32_t poli // global to the event. // XXX Maybe we should revise the edge flags API to work on a per-pointer basis. int32_t motionEventEdgeFlags = 0; - if (motionEventAction == MOTION_EVENT_ACTION_DOWN) { + if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { if (pointerCoords[0].x <= 0) { - motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_LEFT; + motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; } else if (pointerCoords[0].x >= orientedWidth) { - motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_RIGHT; + motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; } if (pointerCoords[0].y <= 0) { - motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_TOP; + motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; } else if (pointerCoords[0].y >= orientedHeight) { - motionEventEdgeFlags |= MOTION_EVENT_EDGE_FLAG_BOTTOM; + motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; } } nsecs_t downTime = device->touchScreen.downTime; - mDispatcher->notifyMotion(when, device->id, INPUT_EVENT_NATURE_TOUCH, policyFlags, + mDispatcher->notifyMotion(when, device->id, AINPUT_SOURCE_TOUCHSCREEN, policyFlags, motionEventAction, globalMetaState(), motionEventEdgeFlags, pointerCount, pointerIds, pointerCoords, 0, 0, downTime); @@ -912,9 +976,9 @@ void InputReader::onTrackballStateChanged(nsecs_t when, int32_t motionEventAction; if (downChanged) { - motionEventAction = down ? MOTION_EVENT_ACTION_DOWN : MOTION_EVENT_ACTION_UP; + motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; } else { - motionEventAction = MOTION_EVENT_ACTION_MOVE; + motionEventAction = AMOTION_EVENT_ACTION_MOVE; } int32_t pointerId = 0; @@ -925,6 +989,11 @@ void InputReader::onTrackballStateChanged(nsecs_t when, ? device->trackball.accumulator.relY * device->trackball.precalculated.yScale : 0; pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise. pointerCoords.size = 0; + pointerCoords.touchMajor = 0; + pointerCoords.touchMinor = 0; + pointerCoords.toolMajor = 0; + pointerCoords.toolMinor = 0; + pointerCoords.orientation = 0; float temp; switch (mDisplayOrientation) { @@ -946,8 +1015,8 @@ void InputReader::onTrackballStateChanged(nsecs_t when, break; } - mDispatcher->notifyMotion(when, device->id, INPUT_EVENT_NATURE_TRACKBALL, policyFlags, - motionEventAction, globalMetaState(), MOTION_EVENT_EDGE_FLAG_NONE, + mDispatcher->notifyMotion(when, device->id, AINPUT_SOURCE_TRACKBALL, policyFlags, + motionEventAction, globalMetaState(), AMOTION_EVENT_EDGE_FLAG_NONE, 1, & pointerId, & pointerCoords, device->trackball.precalculated.xPrecision, device->trackball.precalculated.yPrecision, @@ -1079,6 +1148,8 @@ void InputReader::configureDevice(InputDevice* device) { & device->touchScreen.parameters.pressureAxis); configureAbsoluteAxisInfo(device, ABS_MT_WIDTH_MAJOR, "Size", & device->touchScreen.parameters.sizeAxis); + configureAbsoluteAxisInfo(device, ABS_MT_ORIENTATION, "Orientation", + & device->touchScreen.parameters.orientationAxis); } else if (device->isSingleTouchScreen()) { configureAbsoluteAxisInfo(device, ABS_X, "X", & device->touchScreen.parameters.xAxis); @@ -1088,6 +1159,7 @@ void InputReader::configureDevice(InputDevice* device) { & device->touchScreen.parameters.pressureAxis); configureAbsoluteAxisInfo(device, ABS_TOOL_WIDTH, "Size", & device->touchScreen.parameters.sizeAxis); + device->touchScreen.parameters.orientationAxis.valid = false; } if (device->isTouchScreen()) { @@ -1117,6 +1189,14 @@ void InputReader::configureDevice(InputDevice* device) { device->touchScreen.precalculated.sizeOrigin = 0; device->touchScreen.precalculated.sizeScale = 1.0f; } + + if (device->touchScreen.parameters.orientationAxis.valid + && device->touchScreen.parameters.orientationAxis.maxValue > 0) { + device->touchScreen.precalculated.orientationScale = + M_PI_4 / device->touchScreen.parameters.orientationAxis.maxValue; + } else { + device->touchScreen.precalculated.orientationScale = 0.0f; + } } if (device->isTrackball()) { @@ -1347,7 +1427,7 @@ int32_t InputReader::getCurrentScanCodeState(int32_t deviceId, int32_t deviceCla AutoMutex _l(mExportedStateLock); if (mExportedVirtualScanCode == scanCode) { - return KEY_STATE_VIRTUAL; + return AKEY_STATE_VIRTUAL; } } // release exported state lock @@ -1360,7 +1440,7 @@ int32_t InputReader::getCurrentKeyCodeState(int32_t deviceId, int32_t deviceClas AutoMutex _l(mExportedStateLock); if (mExportedVirtualKeyCode == keyCode) { - return KEY_STATE_VIRTUAL; + return AKEY_STATE_VIRTUAL; } } // release exported state lock diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp index fc83e31..cf0f63e 100644 --- a/libs/ui/InputTransport.cpp +++ b/libs/ui/InputTransport.cpp @@ -270,7 +270,7 @@ status_t InputPublisher::reset() { status_t InputPublisher::publishInputEvent( int32_t type, int32_t deviceId, - int32_t nature) { + int32_t source) { if (mPinned) { LOGE("channel '%s' publisher ~ Attempted to publish a new event but publisher has " "not yet been reset.", mChannel->getName().string()); @@ -302,13 +302,13 @@ status_t InputPublisher::publishInputEvent( mSharedMessage->consumed = false; mSharedMessage->type = type; mSharedMessage->deviceId = deviceId; - mSharedMessage->nature = nature; + mSharedMessage->source = source; return OK; } status_t InputPublisher::publishKeyEvent( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t flags, int32_t keyCode, @@ -318,15 +318,15 @@ status_t InputPublisher::publishKeyEvent( nsecs_t downTime, nsecs_t eventTime) { #if DEBUG_TRANSPORT_ACTIONS - LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, nature=%d, " + LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=%d, " "action=%d, flags=%d, keyCode=%d, scanCode=%d, metaState=%d, repeatCount=%d," "downTime=%lld, eventTime=%lld", mChannel->getName().string(), - deviceId, nature, action, flags, keyCode, scanCode, metaState, repeatCount, + deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, downTime, eventTime); #endif - status_t result = publishInputEvent(INPUT_EVENT_TYPE_KEY, deviceId, nature); + status_t result = publishInputEvent(AINPUT_EVENT_TYPE_KEY, deviceId, source); if (result < 0) { return result; } @@ -344,7 +344,7 @@ status_t InputPublisher::publishKeyEvent( status_t InputPublisher::publishMotionEvent( int32_t deviceId, - int32_t nature, + int32_t source, int32_t action, int32_t edgeFlags, int32_t metaState, @@ -358,12 +358,12 @@ status_t InputPublisher::publishMotionEvent( const int32_t* pointerIds, const PointerCoords* pointerCoords) { #if DEBUG_TRANSPORT_ACTIONS - LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, nature=%d, " + LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=%d, " "action=%d, edgeFlags=%d, metaState=%d, xOffset=%f, yOffset=%f, " "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, " "pointerCount=%d", mChannel->getName().string(), - deviceId, nature, action, edgeFlags, metaState, xOffset, yOffset, + deviceId, source, action, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); #endif @@ -373,7 +373,7 @@ status_t InputPublisher::publishMotionEvent( return BAD_VALUE; } - status_t result = publishInputEvent(INPUT_EVENT_TYPE_MOTION, deviceId, nature); + status_t result = publishInputEvent(AINPUT_EVENT_TYPE_MOTION, deviceId, source); if (result < 0) { return result; } @@ -399,7 +399,7 @@ status_t InputPublisher::publishMotionEvent( // Cache essential information about the motion event to ensure that a malicious consumer // cannot confuse the publisher by modifying the contents of the shared memory buffer while // it is being updated. - if (action == MOTION_EVENT_ACTION_MOVE) { + if (action == AMOTION_EVENT_ACTION_MOVE) { mMotionEventPointerCount = pointerCount; mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount); mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement( @@ -420,7 +420,7 @@ status_t InputPublisher::appendMotionSample( if (! mPinned || ! mMotionEventSampleDataTail) { LOGE("channel '%s' publisher ~ Cannot append motion sample because there is no current " - "MOTION_EVENT_ACTION_MOVE event.", mChannel->getName().string()); + "AMOTION_EVENT_ACTION_MOVE event.", mChannel->getName().string()); return INVALID_OPERATION; } @@ -588,7 +588,7 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent* mSharedMessage->consumed = true; switch (mSharedMessage->type) { - case INPUT_EVENT_TYPE_KEY: { + case AINPUT_EVENT_TYPE_KEY: { KeyEvent* keyEvent = factory->createKeyEvent(); if (! keyEvent) return NO_MEMORY; @@ -598,7 +598,7 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent* break; } - case INPUT_EVENT_TYPE_MOTION: { + case AINPUT_EVENT_TYPE_MOTION: { MotionEvent* motionEvent = factory->createMotionEvent(); if (! motionEvent) return NO_MEMORY; @@ -648,7 +648,7 @@ status_t InputConsumer::receiveDispatchSignal() { void InputConsumer::populateKeyEvent(KeyEvent* keyEvent) const { keyEvent->initialize( mSharedMessage->deviceId, - mSharedMessage->nature, + mSharedMessage->source, mSharedMessage->key.action, mSharedMessage->key.flags, mSharedMessage->key.keyCode, @@ -662,7 +662,7 @@ void InputConsumer::populateKeyEvent(KeyEvent* keyEvent) const { void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const { motionEvent->initialize( mSharedMessage->deviceId, - mSharedMessage->nature, + mSharedMessage->source, mSharedMessage->motion.action, mSharedMessage->motion.edgeFlags, mSharedMessage->motion.metaState, diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp index 55504f2..3bc21fa 100644 --- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp @@ -73,17 +73,17 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { status_t status; const int32_t deviceId = 1; - const int32_t nature = INPUT_EVENT_NATURE_KEY; - const int32_t action = KEY_EVENT_ACTION_DOWN; - const int32_t flags = KEY_EVENT_FLAG_FROM_SYSTEM; + const int32_t source = AINPUT_SOURCE_KEYBOARD; + const int32_t action = AKEY_EVENT_ACTION_DOWN; + const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM; const int32_t keyCode = AKEYCODE_ENTER; const int32_t scanCode = 13; - const int32_t metaState = META_ALT_LEFT_ON | META_ALT_ON; + const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON; const int32_t repeatCount = 1; const nsecs_t downTime = 3; const nsecs_t eventTime = 4; - status = mPublisher->publishKeyEvent(deviceId, nature, action, flags, + status = mPublisher->publishKeyEvent(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, downTime, eventTime); ASSERT_EQ(OK, status) << "publisher publishKeyEvent should return OK"; @@ -103,12 +103,12 @@ void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() { ASSERT_TRUE(event != NULL) << "consumer should have returned non-NULL event"; - ASSERT_EQ(INPUT_EVENT_TYPE_KEY, event->getType()) + ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType()) << "consumer should have returned a key event"; KeyEvent* keyEvent = static_cast<KeyEvent*>(event); EXPECT_EQ(deviceId, keyEvent->getDeviceId()); - EXPECT_EQ(nature, keyEvent->getNature()); + EXPECT_EQ(source, keyEvent->getSource()); EXPECT_EQ(action, keyEvent->getAction()); EXPECT_EQ(flags, keyEvent->getFlags()); EXPECT_EQ(keyCode, keyEvent->getKeyCode()); @@ -136,10 +136,10 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( status_t status; const int32_t deviceId = 1; - const int32_t nature = INPUT_EVENT_NATURE_TOUCH; - const int32_t action = MOTION_EVENT_ACTION_MOVE; - const int32_t edgeFlags = MOTION_EVENT_EDGE_FLAG_TOP; - const int32_t metaState = META_ALT_LEFT_ON | META_ALT_ON; + const int32_t source = AINPUT_SOURCE_TOUCHSCREEN; + const int32_t action = AMOTION_EVENT_ACTION_MOVE; + const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP; + const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON; const float xOffset = -10; const float yOffset = -20; const float xPrecision = 0.25; @@ -159,10 +159,15 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( samplePointerCoords.editTop().y = 200 * i + j; samplePointerCoords.editTop().pressure = 0.5 * i + j; samplePointerCoords.editTop().size = 0.7 * i + j; + samplePointerCoords.editTop().touchMajor = 1.5 * i + j; + samplePointerCoords.editTop().touchMinor = 1.7 * i + j; + samplePointerCoords.editTop().toolMajor = 2.5 * i + j; + samplePointerCoords.editTop().toolMinor = 2.7 * i + j; + samplePointerCoords.editTop().orientation = 3.5 * i + j; } } - status = mPublisher->publishMotionEvent(deviceId, nature, action, edgeFlags, + status = mPublisher->publishMotionEvent(deviceId, source, action, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTime, sampleEventTimes[0], pointerCount, pointerIds, samplePointerCoords.array()); ASSERT_EQ(OK, status) @@ -199,14 +204,14 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( ASSERT_TRUE(event != NULL) << "consumer should have returned non-NULL event"; - ASSERT_EQ(INPUT_EVENT_TYPE_MOTION, event->getType()) + ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType()) << "consumer should have returned a motion event"; size_t lastSampleIndex = samplesToAppendBeforeDispatch + samplesToAppendAfterDispatch; MotionEvent* motionEvent = static_cast<MotionEvent*>(event); EXPECT_EQ(deviceId, motionEvent->getDeviceId()); - EXPECT_EQ(nature, motionEvent->getNature()); + EXPECT_EQ(source, motionEvent->getSource()); EXPECT_EQ(action, motionEvent->getAction()); EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags()); EXPECT_EQ(metaState, motionEvent->getMetaState()); @@ -241,6 +246,16 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( motionEvent->getHistoricalPressure(i, sampleIndex)); EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getHistoricalSize(i, sampleIndex)); + EXPECT_EQ(samplePointerCoords[offset].touchMajor, + motionEvent->getHistoricalTouchMajor(i, sampleIndex)); + EXPECT_EQ(samplePointerCoords[offset].touchMinor, + motionEvent->getHistoricalTouchMinor(i, sampleIndex)); + EXPECT_EQ(samplePointerCoords[offset].toolMajor, + motionEvent->getHistoricalToolMajor(i, sampleIndex)); + EXPECT_EQ(samplePointerCoords[offset].toolMinor, + motionEvent->getHistoricalToolMinor(i, sampleIndex)); + EXPECT_EQ(samplePointerCoords[offset].orientation, + motionEvent->getHistoricalOrientation(i, sampleIndex)); } } @@ -255,6 +270,11 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i)); EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i)); EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i)); + EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i)); + EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i)); + EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i)); + EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i)); + EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i)); } status = mConsumer->sendFinishedSignal(); @@ -300,7 +320,7 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenNotReset_ReturnsErr const size_t pointerCount = 1; int32_t pointerIds[pointerCount] = { 0 }; - PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0 } }; + PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); @@ -381,7 +401,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenPublishedMotionEven int32_t pointerIds[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(0, 0, MOTION_EVENT_ACTION_DOWN, + status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_DOWN, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); @@ -398,7 +418,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenAlreadyConsumed_Ret int32_t pointerIds[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(0, 0, MOTION_EVENT_ACTION_MOVE, + status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); @@ -425,7 +445,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenBufferFull_ReturnsE int32_t pointerIds[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(0, 0, MOTION_EVENT_ACTION_MOVE, + status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); diff --git a/native/android/input.cpp b/native/android/input.cpp index a4dde51..4e1b6dc 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -38,8 +38,8 @@ int32_t AInputEvent_getDeviceId(const AInputEvent* event) { return static_cast<const InputEvent*>(event)->getDeviceId(); } -int32_t AInputEvent_getNature(const AInputEvent* event) { - return static_cast<const InputEvent*>(event)->getNature(); +int32_t AInputEvent_getSource(const AInputEvent* event) { + return static_cast<const InputEvent*>(event)->getSource(); } int32_t AKeyEvent_getAction(const AInputEvent* key_event) { @@ -69,6 +69,7 @@ int64_t AKeyEvent_getDownTime(const AInputEvent* key_event) { return static_cast<const KeyEvent*>(key_event)->getDownTime(); } + int64_t AKeyEvent_getEventTime(const AInputEvent* key_event) { return static_cast<const KeyEvent*>(key_event)->getEventTime(); } @@ -141,6 +142,26 @@ float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index return static_cast<const MotionEvent*>(motion_event)->getSize(pointer_index); } +float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index) { + return static_cast<const MotionEvent*>(motion_event)->getTouchMajor(pointer_index); +} + +float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index) { + return static_cast<const MotionEvent*>(motion_event)->getTouchMinor(pointer_index); +} + +float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index) { + return static_cast<const MotionEvent*>(motion_event)->getToolMajor(pointer_index); +} + +float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index) { + return static_cast<const MotionEvent*>(motion_event)->getToolMinor(pointer_index); +} + +float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index) { + return static_cast<const MotionEvent*>(motion_event)->getOrientation(pointer_index); +} + size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event) { return static_cast<const MotionEvent*>(motion_event)->getHistorySize(); } @@ -187,6 +208,37 @@ float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_i pointer_index, history_index); } +float AMotionEvent_getHistoricalTouchMajor(AInputEvent* motion_event, size_t pointer_index, + size_t history_index) { + return static_cast<const MotionEvent*>(motion_event)->getHistoricalTouchMajor( + pointer_index, history_index); +} + +float AMotionEvent_getHistoricalTouchMinor(AInputEvent* motion_event, size_t pointer_index, + size_t history_index) { + return static_cast<const MotionEvent*>(motion_event)->getHistoricalTouchMinor( + pointer_index, history_index); +} + +float AMotionEvent_getHistoricalToolMajor(AInputEvent* motion_event, size_t pointer_index, + size_t history_index) { + return static_cast<const MotionEvent*>(motion_event)->getHistoricalToolMajor( + pointer_index, history_index); +} + +float AMotionEvent_getHistoricalToolMinor(AInputEvent* motion_event, size_t pointer_index, + size_t history_index) { + return static_cast<const MotionEvent*>(motion_event)->getHistoricalToolMinor( + pointer_index, history_index); +} + +float AMotionEvent_getHistoricalOrientation(AInputEvent* motion_event, size_t pointer_index, + size_t history_index) { + return static_cast<const MotionEvent*>(motion_event)->getHistoricalOrientation( + pointer_index, history_index); +} + + void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, ALooper_callbackFunc* callback, void* data) { queue->attachLooper(looper, callback, data); diff --git a/native/include/android/input.h b/native/include/android/input.h index 25dd68e..ce79cd4 100644 --- a/native/include/android/input.h +++ b/native/include/android/input.h @@ -49,49 +49,21 @@ extern "C" { #endif /* - * Input device classes. - */ -enum { - /* The input device is a keyboard. */ - INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001, - - /* The input device is an alpha-numeric keyboard (not just a dial pad). */ - INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002, - - /* The input device is a touchscreen (either single-touch or multi-touch). */ - INPUT_DEVICE_CLASS_TOUCHSCREEN = 0x00000004, - - /* The input device is a trackball. */ - INPUT_DEVICE_CLASS_TRACKBALL = 0x00000008, - - /* The input device is a multi-touch touchscreen. */ - INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010, - - /* The input device is a directional pad. */ - INPUT_DEVICE_CLASS_DPAD = 0x00000020, - - /* The input device is a gamepad (implies keyboard). */ - INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040 -}; - -/* * Key states (may be returned by queries about the current state of a * particular key code, scan code or switch). - * - * XXX should we call this BUTTON_STATE_XXX? */ enum { /* The key state is unknown or the requested key itself is not supported. */ - KEY_STATE_UNKNOWN = -1, + AKEY_STATE_UNKNOWN = -1, /* The key is up. */ - KEY_STATE_UP = 0, + AKEY_STATE_UP = 0, /* The key is down. */ - KEY_STATE_DOWN = 1, + AKEY_STATE_DOWN = 1, /* The key is down but is a virtual key press that is being emulated by the system. */ - KEY_STATE_VIRTUAL = 2 + AKEY_STATE_VIRTUAL = 2 }; /* @@ -99,28 +71,28 @@ enum { */ enum { /* No meta keys are pressed. */ - META_NONE = 0, + AMETA_NONE = 0, /* This mask is used to check whether one of the ALT meta keys is pressed. */ - META_ALT_ON = 0x02, + AMETA_ALT_ON = 0x02, /* This mask is used to check whether the left ALT meta key is pressed. */ - META_ALT_LEFT_ON = 0x10, + AMETA_ALT_LEFT_ON = 0x10, /* This mask is used to check whether the right ALT meta key is pressed. */ - META_ALT_RIGHT_ON = 0x20, + AMETA_ALT_RIGHT_ON = 0x20, /* This mask is used to check whether one of the SHIFT meta keys is pressed. */ - META_SHIFT_ON = 0x01, + AMETA_SHIFT_ON = 0x01, /* This mask is used to check whether the left SHIFT meta key is pressed. */ - META_SHIFT_LEFT_ON = 0x40, + AMETA_SHIFT_LEFT_ON = 0x40, /* This mask is used to check whether the right SHIFT meta key is pressed. */ - META_SHIFT_RIGHT_ON = 0x80, + AMETA_SHIFT_RIGHT_ON = 0x80, /* This mask is used to check whether the SYM meta key is pressed. */ - META_SYM_ON = 0x04 + AMETA_SYM_ON = 0x04 }; /* @@ -137,10 +109,10 @@ typedef struct AInputEvent AInputEvent; */ enum { /* Indicates that the input event is a key event. */ - INPUT_EVENT_TYPE_KEY = 1, + AINPUT_EVENT_TYPE_KEY = 1, /* Indicates that the input event is a motion event. */ - INPUT_EVENT_TYPE_MOTION = 2 + AINPUT_EVENT_TYPE_MOTION = 2 }; /* @@ -148,16 +120,16 @@ enum { */ enum { /* The key has been pressed down. */ - KEY_EVENT_ACTION_DOWN = 0, + AKEY_EVENT_ACTION_DOWN = 0, /* The key has been released. */ - KEY_EVENT_ACTION_UP = 1, + AKEY_EVENT_ACTION_UP = 1, /* Multiple duplicate key events have occurred in a row, or a complex string is * being delivered. The repeat_count property of the key event contains the number * of times the given key code should be executed. */ - KEY_EVENT_ACTION_MULTIPLE = 2 + AKEY_EVENT_ACTION_MULTIPLE = 2 }; /* @@ -165,25 +137,25 @@ enum { */ enum { /* This mask is set if the device woke because of this key event. */ - KEY_EVENT_FLAG_WOKE_HERE = 0x1, + AKEY_EVENT_FLAG_WOKE_HERE = 0x1, /* This mask is set if the key event was generated by a software keyboard. */ - KEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2, + AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2, /* This mask is set if we don't want the key event to cause us to leave touch mode. */ - KEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4, + AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4, /* This mask is set if an event was known to come from a trusted part * of the system. That is, the event is known to come from the user, * and could not have been spoofed by a third party component. */ - KEY_EVENT_FLAG_FROM_SYSTEM = 0x8, + AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8, /* This mask is used for compatibility, to identify enter keys that are * coming from an IME whose enter key has been auto-labelled "next" or * "done". This allows TextView to dispatch these as normal enter keys * for old applications, but still do the appropriate action when * receiving them. */ - KEY_EVENT_FLAG_EDITOR_ACTION = 0x10, + AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10, /* When associated with up key events, this indicates that the key press * has been canceled. Typically this is used with virtual touch screen @@ -193,26 +165,26 @@ enum { * key. Note that for this to work, the application can not perform an * action for a key until it receives an up or the long press timeout has * expired. */ - KEY_EVENT_FLAG_CANCELED = 0x20, + AKEY_EVENT_FLAG_CANCELED = 0x20, /* This key event was generated by a virtual (on-screen) hard key area. * Typically this is an area of the touchscreen, outside of the regular * display, dedicated to "hardware" buttons. */ - KEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40, + AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40, /* This flag is set for the first key repeat that occurs after the * long press timeout. */ - KEY_EVENT_FLAG_LONG_PRESS = 0x80, + AKEY_EVENT_FLAG_LONG_PRESS = 0x80, - /* Set when a key event has KEY_EVENT_FLAG_CANCELED set because a long + /* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long * press action was executed while it was down. */ - KEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100, + AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100, - /* Set for KEY_EVENT_ACTION_UP when this event's key code is still being + /* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being * tracked from its initial down. That is, somebody requested that tracking * started on the key down and a long press has not caused * the tracking to be canceled. */ - KEY_EVENT_FLAG_TRACKING = 0x200 + AKEY_EVENT_FLAG_TRACKING = 0x200 }; /* @@ -220,57 +192,57 @@ enum { */ /* Bit shift for the action bits holding the pointer index as - * defined by MOTION_EVENT_ACTION_POINTER_INDEX_MASK. + * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK. */ -#define MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8 +#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8 enum { /* Bit mask of the parts of the action code that are the action itself. */ - MOTION_EVENT_ACTION_MASK = 0xff, + AMOTION_EVENT_ACTION_MASK = 0xff, /* Bits in the action code that represent a pointer index, used with - * MOTION_EVENT_ACTION_POINTER_DOWN and MOTION_EVENT_ACTION_POINTER_UP. Shifting - * down by MOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer + * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP. Shifting + * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer * index where the data for the pointer going up or down can be found. */ - MOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00, + AMOTION_EVENT_ACTION_POINTER_INDEX_MASK = 0xff00, /* A pressed gesture has started, the motion contains the initial starting location. */ - MOTION_EVENT_ACTION_DOWN = 0, + AMOTION_EVENT_ACTION_DOWN = 0, /* A pressed gesture has finished, the motion contains the final release location * as well as any intermediate points since the last down or move event. */ - MOTION_EVENT_ACTION_UP = 1, + AMOTION_EVENT_ACTION_UP = 1, - /* A change has happened during a press gesture (between MOTION_EVENT_ACTION_DOWN and - * MOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as + /* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and + * AMOTION_EVENT_ACTION_UP). The motion contains the most recent point, as well as * any intermediate points since the last down or move event. */ - MOTION_EVENT_ACTION_MOVE = 2, + AMOTION_EVENT_ACTION_MOVE = 2, /* The current gesture has been aborted. * You will not receive any more points in it. You should treat this as * an up event, but not perform any action that you normally would. */ - MOTION_EVENT_ACTION_CANCEL = 3, + AMOTION_EVENT_ACTION_CANCEL = 3, /* A movement has happened outside of the normal bounds of the UI element. * This does not provide a full gesture, but only the initial location of the movement/touch. */ - MOTION_EVENT_ACTION_OUTSIDE = 4, + AMOTION_EVENT_ACTION_OUTSIDE = 4, /* A non-primary pointer has gone down. - * The bits in MOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. + * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. */ - MOTION_EVENT_ACTION_POINTER_DOWN = 5, + AMOTION_EVENT_ACTION_POINTER_DOWN = 5, /* A non-primary pointer has gone up. - * The bits in MOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. + * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed. */ - MOTION_EVENT_ACTION_POINTER_UP = 6 + AMOTION_EVENT_ACTION_POINTER_UP = 6 }; /* @@ -278,39 +250,50 @@ enum { */ enum { /* No edges intersected */ - MOTION_EVENT_EDGE_FLAG_NONE = 0, + AMOTION_EVENT_EDGE_FLAG_NONE = 0, /* Flag indicating the motion event intersected the top edge of the screen. */ - MOTION_EVENT_EDGE_FLAG_TOP = 0x01, + AMOTION_EVENT_EDGE_FLAG_TOP = 0x01, /* Flag indicating the motion event intersected the bottom edge of the screen. */ - MOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02, + AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02, /* Flag indicating the motion event intersected the left edge of the screen. */ - MOTION_EVENT_EDGE_FLAG_LEFT = 0x04, + AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04, /* Flag indicating the motion event intersected the right edge of the screen. */ - MOTION_EVENT_EDGE_FLAG_RIGHT = 0x08 + AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08 }; /* - * Specifies the logical nature of an input event. - * For example, the nature distinguishes between motion events that represent touches and - * those that represent trackball moves. + * Input sources. * - * XXX This concept is tentative. Another idea would be to associate events with logical - * controllers rather than physical devices. The interpretation of an event would - * be made with respect to the nature of the controller that is considered the logical - * source of an event. The decoupling is beneficial since multiple physical (and virtual) - * devices could be responsible for producing events that would be associated with - * various logical controllers. For example, the hard keyboard, on screen keyboard, - * and peripheral keyboard could be mapped onto a single logical "keyboard" controller - * (or treated independently, if desired). + * The appropriate interpretation for an input event depends on its source. + * Refer to the documentation on android.view.InputDevice for more details about input sources + * and their correct interpretation. */ enum { - INPUT_EVENT_NATURE_KEY = 1, - INPUT_EVENT_NATURE_TOUCH = 2, - INPUT_EVENT_NATURE_TRACKBALL = 3 + AINPUT_SOURCE_CLASS_MASK = 0x000000ff, + + AINPUT_SOURCE_CLASS_BUTTON = 0x00000001, + AINPUT_SOURCE_CLASS_POINTER = 0x00000002, + AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004, + AINPUT_SOURCE_CLASS_POSITION = 0x00000008, + AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010, +}; + +enum { + AINPUT_SOURCE_UNKNOWN = 0x00000000, + + AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON, + AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON, + AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON, + AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER, + AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER, + AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION, + AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION, + AINPUT_SOURCE_JOYSTICK_LEFT = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK, + AINPUT_SOURCE_JOYSTICK_RIGHT = 0x02000000 | AINPUT_SOURCE_CLASS_JOYSTICK, }; /* @@ -337,8 +320,8 @@ int32_t AInputEvent_getType(const AInputEvent* event); */ int32_t AInputEvent_getDeviceId(const AInputEvent* event); -/* Get the input event nature. */ -int32_t AInputEvent_getNature(const AInputEvent* event); +/* Get the input event source. */ +int32_t AInputEvent_getSource(const AInputEvent* event); /*** Accessors for key events only. ***/ @@ -466,11 +449,41 @@ float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_i * determine fat touch events. */ float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index); +/* Get the current length of the major axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index. */ +float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index); + +/* Get the current length of the minor axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index. */ +float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index); + +/* Get the current length of the major axis of an ellipse that describes the size + * of the approaching tool for the given pointer 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. */ +float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index); + +/* Get the current length of the minor axis of an ellipse that describes the size + * of the approaching tool for the given pointer 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. */ +float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index); + +/* Get the current orientation of the touch area and tool area in radians clockwise from + * vertical for the given pointer 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). */ +float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index); + /* Get the number of historical points in this event. These are movements that * have occurred between this event and the previous event. This only applies - * to MOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0. + * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0. * Historical samples are indexed from oldest to newest. */ -size_t AMotionEvent_get_history_size(const AInputEvent* motion_event); +size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event); /* Get the time that a historical movement occurred between this event and * the previous event, in the java.lang.System.nanoTime() time base. */ @@ -527,6 +540,47 @@ float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t point float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index, size_t history_index); +/* Get the historical length of the major axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index that + * occurred between this event and the previous motion event. */ +float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/* Get the historical length of the minor axis of an ellipse that describes the touch area + * at the point of contact for the given pointer index that + * occurred between this event and the previous motion event. */ +float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/* Get the historical length of the major axis of an ellipse that describes the size + * of the approaching tool for the given pointer index that + * occurred between this event and the previous motion event. + * 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. */ +float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/* Get the historical length of the minor axis of an ellipse that describes the size + * of the approaching tool for the given pointer index that + * occurred between this event and the previous motion event. + * 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. */ +float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + +/* Get the historical orientation of the touch area and tool area in radians clockwise from + * vertical for the given pointer index that + * occurred between this event and the previous motion event. + * 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). */ +float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index, + size_t history_index); + + /* * Input queue * diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java index cdae27c..3c60a98 100644 --- a/services/java/com/android/server/InputManager.java +++ b/services/java/com/android/server/InputManager.java @@ -77,9 +77,9 @@ public class InputManager { private static native boolean nativeHasKeys(int[] keyCodes, boolean[] keyExists); private static native void nativeRegisterInputChannel(InputChannel inputChannel); private static native void nativeUnregisterInputChannel(InputChannel inputChannel); - private static native int nativeInjectKeyEvent(KeyEvent event, int nature, + private static native int nativeInjectKeyEvent(KeyEvent event, int injectorPid, int injectorUid, boolean sync, int timeoutMillis); - private static native int nativeInjectMotionEvent(MotionEvent event, int nature, + private static native int nativeInjectMotionEvent(MotionEvent event, int injectorPid, int injectorUid, boolean sync, int timeoutMillis); private static native void nativeSetInputWindows(InputWindow[] windows); private static native void nativeSetInputDispatchMode(boolean enabled, boolean frozen); @@ -229,14 +229,13 @@ public class InputManager { * to be dispatched before it can determine whether input event injection will be * permitted based on the current input focus. * @param event The event to inject. - * @param nature The nature of the event. * @param injectorPid The pid of the injecting application. * @param injectorUid The uid of the injecting application. * @param sync If true, waits for the event to be completed before returning. * @param timeoutMillis The injection timeout in milliseconds. * @return One of the INPUT_EVENT_INJECTION_XXX constants. */ - public int injectKeyEvent(KeyEvent event, int nature, int injectorPid, int injectorUid, + public int injectKeyEvent(KeyEvent event, int injectorPid, int injectorUid, boolean sync, int timeoutMillis) { if (event == null) { throw new IllegalArgumentException("event must not be null"); @@ -248,7 +247,7 @@ public class InputManager { throw new IllegalArgumentException("timeoutMillis must be positive"); } - return nativeInjectKeyEvent(event, nature, injectorPid, injectorUid, + return nativeInjectKeyEvent(event, injectorPid, injectorUid, sync, timeoutMillis); } @@ -258,7 +257,6 @@ public class InputManager { * to be dispatched before it can determine whether input event injection will be * permitted based on the current input focus. * @param event The event to inject. - * @param nature The nature of the event. * @param sync If true, waits for the event to be completed before returning. * @param injectorPid The pid of the injecting application. * @param injectorUid The uid of the injecting application. @@ -266,7 +264,7 @@ public class InputManager { * @param timeoutMillis The injection timeout in milliseconds. * @return One of the INPUT_EVENT_INJECTION_XXX constants. */ - public int injectMotionEvent(MotionEvent event, int nature, int injectorPid, int injectorUid, + public int injectMotionEvent(MotionEvent event, int injectorPid, int injectorUid, boolean sync, int timeoutMillis) { if (event == null) { throw new IllegalArgumentException("event must not be null"); @@ -278,7 +276,7 @@ public class InputManager { throw new IllegalArgumentException("timeoutMillis must be positive"); } - return nativeInjectMotionEvent(event, nature, injectorPid, injectorUid, + return nativeInjectMotionEvent(event, injectorPid, injectorUid, sync, timeoutMillis); } diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index c6e5cd2..37a2a58 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -102,6 +102,7 @@ import android.view.IWindow; import android.view.IWindowManager; import android.view.IWindowSession; import android.view.InputChannel; +import android.view.InputDevice; import android.view.InputQueue; import android.view.KeyEvent; import android.view.MotionEvent; @@ -2017,6 +2018,8 @@ public class WindowManagerService extends IWindowManager.Stub + ", surface=" + win.mSurface); final long origId = Binder.clearCallingIdentity(); + + win.disposeInputChannel(); if (DEBUG_APP_TRANSITIONS) Slog.v( TAG, "Remove " + win + ": mSurface=" + win.mSurface @@ -2077,8 +2080,6 @@ public class WindowManagerService extends IWindowManager.Stub } private void removeWindowInnerLocked(Session session, WindowState win) { - mInputMonitor.windowIsBeingRemovedLw(win); - win.mRemoved = true; if (mInputMethodTarget == win) { @@ -2157,6 +2158,8 @@ public class WindowManagerService extends IWindowManager.Stub win.mAppToken.updateReportedVisibilityLocked(); } } + + mInputMonitor.updateInputWindowsLw(); } private static void logSurface(WindowState w, String msg, RuntimeException where) { @@ -2907,7 +2910,6 @@ public class WindowManagerService extends IWindowManager.Stub if (win.isVisibleNow()) { applyAnimationLocked(win, WindowManagerPolicy.TRANSIT_EXIT, false); - mInputMonitor.windowIsBeingRemovedLw(win); changed = true; } } @@ -2925,6 +2927,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + mInputMonitor.updateInputWindowsLw(); } else { Slog.w(TAG, "Attempted to remove non-existing token: " + token); } @@ -5111,7 +5114,7 @@ public class WindowManagerService extends IWindowManager.Stub final int N = windows.size(); for (int i = N - 1; i >= 0; i--) { final WindowState child = (WindowState) windows.get(i); - if (child.mInputChannel == null) { + if (child.mInputChannel == null || child.mRemoved) { // Skip this window because it cannot possibly receive input. continue; } @@ -5288,11 +5291,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - public void windowIsBeingRemovedLw(WindowState window) { - // Window is being removed. - updateInputWindowsLw(); - } - public void pauseDispatchingLw(WindowToken window) { if (! window.paused) { if (DEBUG_INPUT) { @@ -5410,19 +5408,24 @@ public class WindowManagerService extends IWindowManager.Stub int metaState = ev.getMetaState(); int deviceId = ev.getDeviceId(); int scancode = ev.getScanCode(); + int source = ev.getSource(); + + if (source == InputDevice.SOURCE_UNKNOWN) { + source = InputDevice.SOURCE_KEYBOARD; + } if (eventTime == 0) eventTime = SystemClock.uptimeMillis(); if (downTime == 0) downTime = eventTime; KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState, - deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM); + deviceId, scancode, KeyEvent.FLAG_FROM_SYSTEM, source); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); final int result = mInputManager.injectKeyEvent(newEvent, - InputQueue.INPUT_EVENT_NATURE_KEY, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); + pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); @@ -5442,8 +5445,13 @@ public class WindowManagerService extends IWindowManager.Stub final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); - final int result = mInputManager.injectMotionEvent(ev, - InputQueue.INPUT_EVENT_NATURE_TOUCH, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); + MotionEvent newEvent = MotionEvent.obtain(ev); + if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { + newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN); + } + + final int result = mInputManager.injectMotionEvent(newEvent, + pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); @@ -5463,8 +5471,13 @@ public class WindowManagerService extends IWindowManager.Stub final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); - final int result = mInputManager.injectMotionEvent(ev, - InputQueue.INPUT_EVENT_NATURE_TRACKBALL, pid, uid, sync, INJECTION_TIMEOUT_MILLIS); + MotionEvent newEvent = MotionEvent.obtain(ev); + if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) { + newEvent.setSource(InputDevice.SOURCE_TRACKBALL); + } + + final int result = mInputManager.injectMotionEvent(newEvent, + pid, uid, sync, INJECTION_TIMEOUT_MILLIS); Binder.restoreCallingIdentity(ident); return reportInjectionResult(result); @@ -6960,6 +6973,8 @@ public class WindowManagerService extends IWindowManager.Stub } void removeLocked() { + disposeInputChannel(); + if (mAttachedWindow != null) { mAttachedWindow.mChildWindows.remove(this); } @@ -6971,7 +6986,9 @@ public class WindowManagerService extends IWindowManager.Stub // Ignore if it has already been removed (usually because // we are doing this as part of processing a death note.) } - + } + + void disposeInputChannel() { if (mInputChannel != null) { mInputManager.unregisterInputChannel(mInputChannel); diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index 26e105a..bc052a0 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -354,7 +354,7 @@ private: void releaseTouchedWindowLd(); - int32_t waitForTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, + int32_t waitForNonTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets); int32_t waitForTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets); @@ -1222,14 +1222,17 @@ int32_t NativeInputManager::waitForFocusedWindowLd(uint32_t policyFlags, return injectionResult; } +enum InjectionPermission { + INJECTION_PERMISSION_UNKNOWN, + INJECTION_PERMISSION_GRANTED, + INJECTION_PERMISSION_DENIED +}; + int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets, InputWindow*& outTouchedWindow) { nsecs_t startTime = now(); - int32_t injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; - int32_t action = motionEvent->getAction(); - // For security reasons, we defer updating the touch state until we are sure that // event injection will be allowed. // @@ -1255,8 +1258,13 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin // instead of POLICY_FLAG_WOKE_HERE... // bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE; + + int32_t action = motionEvent->getAction(); + bool firstIteration = true; ANRTimer anrTimer; + int32_t injectionResult; + InjectionPermission injectionPermission; for (;;) { if (firstIteration) { firstIteration = false; @@ -1265,7 +1273,8 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin LOGW("Dropping event because the dispatcher timed out waiting to identify " "the window that should receive it."); injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT; - break; + injectionPermission = INJECTION_PERMISSION_UNKNOWN; + break; // timed out, exit wait loop } } @@ -1273,6 +1282,7 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin if (! mDispatchEnabled) { LOGI("Dropping event because input dispatch is disabled."); injectionResult = INPUT_EVENT_INJECTION_FAILED; + injectionPermission = INJECTION_PERMISSION_UNKNOWN; break; // failed, exit wait loop } @@ -1286,7 +1296,9 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin } // Update the touch state as needed based on the properties of the touch event. - if (action == MOTION_EVENT_ACTION_DOWN) { + if (action == AMOTION_EVENT_ACTION_DOWN) { + /* Case 1: ACTION_DOWN */ + InputWindow* newTouchedWindow = NULL; mTempTouchedOutsideWindows.clear(); @@ -1348,12 +1360,14 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin LOGI("Dropping event because there is no touched window or focused application."); injectionResult = INPUT_EVENT_INJECTION_FAILED; + injectionPermission = INJECTION_PERMISSION_UNKNOWN; break; // failed, exit wait loop } // Check permissions. if (! checkInjectionPermission(newTouchedWindow, injectorPid, injectorUid)) { injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; + injectionPermission = INJECTION_PERMISSION_DENIED; break; // failed, exit wait loop } @@ -1374,18 +1388,33 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin if (newTouchedWindow->hasWallpaper) { mTouchedWallpaperWindows.appendVector(mWallpaperWindows); } + + injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; + injectionPermission = INJECTION_PERMISSION_GRANTED; break; // done } else { + /* Case 2: Everything but ACTION_DOWN */ + // Check permissions. if (! checkInjectionPermission(mTouchedWindow, injectorPid, injectorUid)) { injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; + injectionPermission = INJECTION_PERMISSION_DENIED; + break; // failed, exit wait loop + } + + // If the pointer is not currently down, then ignore the event. + if (! mTouchDown) { + LOGI("Dropping event because the pointer is not down."); + injectionResult = INPUT_EVENT_INJECTION_FAILED; + injectionPermission = INJECTION_PERMISSION_GRANTED; break; // failed, exit wait loop } // If there is no currently touched window then fail. - if (! mTouchedWindow || ! mTouchDown) { - LOGI("Dropping event because touched window is no longer valid."); + if (! mTouchedWindow) { + LOGW("Dropping event because there is no touched window to receive it."); injectionResult = INPUT_EVENT_INJECTION_FAILED; + injectionPermission = INJECTION_PERMISSION_GRANTED; break; // failed, exit wait loop } @@ -1399,16 +1428,14 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin } // Success! + injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; + injectionPermission = INJECTION_PERMISSION_GRANTED; break; // done } } // Output targets. - bool havePermission; if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) { - // Injection succeeded so the injector must have permission. - havePermission = true; - size_t numWallpaperWindows = mTouchedWallpaperWindows.size(); for (size_t i = 0; i < numWallpaperWindows; i++) { addTarget(mTouchedWallpaperWindows[i], 0, 0, outTargets); @@ -1423,25 +1450,23 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin anrTimer.getTimeSpentWaitingForApplication(), outTargets); outTouchedWindow = mTouchedWindow; } else { - if (injectionResult != INPUT_EVENT_INJECTION_PERMISSION_DENIED - && checkInjectionPermission(NULL, injectorPid, injectorUid)) { - // Injection failed but the injector does have permission to inject events. - // While we might not have found a valid target for the injected event, we - // still want to update the dispatch state to take it into account. - havePermission = true; - } else { - // Injector does not have permission to inject events. - // We make sure to leave the dispatch state unchanged. - havePermission = false; - } outTouchedWindow = NULL; } mTempTouchedOutsideWindows.clear(); - // Update final pieces of touch state now that we know for sure whether the injector - // had permission to perform the injection. - if (havePermission) { - if (action == MOTION_EVENT_ACTION_DOWN) { + // Check injection permission once and for all. + if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) { + if (checkInjectionPermission(action == AMOTION_EVENT_ACTION_DOWN ? NULL : mTouchedWindow, + injectorPid, injectorUid)) { + injectionPermission = INJECTION_PERMISSION_GRANTED; + } else { + injectionPermission = INJECTION_PERMISSION_DENIED; + } + } + + // Update final pieces of touch state if the injector had permission. + if (injectionPermission == INJECTION_PERMISSION_GRANTED) { + if (action == AMOTION_EVENT_ACTION_DOWN) { if (mTouchDown) { // This is weird. We got a down but we thought it was already down! LOGW("Pointer down received while already down."); @@ -1454,10 +1479,12 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin // be holding on to an earlier target from a previous touch down. Release it. releaseTouchedWindowLd(); } - } else if (action == MOTION_EVENT_ACTION_UP) { + } else if (action == AMOTION_EVENT_ACTION_UP) { mTouchDown = false; releaseTouchedWindowLd(); } + } else { + LOGW("Not updating touch focus because injection was denied."); } #if DEBUG_FOCUS @@ -1557,26 +1584,21 @@ int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent, policyFlags, injectorPid, injectorUid); #endif - switch (motionEvent->getNature()) { - case INPUT_EVENT_NATURE_TRACKBALL: - return waitForTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, - outTargets); - - case INPUT_EVENT_NATURE_TOUCH: + int32_t source = motionEvent->getSource(); + if (source & AINPUT_SOURCE_CLASS_POINTER) { return waitForTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, outTargets); - - default: - assert(false); - return INPUT_EVENT_INJECTION_FAILED; + } else { + return waitForNonTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, + outTargets); } } -int32_t NativeInputManager::waitForTrackballEventTargets(MotionEvent* motionEvent, +int32_t NativeInputManager::waitForNonTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) { #if DEBUG_INPUT_DISPATCHER_POLICY - LOGD("waitForTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", + LOGD("waitForNonTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", policyFlags, injectorPid, injectorUid); #endif @@ -1622,10 +1644,10 @@ int32_t NativeInputManager::waitForTouchEventTargets(MotionEvent* motionEvent, int32_t eventType; switch (motionEvent->getAction()) { - case MOTION_EVENT_ACTION_DOWN: + case AMOTION_EVENT_ACTION_DOWN: eventType = POWER_MANAGER_TOUCH_EVENT; break; - case MOTION_EVENT_ACTION_UP: + case AMOTION_EVENT_ACTION_UP: eventType = POWER_MANAGER_TOUCH_UP_EVENT; break; default: @@ -1852,7 +1874,7 @@ static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz, jint deviceId, jint deviceClasses, jint scanCode) { if (checkInputManagerUnitialized(env)) { - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } return gNativeInputManager->getInputManager()->getScanCodeState( @@ -1862,7 +1884,7 @@ static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jcla static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz, jint deviceId, jint deviceClasses, jint keyCode) { if (checkInputManagerUnitialized(env)) { - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } return gNativeInputManager->getInputManager()->getKeyCodeState( @@ -1872,7 +1894,7 @@ static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclas static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz, jint deviceId, jint deviceClasses, jint sw) { if (checkInputManagerUnitialized(env)) { - return KEY_STATE_UNKNOWN; + return AKEY_STATE_UNKNOWN; } return gNativeInputManager->getInputManager()->getSwitchState(deviceId, deviceClasses, sw); @@ -1963,28 +1985,28 @@ static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env } static jint android_server_InputManager_nativeInjectKeyEvent(JNIEnv* env, jclass clazz, - jobject keyEventObj, jint nature, jint injectorPid, jint injectorUid, + jobject keyEventObj, jint injectorPid, jint injectorUid, jboolean sync, jint timeoutMillis) { if (checkInputManagerUnitialized(env)) { return INPUT_EVENT_INJECTION_FAILED; } KeyEvent keyEvent; - android_view_KeyEvent_toNative(env, keyEventObj, nature, & keyEvent); + android_view_KeyEvent_toNative(env, keyEventObj, & keyEvent); return gNativeInputManager->getInputManager()->injectInputEvent(& keyEvent, injectorPid, injectorUid, sync, timeoutMillis); } static jint android_server_InputManager_nativeInjectMotionEvent(JNIEnv* env, jclass clazz, - jobject motionEventObj, jint nature, jint injectorPid, jint injectorUid, + jobject motionEventObj, jint injectorPid, jint injectorUid, jboolean sync, jint timeoutMillis) { if (checkInputManagerUnitialized(env)) { return INPUT_EVENT_INJECTION_FAILED; } MotionEvent motionEvent; - android_view_MotionEvent_toNative(env, motionEventObj, nature, & motionEvent); + android_view_MotionEvent_toNative(env, motionEventObj, & motionEvent); return gNativeInputManager->getInputManager()->injectInputEvent(& motionEvent, injectorPid, injectorUid, sync, timeoutMillis); @@ -2050,9 +2072,9 @@ static JNINativeMethod gInputManagerMethods[] = { (void*) android_server_InputManager_nativeRegisterInputChannel }, { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V", (void*) android_server_InputManager_nativeUnregisterInputChannel }, - { "nativeInjectKeyEvent", "(Landroid/view/KeyEvent;IIIZI)I", + { "nativeInjectKeyEvent", "(Landroid/view/KeyEvent;IIZI)I", (void*) android_server_InputManager_nativeInjectKeyEvent }, - { "nativeInjectMotionEvent", "(Landroid/view/MotionEvent;IIIZI)I", + { "nativeInjectMotionEvent", "(Landroid/view/MotionEvent;IIZI)I", (void*) android_server_InputManager_nativeInjectMotionEvent }, { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V", (void*) android_server_InputManager_nativeSetInputWindows }, |