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

Commit 56852762 authored by Abdelrahman Awadalla's avatar Abdelrahman Awadalla Committed by Android (Google) Code Review
Browse files

Merge "Visualize the fingers on the touchpad visualizer" into main

parents c7370bae 6ba013cf
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.server.input.TouchpadFingerState;
import com.android.server.input.TouchpadHardwareProperties;
import com.android.server.input.TouchpadHardwareState;

import java.util.Objects;
@@ -60,13 +61,15 @@ public class TouchpadDebugView extends LinearLayout {
    private TouchpadHardwareState mLastTouchpadState =
            new TouchpadHardwareState(0, 0 /* buttonsDown */, 0, 0,
                    new TouchpadFingerState[0]);
    private TouchpadVisualizationView mTouchpadVisualizationView;

    public TouchpadDebugView(Context context, int touchpadId) {
    public TouchpadDebugView(Context context, int touchpadId,
            TouchpadHardwareProperties touchpadHardwareProperties) {
        super(context);
        mTouchpadId = touchpadId;
        mWindowManager =
                Objects.requireNonNull(getContext().getSystemService(WindowManager.class));
        init(context, touchpadId);
        init(context, touchpadHardwareProperties, touchpadId);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        // TODO(b/360137366): Use the hardware properties to initialise layout parameters.
@@ -89,7 +92,8 @@ public class TouchpadDebugView extends LinearLayout {
        mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
    }

    private void init(Context context, int touchpadId) {
    private void init(Context context, TouchpadHardwareProperties touchpadHardwareProperties,
            int touchpadId) {
        setOrientation(VERTICAL);
        setLayoutParams(new LayoutParams(
                LayoutParams.WRAP_CONTENT,
@@ -106,10 +110,12 @@ public class TouchpadDebugView extends LinearLayout {
        nameView.setTextColor(Color.WHITE);
        nameView.setLayoutParams(new LayoutParams(1000, 200));

        TouchpadVisualisationView touchpadVisualisationView =
                new TouchpadVisualisationView(context);
        touchpadVisualisationView.setBackgroundColor(Color.WHITE);
        touchpadVisualisationView.setLayoutParams(new LayoutParams(1000, 200));
        mTouchpadVisualizationView = new TouchpadVisualizationView(context,
                touchpadHardwareProperties);
        mTouchpadVisualizationView.setBackgroundColor(Color.WHITE);
        //TODO(b/365568238): set the view size according to the touchpad size from the
        // TouchpadHardwareProperties
        mTouchpadVisualizationView.setLayoutParams(new LayoutParams(778, 500));

        //TODO(b/365562952): Add a display for recognized gesture info here
        TextView gestureInfoView = new TextView(context);
@@ -121,7 +127,7 @@ public class TouchpadDebugView extends LinearLayout {
        gestureInfoView.setLayoutParams(new LayoutParams(1000, 200));

        addView(nameView);
        addView(touchpadVisualisationView);
        addView(mTouchpadVisualizationView);
        addView(gestureInfoView);

        updateScreenDimensions();
@@ -214,14 +220,18 @@ public class TouchpadDebugView extends LinearLayout {
    }

    /**
     * Notify the view of a change in TouchpadHardwareState and changing the
     * color of the view based on the status of the button click.
     * 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
     */
    public void updateHardwareState(TouchpadHardwareState touchpadHardwareState, int deviceId) {
        if (deviceId != mTouchpadId) {
            return;
        }

        mTouchpadVisualizationView.onTouchpadHardwareStateNotified(touchpadHardwareState);
        if (mLastTouchpadState.getButtonsDown() == 0) {
            if (touchpadHardwareState.getButtonsDown() > 0) {
                onTouchpadButtonPress();
+13 −8
Original line number Diff line number Diff line
@@ -112,18 +112,20 @@ public class TouchpadDebugViewController implements InputManager.InputDeviceList
        final WindowManager wm = Objects.requireNonNull(
                mContext.getSystemService(WindowManager.class));

        mTouchpadDebugView = new TouchpadDebugView(mContext, touchpadId);
        TouchpadHardwareProperties touchpadHardwareProperties =
                mInputManagerService.getTouchpadHardwareProperties(
                        touchpadId);

        mTouchpadDebugView = new TouchpadDebugView(mContext, touchpadId,
                touchpadHardwareProperties);
        final WindowManager.LayoutParams mWindowLayoutParams =
                mTouchpadDebugView.getWindowLayoutParams();

        wm.addView(mTouchpadDebugView, mWindowLayoutParams);
        Slog.d(TAG, "Touchpad debug view created.");

        TouchpadHardwareProperties mTouchpadHardwareProperties =
                mInputManagerService.getTouchpadHardwareProperties(
                        touchpadId);
        if (mTouchpadHardwareProperties != null) {
            Slog.d(TAG, mTouchpadHardwareProperties.toString());
        if (touchpadHardwareProperties != null) {
            Slog.d(TAG, touchpadHardwareProperties.toString());
        } else {
            Slog.w(TAG, "Failed to retrieve touchpad hardware properties for "
                    + "device ID: " + touchpadId);
@@ -142,7 +144,10 @@ public class TouchpadDebugViewController implements InputManager.InputDeviceList
    }

    /**
     * Notify the TouchpadDebugView with the new TouchpadHardwareState.
     * Notifies about an update in the touchpad's hardware state.
     *
     * @param touchpadHardwareState the hardware state of a touchpad
     * @param deviceId              the deviceId of the touchpad that is sending the hardware state
     */
    public void updateTouchpadHardwareState(TouchpadHardwareState touchpadHardwareState,
            int deviceId) {
+0 −26
Original line number Diff line number Diff line
/*
 * Copyright 2024 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 com.android.server.input.debug;

import android.content.Context;
import android.view.View;

public class TouchpadVisualisationView extends View {
    public TouchpadVisualisationView(Context context) {
        super(context);
    }
}
+130 −0
Original line number Diff line number Diff line
/*
 * Copyright 2024 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 com.android.server.input.debug;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.Slog;
import android.view.View;

import com.android.server.input.TouchpadFingerState;
import com.android.server.input.TouchpadHardwareProperties;
import com.android.server.input.TouchpadHardwareState;

public class TouchpadVisualizationView extends View {
    private static final String TAG = "TouchpadVizMain";
    private static final boolean DEBUG = true;

    private final TouchpadHardwareProperties mTouchpadHardwareProperties;

    TouchpadHardwareState mLatestHardwareState = new TouchpadHardwareState(0, 0, 0, 0,
            new TouchpadFingerState[]{});

    private final Paint mOvalPaint;

    public TouchpadVisualizationView(Context context,
            TouchpadHardwareProperties touchpadHardwareProperties) {
        super(context);
        mTouchpadHardwareProperties = touchpadHardwareProperties;
        mOvalPaint = new Paint();
        mOvalPaint.setAntiAlias(true);
        mOvalPaint.setARGB(255, 0, 0, 0);
        mOvalPaint.setStyle(Paint.Style.STROKE);
    }

    private final RectF mOvalRect = new RectF();

    private void drawOval(Canvas canvas, float x, float y, float major, float minor, float angle,
            Paint paint) {
        canvas.save(Canvas.MATRIX_SAVE_FLAG);
        canvas.rotate(angle, x, y);
        mOvalRect.left = x - minor / 2;
        mOvalRect.right = x + minor / 2;
        mOvalRect.top = y - major / 2;
        mOvalRect.bottom = y + major / 2;
        canvas.drawOval(mOvalRect, paint);
        canvas.restore();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (TouchpadFingerState touchpadFingerState : mLatestHardwareState.getFingerStates()) {
            float newX = translateRange(mTouchpadHardwareProperties.getLeft(),
                    mTouchpadHardwareProperties.getRight(), 0, getWidth(),
                    touchpadFingerState.getPositionX());

            float newY = translateRange(mTouchpadHardwareProperties.getTop(),
                    mTouchpadHardwareProperties.getBottom(), 0, getHeight(),
                    touchpadFingerState.getPositionY());

            float newAngle = -translateRange(mTouchpadHardwareProperties.getOrientationMinimum(),
                    mTouchpadHardwareProperties.getOrientationMaximum(), 0, 360,
                    touchpadFingerState.getOrientation());

            float newTouchMajor =
                    touchpadFingerState.getTouchMajor() / mTouchpadHardwareProperties.getResX();
            float newTouchMinor =
                    touchpadFingerState.getTouchMinor() / mTouchpadHardwareProperties.getResY();

            drawOval(canvas, newX, newY, newTouchMajor, newTouchMinor, newAngle, mOvalPaint);
        }
    }

    /**
     * Receiving the touchpad hardware state and based on it update the latest hardware state.
     *
     * @param schs The new hardware state received.
     */
    public void onTouchpadHardwareStateNotified(TouchpadHardwareState schs) {
        if (DEBUG) {
            logHardwareState(schs);
        }

        mLatestHardwareState = schs;

        invalidate();
    }

    private float translateRange(float rangeBeforeMin, float rangeBeforeMax,
            float rangeAfterMin, float rangeAfterMax, float value) {
        return rangeAfterMin + (value - rangeBeforeMin) / (rangeBeforeMax - rangeBeforeMin) * (
                rangeAfterMax - rangeAfterMin);
    }

    private void logHardwareState(TouchpadHardwareState schs) {
        Slog.d(TAG, "notifyTouchpadHardwareState: Time: "
                + schs.getTimestamp() + ", No. Buttons: "
                + schs.getButtonsDown() + ", No. Fingers: "
                + schs.getFingerCount() + ", No. Touch: "
                + schs.getTouchCount());

        for (TouchpadFingerState finger : schs.getFingerStates()) {
            Slog.d(TAG, "Finger #" + finger.getTrackingId()
                    + ": touchMajor= " + finger.getTouchMajor()
                    + ", touchMinor= " + finger.getTouchMinor()
                    + ", widthMajor= " + finger.getWidthMajor()
                    + ", widthMinor= " + finger.getWidthMinor()
                    + ", pressure= " + finger.getPressure()
                    + ", orientation= " + finger.getOrientation()
                    + ", positionX= " + finger.getPositionX()
                    + ", positionY= " + finger.getPositionY());
        }
    }

}
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.view.WindowMetrics;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.server.input.InputManagerService;
import com.android.server.input.TouchpadHardwareProperties;

import org.junit.Before;
import org.junit.Rule;
@@ -87,6 +88,9 @@ public class TouchpadDebugViewControllerTests {
        mTestableLooper = TestableLooper.get(this);

        mTestableContext.addMockSystemService(InputManager.class, mInputManagerMock);
        when(mInputManagerServiceMock.getTouchpadHardwareProperties(DEVICE_ID)).thenReturn(
                new TouchpadHardwareProperties.Builder(-100f, 100f, -100f, 100f, 45f, 45f, -5f, 5f,
                        (short) 10, true, false).build());

        mTouchpadDebugViewController = new TouchpadDebugViewController(mTestableContext,
                mTestableLooper.getLooper(), mInputManagerServiceMock);
Loading