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

Commit d2c752ca authored by Vladimir Komsiyski's avatar Vladimir Komsiyski Committed by Android (Google) Code Review
Browse files

Merge "Tap and swipe API in relative display space." into main

parents 34879414 6a5f4d9d
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.companion.virtual.computercontrol;

import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -143,6 +144,50 @@ public final class ComputerControlSession implements AutoCloseable {
        return mImageReader == null ? null : mImageReader.acquireLatestImage();
    }

    /**
     * Sends a tap event to the computer control session at the given location.
     *
     * <p>The coordinates are in relative display space, e.g. (0.5, 0.5) is the center of the
     * display.</p>
     */
    public void tap(@FloatRange(from = 0.0, to = 1.0) float x,
            @FloatRange(from = 0.0, to = 1.0) float y) {
        if (x < 0 || x > 1 || y < 0 || y > 1) {
            throw new IllegalArgumentException("Tap coordinates must be in range [0, 1]");
        }
        try {
            mSession.tap(x, y);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Sends a swipe event to the computer control session for the given coordinates.
     *
     * <p>To avoid misinterpreting the swipe as a fling, the individual touches are throttled, so
     * the entire action will take ~500ms. However, this is done in the background and this method
     * returns immediately. Any ongoing swipe will be canceled if a new swipe is requested.</p>
     *
     * <p>The coordinates are in relative display space, e.g. (0.5, 0.5) is the center of the
     * display.</p>
     */
    public void swipe(
            @FloatRange(from = 0.0, to = 1.0) float fromX,
            @FloatRange(from = 0.0, to = 1.0) float fromY,
            @FloatRange(from = 0.0, to = 1.0) float toX,
            @FloatRange(from = 0.0, to = 1.0) float toY) {
        if (fromX < 0 || fromX > 1 || fromY < 0 || fromY > 1
                || toX < 0 || toX > 1 || toY < 0 || toY > 1) {
            throw new IllegalArgumentException("Swipe coordinates must be in range [0, 1]");
        }
        try {
            mSession.swipe(fromX, fromY, toX, toY);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** Returns the ID of the single trusted virtual display for this session. */
    public int getVirtualDisplayId() {
        try {
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,12 @@ import android.view.Surface;
 */
interface IComputerControlSession {

    /* Injects a tap event into the trusted virtual display. */
    void tap(float x, float y);

    /* Injects a swipe event into the trusted virtual display. */
    void swipe(float fromX, float fromY, float toX, float toY);

    /** Returns the ID of the single trusted virtual display for this session. */
    int getVirtualDisplayId();

+41 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;

import android.hardware.display.DisplayManagerGlobal;
import android.hardware.display.IDisplayManager;
@@ -126,4 +127,44 @@ public class ComputerControlSessionTest {
        mSession.close();
        verify(mMockSession).close();
    }

    @Test
    public void tap_taps() throws RemoteException {
        mSession.tap(0.1f, 0.2f);
        verify(mMockSession).tap(eq(0.1f), eq(0.2f));
    }

    @Test
    public void tapNotInRange_throws() {
        assertThrows(IllegalArgumentException.class, () -> mSession.tap(-0.1f, 0.2f));
        assertThrows(IllegalArgumentException.class, () -> mSession.tap(1.1f, 0.2f));
        assertThrows(IllegalArgumentException.class, () -> mSession.tap(0.1f, -0.2f));
        assertThrows(IllegalArgumentException.class, () -> mSession.tap(0.1f, 1.2f));
    }

    @Test
    public void swipe_swipes() throws RemoteException {
        mSession.swipe(0.1f, 0.2f, 0.3f, 0.4f);
        verify(mMockSession).swipe(eq(0.1f), eq(0.2f), eq(0.3f), eq(0.4f));
    }

    @Test
    public void swipeNotInRange_throws() {
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(-0.1f, 0.2f, 0.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(1.1f, 0.2f, 0.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, -0.2f, 0.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, 1.2f, 0.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, 0.2f, -0.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, 0.2f, 1.3f, 0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, 0.2f, 0.3f, -0.4f));
        assertThrows(IllegalArgumentException.class,
                () -> mSession.swipe(0.1f, 0.2f, 0.3f, 1.4f));
    }
}
+30 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.extensions.computercontrol;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.FloatRange;
import android.app.ActivityOptions;
import android.companion.virtual.computercontrol.InteractiveMirrorDisplay;
import android.content.Context;
@@ -111,6 +112,35 @@ public final class ComputerControlSession implements AutoCloseable {
        return mSession.getScreenshot();
    }

    /**
     * Sends a tap event to the computer control session at the given location.
     *
     * <p>The coordinates are in relative display space, e.g. (0.5, 0.5) is the center of the
     * display.</p>
     */
    public void tap(@FloatRange(from = 0.0, to = 1.0) float x,
            @FloatRange(from = 0.0, to = 1.0) float y) {
        mSession.tap(x, y);
    }

    /**
     * Sends a swipe event to the computer control session for the given coordinates.
     *
     * <p>To avoid misinterpreting the swipe as a fling, the individual touches are throttled, so
     * the entire action will take ~500ms. However, this is done in the background and this method
     * returns immediately. Any ongoing swipe will be canceled if a new swipe is requested.</p>
     *
     * <p>The coordinates are in relative display space, e.g. (0.5, 0.5) is the center of the
     * display.</p>
     */
    public void swipe(
            @FloatRange(from = 0.0, to = 1.0) float fromX,
            @FloatRange(from = 0.0, to = 1.0) float fromY,
            @FloatRange(from = 0.0, to = 1.0) float toX,
            @FloatRange(from = 0.0, to = 1.0) float toY) {
        mSession.swipe(fromX, fromY, toX, toY);
    }

    /**
     * Injects a {@link TouchEvent} into the computer control session.
     */
+12 −0
Original line number Diff line number Diff line
@@ -127,6 +127,18 @@ public class ComputerControlSessionTest {
        verify(mIComputerControlSession, times(1)).close();
    }

    @Test
    public void tap_taps() throws Exception {
        mSession.tap(0.1f, 0.2f);
        verify(mIComputerControlSession).tap(eq(0.1f), eq(0.2f));
    }

    @Test
    public void swipe_swipes() throws Exception {
        mSession.swipe(0.1f, 0.2f, 0.3f, 0.4f);
        verify(mIComputerControlSession).swipe(eq(0.1f), eq(0.2f), eq(0.3f), eq(0.4f));
    }

    @Test
    public void sendKeyEvent_sendsKeyEvent() throws Exception {
        KeyEvent event = new KeyEvent.Builder()
Loading