• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package android.view;
18 
19 import android.os.Parcel;
20 import android.os.Parcelable;
21 import android.os.RemoteException;
22 import android.os.ServiceManager;
23 
24 import java.util.ArrayList;
25 import java.util.List;
26 
27 /**
28  * Describes the capabilities of a particular input device.
29  * <p>
30  * Each input device may support multiple classes of input.  For example, a multifunction
31  * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
32  * or other pointing device.
33  * </p><p>
34  * Some input devices present multiple distinguishable sources of input.
35  * Applications can query the framework about the characteristics of each distinct source.
36  * </p><p>
37  * As a further wrinkle, different kinds of input sources uses different coordinate systems
38  * to describe motion events.  Refer to the comments on the input source constants for
39  * the appropriate interpretation.
40  * </p>
41  */
42 public final class InputDevice implements Parcelable {
43     private int mId;
44     private String mName;
45     private int mSources;
46     private int mKeyboardType;
47 
48     private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();
49 
50     /**
51      * A mask for input source classes.
52      *
53      * Each distinct input source constant has one or more input source class bits set to
54      * specify the desired interpretation for its input events.
55      */
56     public static final int SOURCE_CLASS_MASK = 0x000000ff;
57 
58     /**
59      * The input source has buttons or keys.
60      * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}.
61      *
62      * A {@link KeyEvent} should be interpreted as a button or key press.
63      *
64      * Use {@link #getKeyCharacterMap} to query the device's button and key mappings.
65      */
66     public static final int SOURCE_CLASS_BUTTON = 0x00000001;
67 
68     /**
69      * The input source is a pointing device associated with a display.
70      * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}.
71      *
72      * A {@link MotionEvent} should be interpreted as absolute coordinates in
73      * display units according to the {@link View} hierarchy.  Pointer down/up indicated when
74      * the finger touches the display or when the selection button is pressed/released.
75      *
76      * Use {@link #getMotionRange} to query the range of the pointing device.  Some devices permit
77      * touches outside the display area so the effective range may be somewhat smaller or larger
78      * than the actual display size.
79      */
80     public static final int SOURCE_CLASS_POINTER = 0x00000002;
81 
82     /**
83      * The input source is a trackball navigation device.
84      * Examples: {@link #SOURCE_TRACKBALL}.
85      *
86      * A {@link MotionEvent} should be interpreted as relative movements in device-specific
87      * units used for navigation purposes.  Pointer down/up indicates when the selection button
88      * is pressed/released.
89      *
90      * Use {@link #getMotionRange} to query the range of motion.
91      */
92     public static final int SOURCE_CLASS_TRACKBALL = 0x00000004;
93 
94     /**
95      * The input source is an absolute positioning device not associated with a display
96      * (unlike {@link #SOURCE_CLASS_POINTER}).
97      *
98      * A {@link MotionEvent} should be interpreted as absolute coordinates in
99      * device-specific surface units.
100      *
101      * Use {@link #getMotionRange} to query the range of positions.
102      */
103     public static final int SOURCE_CLASS_POSITION = 0x00000008;
104 
105     /**
106      * The input source is a joystick.
107      *
108      * A {@link MotionEvent} should be interpreted as absolute joystick movements.
109      *
110      * Use {@link #getMotionRange} to query the range of positions.
111      */
112     public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;
113 
114     /**
115      * The input source is unknown.
116      */
117     public static final int SOURCE_UNKNOWN = 0x00000000;
118 
119     /**
120      * The input source is a keyboard.
121      *
122      * @see #SOURCE_CLASS_BUTTON
123      */
124     public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;
125 
126     /**
127      * The input source is a DPad.
128      *
129      * @see #SOURCE_CLASS_BUTTON
130      */
131     public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON;
132 
133     /**
134      * The input source is a game pad.
135      * (It may also be a {@link #SOURCE_JOYSTICK}).
136      *
137      * @see #SOURCE_CLASS_BUTTON
138      */
139     public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;
140 
141     /**
142      * The input source is a touch screen pointing device.
143      *
144      * @see #SOURCE_CLASS_POINTER
145      */
146     public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;
147 
148     /**
149      * The input source is a mouse pointing device.
150      * This code is also used for other mouse-like pointing devices such as trackpads
151      * and trackpoints.
152      *
153      * @see #SOURCE_CLASS_POINTER
154      */
155     public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER;
156 
157     /**
158      * The input source is a stylus pointing device.
159      *
160      * @see #SOURCE_CLASS_POINTER
161      */
162     public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER;
163 
164     /**
165      * The input source is a trackball.
166      *
167      * @see #SOURCE_CLASS_TRACKBALL
168      */
169     public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL;
170 
171     /**
172      * The input source is a touch pad or digitizer tablet that is not
173      * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}).
174      *
175      * @see #SOURCE_CLASS_POSITION
176      */
177     public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;
178 
179     /**
180      * The input source is a joystick.
181      * (It may also be a {@link #SOURCE_GAMEPAD}).
182      *
183      * @see #SOURCE_CLASS_JOYSTICK
184      */
185     public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK;
186 
187     /**
188      * A special input source constant that is used when filtering input devices
189      * to match devices that provide any type of input source.
190      */
191     public static final int SOURCE_ANY = 0xffffff00;
192 
193     /**
194      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
195      *
196      * @see #getMotionRange
197      * @deprecated Use {@link MotionEvent#AXIS_X} instead.
198      */
199     @Deprecated
200     public static final int MOTION_RANGE_X = MotionEvent.AXIS_X;
201 
202     /**
203      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}.
204      *
205      * @see #getMotionRange
206      * @deprecated Use {@link MotionEvent#AXIS_Y} instead.
207      */
208     @Deprecated
209     public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y;
210 
211     /**
212      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}.
213      *
214      * @see #getMotionRange
215      * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead.
216      */
217     @Deprecated
218     public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE;
219 
220     /**
221      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}.
222      *
223      * @see #getMotionRange
224      * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead.
225      */
226     @Deprecated
227     public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE;
228 
229     /**
230      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}.
231      *
232      * @see #getMotionRange
233      * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead.
234      */
235     @Deprecated
236     public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR;
237 
238     /**
239      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}.
240      *
241      * @see #getMotionRange
242      * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead.
243      */
244     @Deprecated
245     public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR;
246 
247     /**
248      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}.
249      *
250      * @see #getMotionRange
251      * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead.
252      */
253     @Deprecated
254     public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR;
255 
256     /**
257      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}.
258      *
259      * @see #getMotionRange
260      * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead.
261      */
262     @Deprecated
263     public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR;
264 
265     /**
266      * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}.
267      *
268      * @see #getMotionRange
269      * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead.
270      */
271     @Deprecated
272     public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION;
273 
274     /**
275      * There is no keyboard.
276      */
277     public static final int KEYBOARD_TYPE_NONE = 0;
278 
279     /**
280      * The keyboard is not fully alphabetic.  It may be a numeric keypad or an assortment
281      * of buttons that are not mapped as alphabetic keys suitable for text input.
282      */
283     public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1;
284 
285     /**
286      * The keyboard supports a complement of alphabetic keys.
287      */
288     public static final int KEYBOARD_TYPE_ALPHABETIC = 2;
289 
290     // Called by native code.
InputDevice()291     private InputDevice() {
292     }
293 
294     /**
295      * Gets information about the input device with the specified id.
296      * @param id The device id.
297      * @return The input device or null if not found.
298      */
getDevice(int id)299     public static InputDevice getDevice(int id) {
300         IWindowManager wm = Display.getWindowManager();
301         try {
302             return wm.getInputDevice(id);
303         } catch (RemoteException ex) {
304             throw new RuntimeException(
305                     "Could not get input device information from Window Manager.", ex);
306         }
307     }
308 
309     /**
310      * Gets the ids of all input devices in the system.
311      * @return The input device ids.
312      */
getDeviceIds()313     public static int[] getDeviceIds() {
314         IWindowManager wm = Display.getWindowManager();
315         try {
316             return wm.getInputDeviceIds();
317         } catch (RemoteException ex) {
318             throw new RuntimeException(
319                     "Could not get input device ids from Window Manager.", ex);
320         }
321     }
322 
323     /**
324      * Gets the input device id.
325      * @return The input device id.
326      */
getId()327     public int getId() {
328         return mId;
329     }
330 
331     /**
332      * Gets the name of this input device.
333      * @return The input device name.
334      */
getName()335     public String getName() {
336         return mName;
337     }
338 
339     /**
340      * Gets the input sources supported by this input device as a combined bitfield.
341      * @return The supported input sources.
342      */
getSources()343     public int getSources() {
344         return mSources;
345     }
346 
347     /**
348      * Gets the keyboard type.
349      * @return The keyboard type.
350      */
getKeyboardType()351     public int getKeyboardType() {
352         return mKeyboardType;
353     }
354 
355     /**
356      * Gets the key character map associated with this input device.
357      * @return The key character map.
358      */
getKeyCharacterMap()359     public KeyCharacterMap getKeyCharacterMap() {
360         return KeyCharacterMap.load(mId);
361     }
362 
363     /**
364      * Gets information about the range of values for a particular {@link MotionEvent} axis.
365      * If the device supports multiple sources, the same axis may have different meanings
366      * for each source.  Returns information about the first axis found for any source.
367      * To obtain information about the axis for a specific source, use
368      * {@link #getMotionRange(int, int)}.
369      *
370      * @param axis The axis constant.
371      * @return The range of values, or null if the requested axis is not
372      * supported by the device.
373      *
374      * @see MotionEvent#AXIS_X
375      * @see MotionEvent#AXIS_Y
376      * @see #getSupportedAxes()
377      */
getMotionRange(int axis)378     public MotionRange getMotionRange(int axis) {
379         final int numRanges = mMotionRanges.size();
380         for (int i = 0; i < numRanges; i++) {
381             final MotionRange range = mMotionRanges.get(i);
382             if (range.mAxis == axis) {
383                 return range;
384             }
385         }
386         return null;
387     }
388 
389     /**
390      * Gets information about the range of values for a particular {@link MotionEvent} axis
391      * used by a particular source on the device.
392      * If the device supports multiple sources, the same axis may have different meanings
393      * for each source.
394      *
395      * @param axis The axis constant.
396      * @param source The source for which to return information.
397      * @return The range of values, or null if the requested axis is not
398      * supported by the device.
399      *
400      * @see MotionEvent#AXIS_X
401      * @see MotionEvent#AXIS_Y
402      * @see #getSupportedAxes()
403      */
getMotionRange(int axis, int source)404     public MotionRange getMotionRange(int axis, int source) {
405         final int numRanges = mMotionRanges.size();
406         for (int i = 0; i < numRanges; i++) {
407             final MotionRange range = mMotionRanges.get(i);
408             if (range.mAxis == axis && range.mSource == source) {
409                 return range;
410             }
411         }
412         return null;
413     }
414 
415     /**
416      * Gets the ranges for all axes supported by the device.
417      * @return The motion ranges for the device.
418      *
419      * @see #getMotionRange(int, int)
420      */
getMotionRanges()421     public List<MotionRange> getMotionRanges() {
422         return mMotionRanges;
423     }
424 
addMotionRange(int axis, int source, float min, float max, float flat, float fuzz)425     private void addMotionRange(int axis, int source,
426             float min, float max, float flat, float fuzz) {
427         mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz));
428     }
429 
430     /**
431      * Provides information about the range of values for a particular {@link MotionEvent} axis.
432      *
433      * @see InputDevice#getMotionRange(int)
434      */
435     public static final class MotionRange {
436         private int mAxis;
437         private int mSource;
438         private float mMin;
439         private float mMax;
440         private float mFlat;
441         private float mFuzz;
442 
MotionRange(int axis, int source, float min, float max, float flat, float fuzz)443         private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) {
444             mAxis = axis;
445             mSource = source;
446             mMin = min;
447             mMax = max;
448             mFlat = flat;
449             mFuzz = fuzz;
450         }
451 
452         /**
453          * Gets the axis id.
454          * @return The axis id.
455          */
getAxis()456         public int getAxis() {
457             return mAxis;
458         }
459 
460         /**
461          * Gets the source for which the axis is defined.
462          * @return The source.
463          */
getSource()464         public int getSource() {
465             return mSource;
466         }
467 
468         /**
469          * Gets the inclusive minimum value for the axis.
470          * @return The inclusive minimum value.
471          */
getMin()472         public float getMin() {
473             return mMin;
474         }
475 
476         /**
477          * Gets the inclusive maximum value for the axis.
478          * @return The inclusive maximum value.
479          */
getMax()480         public float getMax() {
481             return mMax;
482         }
483 
484         /**
485          * Gets the range of the axis (difference between maximum and minimum).
486          * @return The range of values.
487          */
getRange()488         public float getRange() {
489             return mMax - mMin;
490         }
491 
492         /**
493          * Gets the extent of the center flat position with respect to this axis.
494          * <p>
495          * For example, a flat value of 8 means that the center position is between -8 and +8.
496          * This value is mainly useful for calibrating self-centering devices.
497          * </p>
498          * @return The extent of the center flat position.
499          */
getFlat()500         public float getFlat() {
501             return mFlat;
502         }
503 
504         /**
505          * Gets the error tolerance for input device measurements with respect to this axis.
506          * <p>
507          * For example, a value of 2 indicates that the measured value may be up to +/- 2 units
508          * away from the actual value due to noise and device sensitivity limitations.
509          * </p>
510          * @return The error tolerance.
511          */
getFuzz()512         public float getFuzz() {
513             return mFuzz;
514         }
515     }
516 
517     public static final Parcelable.Creator<InputDevice> CREATOR
518             = new Parcelable.Creator<InputDevice>() {
519         public InputDevice createFromParcel(Parcel in) {
520             InputDevice result = new InputDevice();
521             result.readFromParcel(in);
522             return result;
523         }
524 
525         public InputDevice[] newArray(int size) {
526             return new InputDevice[size];
527         }
528     };
529 
readFromParcel(Parcel in)530     private void readFromParcel(Parcel in) {
531         mId = in.readInt();
532         mName = in.readString();
533         mSources = in.readInt();
534         mKeyboardType = in.readInt();
535 
536         for (;;) {
537             int axis = in.readInt();
538             if (axis < 0) {
539                 break;
540             }
541             addMotionRange(axis, in.readInt(),
542                     in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
543         }
544     }
545 
546     @Override
writeToParcel(Parcel out, int flags)547     public void writeToParcel(Parcel out, int flags) {
548         out.writeInt(mId);
549         out.writeString(mName);
550         out.writeInt(mSources);
551         out.writeInt(mKeyboardType);
552 
553         final int numRanges = mMotionRanges.size();
554         for (int i = 0; i < numRanges; i++) {
555             MotionRange range = mMotionRanges.get(i);
556             out.writeInt(range.mAxis);
557             out.writeInt(range.mSource);
558             out.writeFloat(range.mMin);
559             out.writeFloat(range.mMax);
560             out.writeFloat(range.mFlat);
561             out.writeFloat(range.mFuzz);
562         }
563         out.writeInt(-1);
564     }
565 
566     @Override
describeContents()567     public int describeContents() {
568         return 0;
569     }
570 
571     @Override
toString()572     public String toString() {
573         StringBuilder description = new StringBuilder();
574         description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
575 
576         description.append("  Keyboard Type: ");
577         switch (mKeyboardType) {
578             case KEYBOARD_TYPE_NONE:
579                 description.append("none");
580                 break;
581             case KEYBOARD_TYPE_NON_ALPHABETIC:
582                 description.append("non-alphabetic");
583                 break;
584             case KEYBOARD_TYPE_ALPHABETIC:
585                 description.append("alphabetic");
586                 break;
587         }
588         description.append("\n");
589 
590         description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
591         appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
592         appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
593         appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
594         appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
595         appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus");
596         appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
597         appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
598         appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick");
599         appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
600         description.append(" )\n");
601 
602         final int numAxes = mMotionRanges.size();
603         for (int i = 0; i < numAxes; i++) {
604             MotionRange range = mMotionRanges.get(i);
605             description.append("    ").append(MotionEvent.axisToString(range.mAxis));
606             description.append(": source=0x").append(Integer.toHexString(range.mSource));
607             description.append(" min=").append(range.mMin);
608             description.append(" max=").append(range.mMax);
609             description.append(" flat=").append(range.mFlat);
610             description.append(" fuzz=").append(range.mFuzz);
611             description.append("\n");
612         }
613         return description.toString();
614     }
615 
appendSourceDescriptionIfApplicable(StringBuilder description, int source, String sourceName)616     private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
617             String sourceName) {
618         if ((mSources & source) == source) {
619             description.append(" ");
620             description.append(sourceName);
621         }
622     }
623 }
624