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

Commit 69bba1df authored by Jeff Brown's avatar Jeff Brown Committed by Android (Google) Code Review
Browse files

Merge "Add a unique input device descriptor."

parents 43de94a9 e38fdfae
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -39,12 +39,9 @@ import android.os.ServiceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
import android.view.Display;
import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.KeyCharacterMap;
import android.view.WindowManagerPolicy;
import android.view.KeyCharacterMap.UnavailableException;

import java.util.ArrayList;
+18 −2
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import java.util.List;
public final class InputDevice implements Parcelable {
    private int mId;
    private String mName;
    private String mDescriptor;
    private int mSources;
    private int mKeyboardType;
    private String mKeyCharacterMapFile;
@@ -334,12 +335,24 @@ public final class InputDevice implements Parcelable {
     * 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 bt
     * 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 "PLACEHOLDER"; // TODO: implement for real
        return mDescriptor;
    }

    /**
@@ -548,6 +561,7 @@ public final class InputDevice implements Parcelable {
    private void readFromParcel(Parcel in) {
        mId = in.readInt();
        mName = in.readString();
        mDescriptor = in.readString();
        mSources = in.readInt();
        mKeyboardType = in.readInt();
        mKeyCharacterMapFile = in.readString();
@@ -566,6 +580,7 @@ public final class InputDevice implements Parcelable {
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mId);
        out.writeString(mName);
        out.writeString(mDescriptor);
        out.writeInt(mSources);
        out.writeInt(mKeyboardType);
        out.writeString(mKeyCharacterMapFile);
@@ -592,6 +607,7 @@ public final class InputDevice implements Parcelable {
    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("  Keyboard Type: ");
        switch (mKeyboardType) {
+28 −18
Original line number Diff line number Diff line
@@ -811,6 +811,31 @@ private:
    VelocityTracker mVelocityTracker;
};

/*
 * Identifies a device.
 */
struct InputDeviceIdentifier {
    inline InputDeviceIdentifier() :
            bus(0), vendor(0), product(0), version(0) {
    }

    // Information provided by the kernel.
    String8 name;
    String8 location;
    String8 uniqueId;
    uint16_t bus;
    uint16_t vendor;
    uint16_t product;
    uint16_t version;

    // A composite input device descriptor string that uniquely identifies the device
    // even across reboots or reconnections.  The value of this field is used by
    // upper layers of the input system to associate settings with individual devices.
    // It is hashed from whatever kernel provided information is available.
    // Ideally, the way this value is computed should not change between Android releases
    // because that would invalidate persistent settings that rely on it.
    String8 descriptor;
};

/*
 * Describes the characteristics and capabilities of an input device.
@@ -830,10 +855,11 @@ public:
        float fuzz;
    };

    void initialize(int32_t id, const String8& name);
    void initialize(int32_t id, const String8& name, const String8& descriptor);

    inline int32_t getId() const { return mId; }
    inline const String8 getName() const { return mName; }
    inline const String8 getDescriptor() const { return mDescriptor; }
    inline uint32_t getSources() const { return mSources; }

    const MotionRange* getMotionRange(int32_t axis, uint32_t source) const;
@@ -856,6 +882,7 @@ public:
private:
    int32_t mId;
    String8 mName;
    String8 mDescriptor;
    uint32_t mSources;
    int32_t mKeyboardType;
    String8 mKeyCharacterMapFile;
@@ -863,23 +890,6 @@ private:
    Vector<MotionRange> mMotionRanges;
};

/*
 * Identifies a device.
 */
struct InputDeviceIdentifier {
    inline InputDeviceIdentifier() :
            bus(0), vendor(0), product(0), version(0) {
    }

