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

Commit a2e92266 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Maybe fix issue #2482201: Paired bluetooth device looks like a qwerty keyboard

We now only consider a device to be a default keyboard if its name
has "-keypad".  A hack, but whatever.

Also add some debug logging for the input state to help identify such
issues in the future.
parent c018f3cf
Loading
Loading
Loading
Loading
+12 −14
Original line number Diff line number Diff line
@@ -604,8 +604,11 @@ int EventHub::open_device(const char *deviceName)

    // figure out the kinds of events the device reports
    
    // See if this is a keyboard, and classify it.
    uint8_t key_bitmask[(KEY_MAX+1)/8];
    // See if this is a keyboard, and classify it.  Note that we only
    // consider up through the function keys; we don't want to include
    // ones after that (play cd etc) so we don't mistakenly consider a
    // controller to be a keyboard.
    uint8_t key_bitmask[(KEY_PLAYCD+1)/8];
    memset(key_bitmask, 0, sizeof(key_bitmask));
    LOGV("Getting keys...");
    if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
@@ -702,22 +705,20 @@ int EventHub::open_device(const char *deviceName)
        device->layoutMap->load(keylayoutFilename);

        // tell the world about the devname (the descriptive name)
        int32_t publicID;
        if (!mHaveFirstKeyboard && !defaultKeymap) {
            publicID = 0;
        if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) {
            // the built-in keyboard has a well-known device ID of 0,
            // this device better not go away.
            mHaveFirstKeyboard = true;
            mFirstKeyboardId = device->id;
            property_set("hw.keyboards.0.devname", name);
        } else {
            publicID = device->id;
            // ensure mFirstKeyboardId is set to -something-.
            if (mFirstKeyboardId == 0) {
                mFirstKeyboardId = device->id;
            }
        }
        char propName[100];
        sprintf(propName, "hw.keyboards.%u.devname", publicID);
        sprintf(propName, "hw.keyboards.%u.devname", device->id);
        property_set(propName, name);

        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
@@ -734,8 +735,8 @@ int EventHub::open_device(const char *deviceName)
            device->classes |= CLASS_DPAD;
        }
        
        LOGI("New keyboard: publicID=%d device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
                publicID, device->id, name, propName, keylayoutFilename);
        LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
                device->id, name, propName, keylayoutFilename);
    }

    LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
@@ -808,18 +809,15 @@ int EventHub::close_device(const char *deviceName)
            device->next = mClosingDevices;
            mClosingDevices = device;

            uint32_t publicID;
            if (device->id == mFirstKeyboardId) {
                LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
                        device->path.string(), mFirstKeyboardId);
                mFirstKeyboardId = 0;
                publicID = 0;
            } else {
                publicID = device->id;
                property_set("hw.keyboards.0.devname", NULL);
            }
            // clear the property
            char propName[100];
            sprintf(propName, "hw.keyboards.%u.devname", publicID);
            sprintf(propName, "hw.keyboards.%u.devname", device->id);
            property_set(propName, NULL);
            return 0;
        }
+61 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.view.MotionEvent;
import android.view.Surface;
import android.view.WindowManagerPolicy;

import java.io.PrintWriter;

