diff options
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/build-apk | 87 | ||||
| -rwxr-xr-x | scripts/build-server | 34 | ||||
| -rwxr-xr-x | scripts/check | 2 | ||||
| -rwxr-xr-x | scripts/check-server | 12 | ||||
| -rwxr-xr-x | scripts/check-server-source | 27 | ||||
| -rwxr-xr-x | scripts/check-wrapper | 24 | ||||
| -rwxr-xr-x | scripts/update-server | 22 |
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 |