Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efd3266b authored by Jeff Brown's avatar Jeff Brown
Browse files

Input improvements and bug fixes.

Associate each motion axis with the source from which it comes.
It is possible for multiple sources of the same device to define
the same axis.  This fixes new API that was introduced in MR1.
(Bug: 4066146)

Fixed a bug that might cause a segfault when using a trackball.

Only fade out the mouse pointer when touching the touch screen,
ignore other touch pads.

Changed the plural "sources" to "source" in several places in
the InputReader where we intend to refer to a particular source
rather than to a combination of sources.

Improved the batching code to support batching events from different
sources of the same device in parallel.  (Bug: 3391564)

Change-Id: I0189e18e464338f126f7bf94370b928e1b1695f2
parent 9e8e40cb
Loading
Loading
Loading
Loading
+39 −2
Original line number Diff line number Diff line
@@ -211374,9 +211374,11 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="axis" type="int">
</parameter>
</method>
<method name="getMotionAxes"
 return="int[]"
<method name="getMotionRange"
 return="android.view.InputDevice.MotionRange"
 abstract="false"
 native="false"
 synchronized="false"
@@ -211398,6 +211400,19 @@
>
<parameter name="axis" type="int">
</parameter>
<parameter name="source" type="int">
</parameter>
</method>
<method name="getMotionRanges"
 return="java.util.List&lt;android.view.InputDevice.MotionRange&gt;"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getName"
 return="java.lang.String"
@@ -211763,6 +211778,17 @@
 deprecated="not deprecated"
 visibility="public"
>
<method name="getAxis"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getFlat"
 return="float"
 abstract="false"
@@ -211818,6 +211844,17 @@
 visibility="public"
>
</method>
<method name="getSource"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
</class>
<class name="InputEvent"
 extends="java.lang.Object"
+83 −31
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.SparseArray;

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