public class InputDevice {
    static final boolean DEBUG_POINTERS = false;
    static final boolean DEBUG_HACKS = false;
@@ -58,6 +60,7 @@ public class InputDevice {
        float yMoveScale;
        MotionEvent currentMove = null;
        boolean changed = false;
        boolean everChanged = false;
        long mDownTime = 0;
        
        // The currently assigned pointer IDs, corresponding to the last data.
@@ -103,6 +106,56 @@ public class InputDevice {
        int mAddingPointerOffset = 0;
        final boolean[] mDown = new boolean[MAX_POINTERS];
        
        void dumpIntArray(PrintWriter pw, int[] array) {
            pw.print("[");
            for (int i=0; i<array.length; i++) {
                if (i > 0) pw.print(", ");
                pw.print(array[i]);
            }
            pw.print("]");
        }
        
        void dumpBooleanArray(PrintWriter pw, boolean[] array) {
            pw.print("[");
            for (int i=0; i<array.length; i++) {
                if (i > 0) pw.print(", ");
                pw.print(array[i] ? "true" : "false");
            }
            pw.print("]");
        }
        
        void dump(PrintWriter pw, String prefix) {
            pw.print(prefix); pw.print("xPrecision="); pw.print(xPrecision);
                    pw.print(" yPrecision="); pw.println(yPrecision);
            pw.print(prefix); pw.print("xMoveScale="); pw.print(xMoveScale);
                    pw.print(" yMoveScale="); pw.println(yMoveScale);
            if (currentMove != null) {
                pw.print(prefix); pw.print("currentMove="); pw.println(currentMove);
            }
            if (changed || mDownTime != 0) {
                pw.print(prefix); pw.print("changed="); pw.print(changed);
                        pw.print(" mDownTime="); pw.println(mDownTime);
            }
            pw.print(prefix); pw.print("mPointerIds="); dumpIntArray(pw, mPointerIds);
                    pw.println("");
            if (mSkipLastPointers || mLastNumPointers != 0) {
                pw.print(prefix); pw.print("mSkipLastPointers="); pw.print(mSkipLastPointers);
                        pw.print(" mLastNumPointers="); pw.println(mLastNumPointers);
                pw.print(prefix); pw.print("mLastData="); dumpIntArray(pw, mLastData);
                        pw.println("");
            }
            if (mNextNumPointers != 0) {
                pw.print(prefix); pw.print("mNextNumPointers="); pw.println(mNextNumPointers);
                pw.print(prefix); pw.print("mNextData="); dumpIntArray(pw, mNextData);
                        pw.println("");
            }
            pw.print(prefix); pw.print("mDroppedBadPoint=");
                    dumpBooleanArray(pw, mDroppedBadPoint); pw.println("");
            pw.print(prefix); pw.print("mAddingPointerOffset="); pw.println(mAddingPointerOffset);
            pw.print(prefix); pw.print("mDown=");
                    dumpBooleanArray(pw, mDown); pw.println("");
        }
        
        MotionState(int mx, int my) {
            xPrecision = mx;
            yPrecision = my;
@@ -775,6 +828,14 @@ public class InputDevice {
        int range;
        int flat;
        int fuzz;
        
        final void dump(PrintWriter pw) {
            pw.print("minValue="); pw.print(minValue);
            pw.print(" maxValue="); pw.print(maxValue);
            pw.print(" range="); pw.print(range);
            pw.print(" flat="); pw.print(flat);
            pw.print(" fuzz="); pw.print(fuzz);
        }
    };
    
    InputDevice(int _id, int _classes, String _name,
+91 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.os.Environment;
import android.os.LatencyTimer;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Slog;
import android.util.SparseArray;
import android.util.Xml;
@@ -43,6 +44,7 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;

public abstract class KeyInputQueue {
@@ -738,6 +740,7 @@ public abstract class KeyInputQueue {
                                
                                InputDevice.MotionState ms = di.mAbs;
                                if (ms.changed) {
                                    ms.everChanged = true;
                                    ms.changed = false;
                                    
                                    if ((classes&(RawInputEvent.CLASS_TOUCHSCREEN
@@ -809,6 +812,7 @@ public abstract class KeyInputQueue {
                                
                                ms = di.mRel;
                                if (ms.changed) {
                                    ms.everChanged = true;
                                    ms.changed = false;
                                    
                                    me = ms.generateRelMotion(di, curTime,
@@ -1280,4 +1284,91 @@ public abstract class KeyInputQueue {
        return null;
    }
    private static native boolean readEvent(RawInputEvent outEvent);
    
    void dump(PrintWriter pw, String prefix) {
        synchronized (mFirst) {
            for (int i=0; i<mDevices.size(); i++) {
                InputDevice dev = mDevices.valueAt(i);
                pw.print(prefix); pw.print("Device #");
                        pw.print(mDevices.keyAt(i)); pw.print(" ");
                        pw.print(dev.name); pw.print(" (classes=0x");
                        pw.print(Integer.toHexString(dev.classes));
                        pw.println("):");
                pw.print(prefix); pw.print("  mKeyDownTime=");
                        pw.print(dev.mKeyDownTime); pw.print(" mMetaKeysState=");
                        pw.println(dev.mMetaKeysState);
                if (dev.absX != null) {
                    pw.print(prefix); pw.print("  absX: "); dev.absX.dump(pw);
                            pw.println("");
                }
                if (dev.absY != null) {
                    pw.print(prefix); pw.print("  absY: "); dev.absY.dump(pw);
                            pw.println("");
                }
                if (dev.absPressure != null) {
                    pw.print(prefix); pw.print("  absPressure: ");
                            dev.absPressure.dump(pw); pw.println("");
                }
                if (dev.absSize != null) {
                    pw.print(prefix); pw.print("  absSize: ");
                            dev.absSize.dump(pw); pw.println("");
                }
                if (dev.mAbs.everChanged) {
                    pw.print(prefix); pw.println("  mAbs:");
                    dev.mAbs.dump(pw, prefix + "    ");
                }
                if (dev.mRel.everChanged) {
                    pw.print(prefix); pw.println("  mRel:");
                    dev.mRel.dump(pw, prefix + "    ");
                }
            }
            pw.println(" ");
            for (int i=0; i<mIgnoredDevices.size(); i++) {
                InputDevice dev = mIgnoredDevices.valueAt(i);
                pw.print(prefix); pw.print("Ignored Device #");
                        pw.print(mIgnoredDevices.keyAt(i)); pw.print(" ");
                        pw.print(dev.name); pw.print(" (classes=0x");
                        pw.print(Integer.toHexString(dev.classes));
                        pw.println(")");
            }
            pw.println(" ");
            for (int i=0; i<mVirtualKeys.size(); i++) {
                VirtualKey vk = mVirtualKeys.get(i);
                pw.print(prefix); pw.print("Virtual Key #");
                        pw.print(i); pw.println(":");
                pw.print(prefix); pw.print("  scancode="); pw.println(vk.scancode);
                pw.print(prefix); pw.print("  centerx="); pw.print(vk.centerx);
                        pw.print(" centery="); pw.print(vk.centery);
                        pw.print(" width="); pw.print(vk.width);
                        pw.print(" height="); pw.println(vk.height);
                pw.print(prefix); pw.print("  hitLeft="); pw.print(vk.hitLeft);
                        pw.print(" hitTop="); pw.print(vk.hitTop);
                        pw.print(" hitRight="); pw.print(vk.hitRight);
                        pw.print(" hitBottom="); pw.println(vk.hitBottom);
                if (vk.lastDevice != null) {
                    pw.print(prefix); pw.print("  lastDevice=#");
                            pw.println(vk.lastDevice.id);
                }
                if (vk.lastKeycode != 0) {
                    pw.print(prefix); pw.print("  lastKeycode=");
                            pw.println(vk.lastKeycode);
                }
            }
            pw.println(" ");
            pw.print(prefix); pw.print("  Default keyboard: ");
                    pw.println(SystemProperties.get("hw.keyboards.0.devname"));
            pw.print(prefix); pw.print("  mGlobalMetaState=");
                    pw.print(mGlobalMetaState); pw.print(" mHaveGlobalMetaState=");
                    pw.println(mHaveGlobalMetaState);
            pw.print(prefix); pw.print("  mDisplayWidth=");
                    pw.print(mDisplayWidth); pw.print(" mDisplayHeight=");
                    pw.println(mDisplayHeight);
            pw.print(prefix); pw.print("  mOrientation=");
                    pw.println(mOrientation);
            if (mPressedVirtualKey != null) {
                pw.print(prefix); pw.print("  mPressedVirtualKey.scancode=");
                        pw.println(mPressedVirtualKey.scancode);
            }
        }
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -10851,6 +10851,10 @@ public class WindowManagerService extends IWindowManager.Stub
            return;
        }

        pw.println("Input State:");
        mQueue.dump(pw, "  ");
        pw.println(" ");
        
        synchronized(mWindowMap) {
            pw.println("Current Window Manager state:");
            for (int i=mWindows.size()-1; i>=0; i--) {
@@ -11014,7 +11018,7 @@ public class WindowManagerService extends IWindowManager.Stub
            if (mDimAnimator != null) {
                mDimAnimator.printTo(pw);
            } else {
                pw.print( "  no DimAnimator ");
                pw.println( "  no DimAnimator ");
            }
            pw.print("  mInputMethodAnimLayerAdjustment=");
                    pw.print(mInputMethodAnimLayerAdjustment);