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

Commit 3d1dc8b0 authored by Omar Abdelmonem's avatar Omar Abdelmonem
Browse files

Display the gesture name on the TouchpadDebugView

Fetch the gesture type and display it on the TouchpadDebugView
while updating the view display each time a new gesture is received.
Made the view edges rounded.

Bug: 365562952
Test: Added unit tests to that sends a gesture type index to the
TouchpadDebugView and confirms the displayed gesture name matches
the sent one.
Flag: com.android.hardware.input.touchpad_visualizer

Change-Id: I42a9a09403905c0fff2d2cc693731db21083c7ff
parent 48cdc816
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -2274,6 +2274,14 @@ public class InputManagerService extends IInputManager.Stub
        }
    }

    // Native callback.
    @SuppressWarnings("unused")
    private void notifyTouchpadGestureInfo(int type, int deviceId) {
        if (mTouchpadDebugViewController != null) {
            mTouchpadDebugViewController.updateTouchpadGestureInfo(type, deviceId);
        }
    }

    // Native callback.
    @SuppressWarnings("unused")
    private void notifySwitch(long whenNanos, int switchValues, int switchMask) {
+59 −18
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.input.TouchpadFingerState;
import com.android.server.input.TouchpadHardwareProperties;
import com.android.server.input.TouchpadHardwareState;
@@ -47,11 +48,13 @@ public class TouchpadDebugView extends LinearLayout {
    private static final float TEXT_SIZE_SP = 16.0f;
    private static final float DEFAULT_RES_X = 47f;
    private static final float DEFAULT_RES_Y = 45f;
    private static final int TEXT_PADDING_DP = 12;

    /**
     * Input device ID for the touchpad that this debug view is displaying.
     */
    private final int mTouchpadId;
    private static final String TAG = "TouchpadDebugView";

    @NonNull
    private final WindowManager mWindowManager;
@@ -67,6 +70,8 @@ public class TouchpadDebugView extends LinearLayout {
    private int mScreenHeight;
    private int mWindowLocationBeforeDragX;
    private int mWindowLocationBeforeDragY;
    private int mLatestGestureType = 0;
    private TextView mGestureInfoView;
    @NonNull
    private TouchpadHardwareState mLastTouchpadState =
            new TouchpadHardwareState(0, 0 /* buttonsDown */, 0, 0,
@@ -119,6 +124,9 @@ public class TouchpadDebugView extends LinearLayout {
                .getInputDevice(touchpadId)).getName());
        nameView.setGravity(Gravity.CENTER);
        nameView.setTextColor(Color.WHITE);
        int paddingInDP = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, TEXT_PADDING_DP,
                getResources().getDisplayMetrics());
        nameView.setPadding(paddingInDP, paddingInDP, paddingInDP, paddingInDP);
        nameView.setLayoutParams(
                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

@@ -126,19 +134,19 @@ public class TouchpadDebugView extends LinearLayout {
                mTouchpadHardwareProperties);
        mTouchpadVisualizationView.setBackgroundColor(Color.WHITE);

        //TODO(b/365562952): Add a display for recognized gesture info here
        TextView gestureInfoView = new TextView(context);
        gestureInfoView.setBackgroundColor(Color.GRAY);
        gestureInfoView.setTextSize(TEXT_SIZE_SP);
        gestureInfoView.setText("Touchpad Debug View 3");
        gestureInfoView.setGravity(Gravity.CENTER);
        gestureInfoView.setTextColor(Color.BLACK);
        gestureInfoView.setLayoutParams(
        mGestureInfoView = new TextView(context);
        mGestureInfoView.setBackgroundColor(Color.BLACK);
        mGestureInfoView.setTextSize(TEXT_SIZE_SP);
        mGestureInfoView.setText("Latest Gesture: ");
        mGestureInfoView.setGravity(Gravity.CENTER);
        mGestureInfoView.setTextColor(Color.WHITE);
        mGestureInfoView.setPadding(paddingInDP, paddingInDP, paddingInDP, paddingInDP);
        mGestureInfoView.setLayoutParams(
                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));

        addView(nameView);
        addView(mTouchpadVisualizationView);
        addView(gestureInfoView);
        addView(mGestureInfoView);

        updateViewsDimensions();
    }
@@ -193,7 +201,7 @@ public class TouchpadDebugView extends LinearLayout {
    @Override
    public boolean performClick() {
        super.performClick();
        Slog.d("TouchpadDebugView", "You tapped the window!");
        Slog.d(TAG, "You tapped the window!");
        return true;
    }

@@ -265,12 +273,14 @@ public class TouchpadDebugView extends LinearLayout {
        return mWindowLayoutParams;
    }

    @VisibleForTesting
    TextView getGestureInfoView() {
        return mGestureInfoView;
    }

    /**
     * Notify the view of a change in the hardware state of a touchpad. The view should
     * update its content to reflect the new state.
     *
     * @param touchpadHardwareState the hardware state of a touchpad
     * @param deviceId              the deviceId of the touchpad that is sending the hardware state
     * Notify the view of a change in TouchpadHardwareState and changing the
     * color of the view based on the status of the button click.
     */
    public void updateHardwareState(TouchpadHardwareState touchpadHardwareState, int deviceId) {
        if (deviceId != mTouchpadId) {
@@ -291,12 +301,43 @@ public class TouchpadDebugView extends LinearLayout {
    }

    private void onTouchpadButtonPress() {
        Slog.d("TouchpadDebugView", "You clicked me!");
        Slog.d(TAG, "You clicked me!");
        getChildAt(0).setBackgroundColor(Color.BLUE);
    }

    private void onTouchpadButtonRelease() {
        Slog.d("TouchpadDebugView", "You released the click");
        Slog.d(TAG, "You released the click");
        getChildAt(0).setBackgroundColor(Color.RED);
    }

    /**
     * Notify the view of any new gesture on the touchpad and displaying its name
     */
    public void updateGestureInfo(int newGestureType, int deviceId) {
        if (deviceId == mTouchpadId && mLatestGestureType != newGestureType) {
            mGestureInfoView.setText(getGestureText(newGestureType));
            mLatestGestureType = newGestureType;
        }
    }

    @NonNull
    static String getGestureText(int gestureType) {
        // These values are a representation of the GestureType enum in the
        // external/libchrome-gestures/include/gestures.h library in the C++ code
        String mGestureName = switch (gestureType) {
            case 1 -> "Move, 1 Finger";
            case 2 -> "Scroll, 2 Fingers";
            case 3 -> "Buttons Change, 1 Fingers";
            case 4 -> "Fling";
            case 5 -> "Swipe, 3 Fingers";
            case 6 -> "Pinch, 2 Fingers";
            case 7 -> "Swipe Lift, 3 Fingers";
            case 8 -> "Metrics";
            case 9 -> "Four Finger Swipe, 4 Fingers";
            case 10 -> "Four Finger Swipe Lift, 4 Fingers";
            case 11 -> "Mouse Wheel";
            default -> "Unknown Gesture";
        };
        return "Latest Gesture: " + mGestureName;
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -155,4 +155,13 @@ public class TouchpadDebugViewController implements InputManager.InputDeviceList
            mTouchpadDebugView.updateHardwareState(touchpadHardwareState, deviceId);
        }
    }

    /**
     * Notify the TouchpadDebugView of a new touchpad gesture.
     */
    public void updateTouchpadGestureInfo(int gestureType, int deviceId) {
        if (mTouchpadDebugView != null) {
            mTouchpadDebugView.updateGestureInfo(gestureType, deviceId);
        }
    }
}
+14 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ static struct {
    jclass clazz;
    jmethodID notifyInputDevicesChanged;
    jmethodID notifyTouchpadHardwareState;
    jmethodID notifyTouchpadGestureInfo;
    jmethodID notifySwitch;
    jmethodID notifyInputChannelBroken;
    jmethodID notifyNoFocusedWindowAnr;
@@ -363,6 +364,7 @@ public:
    void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override;
    void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
                                     int32_t deviceId) override;
    void notifyTouchpadGestureInfo(enum GestureType type, int32_t deviceId) override;
    std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
            const InputDeviceIdentifier& identifier,
            const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo) override;
@@ -996,6 +998,15 @@ void NativeInputManager::notifyTouchpadHardwareState(const SelfContainedHardware
    checkAndClearExceptionFromCallback(env, "notifyTouchpadHardwareState");
}

void NativeInputManager::notifyTouchpadGestureInfo(enum GestureType type, int32_t deviceId) {
    ATRACE_CALL();
    JNIEnv* env = jniEnv();

    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyTouchpadGestureInfo, type, deviceId);

    checkAndClearExceptionFromCallback(env, "notifyTouchpadGestureInfo");
}

std::shared_ptr<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
        const InputDeviceIdentifier& identifier,
        const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo) {
@@ -3068,6 +3079,9 @@ int register_android_server_InputManager(JNIEnv* env) {
                  "notifyTouchpadHardwareState",
                  "(Lcom/android/server/input/TouchpadHardwareState;I)V")

    GET_METHOD_ID(gServiceClassInfo.notifyTouchpadGestureInfo, clazz, "notifyTouchpadGestureInfo",
                  "(II)V")

    GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz,
            "notifySwitch", "(JII)V");

+14 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowMetrics;
import android.widget.TextView;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
@@ -327,4 +328,17 @@ public class TouchpadDebugViewTest {

        assertEquals(((ColorDrawable) child.getBackground()).getColor(), Color.BLUE);
    }

    @Test
    public void testTouchpadGesture() {
        int gestureType = 3;
        TextView child = mTouchpadDebugView.getGestureInfoView();

        mTouchpadDebugView.updateGestureInfo(gestureType, TOUCHPAD_DEVICE_ID);
        assertEquals(child.getText().toString(), TouchpadDebugView.getGestureText(gestureType));

        gestureType = 6;
        mTouchpadDebugView.updateGestureInfo(gestureType, TOUCHPAD_DEVICE_ID);
        assertEquals(child.getText().toString(), TouchpadDebugView.getGestureText(gestureType));
    }
}