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

Commit fcc4c24d authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge "Add an API to get the supported USI version for a display"

parents 9ac6a634 84dc597f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -19278,7 +19278,16 @@ package android.hardware.fingerprint {
package android.hardware.input {
  public final class HostUsiVersion implements android.os.Parcelable {
    method public int describeContents();
    method public int getMajorVersion();
    method public int getMinorVersion();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.hardware.input.HostUsiVersion> CREATOR;
  }
  public final class InputManager {
    method @Nullable public android.hardware.input.HostUsiVersion getHostUsiVersion(@NonNull android.view.Display);
    method @Nullable public android.view.InputDevice getInputDevice(int);
    method public int[] getInputDeviceIds();
    method @FloatRange(from=0, to=1) public float getMaximumObscuringOpacityForTouch();
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.hardware.input;

parcelable HostUsiVersion;
+204 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.hardware.input;

import android.os.Parcelable;

import com.android.internal.util.DataClass;

/**
 * Provides information about the supported Universal Stylus Initiative (USI) version of the
 * host device.
 *
 * This holds version information about the host device (e.g. the touchscreen/display), not
 * the USI version of a stylus.
 *
 * @see InputManager#getHostUsiVersion(android.view.Display)
 * @see <a href="https://universalstylus.org">Universal Stylus Initiative</a>
 */
@DataClass(genParcelable = true, genHiddenConstructor = true, genToString = true,
        genEqualsHashCode = true)
public final class HostUsiVersion implements Parcelable {
    /**
     * The major USI version supported by the input device.
     * For example, if the device supports USI 2.0, this will return 2.
     */
    private final int mMajorVersion;

    /**
     * The minor USI version supported by the input device.
     * For example, if the device supports USI 2.0, this will return 0.
     */
    private final int mMinorVersion;

    /** @hide */
    public boolean isValid() {
        return mMajorVersion >= 0 && mMinorVersion >= 0;
    }



    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/hardware/input/HostUsiVersion.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    /**
     * Creates a new HostUsiVersion.
     *
     * @param majorVersion
     *   The major USI version supported by the input device.
     *   For example, if the device supports USI 2.0, this will return 2.
     * @param minorVersion
     *   The minor USI version supported by the input device.
     *   For example, if the device supports USI 2.0, this will return 0.
     * @hide
     */
    @DataClass.Generated.Member
    public HostUsiVersion(
            int majorVersion,
            int minorVersion) {
        this.mMajorVersion = majorVersion;
        this.mMinorVersion = minorVersion;

        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * The major USI version supported by the input device.
     * For example, if the device supports USI 2.0, this will return 2.
     */
    @DataClass.Generated.Member
    public int getMajorVersion() {
        return mMajorVersion;
    }

    /**
     * The minor USI version supported by the input device.
     * For example, if the device supports USI 2.0, this will return 0.
     */
    @DataClass.Generated.Member
    public int getMinorVersion() {
        return mMinorVersion;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
        // You can override field toString logic by defining methods like:
        // String fieldNameToString() { ... }

        return "HostUsiVersion { " +
                "majorVersion = " + mMajorVersion + ", " +
                "minorVersion = " + mMinorVersion +
        " }";
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@android.annotation.Nullable Object o) {
        // You can override field equality logic by defining either of the methods like:
        // boolean fieldNameEquals(HostUsiVersion other) { ... }
        // boolean fieldNameEquals(FieldType otherValue) { ... }

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        HostUsiVersion that = (HostUsiVersion) o;
        //noinspection PointlessBooleanExpression
        return true
                && mMajorVersion == that.mMajorVersion
                && mMinorVersion == that.mMinorVersion;
    }

    @Override
    @DataClass.Generated.Member
    public int hashCode() {
        // You can override field hashCode logic by defining methods like:
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + mMajorVersion;
        _hash = 31 * _hash + mMinorVersion;
        return _hash;
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@android.annotation.NonNull android.os.Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        dest.writeInt(mMajorVersion);
        dest.writeInt(mMinorVersion);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ HostUsiVersion(@android.annotation.NonNull android.os.Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        int majorVersion = in.readInt();
        int minorVersion = in.readInt();

        this.mMajorVersion = majorVersion;
        this.mMinorVersion = minorVersion;

        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
    public static final @android.annotation.NonNull Parcelable.Creator<HostUsiVersion> CREATOR
            = new Parcelable.Creator<HostUsiVersion>() {
        @Override
        public HostUsiVersion[] newArray(int size) {
            return new HostUsiVersion[size];
        }

        @Override
        public HostUsiVersion createFromParcel(@android.annotation.NonNull android.os.Parcel in) {
            return new HostUsiVersion(in);
        }
    };

    @DataClass.Generated(
            time = 1673884256908L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/hardware/input/HostUsiVersion.java",
            inputSignatures = "private final  int mMajorVersion\nprivate final  int mMinorVersion\npublic  boolean isValid()\nclass HostUsiVersion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genHiddenConstructor=true, genToString=true, genEqualsHashCode=true)")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
+63 −0
Original line number Diff line number Diff line
@@ -56,8 +56,10 @@ import android.os.Vibrator;
import android.os.VibratorManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.DisplayUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputMonitor;
@@ -69,6 +71,7 @@ import android.view.WindowManager.LayoutParams;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
@@ -1584,6 +1587,66 @@ public final class InputManager {
        }
    }

    /**
     * Reports the version of the Universal Stylus Initiative (USI) protocol supported by the given
     * display, if any.
     *
     * @return the USI version supported by the display, or null if the device does not support USI
     * @see <a href="https://universalstylus.org">Universal Stylus Initiative</a>
     */
    @Nullable
    public HostUsiVersion getHostUsiVersion(@NonNull Display display) {
        Objects.requireNonNull(display, "display should not be null");

        // Return the first valid USI version reported by any input device associated with
        // the display.
        synchronized (mInputDevicesLock) {
            populateInputDevicesLocked();

            for (int i = 0; i < mInputDevices.size(); i++) {
                final InputDevice device = getInputDevice(mInputDevices.keyAt(i));
                if (device != null && device.getAssociatedDisplayId() == display.getDisplayId()) {
                    if (device.getHostUsiVersion() != null) {
                        return device.getHostUsiVersion();
                    }
                }
            }
        }

        // If there are no input devices that report a valid USI version, see if there is a config
        // that specifies the USI version for the display. This is to handle cases where the USI
        // input device is not registered by the kernel/driver all the time.
        return findConfigUsiVersionForDisplay(display);
    }

    private HostUsiVersion findConfigUsiVersionForDisplay(@NonNull Display display) {
        final Context context = Objects.requireNonNull(ActivityThread.currentApplication());
        final String[] displayUniqueIds = context.getResources().getStringArray(
                R.array.config_displayUniqueIdArray);
        final int index;
        if (displayUniqueIds.length == 0 && display.getDisplayId() == context.getDisplayId()) {
            index = 0;
        } else {
            index = DisplayUtils.getDisplayUniqueIdConfigIndex(context.getResources(),
                    display.getUniqueId());
        }

        final String[] versions = context.getResources().getStringArray(
                R.array.config_displayUsiVersionArray);
        if (index < 0 || index >= versions.length) {
            return null;
        }
        final String version = versions[index];
        if (version == null || version.isEmpty()) {
            return null;
        }
        final String[] majorMinor = version.split("\\.");
        if (majorMinor.length != 2) {
            throw new IllegalStateException("Failed to parse USI version: " + version);
        }
        return new HostUsiVersion(Integer.parseInt(majorMinor[0]), Integer.parseInt(majorMinor[1]));
    }

    private void populateInputDevicesLocked() {
        if (mInputDevicesChangedListener == null) {
            final InputDevicesChangedListener listener = new InputDevicesChangedListener();
+35 −15
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.hardware.BatteryState;
import android.hardware.SensorManager;
import android.hardware.input.HostUsiVersion;
import android.hardware.input.InputDeviceIdentifier;
import android.hardware.input.InputManager;
import android.hardware.lights.LightsManager;
@@ -83,7 +84,8 @@ public final class InputDevice implements Parcelable {
    private final boolean mHasButtonUnderPad;
    private final boolean mHasSensor;
    private final boolean mHasBattery;
    private final boolean mSupportsUsi;
    private final HostUsiVersion mHostUsiVersion;
    private final int mAssociatedDisplayId;
    private final ArrayList<MotionRange> mMotionRanges = new ArrayList<MotionRange>();

    @GuardedBy("mMotionRanges")
@@ -467,7 +469,8 @@ public final class InputDevice implements Parcelable {
            int productId, String descriptor, boolean isExternal, int sources, int keyboardType,
            KeyCharacterMap keyCharacterMap, @Nullable String keyboardLanguageTag,
            @Nullable String keyboardLayoutType, boolean hasVibrator, boolean hasMicrophone,
            boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery, boolean supportsUsi) {
            boolean hasButtonUnderPad, boolean hasSensor, boolean hasBattery, int usiVersionMajor,
            int usiVersionMinor, int associatedDisplayId) {
        mId = id;
        mGeneration = generation;
        mControllerNumber = controllerNumber;
@@ -493,7 +496,8 @@ public final class InputDevice implements Parcelable {
        mHasSensor = hasSensor;
        mHasBattery = hasBattery;
        mIdentifier = new InputDeviceIdentifier(descriptor, vendorId, productId);
        mSupportsUsi = supportsUsi;
        mHostUsiVersion = new HostUsiVersion(usiVersionMajor, usiVersionMinor);
        mAssociatedDisplayId = associatedDisplayId;
    }

    private InputDevice(Parcel in) {
@@ -515,7 +519,8 @@ public final class InputDevice implements Parcelable {
        mHasButtonUnderPad = in.readInt() != 0;
        mHasSensor = in.readInt() != 0;
        mHasBattery = in.readInt() != 0;
        mSupportsUsi = in.readInt() != 0;
        mHostUsiVersion = HostUsiVersion.CREATOR.createFromParcel(in);
        mAssociatedDisplayId = in.readInt();
        mIdentifier = new InputDeviceIdentifier(mDescriptor, mVendorId, mProductId);

        int numRanges = in.readInt();
@@ -554,7 +559,8 @@ public final class InputDevice implements Parcelable {
        private boolean mHasBattery = false;
        private String mKeyboardLanguageTag = null;
        private String mKeyboardLayoutType = null;
        private boolean mSupportsUsi = false;
        private int mUsiVersionMajor = -1;
        private int mUsiVersionMinor = -1;
        private List<MotionRange> mMotionRanges = new ArrayList<>();

        /** @see InputDevice#getId() */
@@ -665,9 +671,10 @@ public final class InputDevice implements Parcelable {
            return this;
        }

        /** @see InputDevice#supportsUsi() () */
        public Builder setSupportsUsi(boolean supportsUsi) {
            mSupportsUsi = supportsUsi;
        /** @see InputDevice#getHostUsiVersion() */
        public Builder setUsiVersion(@Nullable HostUsiVersion usiVersion) {
            mUsiVersionMajor = usiVersion != null ? usiVersion.getMajorVersion() : -1;
            mUsiVersionMinor = usiVersion != null ? usiVersion.getMinorVersion() : -1;
            return this;
        }

@@ -699,7 +706,9 @@ public final class InputDevice implements Parcelable {
                    mHasButtonUnderPad,
                    mHasSensor,
                    mHasBattery,
                    mSupportsUsi);
                    mUsiVersionMajor,
                    mUsiVersionMinor,
                    Display.INVALID_DISPLAY);

            final int numRanges = mMotionRanges.size();
            for (int i = 0; i < numRanges; i++) {
@@ -1276,12 +1285,22 @@ public final class InputDevice implements Parcelable {
    }

    /**
     * Reports whether the device supports the Universal Stylus Initiative (USI) protocol for
     * styluses.
     * Reports the version of the Universal Stylus Initiative (USI) protocol supported by this
     * input device.
     *
     * @return the supported USI version, or null if the device does not support USI
     * @see <a href="https://universalstylus.org">Universal Stylus Initiative</a>
     * @see InputManager#getHostUsiVersion(int)
     * @hide
     */
    public boolean supportsUsi() {
        return mSupportsUsi;
    @Nullable
    public HostUsiVersion getHostUsiVersion() {
        return mHostUsiVersion.isValid() ? mHostUsiVersion : null;
    }

    /** @hide */
    public int getAssociatedDisplayId() {
        return mAssociatedDisplayId;
    }

    /**
@@ -1415,7 +1434,8 @@ public final class InputDevice implements Parcelable {
        out.writeInt(mHasButtonUnderPad ? 1 : 0);
        out.writeInt(mHasSensor ? 1 : 0);
        out.writeInt(mHasBattery ? 1 : 0);
        out.writeInt(mSupportsUsi ? 1 : 0);
        mHostUsiVersion.writeToParcel(out, flags);
        out.writeInt(mAssociatedDisplayId);

        int numRanges = mMotionRanges.size();
        numRanges = numRanges > MAX_RANGES ? MAX_RANGES : numRanges;
@@ -1468,7 +1488,7 @@ public final class InputDevice implements Parcelable {

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

        description.append("  Supports USI: ").append(mSupportsUsi).append("\n");
        description.append("  USI Version: ").append(getHostUsiVersion()).append("\n");

        if (mKeyboardLanguageTag != null) {
            description.append(" Keyboard language tag: ").append(mKeyboardLanguageTag).append(
Loading