/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.view;

import android.annotation.RequiresPermission;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.os.Build;
import android.os.NullVibrator;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Vibrator;

import java.util.ArrayList;
import java.util.List;

/**
 * Describes the capabilities of a particular input device.
 * <p>
 * Each input device may support multiple classes of input.  For example, a multi-function
 * keyboard may compose the capabilities of a standard keyboard together with a track pad mouse
 * or other pointing device.
 * </p><p>
 * Some input devices present multiple distinguishable sources of input.
 * Applications can query the framework about the characteristics of each distinct source.
 * </p><p>
 * As a further wrinkle, different kinds of input sources uses different coordinate systems
 * to describe motion events.  Refer to the comments on the input source constants for
 * the appropriate interpretation.
 * </p>
 */
public final class InputDevice implements Parcelable {
    private final int mId;
    private final int mGeneration;
    private final int mControllerNumber;
    private final String mName;
    private final int mVendorId;
    private final int mProductId;
    private final String mDescriptor;
    private final InputDeviceIdentifier mIdentifier;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
    private final boolean mIsExternal;
    private final int mSources;
    private final int mKeyboardType;
    private final KeyCharacterMap mKeyCharacterMap;
    private final boolean mHasVibrator;
    private final boolean mHasMicrophone;
    private final boolean mHasButtonUnderPad;
    private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();

    private Vibrator mVibrator; // guarded by mMotionRanges during initialization

    /**
     * A mask for input source classes.
     *
     * Each distinct input source constant has one or more input source class bits set to
     * specify the desired interpretation for its input events.
     */
    public static final int SOURCE_CLASS_MASK = 0x000000ff;

    /**
     * The input source has no class.
     *
     * It is up to the application to determine how to handle the device based on the device type.
     */
    public static final int SOURCE_CLASS_NONE = 0x00000000;

    /**
     * The input source has buttons or keys.
     * Examples: {@link #SOURCE_KEYBOARD}, {@link #SOURCE_DPAD}.
     *
     * A {@link KeyEvent} should be interpreted as a button or key press.
     *
     * Use {@link #getKeyCharacterMap} to query the device's button and key mappings.
     */
    public static final int SOURCE_CLASS_BUTTON = 0x00000001;

    /**
     * The input source is a pointing device associated with a display.
     * Examples: {@link #SOURCE_TOUCHSCREEN}, {@link #SOURCE_MOUSE}.
     *
     * A {@link MotionEvent} should be interpreted as absolute coordinates in
     * display units according to the {@link View} hierarchy.  Pointer down/up indicated when
     * the finger touches the display or when the selection button is pressed/released.
     *
     * Use {@link #getMotionRange} to query the range of the pointing device.  Some devices permit
     * touches outside the display area so the effective range may be somewhat smaller or larger
     * than the actual display size.
     */
    public static final int SOURCE_CLASS_POINTER = 0x00000002;

    /**
     * The input source is a trackball navigation device.
     * Examples: {@link #SOURCE_TRACKBALL}.
     *
     * A {@link MotionEvent} should be interpreted as relative movements in device-specific
     * units used for navigation purposes.  Pointer down/up indicates when the selection button
     * is pressed/released.
     *
     * Use {@link #getMotionRange} to query the range of motion.
     */
    public static final int SOURCE_CLASS_TRACKBALL = 0x00000004;

    /**
     * The input source is an absolute positioning device not associated with a display
     * (unlike {@link #SOURCE_CLASS_POINTER}).
     *
     * A {@link MotionEvent} should be interpreted as absolute coordinates in
     * device-specific surface units.
     *
     * Use {@link #getMotionRange} to query the range of positions.
     */
    public static final int SOURCE_CLASS_POSITION = 0x00000008;

    /**
     * The input source is a joystick.
     *
     * A {@link MotionEvent} should be interpreted as absolute joystick movements.
     *
     * Use {@link #getMotionRange} to query the range of positions.
     */
    public static final int SOURCE_CLASS_JOYSTICK = 0x00000010;

    /**
     * The input source is unknown.
     */
    public static final int SOURCE_UNKNOWN = 0x00000000;

    /**
     * The input source is a keyboard.
     *
     * This source indicates pretty much anything that has buttons.  Use
     * {@link #getKeyboardType()} to determine whether the keyboard has alphabetic keys
     * and can be used to enter text.
     *
     * @see #SOURCE_CLASS_BUTTON
     */
    public static final int SOURCE_KEYBOARD = 0x00000100 | SOURCE_CLASS_BUTTON;

