From 3d1dc8b0c919fc2c6e482082b4485c6d7c6acbe7 Mon Sep 17 00:00:00 2001 From: Omar Abdelmonem Date: Wed, 11 Sep 2024 16:29:57 +0000 Subject: 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 --- .../android/server/input/InputManagerService.java | 8 +++ .../server/input/debug/TouchpadDebugView.java | 77 +++++++++++++++++----- .../input/debug/TouchpadDebugViewController.java | 9 +++ ...om_android_server_input_InputManagerService.cpp | 14 ++++ .../server/input/debug/TouchpadDebugViewTest.java | 14 ++++ 5 files changed, 104 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index ca8ae6e2e68d..0a8c158aba9f 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -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) { diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java index cc13e8e5ccc7..3f11e7836609 100644 --- a/services/core/java/com/android/server/input/debug/TouchpadDebugView.java +++ b/services/core/java/com/android/server/input/debug/TouchpadDebugView.java @@ -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, @@ -75,7 +80,7 @@ public class TouchpadDebugView extends LinearLayout { private final TouchpadHardwareProperties mTouchpadHardwareProperties; public TouchpadDebugView(Context context, int touchpadId, - TouchpadHardwareProperties touchpadHardwareProperties) { + TouchpadHardwareProperties touchpadHardwareProperties) { super(context); mTouchpadId = touchpadId; mWindowManager = @@ -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; + } } diff --git a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java index b4b357a29363..cb43977d9911 100644 --- a/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java +++ b/services/core/java/com/android/server/input/debug/TouchpadDebugViewController.java @@ -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); + } + } } diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 67346ab1b358..8c4448e7915f 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -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& inputDevices) override; void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs, int32_t deviceId) override; + void notifyTouchpadGestureInfo(enum GestureType type, int32_t deviceId) override; std::shared_ptr getKeyboardLayoutOverlay( const InputDeviceIdentifier& identifier, const std::optional 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 NativeInputManager::getKeyboardLayoutOverlay( const InputDeviceIdentifier& identifier, const std::optional 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"); diff --git a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java index 071968679b9b..681b7f28451b 100644 --- a/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java +++ b/tests/Input/src/com/android/server/input/debug/TouchpadDebugViewTest.java @@ -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)); + } } -- cgit v1.2.3-59-g8ed1b