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