    String8 name;
    String8 location;
    String8 uniqueId;
    uint16_t bus;
    uint16_t vendor;
    uint16_t product;
    uint16_t version;
};

/* Types of input device configuration files. */
enum InputDeviceConfigurationFileType {
    INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION = 0,     /* .idc file */
+6 −3
Original line number Diff line number Diff line
@@ -1226,21 +1226,24 @@ void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
// --- InputDeviceInfo ---

InputDeviceInfo::InputDeviceInfo() {
    initialize(-1, String8("uninitialized device info"));
    initialize(-1, String8("uninitialized device info"), String8("unknown"));
}

InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
        mId(other.mId), mName(other.mName), mSources(other.mSources),
        mId(other.mId), mName(other.mName), mDescriptor(other.mDescriptor),
        mSources(other.mSources),
        mKeyboardType(other.mKeyboardType),
        mKeyCharacterMapFile(other.mKeyCharacterMapFile),
        mMotionRanges(other.mMotionRanges) {
}

InputDeviceInfo::~InputDeviceInfo() {
}

void InputDeviceInfo::initialize(int32_t id, const String8& name) {
void InputDeviceInfo::initialize(int32_t id, const String8& name, const String8& descriptor) {
    mId = id;
    mName = name;
    mDescriptor = descriptor;
    mSources = 0;
    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
    mMotionRanges.clear();
+53 −14
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include <androidfw/KeyCharacterMap.h>
#include <androidfw/VirtualKeyMap.h>

#include <sha1.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
@@ -78,6 +79,20 @@ static inline const char* toString(bool value) {
    return value ? "true" : "false";
}

static String8 sha1(const String8& in) {
    SHA1_CTX ctx;
    SHA1Init(&ctx);
    SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
    u_char digest[SHA1_DIGEST_LENGTH];
    SHA1Final(digest, &ctx);

    String8 out;
    for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) {
        out.appendFormat("%02x", digest[i]);
    }
    return out;
}

// --- Global Functions ---

uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
@@ -209,11 +224,11 @@ EventHub::~EventHub(void) {
    release_wake_lock(WAKE_LOCK_ID);
}

String8 EventHub::getDeviceName(int32_t deviceId) const {
InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
    AutoMutex _l(mLock);
    Device* device = getDeviceLocked(deviceId);
    if (device == NULL) return String8();
    return device->identifier.name;
    if (device == NULL) return InputDeviceIdentifier();
    return device->identifier;
}

uint32_t EventHub::getDeviceClasses(int32_t deviceId) const {
@@ -893,6 +908,30 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
        identifier.uniqueId.setTo(buffer);
    }

    // Compute a device descriptor that uniquely identifies the device.
    // The descriptor is assumed to be a stable identifier.  Its value should not
    // change between reboots, reconnections, firmware updates or new releases of Android.
    // Ideally, we also want the descriptor to be short and relatively opaque.
    String8 rawDescriptor;
    rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product);
    if (!identifier.uniqueId.isEmpty()) {
        rawDescriptor.append("uniqueId:");
        rawDescriptor.append(identifier.uniqueId);
    } if (identifier.vendor == 0 && identifier.product == 0) {
        // If we don't know the vendor and product id, then the device is probably
        // built-in so we need to rely on other information to uniquely identify
        // the input device.  Usually we try to avoid relying on the device name or
        // location but for built-in input device, they are unlikely to ever change.
        if (!identifier.name.isEmpty()) {
            rawDescriptor.append("name:");
            rawDescriptor.append(identifier.name);
        } else if (!identifier.location.isEmpty()) {
            rawDescriptor.append("location:");
            rawDescriptor.append(identifier.location);
        }
    }
    identifier.descriptor = sha1(rawDescriptor);

    // Make file descriptor non-blocking for use with poll().
    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
        ALOGE("Error %d making device file descriptor non-blocking.", errno);
@@ -904,19 +943,18 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
    int32_t deviceId = mNextDeviceId++;
    Device* device = new Device(fd, deviceId, String8(devicePath), identifier);

#if 0
    ALOGI("add device %d: %s\n", deviceId, devicePath);
    ALOGI("  bus:       %04x\n"
    ALOGV("add device %d: %s\n", deviceId, devicePath);
    ALOGV("  bus:        %04x\n"
         "  vendor      %04x\n"
         "  product     %04x\n"
         "  version     %04x\n",
        identifier.bus, identifier.vendor, identifier.product, identifier.version);
    ALOGI("  name:      \"%s\"\n", identifier.name.string());
    ALOGI("  location:  \"%s\"\n", identifier.location.string());
    ALOGI("  unique id: \"%s\"\n", identifier.uniqueId.string());
    ALOGI("  driver:    v%d.%d.%d\n",
    ALOGV("  name:       \"%s\"\n", identifier.name.string());
    ALOGV("  location:   \"%s\"\n", identifier.location.string());
    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
    ALOGV("  descriptor: \"%s\" (%s)\n", identifier.descriptor.string(), rawDescriptor.string());
    ALOGV("  driver:     v%d.%d.%d\n",
        driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
#endif

    // Load the configuration file for the device.
    loadConfigurationLocked(device);
@@ -1303,6 +1341,7 @@ void EventHub::dump(String8& dump) {
            }
            dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
            dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
            dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string());
            dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string());
            dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string());
            dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, "
Loading