aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/build-apk87
-rwxr-xr-xscripts/build-server34
-rwxr-xr-xscripts/check2
-rwxr-xr-xscripts/check-server12
-rwxr-xr-xscripts/check-server-source27
-rwxr-xr-xscripts/check-wrapper24
-rwxr-xr-xscripts/update-server22
7 files changed, 183 insertions, 25 deletions
diff --git a/scripts/build-apk b/scripts/build-apk
index 476731b..3040ee0 100755
--- a/scripts/build-apk
+++ b/scripts/build-apk
@@ -8,7 +8,7 @@
# KEY_PASS password for that key (often the same as KEYSTORE_PASS)
#
# Required tooling:
-# Android build-tools 35.0.0 apksigner under ANDROID_SDK_ROOT or on PATH.
+# Android build-tools 35.0.0 under ANDROID_SDK_ROOT or on PATH.
#
# Usage:
# scripts/build-apk
@@ -25,11 +25,10 @@ set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
APK="$ROOT/app/build/outputs/apk/release/app-release.apk"
-JAR="$ROOT/app/src/main/assets/scrcpy-server.jar"
require() {
name="$1"
- eval "val=\${$name:-}"
+ val="$2"
if [ -z "$val" ]; then
echo "build-apk: \$$name is not set" >&2
echo " see the header of $0 for the required environment" >&2
@@ -37,10 +36,10 @@ require() {
fi
}
-require KEYSTORE_PATH
-require KEYSTORE_PASS
-require KEY_ALIAS
-require KEY_PASS
+require KEYSTORE_PATH "${KEYSTORE_PATH:-}"
+require KEYSTORE_PASS "${KEYSTORE_PASS:-}"
+require KEY_ALIAS "${KEY_ALIAS:-}"
+require KEY_PASS "${KEY_PASS:-}"
if [ ! -f "$KEYSTORE_PATH" ]; then
echo "build-apk: keystore not found at $KEYSTORE_PATH" >&2
@@ -62,23 +61,79 @@ fi
SUM=$(sha256sum "$APK" | awk '{print $1}')
APKSIGNER=""
-if [ -n "${ANDROID_SDK_ROOT:-}" ]; then
- APKSIGNER="$ANDROID_SDK_ROOT/build-tools/35.0.0/apksigner"
- if [ ! -x "$APKSIGNER" ]; then
- APKSIGNER=""
- fi
+AAPT2=""
+ZIPALIGN=""
+SDK_ROOT="${ANDROID_SDK_ROOT:-${ANDROID_HOME:-}}"
+if [ -n "$SDK_ROOT" ]; then
+ APKSIGNER="$SDK_ROOT/build-tools/35.0.0/apksigner"
+ AAPT2="$SDK_ROOT/build-tools/35.0.0/aapt2"
+ ZIPALIGN="$SDK_ROOT/build-tools/35.0.0/zipalign"
+ [ -x "$APKSIGNER" ] || APKSIGNER=""
+ [ -x "$AAPT2" ] || AAPT2=""
+ [ -x "$ZIPALIGN" ] || ZIPALIGN=""
fi
if [ -z "$APKSIGNER" ] && command -v apksigner >/dev/null 2>&1; then
APKSIGNER=$(command -v apksigner)
fi
-if [ -z "$APKSIGNER" ]; then
- echo "build-apk: apksigner 35.0.0 is required" >&2
- echo " set ANDROID_SDK_ROOT or put apksigner on PATH" >&2
+if [ -z "$AAPT2" ] && command -v aapt2 >/dev/null 2>&1; then
+ AAPT2=$(command -v aapt2)
+fi
+if [ -z "$ZIPALIGN" ] && command -v zipalign >/dev/null 2>&1; then
+ ZIPALIGN=$(command -v zipalign)
+fi
+if [ -z "$APKSIGNER" ] || [ -z "$AAPT2" ] || [ -z "$ZIPALIGN" ]; then
+ echo "build-apk: build-tools 35.0.0 are required" >&2
+ echo " set ANDROID_SDK_ROOT or put apksigner, aapt2, and zipalign on PATH" >&2
exit 1
fi
+# Capture rather than pipe: POSIX sh has no pipefail, so
+# `apksigner verify | sed` reports sed's status and a rejected APK would
+# sail past set -e and be announced below as if it were signed.
echo "build-apk: apksigner verify"
-"$APKSIGNER" verify --verbose --print-certs "$APK" | sed 's/^/ /'
+if ! verify_out=$("$APKSIGNER" verify --verbose --print-certs "$APK" 2>&1); then
+ printf '%s\n' "$verify_out" >&2
+ echo "build-apk: apksigner rejected $APK" >&2
+ exit 1
+fi
+printf '%s\n' "$verify_out" | sed 's/^/ /'
+
+"$ZIPALIGN" -c -P 16 4 "$APK"
+
+expected_permissions=$(cat <<EOF
+package: invalid.lena.scrcpy
+uses-permission: name='android.permission.INTERNET'
+uses-permission: name='android.permission.FOREGROUND_SERVICE'
+uses-permission: name='android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK'
+uses-permission: name='android.permission.POST_NOTIFICATIONS'
+EOF
+)
+actual_permissions=$("$AAPT2" dump permissions "$APK")
+if [ "$actual_permissions" != "$expected_permissions" ]; then
+ echo "build-apk: unexpected release permissions:" >&2
+ printf '%s\n' "$actual_permissions" >&2
+ exit 1
+fi
+
+expected_sdk=$(cat <<EOF
+minSdkVersion:'31'
+targetSdkVersion:'36'
+EOF
+)
+actual_sdk=$("$AAPT2" dump badging "$APK" \
+ | sed -n '/^minSdkVersion:/p; /^targetSdkVersion:/p')
+if [ "$actual_sdk" != "$expected_sdk" ]; then
+ echo "build-apk: unexpected release SDK levels:" >&2
+ printf '%s\n' "$actual_sdk" >&2
+ exit 1
+fi
+
+expected_abis="native-code: 'arm64-v8a' 'x86_64'"
+actual_abis=$("$AAPT2" dump badging "$APK" | sed -n '/^native-code:/p')
+if [ "$actual_abis" != "$expected_abis" ]; then
+ echo "build-apk: unexpected release ABIs: $actual_abis" >&2
+ exit 1
+fi
echo "build-apk: $APK"
echo "build-apk: sha256 $SUM"
diff --git a/scripts/build-server b/scripts/build-server
new file mode 100755
index 0000000..ddd814f
--- /dev/null
+++ b/scripts/build-server
@@ -0,0 +1,34 @@
+#!/bin/sh
+# Build the pinned scrcpy server source.
+
+set -eu
+
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+SCRCPY="$ROOT/vendor/scrcpy"
+VERSION_FILE="$ROOT/app/src/main/assets/scrcpy-server.version"
+BUILD_FILE="$SCRCPY/server/build.gradle"
+OUTPUT="$SCRCPY/server/build/outputs/apk/release/server-release-unsigned.apk"
+
+if [ ! -s "$BUILD_FILE" ]; then
+ echo "build-server: vendor/scrcpy is not initialized" >&2
+ exit 1
+fi
+if [ ! -s "$VERSION_FILE" ]; then
+ echo "build-server: missing $VERSION_FILE" >&2
+ exit 1
+fi
+
+expected=$(cat "$VERSION_FILE")
+declared=$(sed -n 's/.*versionName[ =]*"\([^"]*\)".*/\1/p' "$BUILD_FILE")
+if [ -z "$declared" ] || [ "$declared" != "$expected" ]; then
+ echo "build-server: source version '$declared', asset version '$expected'" >&2
+ exit 1
+fi
+
+echo "build-server: scrcpy $expected" >&2
+"$SCRCPY/gradlew" -p "$SCRCPY" --no-daemon :server:assembleRelease >&2
+if [ ! -s "$OUTPUT" ]; then
+ echo "build-server: Gradle did not produce $OUTPUT" >&2
+ exit 1
+fi
+printf '%s\n' "$OUTPUT"
diff --git a/scripts/check b/scripts/check
index 6886411..8196859 100755
--- a/scripts/check
+++ b/scripts/check
@@ -7,4 +7,6 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"
"$ROOT/scripts/check-wrapper"
"$ROOT/scripts/check-server"
+cd "$ROOT"
"$ROOT/gradlew" --no-daemon :app:test :adb:test :app:lint
+"$ROOT/scripts/check-server-source"
diff --git a/scripts/check-server b/scripts/check-server
index 9a895a1..6b773a5 100755
--- a/scripts/check-server
+++ b/scripts/check-server
@@ -16,7 +16,7 @@ for file in "$JAR" "$SUM" "$VERSION"; do
fi
done
-expected=$(awk 'NR == 1 { print $1 }' "$SUM")
+expected=$(cat "$SUM")
case "$expected" in
*[!0-9a-f]*|'')
echo "check-server: invalid SHA-256 in $SUM" >&2
@@ -36,4 +36,12 @@ if [ "$actual" != "$expected" ]; then
exit 1
fi
-echo "check-server: ok ($(cat "$VERSION"))"
+if ! awk 'BEGIN { ok = 0 }
+ /^[0-9]+([.][0-9]+)*$/ { if (NR == 1) ok = 1; next }
+ { ok = 0 }
+ END { exit !(ok && NR == 1) }' "$VERSION"; then
+ echo "check-server: invalid version in $VERSION" >&2
+ exit 1
+fi
+version=$(cat "$VERSION")
+echo "check-server: ok ($version)"
diff --git a/scripts/check-server-source b/scripts/check-server-source
new file mode 100755
index 0000000..47d161a
--- /dev/null
+++ b/scripts/check-server-source
@@ -0,0 +1,27 @@
+#!/bin/sh
+# Build and test the pinned scrcpy server, then compare its executable dex
+# with the bundled upstream release.
+
+set -eu
+
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+SCRCPY="$ROOT/vendor/scrcpy"
+OFFICIAL="$ROOT/app/src/main/assets/scrcpy-server.jar"
+
+"$ROOT/scripts/check-server"
+built=$("$ROOT/scripts/build-server")
+
+echo "check-server-source: unit, lint, checkstyle" >&2
+"$SCRCPY/gradlew" -p "$SCRCPY" --no-daemon \
+ :server:testDebugUnitTest :server:lint :server:checkstyle >&2
+
+tmp=$(mktemp -d)
+trap 'rm -rf "$tmp"' EXIT INT TERM
+unzip -p "$OFFICIAL" classes.dex >"$tmp/official.dex"
+unzip -p "$built" classes.dex >"$tmp/source.dex"
+if ! cmp -s "$tmp/official.dex" "$tmp/source.dex"; then
+ echo "check-server-source: source dex differs from upstream release" >&2
+ sha256sum "$tmp/official.dex" "$tmp/source.dex" >&2
+ exit 1
+fi
+echo "check-server-source: ok"
diff --git a/scripts/check-wrapper b/scripts/check-wrapper
index 3997bed..c56b935 100755
--- a/scripts/check-wrapper
+++ b/scripts/check-wrapper
@@ -18,7 +18,25 @@ if [ ! -f "$EXPECTED_FILE" ]; then
exit 1
fi
-# sha256sum reads its first column from the .sha256 sidecar; the second
-# column ('gradle-wrapper.jar') is informational.
-( cd "$(dirname "$WRAPPER")" && sha256sum -c "$(basename "$EXPECTED_FILE")" >/dev/null )
+line=$(cat "$EXPECTED_FILE")
+expected=${line% gradle-wrapper.jar}
+if [ "$line" != "$expected gradle-wrapper.jar" ]; then
+ echo "check-wrapper: malformed $EXPECTED_FILE" >&2
+ exit 1
+fi
+case "$expected" in
+ *[!0-9a-f]*|'')
+ echo "check-wrapper: invalid SHA-256 in $EXPECTED_FILE" >&2
+ exit 1
+ ;;
+esac
+if [ "${#expected}" -ne 64 ]; then
+ echo "check-wrapper: invalid SHA-256 length in $EXPECTED_FILE" >&2
+ exit 1
+fi
+actual=$(sha256sum "$WRAPPER" | awk '{ print $1 }')
+if [ "$actual" != "$expected" ]; then
+ echo "check-wrapper: gradle-wrapper.jar checksum mismatch" >&2
+ exit 1
+fi
echo "check-wrapper: ok"
diff --git a/scripts/update-server b/scripts/update-server
index df12e3a..337ef67 100755
--- a/scripts/update-server
+++ b/scripts/update-server
@@ -4,7 +4,7 @@
#
# Usage:
# scripts/update-server # use DEFAULT_VERSION below
-# scripts/update-server 4.0 # use explicit version
+# scripts/update-server 4.1 # use explicit version
#
# Bumping to a new release:
# 1. Run with the new version. The script will print the observed SHA-256
@@ -15,16 +15,22 @@
set -eu
-DEFAULT_VERSION='4.0'
+DEFAULT_VERSION='4.1'
VERSION="${1:-$DEFAULT_VERSION}"
-ROOT="$(git rev-parse --show-toplevel)"
+if ! printf '%s\n' "$VERSION" \
+ | awk '/^[0-9]+([.][0-9]+)*$/ { ok = 1 } END { exit !ok }'; then
+ echo "update-server: invalid version: $VERSION" >&2
+ exit 2
+fi
+
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"
ASSETS="$ROOT/app/src/main/assets"
URL="https://github.com/Genymobile/scrcpy/releases/download/v$VERSION/scrcpy-server-v$VERSION"
# Known-good SHA-256 sums. Keep one line per blessed version.
EXPECTED=$(cat <<EOF
-4.0 84924bd564a1eb6089c872c7521f968058977f91f5ff02514a8c74aff3210f3a
+4.1 deacb991ed2509715160ffdc7907e47b4160eb30d1566217e9047fd5b8850cae
EOF
)
@@ -35,6 +41,14 @@ if [ -z "$want" ]; then
echo " $VERSION <sha256-of-the-downloaded-binary>" >&2
fi
+if [ -f "$ASSETS/scrcpy-server.jar" ] \
+ && [ "$(cat "$ASSETS/scrcpy-server.version" 2>/dev/null || true)" = "$VERSION" ] \
+ && [ "$(sha256sum "$ASSETS/scrcpy-server.jar" | awk '{print $1}')" = "$want" ]; then
+ printf '%s\n' "$want" >"$ASSETS/scrcpy-server.sha256"
+ echo "update-server: already installed $ASSETS/scrcpy-server.jar v$VERSION"
+ exit 0
+fi
+
mkdir -p "$ASSETS"
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT