aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/build-apk83
-rwxr-xr-xscripts/check-wrapper24
-rwxr-xr-xscripts/fetch-vendor44
-rwxr-xr-xscripts/update-server64
4 files changed, 215 insertions, 0 deletions
diff --git a/scripts/build-apk b/scripts/build-apk
new file mode 100755
index 0000000..9fd1409
--- /dev/null
+++ b/scripts/build-apk
@@ -0,0 +1,83 @@
+#!/bin/sh
+# Build a signed release APK.
+#
+# Required environment:
+# KEYSTORE_PATH absolute path to a JKS / PKCS12 keystore
+# KEYSTORE_PASS password for the keystore
+# KEY_ALIAS alias of the signing key inside the keystore
+# KEY_PASS password for that key (often the same as KEYSTORE_PASS)
+#
+# Optional:
+# ANDROID_SDK_ROOT if set, apksigner is located via this; otherwise
+# the script trusts gradle's output and skips the
+# post-build verification step.
+#
+# Usage:
+# scripts/build-apk
+#
+# Output: prints the absolute path of the signed APK and its sha256.
+# The signed APK lives at app/build/outputs/apk/release/app-release.apk.
+#
+# This script does NOT generate a keystore. Generate one once with:
+# keytool -genkey -v -keystore release.jks -alias scrcpy-android \
+# -keyalg RSA -keysize 2048 -validity 10000
+# and keep it outside the repo (it must never be committed).
+
+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:-}"
+ if [ -z "$val" ]; then
+ echo "build-apk: \$$name is not set" >&2
+ echo " see the header of $0 for the required environment" >&2
+ exit 1
+ fi
+}
+
+require KEYSTORE_PATH
+require KEYSTORE_PASS
+require KEY_ALIAS
+require KEY_PASS
+
+if [ ! -f "$KEYSTORE_PATH" ]; then
+ echo "build-apk: keystore not found at $KEYSTORE_PATH" >&2
+ exit 1
+fi
+
+if [ ! -f "$JAR" ]; then
+ echo "build-apk: $JAR is missing" >&2
+ echo " run scripts/update-server first" >&2
+ exit 1
+fi
+
+echo "build-apk: gradle :app:assembleRelease"
+cd "$ROOT"
+./gradlew --no-daemon :app:assembleRelease
+
+if [ ! -f "$APK" ]; then
+ echo "build-apk: gradle finished but $APK does not exist" >&2
+ exit 1
+fi
+
+SUM=$(sha256sum "$APK" | awk '{print $1}')
+
+# Best-effort: if apksigner is reachable, confirm the signature.
+APKSIGNER=""
+if [ -n "${ANDROID_SDK_ROOT:-}" ]; then
+ APKSIGNER=$(ls "$ANDROID_SDK_ROOT"/build-tools/*/apksigner 2>/dev/null | sort | tail -n 1 || true)
+fi
+if [ -z "$APKSIGNER" ] && command -v apksigner >/dev/null 2>&1; then
+ APKSIGNER=$(command -v apksigner)
+fi
+if [ -n "$APKSIGNER" ]; then
+ echo "build-apk: apksigner verify"
+ "$APKSIGNER" verify --verbose "$APK" | sed 's/^/ /'
+fi
+
+echo "build-apk: $APK"
+echo "build-apk: sha256 $SUM"
diff --git a/scripts/check-wrapper b/scripts/check-wrapper
new file mode 100755
index 0000000..31531b6
--- /dev/null
+++ b/scripts/check-wrapper
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Verify the checked-in gradle-wrapper.jar matches the expected SHA-256.
+# Catches accidental swaps or supply-chain mischief.
+
+set -eu
+
+cd "$(git rev-parse --show-toplevel)"
+
+WRAPPER='gradle/wrapper/gradle-wrapper.jar'
+EXPECTED_FILE="$WRAPPER.sha256"
+
+if [ ! -f "$WRAPPER" ]; then
+ echo "check-wrapper: $WRAPPER is missing" >&2
+ exit 1
+fi
+if [ ! -f "$EXPECTED_FILE" ]; then
+ echo "check-wrapper: $EXPECTED_FILE is missing" >&2
+ 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 )
+echo "check-wrapper: ok"
diff --git a/scripts/fetch-vendor b/scripts/fetch-vendor
new file mode 100755
index 0000000..4c73381
--- /dev/null
+++ b/scripts/fetch-vendor
@@ -0,0 +1,44 @@
+#!/bin/sh
+# Pull pinned vendor sources via git subtree. Idempotent.
+#
+# Usage:
+# scripts/fetch-vendor # add or update to pinned tag, verify SHA
+#
+# Bump:
+# 1. Pick a new tag from https://github.com/MuntashirAkon/libadb-android
+# 2. git ls-remote https://github.com/MuntashirAkon/libadb-android.git \
+# refs/tags/<tag>
+# → copy the commit hex.
+# 3. Update LIBADB_TAG and LIBADB_SHA below.
+# 4. Run this script.
+# 5. Re-prune. This repo keeps only the libadb module plus license files
+# (vendor/libadb-android/{libadb,LICENSES,COPYING,README.md,
+# SERVICES.md}); the rest of upstream - sample app, gradle wrapper,
+# jitpack.yml - is unused. A subtree pull re-adds it; delete it again.
+
+set -eu
+
+LIBADB_REPO='https://github.com/MuntashirAkon/libadb-android.git'
+LIBADB_TAG='3.1.1'
+LIBADB_SHA='c849886ebc6d48e7b46d967e78a6bb65c90c3b74'
+LIBADB_PREFIX='vendor/libadb-android'
+
+cd "$(git rev-parse --show-toplevel)"
+
+# Tags can be re-pointed upstream; cross-check against the pinned commit.
+remote_sha=$(git ls-remote "$LIBADB_REPO" "refs/tags/$LIBADB_TAG" | awk '{print $1}')
+if [ "$remote_sha" != "$LIBADB_SHA" ]; then
+ echo "fetch-vendor: refs/tags/$LIBADB_TAG points at $remote_sha," >&2
+ echo " expected $LIBADB_SHA. Refusing to pull." >&2
+ exit 1
+fi
+
+if [ ! -d "$LIBADB_PREFIX" ]; then
+ echo "fetch-vendor: adding $LIBADB_PREFIX @ $LIBADB_TAG ($LIBADB_SHA)"
+ git subtree add --prefix="$LIBADB_PREFIX" "$LIBADB_REPO" "$LIBADB_TAG" --squash
+else
+ echo "fetch-vendor: pulling $LIBADB_PREFIX @ $LIBADB_TAG ($LIBADB_SHA)"
+ git subtree pull --prefix="$LIBADB_PREFIX" "$LIBADB_REPO" "$LIBADB_TAG" --squash
+fi
+
+echo "fetch-vendor: ok"
diff --git a/scripts/update-server b/scripts/update-server
new file mode 100755
index 0000000..df12e3a
--- /dev/null
+++ b/scripts/update-server
@@ -0,0 +1,64 @@
+#!/bin/sh
+# Download a pinned scrcpy-server.jar release, verify SHA-256 against an
+# in-script allow-list, and install it into app assets. Idempotent.
+#
+# Usage:
+# scripts/update-server # use DEFAULT_VERSION below
+# scripts/update-server 4.0 # use explicit version
+#
+# Bumping to a new release:
+# 1. Run with the new version. The script will print the observed SHA-256
+# and exit non-zero if it is not in the allow-list.
+# 2. Paste the printed line into the `case` below.
+# 3. Update DEFAULT_VERSION.
+# 4. Re-run. Commit the assets.
+
+set -eu
+
+DEFAULT_VERSION='4.0'
+VERSION="${1:-$DEFAULT_VERSION}"
+
+ROOT="$(git rev-parse --show-toplevel)"
+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
+EOF
+)
+
+want=$(printf '%s\n' "$EXPECTED" | awk -v v="$VERSION" '$1==v {print $2}')
+if [ -z "$want" ]; then
+ echo "update-server: version $VERSION is not in the allow-list" >&2
+ echo " to bless it, add this line to the EXPECTED block in this script:" >&2
+ echo " $VERSION <sha256-of-the-downloaded-binary>" >&2
+fi
+
+mkdir -p "$ASSETS"
+tmp=$(mktemp)
+trap 'rm -f "$tmp"' EXIT
+
+echo "update-server: GET $URL"
+curl -fsSL -o "$tmp" "$URL"
+
+got=$(sha256sum "$tmp" | awk '{print $1}')
+echo "update-server: sha256 $got"
+
+if [ -z "$want" ]; then
+ echo "update-server: refusing to install unverified jar" >&2
+ exit 1
+fi
+
+if [ "$got" != "$want" ]; then
+ echo "update-server: sha256 mismatch" >&2
+ echo " want: $want" >&2
+ echo " got: $got" >&2
+ exit 1
+fi
+
+install -m 0644 "$tmp" "$ASSETS/scrcpy-server.jar"
+printf '%s\n' "$VERSION" >"$ASSETS/scrcpy-server.version"
+printf '%s\n' "$got" >"$ASSETS/scrcpy-server.sha256"
+
+echo "update-server: installed $ASSETS/scrcpy-server.jar v$VERSION"