From 31f87f647e7cc3391e0f67ddbdb295bb5ea51802 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 19 Mar 2021 14:27:57 -0300 Subject: [PATCH] Create an OverlayView so we can show taps in espresso tests --- .../briar/android/OverlayTapViewAction.java | 41 +++++++++ .../briar/android/OverlayView.java | 83 +++++++++++++++++++ .../src/screenshotDebug/AndroidManifest.xml | 3 + 3 files changed, 127 insertions(+) create mode 100644 briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayTapViewAction.java create mode 100644 briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayView.java diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayTapViewAction.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayTapViewAction.java new file mode 100644 index 000000000..424150f92 --- /dev/null +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayTapViewAction.java @@ -0,0 +1,41 @@ +package org.briarproject.briar.android; + +import android.view.View; + +import org.hamcrest.Matcher; + +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; + +import static androidx.test.espresso.action.GeneralLocation.VISIBLE_CENTER; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast; + +public class OverlayTapViewAction implements ViewAction { + + public static ViewAction visualClick(OverlayView overlayView) { + return new OverlayTapViewAction(overlayView); + } + + private final OverlayView overlayView; + + public OverlayTapViewAction(OverlayView overlayView) { + this.overlayView = overlayView; + } + + @Override + public Matcher getConstraints() { + return isDisplayingAtLeast(90); + } + + @Override + public String getDescription() { + return null; + } + + @Override + public void perform(UiController uiController, View view) { + float[] coordinates = VISIBLE_CENTER.calculateCoordinates(view); + overlayView.tap(coordinates); + } +} + diff --git a/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayView.java b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayView.java new file mode 100644 index 000000000..5ba5417e2 --- /dev/null +++ b/briar-android/src/androidTestScreenshot/java/org/briarproject/briar/android/OverlayView.java @@ -0,0 +1,83 @@ +package org.briarproject.briar.android; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PixelFormat; +import android.os.Handler; +import android.view.View; +import android.view.WindowManager; + +import java.util.Random; + +import javax.annotation.Nullable; + +import static android.content.Context.WINDOW_SERVICE; +import static android.provider.Settings.canDrawOverlays; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; +import static androidx.test.core.app.ApplicationProvider.getApplicationContext; +import static androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread; +import static org.junit.Assert.assertTrue; + +public class OverlayView extends View { + + public static OverlayView attach(Context ctx) throws Throwable { + assertTrue(canDrawOverlays(ctx)); + OverlayView view = new OverlayView(getApplicationContext()); + runOnUiThread(() -> attachInternal(ctx, view)); + return view; + } + + private static void attachInternal(Context ctx, OverlayView view) { + WindowManager.LayoutParams params = new WindowManager.LayoutParams( + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, + FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE, + PixelFormat.TRANSLUCENT); + WindowManager wm = (WindowManager) ctx.getSystemService(WINDOW_SERVICE); + wm.addView(view, params); + } + + private final Random random = new Random(); + private final Paint paint; + private final int yOffset; + @Nullable + private float[] coordinates; + + public OverlayView(Context ctx) { + super(ctx); + int resourceId = getResources() + .getIdentifier("status_bar_height", "dimen", "android"); + yOffset = getResources().getDimensionPixelSize(resourceId); + paint = new Paint(); + paint.setAntiAlias(true); + paint.setARGB(175, 255, 0, 0); + setWillNotDraw(false); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + } + + void tap(float[] coordinates) { + this.coordinates = coordinates; + invalidate(); + new Handler().postDelayed(this::untap, 750); + } + + private void untap() { + this.coordinates = null; + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (coordinates == null) return; + float x = coordinates[0] + random.nextInt(42); + float y = coordinates[1] - yOffset + random.nextInt(13); + canvas.drawCircle(x, y, 42, paint); + } +} diff --git a/briar-android/src/screenshotDebug/AndroidManifest.xml b/briar-android/src/screenshotDebug/AndroidManifest.xml index d3e565327..376a33b94 100644 --- a/briar-android/src/screenshotDebug/AndroidManifest.xml +++ b/briar-android/src/screenshotDebug/AndroidManifest.xml @@ -16,4 +16,7 @@ + + +