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