    /**
     * The input source is a DPad.
     *
     * @see #SOURCE_CLASS_BUTTON
     */
    public static final int SOURCE_DPAD = 0x00000200 | SOURCE_CLASS_BUTTON;

    /**
     * The input source is a game pad.
     * (It may also be a {@link #SOURCE_JOYSTICK}).
     *
     * @see #SOURCE_CLASS_BUTTON
     */
    public static final int SOURCE_GAMEPAD = 0x00000400 | SOURCE_CLASS_BUTTON;

    /**
     * The input source is a touch screen pointing device.
     *
     * @see #SOURCE_CLASS_POINTER
     */
    public static final int SOURCE_TOUCHSCREEN = 0x00001000 | SOURCE_CLASS_POINTER;

    /**
     * The input source is a mouse pointing device.
     * This code is also used for other mouse-like pointing devices such as trackpads
     * and trackpoints.
     *
     * @see #SOURCE_CLASS_POINTER
     */
    public static final int SOURCE_MOUSE = 0x00002000 | SOURCE_CLASS_POINTER;

    /**
     * The input source is a stylus pointing device.
     * <p>
     * Note that this bit merely indicates that an input device is capable of obtaining
     * input from a stylus.  To determine whether a given touch event was produced
     * by a stylus, examine the tool type returned by {@link MotionEvent#getToolType(int)}
     * for each individual pointer.
     * </p><p>
     * A single touch event may multiple pointers with different tool types,
     * such as an event that has one pointer with tool type
     * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
     * {@link MotionEvent#TOOL_TYPE_STYLUS}.  So it is important to examine
     * the tool type of each pointer, regardless of the source reported
     * by {@link MotionEvent#getSource()}.
     * </p>
     *
     * @see #SOURCE_CLASS_POINTER
     */
    public static final int SOURCE_STYLUS = 0x00004000 | SOURCE_CLASS_POINTER;

    /**
     * The input device is a Bluetooth stylus.
     * <p>
     * Note that this bit merely indicates that an input device is capable of
     * obtaining input from a Bluetooth stylus.  To determine whether a given
     * touch event was produced by a stylus, examine the tool type returned by
     * {@link MotionEvent#getToolType(int)} for each individual pointer.
     * </p><p>
     * A single touch event may multiple pointers with different tool types,
     * such as an event that has one pointer with tool type
     * {@link MotionEvent#TOOL_TYPE_FINGER} and another pointer with tool type
     * {@link MotionEvent#TOOL_TYPE_STYLUS}.  So it is important to examine
     * the tool type of each pointer, regardless of the source reported
     * by {@link MotionEvent#getSource()}.
     * </p><p>
     * A bluetooth stylus generally receives its pressure and button state
     * information from the stylus itself, and derives the rest from another
     * source. For example, a Bluetooth stylus used in conjunction with a
     * touchscreen would derive its contact position and pointer size from the
     * touchscreen and may not be any more accurate than other tools such as
     * fingers.
     * </p>
     *
     * @see #SOURCE_STYLUS
     * @see #SOURCE_CLASS_POINTER
     */
    public static final int SOURCE_BLUETOOTH_STYLUS =
            0x00008000 | SOURCE_STYLUS;

    /**
     * The input source is a trackball.
     *
     * @see #SOURCE_CLASS_TRACKBALL
     */
    public static final int SOURCE_TRACKBALL = 0x00010000 | SOURCE_CLASS_TRACKBALL;

    /**
     * The input source is a mouse device whose relative motions should be interpreted as
     * navigation events.
     *
     * @see #SOURCE_CLASS_TRACKBALL
     */
    public static final int SOURCE_MOUSE_RELATIVE = 0x00020000 | SOURCE_CLASS_TRACKBALL;

    /**
     * The input source is a touch pad or digitizer tablet that is not
     * associated with a display (unlike {@link #SOURCE_TOUCHSCREEN}).
     *
     * @see #SOURCE_CLASS_POSITION
     */
    public static final int SOURCE_TOUCHPAD = 0x00100000 | SOURCE_CLASS_POSITION;