/**
 * Describes the capabilities of a particular input device.
@@ -43,8 +45,7 @@ public final class InputDevice implements Parcelable {
    private int mSources;
    private int mKeyboardType;

    private final SparseArray<MotionRange> mMotionRanges = new SparseArray<MotionRange>();
    private int[] mMotionAxes;
    private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();

    /**
     * A mask for input source classes.
@@ -354,6 +355,11 @@ public final class InputDevice implements Parcelable {

    /**
     * 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.
@@ -363,30 +369,55 @@ public final class InputDevice implements Parcelable {
     * @see #getSupportedAxes()
     */
    public MotionRange getMotionRange(int axis) {
        return mMotionRanges.get(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 the axis ids of all motion axes supported by this device.
     * @return The axis ids of all motion axes supported by this device.
     * 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.
     *
     * @see #getMotionRange(int)
     * @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
     * @see #getSupportedAxes()
     */
    public int[] getMotionAxes() {
        synchronized (this) {
            if (mMotionAxes == null) {
                final int count = mMotionRanges.size();
                mMotionAxes = new int[count];
                for (int i = 0; i < count; i++) {
                    mMotionAxes[i] = mMotionRanges.keyAt(i);
    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 mMotionAxes;
        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;
    }

    private void addMotionRange(int axis, float min, float max, float flat, float fuzz) {
        mMotionRanges.append(axis, new MotionRange(min, max, flat, fuzz));
    private void addMotionRange(int axis, int source,
            float min, float max, float flat, float fuzz) {
        mMotionRanges.add(new MotionRange(axis, source, min, max, flat, fuzz));
    }

    /**
@@ -395,18 +426,38 @@ public final class InputDevice implements Parcelable {
     * @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 MotionRange(float min, float max, float flat, float fuzz) {
        private MotionRange(int axis, int source, float min, float max, float flat, float fuzz) {
            mAxis = axis;
            mSource = source;
            mMin = min;
            mMax = max;
            mFlat = flat;
            mFuzz = fuzz;
        }

        /**
         * 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;
        }

        /**
         * Gets the inclusive minimum value for the axis.
         * @return The inclusive minimum value.
@@ -480,7 +531,8 @@ public final class InputDevice implements Parcelable {
            if (axis < 0) {
                break;
            }
            addMotionRange(axis, in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
            addMotionRange(axis, in.readInt(),
                    in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
        }
    }

@@ -491,11 +543,11 @@ public final class InputDevice implements Parcelable {
        out.writeInt(mSources);
        out.writeInt(mKeyboardType);

        final int numAxes = mMotionRanges.size();
        for (int i = 0; i < numAxes; i++) {
            int axis = mMotionRanges.keyAt(i);
            MotionRange range = mMotionRanges.valueAt(i);
            out.writeInt(axis);
        final int numRanges = mMotionRanges.size();
        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);
@@ -528,7 +580,7 @@ public final class InputDevice implements Parcelable {
        }
        description.append("\n");

        description.append("  Sources: ").append(Integer.toHexString(mSources)).append(" (");
        description.append("  Sources: 0x").append(Integer.toHexString(mSources)).append(" (");
        appendSourceDescriptionIfApplicable(description, SOURCE_KEYBOARD, "keyboard");
        appendSourceDescriptionIfApplicable(description, SOURCE_DPAD, "dpad");
        appendSourceDescriptionIfApplicable(description, SOURCE_TOUCHSCREEN, "touchscreen");
@@ -541,10 +593,10 @@ public final class InputDevice implements Parcelable {

        final int numAxes = mMotionRanges.size();
        for (int i = 0; i < numAxes; i++) {
            int axis = mMotionRanges.keyAt(i);
            MotionRange range = mMotionRanges.valueAt(i);
            description.append("    ").append(MotionEvent.axisToString(axis));
            description.append(": min=").append(range.mMin);
            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);
+16 −5
Original line number Diff line number Diff line
@@ -143,6 +143,14 @@ enum {
    POLICY_FLAG_PASS_TO_USER = 0x40000000,
};

/*
 * Button state.
 */
enum {
    // Primary button pressed (left mouse button).
    BUTTON_STATE_PRIMARY = 1 << 0,
};

/*
 * Describes the basic configuration of input devices that are present.
 */
@@ -544,6 +552,8 @@ public:
    ~InputDeviceInfo();

    struct MotionRange {
        int32_t axis;
        uint32_t source;
        float min;
        float max;
        float flat;
@@ -556,16 +566,17 @@ public:
    inline const String8 getName() const { return mName; }
    inline uint32_t getSources() const { return mSources; }

    const MotionRange* getMotionRange(int32_t axis) const;
    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;

    void addSource(uint32_t source);
    void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
    void addMotionRange(int32_t axis, const MotionRange& range);
    void addMotionRange(int32_t axis, uint32_t source,
            float min, float max, float flat, float fuzz);
    void addMotionRange(const MotionRange& range);

    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
    inline int32_t getKeyboardType() const { return mKeyboardType; }

    inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
    inline const Vector<MotionRange>& getMotionRanges() const {
        return mMotionRanges;
    }

@@ -575,7 +586,7 @@ private:
    uint32_t mSources;
    int32_t mKeyboardType;

    KeyedVector<int32_t, MotionRange> mMotionRanges;
    Vector<MotionRange> mMotionRanges;
};

/*
+15 −8
Original line number Diff line number Diff line
@@ -657,23 +657,30 @@ void InputDeviceInfo::initialize(int32_t id, const String8& name) {
    mMotionRanges.clear();
}

const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
    ssize_t index = mMotionRanges.indexOfKey(axis);
    return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(
        int32_t axis, uint32_t source) const {
    size_t numRanges = mMotionRanges.size();
    for (size_t i = 0; i < numRanges; i++) {
        const MotionRange& range = mMotionRanges.itemAt(i);
        if (range.axis == axis && range.source == source) {
            return &range;
        }
    }
    return NULL;
}

void InputDeviceInfo::addSource(uint32_t source) {
    mSources |= source;
}

void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max,
        float flat, float fuzz) {
    MotionRange range = { min, max, flat, fuzz };
    addMotionRange(axis, range);
    MotionRange range = { axis, source, min, max, flat, fuzz };
    mMotionRanges.add(range);
}

void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
    mMotionRanges.add(axis, range);
void InputDeviceInfo::addMotionRange(const MotionRange& range) {
    mMotionRanges.add(range);
}

} // namespace android
+5 −5
Original line number Diff line number Diff line
@@ -2343,17 +2343,17 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
                }

                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
                if (motionEntry->deviceId != deviceId) {
                    // Keep looking for this device.
                if (motionEntry->deviceId != deviceId
                        || motionEntry->source != source) {
                    // Keep looking for this device and source.
                    continue;
                }

                if (motionEntry->action != action
                        || motionEntry->source != source
                        || motionEntry->pointerCount != pointerCount
                        || motionEntry->isInjected()) {
                    // Last motion event in the queue for this device is not compatible for
                    // appending new samples.  Stop here.
                    // Last motion event in the queue for this device and source is
                    // not compatible for appending new samples.  Stop here.
                    goto NoBatchingOrStreaming;
                }

Loading