diff options
| author | Lena <lena@omega> | 2026-01-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-06-24 22:14:50 +0300 |
| commit | eb0c8951196c637e44daf3c0617b131b997d5d2c (patch) | |
| tree | 2f83b6a41cee745467e53fc401942b82cea286ea /app/src/main/res/layout | |
| download | scrcpy-android-eb0c8951196c637e44daf3c0617b131b997d5d2c.tar.gz | |
scrcpy-android: mirror an Android device over wireless ADB0.1
Native Java app for Android 12+ that mirrors another Android
device over wireless ADB, forwarding video, audio, touch input,
and clipboard. Bundles a pinned scrcpy-server.jar and the
vendored libadb-android stack. Supports h264/h265/av1 video and
raw/opus audio with in-app codec selection. No NDK, no Kotlin.
Includes JVM unit tests and a Docker-based emulator e2e rig.
Diffstat (limited to 'app/src/main/res/layout')
| -rw-r--r-- | app/src/main/res/layout/device_row.xml | 28 | ||||
| -rw-r--r-- | app/src/main/res/layout/main.xml | 181 | ||||
| -rw-r--r-- | app/src/main/res/layout/mirror.xml | 67 | ||||
| -rw-r--r-- | app/src/main/res/layout/settings.xml | 294 |
4 files changed, 570 insertions, 0 deletions
diff --git a/app/src/main/res/layout/device_row.xml b/app/src/main/res/layout/device_row.xml new file mode 100644 index 0000000..f06ab20 --- /dev/null +++ b/app/src/main/res/layout/device_row.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Saved-device row: phone glyph + "host:port" label, with the platform + touch ripple. Bound by an ArrayAdapter via R.id.device_label. --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center_vertical" + android:minHeight="56dp" + android:paddingHorizontal="@dimen/space_sm" + android:paddingVertical="@dimen/space_md" + android:background="?android:attr/selectableItemBackground"> + + <ImageView + android:layout_width="24dp" + android:layout_height="24dp" + android:src="@drawable/ic_device" + android:contentDescription="@null"/> + + <TextView + android:id="@+id/device_label" + style="@style/DeviceLabel" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginStart="@dimen/space_md"/> + +</LinearLayout> diff --git a/app/src/main/res/layout/main.xml b/app/src/main/res/layout/main.xml new file mode 100644 index 0000000..acd4a3c --- /dev/null +++ b/app/src/main/res/layout/main.xml @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:padding="@dimen/space_lg"> + + <!-- Header: app glyph + name, Settings on the right. --> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:gravity="center_vertical" + android:layout_marginBottom="@dimen/space_lg"> + + <ImageView + android:layout_width="40dp" + android:layout_height="40dp" + android:src="@drawable/ic_launcher_foreground" + android:scaleType="fitCenter" + android:contentDescription="@null"/> + + <TextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginStart="@dimen/space_sm" + android:text="@string/app_name" + android:textColor="@color/on_surface" + android:textSize="22sp" + android:textStyle="bold"/> + + <ImageButton + android:id="@+id/settings" + android:layout_width="48dp" + android:layout_height="48dp" + android:src="@drawable/ic_settings" + android:scaleType="centerInside" + android:background="?android:attr/selectableItemBackgroundBorderless" + android:contentDescription="@string/settings"/> + + </LinearLayout> + + <!-- Pairing form. Fields are grouped and labelled by where their + value comes from on the target's Wireless debugging screen. --> + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/pair_a_device"/> + + <TextView + style="@style/Caption" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/pair_help"/> + + <TextView + style="@style/FieldLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_host"/> + + <EditText + android:id="@+id/host" + style="@style/Field" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:hint="@string/host_hint" + android:inputType="text" + android:autofillHints="postalAddress"/> + + <TextView + style="@style/FieldLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_pairing"/> + + <TextView + style="@style/Caption" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/sub_pairing"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:layout_marginTop="@dimen/space_xs"> + + <EditText + android:id="@+id/pair_port" + style="@style/Field" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginEnd="@dimen/space_sm" + android:hint="@string/pair_port_hint" + android:inputType="number" + android:autofillHints="off"/> + + <EditText + android:id="@+id/pair_code" + style="@style/Field" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:hint="@string/pair_code_hint" + android:inputType="numberPassword" + android:maxLength="6" + android:autofillHints="off"/> + + </LinearLayout> + + <TextView + style="@style/FieldLabel" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/label_connect"/> + + <TextView + style="@style/Caption" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/sub_connect"/> + + <EditText + android:id="@+id/connect_port" + style="@style/Field" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/space_xs" + android:hint="@string/connect_port_hint" + android:inputType="number" + android:autofillHints="off"/> + + <Button + android:id="@+id/pair" + style="@style/Button.Primary" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/space_lg" + android:text="@string/pair_and_save"/> + + </LinearLayout> + + <TextView + style="@style/SectionHeader" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/saved_devices"/> + + <FrameLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1"> + + <ListView + android:id="@+id/devices" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:divider="@color/stroke" + android:dividerHeight="1dp"/> + + <TextView + android:id="@+id/devices_empty" + style="@style/Note" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:paddingTop="@dimen/space_xl" + android:text="@string/no_devices_yet"/> + + </FrameLayout> + +</LinearLayout> diff --git a/app/src/main/res/layout/mirror.xml b/app/src/main/res/layout/mirror.xml new file mode 100644 index 0000000..cf24e11 --- /dev/null +++ b/app/src/main/res/layout/mirror.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Release Mirror layout: SurfaceView for the video pipeline plus a + floating top status pill with Record and a Reconnect button (visible + only when the session is in DISCONNECTED state). The debug layout + under src/debug/res/layout/mirror.xml shadows this with a TextureView + and extra stats overlay used by the e2e screen capture. --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#000000"> + + <SurfaceView + 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:layout_margin="@dimen/space_sm" + android:orientation="horizontal" + android:gravity="center_vertical" + android:paddingHorizontal="@dimen/space_md" + android:paddingVertical="@dimen/space_sm" + android:background="@drawable/bg_status_pill"> + + <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" + style="@style/Button.Secondary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/space_sm" + android:minHeight="0dp" + android:paddingHorizontal="@dimen/space_md" + android:paddingVertical="@dimen/space_xs" + android:text="@string/record"/> + + <Button + android:id="@+id/reconnect" + style="@style/Button.Secondary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/space_sm" + android:minHeight="0dp" + android:paddingHorizontal="@dimen/space_md" + android:paddingVertical="@dimen/space_xs" + android:text="@string/reconnect" + android:visibility="gone"/> + + </LinearLayout> + +</FrameLayout> diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml new file mode 100644 index 0000000..5d4e450 --- /dev/null +++ b/app/src/main/res/layout/settings.xml @@ -0,0 +1,294 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="@dimen/space_lg"> + + <TextView + style="@style/Note" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="@dimen/space_lg" + android:text="@string/settings_apply_on_reconnect"/> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/video_codec"/> + + <RadioGroup + android:id="@+id/video_codec" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RadioButton + android:id="@+id/video_h264" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="H.264 (default)"/> + + <RadioButton + android:id="@+id/video_h265" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="H.265"/> + + <RadioButton + android:id="@+id/video_av1" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="AV1 (requires target Android 14+)"/> + + </RadioGroup> + + </LinearLayout> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/audio_codec"/> + + <RadioGroup + android:id="@+id/audio_codec" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RadioButton + android:id="@+id/audio_raw" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Raw PCM (1.5 Mbps, default)"/> + + <RadioButton + android:id="@+id/audio_opus" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Opus (~128 kbps)"/> + + </RadioGroup> + + </LinearLayout> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/max_size"/> + + <RadioGroup + android:id="@+id/max_size" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RadioButton + android:id="@+id/max_size_0" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Original (default)"/> + + <RadioButton + android:id="@+id/max_size_480" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="480"/> + + <RadioButton + android:id="@+id/max_size_720" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="720"/> + + <RadioButton + android:id="@+id/max_size_1080" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1080"/> + + <RadioButton + android:id="@+id/max_size_1440" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1440"/> + + <RadioButton + android:id="@+id/max_size_2160" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="2160"/> + + </RadioGroup> + + </LinearLayout> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/video_bit_rate"/> + + <RadioGroup + android:id="@+id/video_bit_rate" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RadioButton + android:id="@+id/bit_rate_1m" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1 Mbps"/> + + <RadioButton + android:id="@+id/bit_rate_2m" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="2 Mbps"/> + + <RadioButton + android:id="@+id/bit_rate_4m" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="4 Mbps"/> + + <RadioButton + android:id="@+id/bit_rate_8m" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="8 Mbps (default)"/> + + <RadioButton + android:id="@+id/bit_rate_16m" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="16 Mbps"/> + + </RadioGroup> + + </LinearLayout> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/max_fps"/> + + <RadioGroup + android:id="@+id/max_fps" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <RadioButton + android:id="@+id/max_fps_0" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Unlimited (default)"/> + + <RadioButton + android:id="@+id/max_fps_30" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="30"/> + + <RadioButton + android:id="@+id/max_fps_60" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="60"/> + + <RadioButton + android:id="@+id/max_fps_90" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="90"/> + + <RadioButton + android:id="@+id/max_fps_120" + style="@style/RadioOption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="120"/> + + </RadioGroup> + + </LinearLayout> + + <LinearLayout + style="@style/Card" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="0dp"> + + <TextView + style="@style/SectionHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/display"/> + + <CheckBox + android:id="@+id/show_status_bar" + style="@style/RadioOption" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/show_status_bar"/> + + </LinearLayout> + + </LinearLayout> + +</ScrollView> |