    /**
     * The input source is a touch device whose motions should be interpreted as navigation events.
     *
     * For example, an upward swipe should be as an upward focus traversal in the same manner as
     * pressing up on a D-Pad would be. Swipes to the left, right and down should be treated in a
     * similar manner.
     *
     * @see #SOURCE_CLASS_NONE
     */
    public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;

    /**
     * The input source is a rotating encoder device whose motions should be interpreted as akin to
     * those of a scroll wheel.
     *
     * @see #SOURCE_CLASS_NONE
     */
    public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;

    /**
     * The input source is a joystick.
     * (It may also be a {@link #SOURCE_GAMEPAD}).
     *
     * @see #SOURCE_CLASS_JOYSTICK
     */
    public static final int SOURCE_JOYSTICK = 0x01000000 | SOURCE_CLASS_JOYSTICK;

    /**
     * The input source is a device connected through HDMI-based bus.
     *
     * The key comes in through HDMI-CEC or MHL signal line, and is treated as if it were
     * generated by a locally connected DPAD or keyboard.
     */
    public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;

    /**
     * A special input source constant that is used when filtering input devices
     * to match devices that provide any type of input source.
     */
    public static final int SOURCE_ANY = 0xffffff00;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_X}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_X} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_X = MotionEvent.AXIS_X;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_Y}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_Y} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_Y = MotionEvent.AXIS_Y;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_PRESSURE}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_PRESSURE} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_PRESSURE = MotionEvent.AXIS_PRESSURE;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_SIZE}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_SIZE} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_SIZE = MotionEvent.AXIS_SIZE;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MAJOR}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MAJOR} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_TOUCH_MAJOR = MotionEvent.AXIS_TOUCH_MAJOR;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOUCH_MINOR}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_TOUCH_MINOR} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_TOUCH_MINOR = MotionEvent.AXIS_TOUCH_MINOR;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MAJOR}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_TOOL_MAJOR} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_TOOL_MAJOR = MotionEvent.AXIS_TOOL_MAJOR;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_TOOL_MINOR}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_TOOL_MINOR} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_TOOL_MINOR = MotionEvent.AXIS_TOOL_MINOR;

    /**
     * Constant for retrieving the range of values for {@link MotionEvent#AXIS_ORIENTATION}.
     *
     * @see #getMotionRange
     * @deprecated Use {@link MotionEvent#AXIS_ORIENTATION} instead.
     */
    @Deprecated
    public static final int MOTION_RANGE_ORIENTATION = MotionEvent.AXIS_ORIENTATION;

    /**
     * There is no keyboard.
     */
    public static final int KEYBOARD_TYPE_NONE = 0;

    /**
     * The keyboard is not fully alphabetic.  It may be a numeric keypad or an assortment
     * of buttons that are not mapped as alphabetic keys suitable for text input.
     */
    public static final int KEYBOARD_TYPE_NON_ALPHABETIC = 1;

    /**
     * The keyboard supports a complement of alphabetic keys.
     */
    public static final int KEYBOARD_TYPE_ALPHABETIC = 2;

    private static final int MAX_RANGES = 1000;

    public static final @android.annotation.NonNull Parcelable.Creator<InputDevice> CREATOR =
            new Parcelable.Creator<InputDevice>() {
        public InputDevice createFromParcel(Parcel in) {
            return new InputDevice(in);
        }
        public InputDevice[] newArray(int size) {
            return new InputDevice[size];
        }
    };

    // Called by native code.
    @UnsupportedAppUsage
    private InputDevice(int id, int generation, int controllerNumber, String name, int vendorId,
            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
            KeyCharacterMap keyCharacterMap, boolean hasVibrator, boolean hasMicrophone,
            boolean hasButtonUnderPad) {
        mId = id;
        mGeneration = generation;
        mControllerNumber = controllerNumber;
        mName = name;
        mVendorId = vendorId;
        mProductId = productId;
        mDescriptor = descriptor;
        mIsExternal = isExternal;
        mSources = sources;
        mKeyboardType = keyboardType;
        mKeyCharacterMap = keyCharacterMap;
        mHasVibrator = hasVibrator;
        mHasMicrophone = hasMicrophone;
        mHasButtonUnderPad = hasButtonUnderPad;
        mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
    }

    private InputDevice(Parcel in) {
        mId = in.readInt();
        mGeneration = in.readInt();
        mControllerNumber = in.readInt();
        mName = in.readString();
        mVendorId = in.readInt();
        mProductId = in.readInt();
        mDescriptor = in.readString();
        mIsExternal = in.readInt() != 0;
        mSources = in.readInt();
        mKeyboardType = in.readInt();
        mKeyCharacterMap = KeyCharacterMap.CREATOR.createFromParcel(in);
        mHasVibrator = in.readInt() != 0;
        mHasMicrophone = in.readInt() != 0;
        mHasButtonUnderPad = in.readInt() != 0;
        mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);

        int numRanges = in.readInt();
        if (numRanges > MAX_RANGES) {
            numRanges = MAX_RANGES;
        }

        for (int i = 0; i < numRanges; i++) {
            addMotionRange(in.readInt(), in.readInt(), in.readFloat(), in.readFloat(),
                    in.readFloat(), in.readFloat(), in.readFloat());
        }
    }

    /**
     * Gets information about the input device with the specified id.
     * @param id The device id.
     * @return The input device or null if not found.
     */
    public static InputDevice getDevice(int id) {
        return InputManager.getInstance().getInputDevice(id);
    }

    /**
     * Gets the ids of all input devices in the system.
     * @return The input device ids.
     */
    public static int[] getDeviceIds() {
        return InputManager.getInstance().getInputDeviceIds();
    }

    /**
     * Gets the input device id.
     * <p>
     * Each input device receives a unique id when it is first configured
     * by the system.  The input device id may change when the system is restarted or if the
     * input device is disconnected, reconnected or reconfigured at any time.
     * If you require a stable identifier for a device that persists across
     * boots and reconfigurations, use {@link #getDescriptor()}.
     * </p>
     *
     * @return The input device id.
     */
    public int getId() {
        return mId;
    }

    /**
     * The controller number for a given input device.
     * <p>
     * Each gamepad or joystick is given a unique, positive controller number when initially
     * configured by the system. This number may change due to events such as device disconnects /
     * reconnects or user initiated reassignment. Any change in number will trigger an event that
     * can be observed by registering an {@link InputManager.InputDeviceListener}.
     * </p>
     * <p>
     * All input devices which are not gamepads or joysticks will be assigned a controller number
     * of 0.
     * </p>
     *
     * @return The controller number of the device.
     */
    public int getControllerNumber() {
        return mControllerNumber;
    }

    /**
     * The set of identifying information for type of input device. This
     * information can be used by the system to configure appropriate settings
     * for the device.
     *
     * @return The identifier object for this device
     * @hide
     */
    public InputDeviceIdentifier getIdentifier() {
        return mIdentifier;
    }

    /**
     * Gets a generation number for this input device.
     * The generation number is incremented whenever the device is reconfigured and its
     * properties may have changed.
     *
     * @return The generation number.
     *
     * @hide
     */
    public int getGeneration() {
        return mGeneration;
    }

    /**
     * Gets the vendor id for the given device, if available.
     * <p>
     * A vendor id uniquely identifies the company who manufactured the device. A value of 0 will
     * be assigned where a vendor id is not available.
     * </p>
     *
     * @return The vendor id of a given device
     */
    public int getVendorId() {
        return mVendorId;
    }

    /**
     * Gets the product id for the given device, if available.
     * <p>
     * A product id uniquely identifies which product within the address space of a given vendor,
     * identified by the device's vendor id. A value of 0 will be assigned where a product id is
     * not available.
     * </p>
     *
     * @return The product id of a given device
     */
    public int getProductId() {
        return mProductId;
    }

    /**
     * Gets the input device descriptor, which is a stable identifier for an input device.
     * <p>
     * An input device descriptor uniquely identifies an input device.  Its value
     * is intended to be persistent across system restarts, and should not change even
     * if the input device is disconnected, reconnected or reconfigured at any time.
     * </p><p>
     * It is possible for there to be multiple {@link InputDevice} instances that have the
     * same input device descriptor.  This might happen in situations where a single
     * human input device registers multiple {@link InputDevice} instances (HID collections)
     * that describe separate features of the device, such as a keyboard that also
     * has a trackpad.  Alternately, it may be that the input devices are simply
     * indistinguishable, such as two keyboards made by the same manufacturer.
     * </p><p>
     * The input device descriptor returned by {@link #getDescriptor} should only be
     * used when an application needs to remember settings associated with a particular
     * input device.  For all other purposes when referring to a logical
     * {@link InputDevice} instance at runtime use the id returned by {@link #getId()}.
     * </p>
     *
     * @return The input device descriptor.
     */
    public String getDescriptor() {
        return mDescriptor;
    }

    /**
     * Returns true if the device is a virtual input device rather than a real one,
     * such as the virtual keyboard (see {@link KeyCharacterMap#VIRTUAL_KEYBOARD}).
     * <p>
     * Virtual input devices are provided to implement system-level functionality
     * and should not be seen or configured by users.
     * </p>
     *
     * @return True if the device is virtual.
     *
     * @see KeyCharacterMap#VIRTUAL_KEYBOARD
     */
    public boolean isVirtual() {
        return mId < 0;
    }

    /**
     * Returns true if the device is external (connected to USB or Bluetooth or some other
     * peripheral bus), otherwise it is built-in.
     *
     * @return True if the device is external.
     */
    public boolean isExternal() {
        return mIsExternal;
    }

    /**
     * Returns true if the device is a full keyboard.
     *
     * @return True if the device is a full keyboard.
     *
     * @hide
     */
    public boolean isFullKeyboard() {
        return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD
                && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC;
    }

    /**
     * Gets the name of this input device.
     * @return The input device name.
     */
    public String getName() {
        return mName;
    }

    /**
     * Gets the input sources supported by this input device as a combined bitfield.
     * @return The supported input sources.
     */
    public int getSources() {
        return mSources;
    }

    /**
     * Determines whether the input device supports the given source or sources.
     *
     * @param source The input source or sources to check against. This can be a generic device
     * type such as {@link InputDevice#SOURCE_MOUSE}, a more generic device class, such as
     * {@link InputDevice#SOURCE_CLASS_POINTER}, or a combination of sources bitwise ORed together.
     * @return Whether the device can produce all of the given sources.
     */
    public boolean supportsSource(int source) {
        return (mSources & source) == source;
    }

    /**
     * Gets the keyboard type.
     * @return The keyboard type.
     */
    public int getKeyboardType() {
        return mKeyboardType;
    }

    /**
     * Gets the key character map associated with this input device.
     * @return The key character map.
     */
    public KeyCharacterMap getKeyCharacterMap() {
        return mKeyCharacterMap;
    }

    /**
     * Gets whether the device is capable of producing the list of keycodes.
     * @param keys The list of android keycodes to check for.
     * @return An array of booleans where each member specifies whether the device is capable of
     * generating the keycode given by the corresponding value at the same index in the keys array.
     */
    public boolean[] hasKeys(int... keys) {
        return InputManager.getInstance().deviceHasKeys(mId, keys);
    }

    /**
     * Gets information about the range of values for a particular {@link MotionEvent} axis.
     * If the device supports multiple sources, the same axis may have different meanings
     * for each source.  Returns information about the first axis found for any source.
     * To obtain information about the axis for a specific source, use
     * {@link #getMotionRange(int, int)}.
     *
     * @param axis The axis constant.
     * @return The range of values, or null if the requested axis is not
     * supported by the device.
     *
     * @see MotionEvent#AXIS_X
     * @see MotionEvent#AXIS_Y
     */
    public MotionRange getMotionRange(int axis) {
        final int numRanges = mMotionRanges.size();
        for (int i = 0; i < numRanges; i++) {
            final MotionRange range = mMotionRanges.get(i);
            if (range.mAxis == axis) {
                return range;
            }
        }
        return null;
    }

    /**
     * Gets information about the range of values for a particular {@link MotionEvent} axis
     * used by a particular source on the device.
     * If the device supports multiple sources, the same axis may have different meanings
     * for each source.
     *
     * @param axis The axis constant.
     * @param source The source for which to return information.
     * @return The range of values, or null if the requested axis is not
     * supported by the device.
     *
     * @see MotionEvent#AXIS_X
     * @see MotionEvent#AXIS_Y
     */
    public MotionRange getMotionRange(int axis, int source) {
        final int numRanges = mMotionRanges.size();
        for (int i = 0; i < numRanges; i++) {
            final MotionRange range = mMotionRanges.get(i);
            if (range.mAxis == axis && range.mSource == source) {
                return range;
            }
        }
        return null;
    }

    /**
     * Gets the ranges for all axes supported by the device.
     * @return The motion ranges for the device.
     *
     * @see #getMotionRange(int, int)
     */
    public List<MotionRange> getMotionRanges() {
        return mMotionRanges;
    }

    // Called from native code.
    @UnsupportedAppUsage
    private void addMotionRange(int axis, int source,
            float min, float max, float flat, float fuzz, float resolution) {
        mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz, resolution));
    }

    /**
     * Gets the vibrator service associated with the device, if there is one.
     * Even if the device does not have a vibrator, the result is never null.
     * Use {@link Vibrator#hasVibrator} to determine whether a vibrator is
     * present.
     *
     * Note that the vibrator associated with the device may be different from
     * the system vibrator.  To obtain an instance of the system vibrator instead, call
     * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as argument.
     *
     * @return The vibrator service associated with the device, never null.
     */
    public Vibrator getVibrator() {
        synchronized (mMotionRanges) {
            if (mVibrator == null) {
                if (mHasVibrator) {
                    mVibrator = InputManager.getInstance().getInputDeviceVibrator(mId);
                } else {
                    mVibrator = NullVibrator.getInstance();
                }
            }
            return mVibrator;
        }
    }

    /**
     * Returns true if input device is enabled.
     * @return Whether the input device is enabled.
     */
    public boolean isEnabled() {
        return InputManager.getInstance().isInputDeviceEnabled(mId);
    }

    /**
     * Enables the input device.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
    @TestApi
    public void enable() {
        InputManager.getInstance().enableInputDevice(mId);
    }

    /**
     * Disables the input device.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.DISABLE_INPUT_DEVICE)
    @TestApi
    public void disable() {
        InputManager.getInstance().disableInputDevice(mId);
    }

    /**
     * Reports whether the device has a built-in microphone.
     * @return Whether the device has a built-in microphone.
     */
    public boolean hasMicrophone() {
        return mHasMicrophone;
    }

    /**
     * Reports whether the device has a button under its touchpad
     * @return Whether the device has a button under its touchpad
     * @hide
     */
    public boolean hasButtonUnderPad() {
        return mHasButtonUnderPad;
    }

    /**
     * Sets the current pointer type.
     * @param pointerType the type of the pointer icon.
     * @hide
     */
    public void setPointerType(int pointerType) {
        InputManager.getInstance().setPointerIconType(pointerType);
    }

    /**
     * Specifies the current custom pointer.
     * @param icon the icon data.
     * @hide
     */
    public void setCustomPointerIcon(PointerIcon icon) {
        InputManager.getInstance().setCustomPointerIcon(icon);
    }

    /**
     * Provides information about the range of values for a particular {@link MotionEvent} axis.
     *
     * @see InputDevice#getMotionRange(int)
     */
    public static final class MotionRange {
        private int mAxis;
        private int mSource;
        private float mMin;
        private float mMax;
        private float mFlat;
        private float mFuzz;
        private float mResolution;

        private MotionRange(int axis, int source, float min, float max, float flat, float fuzz,
                float resolution) {
            mAxis = axis;
            mSource = source;
            mMin = min;
            mMax = max;
            mFlat = flat;
            mFuzz = fuzz;
            mResolution = resolution;
        }

        /**
         * Gets the axis id.
         * @return The axis id.
         */
        public int getAxis() {
            return mAxis;
        }

        /**
         * Gets the source for which the axis is defined.
         * @return The source.
         */
        public int getSource() {
            return mSource;
        }


        /**
         * Determines whether the event is from the given source.
         *
         * @param source The input source to check against. This can be a specific device type,
         * such as {@link InputDevice#SOURCE_TOUCH_NAVIGATION}, or a more generic device class,
         * such as {@link InputDevice#SOURCE_CLASS_POINTER}.
         * @return Whether the event is from the given source.
         */
        public boolean isFromSource(int source) {
            return (getSource() & source) == source;
        }

        /**
         * Gets the inclusive minimum value for the axis.
         * @return The inclusive minimum value.
         */
        public float getMin() {
            return mMin;
        }

        /**
         * Gets the inclusive maximum value for the axis.
         * @return The inclusive maximum value.
         */
        public float getMax() {
            return mMax;
        }

        /**
         * Gets the range of the axis (difference between maximum and minimum).
         * @return The range of values.
         */
        public float getRange() {
            return mMax - mMin;
        }

        /**
         * Gets the extent of the center flat position with respect to this axis.
         * <p>
         * For example, a flat value of 8 means that the center position is between -8 and +8.
         * This value is mainly useful for calibrating self-centering devices.
         * </p>
         * @return The extent of the center flat position.
         */
        public float getFlat() {
            return mFlat;
        }

        /**
         * Gets the error tolerance for input device measurements with respect to this axis.
         * <p>
         * For example, a value of 2 indicates that the measured value may be up to +/- 2 units
         * away from the actual value due to noise and device sensitivity limitations.
         * </p>
         * @return The error tolerance.
         */
        public float getFuzz() {
            return mFuzz;
        }

        /**
         * Gets the resolution for input device measurements with respect to this axis.
         * @return The resolution in units per millimeter, or units per radian for rotational axes.
         */
        public float getResolution() {
            return mResolution;
        }
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mId);
        out.writeInt(mGeneration);
        out.writeInt(mControllerNumber);
        out.writeString(mName);
        out.writeInt(mVendorId);
        out.writeInt(mProductId);
        out.writeString(mDescriptor);
        out.writeInt(mIsExternal ? 1 : 0);
        out.writeInt(mSources);
        out.writeInt(mKeyboardType);
        mKeyCharacterMap.writeToParcel(out, flags);
        out.writeInt(mHasVibrator ? 1 : 0);
        out.writeInt(mHasMicrophone ? 1 : 0);
        out.writeInt(mHasButtonUnderPad ? 1 : 0);

        final int numRanges = mMotionRanges.size();
        out.writeInt(numRanges);
        for (int i = 0; i < numRanges; i++) {
            MotionRange range = mMotionRanges.get(i);
            out.writeInt(range.mAxis);
            out.writeInt(range.mSource);
            out.writeFloat(range.mMin);
            out.writeFloat(range.mMax);
            out.writeFloat(range.mFlat);
            out.writeFloat(range.mFuzz);
            out.writeFloat(range.mResolution);
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder description = new StringBuilder();
        description.append("Input Device ").append(mId).append(": ").append(mName).append("\n");
        description.append("  Descriptor: ").append(mDescriptor).append("\n");
        description.append("  Generation: ").append(mGeneration).append("\n");
        description.append("  Location: ").append(mIsExternal ? "external" : "built-in").append("\n");

        description.append("  Keyboard Type: ");
        switch (mKeyboardType) {
            case KEYBOARD_TYPE_NONE:
                description.append("none");
                break;
            case KEYBOARD_TYPE_NON_ALPHABETIC:
                description.append("non-alphabetic");
                break;
            case KEYBOARD_TYPE_ALPHABETIC:
                description.append("alphabetic");
                break;
        }
        description.append("\n");

        description.append("  Has Vibrator: ").append(mHasVibrator).append("\n");

        description.append("  Has mic: ").append(mHasMicrophone).append("\n");

        description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
        appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
        appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
        appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE, "mouse");
        appendSourceDescriptionIfApplicable(description, SOURCE_STYLUS, "stylus");
        appendSourceDescriptionIfApplicable(description, SOURCE_TRACKBALL, "trackball");
        appendSourceDescriptionIfApplicable(description, SOURCE_MOUSE_RELATIVE, "mouse_relative");
        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHPAD, "touchpad");
        appendSourceDescriptionIfApplicable(description, SOURCE_JOYSTICK, "joystick");
        appendSourceDescriptionIfApplicable(description, SOURCE_GAMEPAD, "gamepad");
        description.append(" )\n");

        final int numAxes = mMotionRanges.size();
        for (int i = 0; i < numAxes; i++) {
            MotionRange range = mMotionRanges.get(i);
            description.append("    ").append(MotionEvent.axisToString(range.mAxis));
            description.append(": source=0x").append(Integer.toHexString(range.mSource));
            description.append(" min=").append(range.mMin);
            description.append(" max=").append(range.mMax);
            description.append(" flat=").append(range.mFlat);
            description.append(" fuzz=").append(range.mFuzz);
            description.append(" resolution=").append(range.mResolution);
            description.append("\n");
        }
        return description.toString();
    }

    private void appendSourceDescriptionIfApplicable(StringBuilder description, int source,
            String sourceName) {
        if ((mSources & source) == source) {
            description.append(" ");
            description.append(sourceName);
        }
    }
}
