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