InputDevice.java revision d4eaef7f4c5a5d281de4fff272cd33e892e26264
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
19import android.content.Context;
20import android.hardware.input.InputDeviceIdentifier;
21import android.hardware.input.InputManager;
22import android.os.Parcel;
23import android.os.Parcelable;
24import android.os.Vibrator;
25import android.os.NullVibrator;
26
27import java.util.ArrayList;
28import java.util.List;
29
30/**
31 * Describes the capabilities of a particular input device.
32 * <p>
33 * Each input device may support multiple classes of input.  For example, a multi-function
34 * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
35 * or other pointing device.
36 * </p><p>
37 * Some input devices present multiple distinguishable sources of input.
38 * Applications can query the framework about the characteristics of each distinct source.
39 * </p><p>
40 * As a further wrinkle, different kinds of input sources uses different coordinate systems
41 * to describe motion events.  Refer to the comments on the input source constants for
42 * the appropriate interpretation.
43 * </p>
44 */
45public final class InputDevice implements Parcelable {
46    private final int mId;
47    private final int mGeneration;
48    private final int mControllerNumber;
49    private final String mName;
50    private final int mVendorId;
51    private final int mProductId;
52    private final String mDescriptor;
53    private final InputDeviceIdentifier mIdentifier;
54    private final boolean mIsExternal;
55    private final int mSources;
56    private final int mKeyboardType;
57    private final KeyCharacterMap mKeyCharacterMap;
58    private final boolean mHasVibrator;
59    private final boolean mHasMicrophone;
60    private final boolean mHasButtonUnderPad;
61    private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
62
63    private Vibrator mVibrator; // guarded by mMotionRanges during initialization
64
65    /**
66     * A mask for input source classes.
67     *
68     * Each distinct input source constant has one or more input source class bits set to
69     * specify the desired interpretation for its input events.
70     */
71    public static final int SOURCE_CLASS_MASK = 0x000000ff;
72
73    /**
74     * The input source has no class.
75     *
76     * It is up to the application to determine how to handle the device based on the device type.
77     */
78    public static final int SOURCE_CLASS_NONE = 0x00000000;
79
80    /**
81     * The input source has buttons or keys.
82     * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}.
83     *
84     * A {@link KeyEvent} should be interpreted as a button or key press.
85     *
86     * Use {@link #getKeyCharacterMap} to query the device's button and key mappings.
87     */
88    public static final int SOURCE_CLASS_BUTTON = 0x00000001;
89
90    /**
91     * The input source is a pointing device associated with a display.
92     * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}.
93     *
94     * A {@link MotionEvent} should be interpreted as absolute coordinates in
95     * display units according to the {@link View} hierarchy.  Pointer down/up indicated when
96     * the finger touches the display or when the selection button is pressed/released.
97     *
98     * Use {@link #getMotionRange} to query the range of the pointing device.  Some devices permit
99     * touches outside the display area so the effective range may be somewhat smaller or larger
100     * than the actual display size.
101     */
102    public static final int SOURCE_CLASS_POINTER = 0x00000002;
103
104    /**
105     * The input source is a trackball navigation device.
106     * Examples: {@link #SOURCE_TRACKBALL}.
107     *
108     * A {@link MotionEvent} should be interpreted as relative movements in device-specific
109     * units used for navigation purposes.  Pointer down/up indicates when the selection button
110     * is pressed/released.
111     *
112     * Use {@link #getMotionRange} to query the range of motion.
113     */
114    public static final int SOURCE_CLASS_TRACKBALL = 0x00000004;
115
116    /**
117     * The input source is an absolute positioning device not associated with a display
118     * (unlike {@link #SOURCE_CLASS_POINTER}).
119     *
120     * A {@link MotionEvent} should be interpreted as absolute coordinates in
121     * device-specific surface units.
122     *
123     * Use {@link #getMotionRange} to query the range of positions.
124     */
125    public static final int SOURCE_CLASS_POSITION = 0x00000008;
126
127    /**
128     * The input source is a joystick.
129     *
130     * A {@link MotionEvent} should be interpreted as absolute joystick movements.
131     *
132     * Use {@link #getMotionRange} to query the range of positions.
133     */
134    public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;
135
136    /**
137     * The input source is unknown.
138     */
139    public static final int SOURCE_UNKNOWN = 0x00000000;
140
141    /**
142     * The input source is a keyboard.
143     *
144     * This source indicates pretty much anything that has buttons.  Use
145     * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys
146     * and can be used to enter text.
147     *
148     * @see #SOURCE_CLASS_BUTTON
149     */
150    public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
151
152    /**
153     * The input source is a DPad.
154     *
155     * @see #SOURCE_CLASS_BUTTON
156     */
157    public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON;
158
159    /**
160     * The input source is a game pad.
161     * (It may also be a {@link #SOURCE_JOYSTICK}).
162     *
163     * @see #SOURCE_CLASS_BUTTON
164     */
165    public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;
166
167    /**
168     * The input source is a touch screen pointing device.
169     *
170     * @see #SOURCE_CLASS_POINTER
171     */
172    public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;
173
174    /**
175     * The input source is a mouse pointing device.
176     * This code is also used for other mouse-like pointing devices such as trackpads
177     * and trackpoints.
178     *
179     * @see #SOURCE_CLASS_POINTER
180     */
181    public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER;
182
183    /**
184     * The input source is a stylus pointing device.
185     * <p>
186     * Note that this bit merely indicates that an input device is capable of obtaining
187     * input from a stylus.  To determine whether a given touch event was produced
188     * by a stylus, examine the tool type returned by {@link MotionEvent#getToolType(int)}
189     * for each individual pointer.
190     * </p><p>
191     * A single touch event may multiple pointers with different tool types,
192     * such as an event that has one pointer with tool type
193     * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
194     * {@link MotionEvent#TOOL_TYPE_STYLUS}.  So it is important to examine
195     * the tool type of each pointer, regardless of the source reported
196     * by {@link MotionEvent#getSource()}.
197     * </p>
198     *
199     * @see #SOURCE_CLASS_POINTER
200     */
201    public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER;
202
203    /**
204     * The input device is a Bluetooth stylus.
205     * <p>
206     * Note that this bit merely indicates that an input device is capable of
207     * obtaining input from a Bluetooth stylus.  To determine whether a given
208     * touch event was produced by a stylus, examine the tool type returned by
209     * {@link MotionEvent#getToolType(int)} for each individual pointer.
210     * </p><p>
211     * A single touch event may multiple pointers with different tool types,
212     * such as an event that has one pointer with tool type
213     * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
214     * {@link MotionEvent#TOOL_TYPE_STYLUS}.  So it is important to examine
215     * the tool type of each pointer, regardless of the source reported
216     * by {@link MotionEvent#getSource()}.
217     * </p><p>
218     * A bluetooth stylus generally receives its pressure and button state
219     * information from the stylus itself, and derives the rest from another
220     * source. For example, a Bluetooth stylus used in conjunction with a
221     * touchscreen would derive its contact position and pointer size from the
222     * touchscreen and may not be any more accurate than other tools such as
223     * fingers.
224     * </p>
225     *
226     * @see #SOURCE_STYLUS
227     * @see #SOURCE_CLASS_POINTER
228     */
229    public static final int SOURCE_BLUETOOTH_STYLUS =
230            0x00008000 | SOURCE_STYLUS;
231
232    /**
233     * The input source is a trackball.
234     *
235     * @see #SOURCE_CLASS_TRACKBALL
236     */
237    public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL;
238
239    /**
240     * The input source is a touch pad or digitizer tablet that is not
241     * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}).
242     *
243     * @see #SOURCE_CLASS_POSITION
244     */
245    public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;
246
247    /**
248     * The input source is a touch device whose motions should be interpreted as navigation events.
249     *
250     * For example, an upward swipe should be as an upward focus traversal in the same manner as
251     * pressing up on a D-Pad would be. Swipes to the left, right and down should be treated in a
252     * similar manner.
253     *
254     * @see #SOURCE_CLASS_NONE
255     */
256    public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;
257
258    /**
259     * The input source is a rotating encoder device whose motions should be interpreted as akin to
260     * those of a scroll wheel.
261     *
262     * @see #SOURCE_CLASS_NONE
263     * {@hide}
264     */
265    public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;
266
267    /**
268     * The input source is a joystick.
269     * (It may also be a {@link #SOURCE_GAMEPAD}).
270     *
271     * @see #SOURCE_CLASS_JOYSTICK
272     */
273    public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK;
274
275    /**
276     * The input source is a device connected through HDMI-based bus.
277     *
278     * The key comes in through HDMI-CEC or MHL signal line, and is treated as if it were
279     * generated by a locally connected DPAD or keyboard.
280     */
281    public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
282
283    /**
284     * A special input source constant that is used when filtering input devices
285     * to match devices that provide any type of input source.
286     */
287    public static final int SOURCE_ANY = 0xffffff00;
288
289    /**
290     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
291     *
292     * @see #getMotionRange
293     * @deprecated Use {@link MotionEvent#AXIS_X} instead.
294     */
295    @Deprecated
296    public static final int MOTION_RANGE_X = MotionEvent.AXIS_X;
297
298    /**
299     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}.
300     *
301     * @see #getMotionRange
302     * @deprecated Use {@link MotionEvent#AXIS_Y} instead.
303     */
304    @Deprecated
305    public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y;
306
307    /**
308     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}.
309     *
310     * @see #getMotionRange
311     * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead.
312     */
313    @Deprecated
314    public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE;
315
316    /**
317     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}.
318     *
319     * @see #getMotionRange
320     * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead.
321     */
322    @Deprecated
323    public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE;
324
325    /**
326     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}.
327     *
328     * @see #getMotionRange
329     * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead.
330     */
331    @Deprecated
332    public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR;
333
334    /**
335     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}.
336     *
337     * @see #getMotionRange
338     * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead.
339     */
340    @Deprecated
341    public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR;
342
343    /**
344     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}.
345     *
346     * @see #getMotionRange
347     * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead.
348     */
349    @Deprecated
350    public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR;
351
352    /**
353     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}.
354     *
355     * @see #getMotionRange
356     * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead.
357     */
358    @Deprecated
359    public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR;
360
361    /**
362     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}.
363     *
364     * @see #getMotionRange
365     * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead.
366     */
367    @Deprecated
368    public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION;
369
370    /**
371     * There is no keyboard.
372     */
373    public static final int KEYBOARD_TYPE_NONE = 0;
374
375    /**
376     * The keyboard is not fully alphabetic.  It may be a numeric keypad or an assortment
377     * of buttons that are not mapped as alphabetic keys suitable for text input.
378     */
379    public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1;
380
381    /**
382     * The keyboard supports a complement of alphabetic keys.
383     */
384    public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
385
386    public static final Parcelable.Creator<InputDevice> CREATOR =
387            new Parcelable.Creator<InputDevice>() {
388        public InputDevice createFromParcel(Parcel in) {
389            return new InputDevice(in);
390        }
391        public InputDevice[] newArray(int size) {
392            return new InputDevice[size];
393        }
394    };
395
396    // Called by native code.
397    private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
398            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
399            KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
400            boolean hasButtonUnderPad) {
401        mId = id;
402        mGeneration = generation;
403        mControllerNumber = controllerNumber;
404        mName = name;
405        mVendorId = vendorId;
406        mProductId = productId;
407        mDescriptor = descriptor;
408        mIsExternal = isExternal;
409        mSources = sources;
410        mKeyboardType = keyboardType;
411        mKeyCharacterMap = keyCharacterMap;
412        mHasVibrator = hasVibrator;
413        mHasMicrophone = hasMicrophone;
414        mHasButtonUnderPad = hasButtonUnderPad;
415        mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
416    }
417
418    private InputDevice(Parcel in) {
419        mId = in.readInt();
420        mGeneration = in.readInt();
421        mControllerNumber = in.readInt();
422        mName = in.readString();
423        mVendorId = in.readInt();
424        mProductId = in.readInt();
425        mDescriptor = in.readString();
426        mIsExternal = in.readInt() != 0;
427        mSources = in.readInt();
428        mKeyboardType = in.readInt();
429        mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in);
430        mHasVibrator = in.readInt() != 0;
431        mHasMicrophone = in.readInt() != 0;
432        mHasButtonUnderPad = in.readInt() != 0;
433        mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);
434
435        for (;;) {
436            int axis = in.readInt();
437            if (axis < 0) {
438                break;
439            }
440            addMotionRange(axis, in.readInt(), in.readFloat(), in.readFloat(), in.readFloat(),
441                    in.readFloat(), in.readFloat());
442        }
443    }
444
445    /**
446     * Gets information about the input device with the specified id.
447     * @param id The device id.
448     * @return The input device or null if not found.
449     */
450    public static InputDevice getDevice(int id) {
451        return InputManager.getInstance().getInputDevice(id);
452    }
453
454    /**
455     * Gets the ids of all input devices in the system.
456     * @return The input device ids.
457     */
458    public static int[] getDeviceIds() {
459        return InputManager.getInstance().getInputDeviceIds();
460    }
461
462    /**
463     * Gets the input device id.
464     * <p>
465     * Each input device receives a unique id when it is first configured
466     * by the system.  The input device id may change when the system is restarted or if the
467     * input device is disconnected, reconnected or reconfigured at any time.
468     * If you require a stable identifier for a device that persists across
469     * boots and reconfigurations, use {@link #getDescriptor()}.
470     * </p>
471     *
472     * @return The input device id.
473     */
474    public int getId() {
475        return mId;
476    }
477
478    /**
479     * The controller number for a given input device.
480     * <p>
481     * Each gamepad or joystick is given a unique, positive controller number when initially
482     * configured by the system. This number may change due to events such as device disconnects /
483     * reconnects or user initiated reassignment. Any change in number will trigger an event that
484     * can be observed by registering an {@link InputManager.InputDeviceListener}.
485     * </p>
486     * <p>
487     * All input devices which are not gamepads or joysticks will be assigned a controller number
488     * of 0.
489     * </p>
490     *
491     * @return The controller number of the device.
492     */
493    public int getControllerNumber() {
494        return mControllerNumber;
495    }
496
497    /**
498     * The set of identifying information for type of input device. This
499     * information can be used by the system to configure appropriate settings
500     * for the device.
501     *
502     * @return The identifier object for this device
503     * @hide
504     */
505    public InputDeviceIdentifier getIdentifier() {
506        return mIdentifier;
507    }
508
509    /**
510     * Gets a generation number for this input device.
511     * The generation number is incremented whenever the device is reconfigured and its
512     * properties may have changed.
513     *
514     * @return The generation number.
515     *
516     * @hide
517     */
518    public int getGeneration() {
519        return mGeneration;
520    }
521
522    /**
523     * Gets the vendor id for the given device, if available.
524     * <p>
525     * A vendor id uniquely identifies the company who manufactured the device. A value of 0 will
526     * be assigned where a vendor id is not available.
527     * </p>
528     *
529     * @return The vendor id of a given device
530     */
531    public int getVendorId() {
532        return mVendorId;
533    }
534
535    /**
536     * Gets the product id for the given device, if available.
537     * <p>
538     * A product id uniquely identifies which product within the address space of a given vendor,
539     * identified by the device's vendor id. A value of 0 will be assigned where a product id is
540     * not available.
541     * </p>
542     *
543     * @return The product id of a given device
544     */
545    public int getProductId() {
546        return mProductId;
547    }
548
549    /**
550     * Gets the input device descriptor, which is a stable identifier for an input device.
551     * <p>
552     * An input device descriptor uniquely identifies an input device.  Its value
553     * is intended to be persistent across system restarts, and should not change even
554     * if the input device is disconnected, reconnected or reconfigured at any time.
555     * </p><p>
556     * It is possible for there to be multiple {@link InputDevice} instances that have the
557     * same input device descriptor.  This might happen in situations where a single
558     * human input device registers multiple {@link InputDevice} instances (HID collections)
559     * that describe separate features of the device, such as a keyboard that also
560     * has a trackpad.  Alternately, it may be that the input devices are simply
561     * indistinguishable, such as two keyboards made by the same manufacturer.
562     * </p><p>
563     * The input device descriptor returned by {@link #getDescriptor} should only be
564     * used when an application needs to remember settings associated with a particular
565     * input device.  For all other purposes when referring to a logical
566     * {@link InputDevice} instance at runtime use the id returned by {@link #getId()}.
567     * </p>
568     *
569     * @return The input device descriptor.
570     */
571    public String getDescriptor() {
572        return mDescriptor;
573    }
574
575    /**
576     * Returns true if the device is a virtual input device rather than a real one,
577     * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}).
578     * <p>
579     * Virtual input devices are provided to implement system-level functionality
580     * and should not be seen or configured by users.
581     * </p>
582     *
583     * @return True if the device is virtual.
584     *
585     * @see KeyCharacterMap#VIRTUAL_KEYBOARD
586     */
587    public boolean isVirtual() {
588        return mId < 0;
589    }
590
591    /**
592     * Returns true if the device is external (connected to USB or Bluetooth or some other
593     * peripheral bus), otherwise it is built-in.
594     *
595     * @return True if the device is external.
596     *
597     * @hide
598     */
599    public boolean isExternal() {
600        return mIsExternal;
601    }
602
603    /**
604     * Returns true if the device is a full keyboard.
605     *
606     * @return True if the device is a full keyboard.
607     *
608     * @hide
609     */
610    public boolean isFullKeyboard() {
611        return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD
612                && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC;
613    }
614
615    /**
616     * Gets the name of this input device.
617     * @return The input device name.
618     */
619    public String getName() {
620        return mName;
621    }
622
623    /**
624     * Gets the input sources supported by this input device as a combined bitfield.
625     * @return The supported input sources.
626     */
627    public int getSources() {
628        return mSources;
629    }
630
631    /**
632     * Determines whether the input device supports the given source or sources.
633     *
634     * @param source The input source or sources to check against. This can be a generic device
635     * type such as {@link InputDevice#SOURCE_MOUSE}, a more generic device class, such as
636     * {@link InputDevice#SOURCE_CLASS_POINTER}, or a combination of sources bitwise ORed together.
637     * @return Whether the device can produce all of the given sources.
638     */
639    public boolean supportsSource(int source) {
640        return (mSources & source) == source;
641    }
642
643    /**
644     * Gets the keyboard type.
645     * @return The keyboard type.
646     */
647    public int getKeyboardType() {
648        return mKeyboardType;
649    }
650
651    /**
652     * Gets the key character map associated with this input device.
653     * @return The key character map.
654     */
655    public KeyCharacterMap getKeyCharacterMap() {
656        return mKeyCharacterMap;
657    }
658
659    /**
660     * Gets whether the device is capable of producing the list of keycodes.
661     * @param keys The list of android keycodes to check for.
662     * @return An array of booleans where each member specifies whether the device is capable of
663     * generating the keycode given by the corresponding value at the same index in the keys array.
664     */
665    public boolean[] hasKeys(int... keys) {
666        return InputManager.getInstance().deviceHasKeys(mId, keys);
667    }
668
669    /**
670     * Gets information about the range of values for a particular {@link MotionEvent} axis.
671     * If the device supports multiple sources, the same axis may have different meanings
672     * for each source.  Returns information about the first axis found for any source.
673     * To obtain information about the axis for a specific source, use
674     * {@link #getMotionRange(int, int)}.
675     *
676     * @param axis The axis constant.
677     * @return The range of values, or null if the requested axis is not
678     * supported by the device.
679     *
680     * @see MotionEvent#AXIS_X
681     * @see MotionEvent#AXIS_Y
682     */
683    public MotionRange getMotionRange(int axis) {
684        final int numRanges = mMotionRanges.size();
685        for (int i = 0; i < numRanges; i++) {
686            final MotionRange range = mMotionRanges.get(i);
687            if (range.mAxis == axis) {
688                return range;
689            }
690        }
691        return null;
692    }
693
694    /**
695     * Gets information about the range of values for a particular {@link MotionEvent} axis
696     * used by a particular source on the device.
697     * If the device supports multiple sources, the same axis may have different meanings
698     * for each source.
699     *
700     * @param axis The axis constant.
701     * @param source The source for which to return information.
702     * @return The range of values, or null if the requested axis is not
703     * supported by the device.
704     *
705     * @see MotionEvent#AXIS_X
706     * @see MotionEvent#AXIS_Y
707     */
708    public MotionRange getMotionRange(int axis, int source) {
709        final int numRanges = mMotionRanges.size();
710        for (int i = 0; i < numRanges; i++) {
711            final MotionRange range = mMotionRanges.get(i);
712            if (range.mAxis == axis && range.mSource == source) {
713                return range;
714            }
715        }
716        return null;
717    }
718
719    /**
720     * Gets the ranges for all axes supported by the device.
721     * @return The motion ranges for the device.
722     *
723     * @see #getMotionRange(int, int)
724     */
725    public List<MotionRange> getMotionRanges() {
726        return mMotionRanges;
727    }
728
729    // Called from native code.
730    private void addMotionRange(int axis, int source,
731            float min, float max, float flat, float fuzz, float resolution) {
732        mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
733    }
734
735    /**
736     * Gets the vibrator service associated with the device, if there is one.
737     * Even if the device does not have a vibrator, the result is never null.
738     * Use {@link Vibrator#hasVibrator} to determine whether a vibrator is
739     * present.
740     *
741     * Note that the vibrator associated with the device may be different from
742     * the system vibrator.  To obtain an instance of the system vibrator instead, call
743     * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
744     *
745     * @return The vibrator service associated with the device, never null.
746     */
747    public Vibrator getVibrator() {
748        synchronized (mMotionRanges) {
749            if (mVibrator == null) {
750                if (mHasVibrator) {
751                    mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId);
752                } else {
753                    mVibrator = NullVibrator.getInstance();
754                }
755            }
756            return mVibrator;
757        }
758    }
759
760    /**
761     * Reports whether the device has a built-in microphone.
762     * @return Whether the device has a built-in microphone.
763     */
764    public boolean hasMicrophone() {
765        return mHasMicrophone;
766    }
767
768    /**
769     * Reports whether the device has a button under its touchpad
770     * @return Whether the device has a button under its touchpad
771     * @hide
772     */
773    public boolean hasButtonUnderPad() {
774        return mHasButtonUnderPad;
775    }
776
777    /**
778     * Sets the current pointer shape.
779     * @param pointerShape the id of the pointer icon.
780     * @hide
781     */
782    public void setPointerShape(int pointerShape) {
783        InputManager.getInstance().setPointerIconShape(pointerShape);
784    }
785
786    /**
787     * Specifies the current custom pointer.
788     * @param icon the icon data.
789     * @hide
790     */
791    public void setCustomPointerIcon(PointerIcon icon) {
792        InputManager.getInstance().setCustomPointerIcon(icon);
793    }
794
795    /**
796     * Provides information about the range of values for a particular {@link MotionEvent} axis.
797     *
798     * @see InputDevice#getMotionRange(int)
799     */
800    public static final class MotionRange {
801        private int mAxis;
802        private int mSource;
803        private float mMin;
804        private float mMax;
805        private float mFlat;
806        private float mFuzz;
807        private float mResolution;
808
809        private MotionRange(int axis, int source, float min, float max, float flat, float fuzz,
810                float resolution) {
811            mAxis = axis;
812            mSource = source;
813            mMin = min;
814            mMax = max;
815            mFlat = flat;
816            mFuzz = fuzz;
817            mResolution = resolution;
818        }
819
820        /**
821         * Gets the axis id.
822         * @return The axis id.
823         */
824        public int getAxis() {
825            return mAxis;
826        }
827
828        /**
829         * Gets the source for which the axis is defined.
830         * @return The source.
831         */
832        public int getSource() {
833            return mSource;
834        }
835
836
837        /**
838         * Determines whether the event is from the given source.
839         *
840         * @param source The input source to check against. This can be a specific device type,
841         * such as {@link InputDevice#SOURCE_TOUCH_NAVIGATION}, or a more generic device class,
842         * such as {@link InputDevice#SOURCE_CLASS_POINTER}.
843         * @return Whether the event is from the given source.
844         */
845        public boolean isFromSource(int source) {
846            return (getSource() & source) == source;
847        }
848
849        /**
850         * Gets the inclusive minimum value for the axis.
851         * @return The inclusive minimum value.
852         */
853        public float getMin() {
854            return mMin;
855        }
856
857        /**
858         * Gets the inclusive maximum value for the axis.
859         * @return The inclusive maximum value.
860         */
861        public float getMax() {
862            return mMax;
863        }
864
865        /**
866         * Gets the range of the axis (difference between maximum and minimum).
867         * @return The range of values.
868         */
869        public float getRange() {
870            return mMax - mMin;
871        }
872
873        /**
874         * Gets the extent of the center flat position with respect to this axis.
875         * <p>
876         * For example, a flat value of 8 means that the center position is between -8 and +8.
877         * This value is mainly useful for calibrating self-centering devices.
878         * </p>
879         * @return The extent of the center flat position.
880         */
881        public float getFlat() {
882            return mFlat;
883        }
884
885        /**
886         * Gets the error tolerance for input device measurements with respect to this axis.
887         * <p>
888         * For example, a value of 2 indicates that the measured value may be up to +/- 2 units
889         * away from the actual value due to noise and device sensitivity limitations.
890         * </p>
891         * @return The error tolerance.
892         */
893        public float getFuzz() {
894            return mFuzz;
895        }
896
897        /**
898         * Gets the resolution for input device measurements with respect to this axis.
899         * @return The resolution in units per millimeter, or units per radian for rotational axes.
900         */
901        public float getResolution() {
902            return mResolution;
903        }
904    }
905
906    @Override
907    public void writeToParcel(Parcel out, int flags) {
908        out.writeInt(mId);
909        out.writeInt(mGeneration);
910        out.writeInt(mControllerNumber);
911        out.writeString(mName);
912        out.writeInt(mVendorId);
913        out.writeInt(mProductId);
914        out.writeString(mDescriptor);
915        out.writeInt(mIsExternal ? 1 : 0);
916        out.writeInt(mSources);
917        out.writeInt(mKeyboardType);
918        mKeyCharacterMap.writeToParcel(out, flags);
919        out.writeInt(mHasVibrator ? 1 : 0);
920        out.writeInt(mHasMicrophone ? 1 : 0);
921        out.writeInt(mHasButtonUnderPad ? 1 : 0);
922
923        final int numRanges = mMotionRanges.size();
924        for (int i = 0; i < numRanges; i++) {
925            MotionRange range = mMotionRanges.get(i);
926            out.writeInt(range.mAxis);
927            out.writeInt(range.mSource);
928            out.writeFloat(range.mMin);
929            out.writeFloat(range.mMax);
930            out.writeFloat(range.mFlat);
931            out.writeFloat(range.mFuzz);
932            out.writeFloat(range.mResolution);
933        }
934        out.writeInt(-1);
935    }
936
937    @Override
938    public int describeContents() {
939        return 0;
940    }
941
942    @Override
943    public String toString() {
944        StringBuilder description = new StringBuilder();
945        description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
946        description.append("  Descriptor: ").append(mDescriptor).append("\n");
947        description.append("  Generation: ").append(mGeneration).append("\n");
948        description.append("  Location: ").append(mIsExternal ? "external" : "built-in").append("\n");
949
950        description.append("  Keyboard Type: ");
951        switch (mKeyboardType) {
952            case KEYBOARD_TYPE_NONE:
953                description.append("none");
954                break;
955            case KEYBOARD_TYPE_NON_ALPHABETIC:
956                description.append("non-alphabetic");
957                break;
958            case KEYBOARD_TYPE_ALPHABETIC:
959                description.append("alphabetic");
960                break;
961        }
962        description.append("\n");
963
964        description.append("  Has Vibrator: ").append(mHasVibrator).append("\n");
965
966        description.append("  Has mic: ").append(mHasMicrophone).append("\n");
967
968        description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
969        appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
970        appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
971        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
972        appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
973        appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus");
974        appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
975        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
976        appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick");
977        appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
978        description.append(" )\n");
979
980        final int numAxes = mMotionRanges.size();
981        for (int i = 0; i < numAxes; i++) {
982            MotionRange range = mMotionRanges.get(i);
983            description.append("    ").append(MotionEvent.axisToString(range.mAxis));
984            description.append(": source=0x").append(Integer.toHexString(range.mSource));
985            description.append(" min=").append(range.mMin);
986            description.append(" max=").append(range.mMax);
987            description.append(" flat=").append(range.mFlat);
988            description.append(" fuzz=").append(range.mFuzz);
989            description.append(" resolution=").append(range.mResolution);
990            description.append("\n");
991        }
992        return description.toString();
993    }
994
995    private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
996            String sourceName) {
997        if ((mSources & source) == source) {
998            description.append(" ");
999            description.append(sourceName);
1000        }
1001    }
1002}
1003