aboutsummaryrefslogtreecommitdiff
path: root/app/src/debug
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/debug')
-rw-r--r--app/src/debug/AndroidManifest.xml9
-rw-r--r--app/src/debug/java/invalid/lena/scrcpy/Pattern.java115
-rw-r--r--app/src/debug/res/layout/mirror.xml93
3 files changed, 124 insertions, 93 deletions
diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..8e04c86
--- /dev/null
+++ b/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <application>
+ <activity
+ android:name=".Pattern"
+ android:exported="true"
+ android:theme="@style/Theme.Scrcpy.Fullscreen"/>
+ </application>
+</manifest>
diff --git a/app/src/debug/java/invalid/lena/scrcpy/Pattern.java b/app/src/debug/java/invalid/lena/scrcpy/Pattern.java
new file mode 100644
index 0000000..39a5d42
--- /dev/null
+++ b/app/src/debug/java/invalid/lena/scrcpy/Pattern.java
@@ -0,0 +1,115 @@
+package invalid.lena.scrcpy;
+
+import android.app.Activity;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowInsetsController;
+
+// Deterministic moving target for the two-emulator E2E test. Debug-only,
+// exported only in the debug manifest, and absent from release artifacts.
+public final class Pattern extends Activity {
+
+ private static final String TARGET_CLIPBOARD_TEXT = "scrcpy-e2e";
+ private static final String SOURCE_CLIPBOARD_TEXT = "source-e2e";
+ private static final String EXTRA_CLIPBOARD_TEXT = "clipboard_text";
+
+ private ClipboardManager clipboard;
+ private String clipboardText;
+ private final ClipboardManager.OnPrimaryClipChangedListener clipboardListener =
+ this::onClipboardChanged;
+
+ @Override
+ @SuppressWarnings("deprecation")
+ protected void onCreate(Bundle state) {
+ super.onCreate(state);
+ String requested = getIntent().getStringExtra(EXTRA_CLIPBOARD_TEXT);
+ clipboardText = SOURCE_CLIPBOARD_TEXT.equals(requested)
+ ? SOURCE_CLIPBOARD_TEXT : TARGET_CLIPBOARD_TEXT;
+ setContentView(new PatternView());
+ clipboard = getSystemService(ClipboardManager.class);
+ if (clipboard != null) clipboard.addPrimaryClipChangedListener(clipboardListener);
+ getWindow().setDecorFitsSystemWindows(false);
+ WindowInsetsController insets = getWindow().getInsetsController();
+ if (insets != null) insets.hide(WindowInsets.Type.systemBars());
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (clipboard != null) clipboard.removePrimaryClipChangedListener(clipboardListener);
+ super.onDestroy();
+ }
+
+ private void onClipboardChanged() {
+ ClipData data = clipboard.getPrimaryClip();
+ if (data == null || data.getItemCount() == 0) return;
+ CharSequence text = data.getItemAt(0).getText();
+ if (SOURCE_CLIPBOARD_TEXT.contentEquals(text)) {
+ Log.i("pattern: clipboard from source");
+ }
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
+ Log.i("pattern: key up code=%d", event.getKeyCode());
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ private final class PatternView extends View {
+ private final Paint paint = new Paint();
+ private int step;
+
+ PatternView() {
+ super(Pattern.this);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ Log.i("pattern: touch up x=%d y=%d", (int) event.getX(), (int) event.getY());
+ performClick();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean performClick() {
+ super.performClick();
+ if (clipboard != null) {
+ clipboard.setPrimaryClip(ClipData.newPlainText("e2e", clipboardText));
+ Log.i("pattern: clipboard set");
+ }
+ return true;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ int w = getWidth();
+ int h = getHeight();
+ int mx = w / 2;
+ int my = h / 2;
+ paint.setColor(Color.rgb(224, 32, 32));
+ canvas.drawRect(0, 0, mx, my, paint);
+ paint.setColor(Color.rgb(32, 192, 48));
+ canvas.drawRect(mx, 0, w, my, paint);
+ paint.setColor(Color.rgb(32, 64, 224));
+ canvas.drawRect(0, my, mx, h, paint);
+ paint.setColor(Color.rgb(224, 192, 32));
+ canvas.drawRect(mx, my, w, h, paint);
+
+ paint.setColor(Color.WHITE);
+ int x = step++ % Math.max(1, w);
+ canvas.drawRect(x, 0, Math.min(w, x + 12), h, paint);
+ postInvalidateDelayed(33);
+ }
+ }
+}
diff --git a/app/src/debug/res/layout/mirror.xml b/app/src/debug/res/layout/mirror.xml
deleted file mode 100644
index 5d0e845..0000000
--- a/app/src/debug/res/layout/mirror.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Debug Mirror layout: TextureView, the same top status bar as
- production, plus a bottom-left stats overlay that screencap can
- capture (target host, video/audio/texture-update counts, last
- forwarded event). The TextureView path is used because emulators
- don't composite SurfaceView's hardware layer into screencap. -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#000000">
-
- <TextureView
- android:id="@+id/surface"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"/>
-
- <LinearLayout
- android:id="@+id/status_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:padding="8dp"
- android:background="#a0000000">
-
- <TextView
- android:id="@+id/status_text"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:textColor="#ffffff"
- android:textSize="14sp"
- android:fontFamily="monospace"
- android:singleLine="true"
- android:ellipsize="end"
- android:text="@string/connecting"/>
-
- <Button
- android:id="@+id/record"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
- android:text="@string/record"/>
-
- <Button
- android:id="@+id/reconnect"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/reconnect"
- android:visibility="gone"/>
-
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|start"
- android:orientation="vertical"
- android:padding="16dp"
- android:background="#a0000000">
-
- <TextView
- android:id="@+id/overlay_target"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="#ffffff"
- android:textSize="16sp"
- android:fontFamily="monospace"
- android:text="target: ..."/>
-
- <TextView
- android:id="@+id/overlay_stats"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="#aef0a0"
- android:textSize="16sp"
- android:fontFamily="monospace"
- android:text="v=0 a=0"/>
-
- <TextView
- android:id="@+id/overlay_event"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="#f0c060"
- android:textSize="16sp"
- android:fontFamily="monospace"
- android:text="event: (idle)"/>
-
- </LinearLayout>
-
-</FrameLayout>