Build the phone's APK as a signed release, and say so in the render report
The phone has been running the debug build: build-apk.sh assembled it, and nothing in the app or its report said which build a frame time came from. A debuggable build runs Compose at a fraction of release speed, so the tuning so far was measured against the wrong number. On the emulator, the same fixture and gestures: measure 1.4ms mean / 14.7ms worst on debug, 0.8ms / 6.6ms on release. build-apk.sh now assembles the release variant, signed with a key it generates once under ~/.config/ai-app (beside the pinned CA, outside any checkout). The report's header names the build. The one native library is declared kept-with-symbols so packaging stops warning about an NDK the build does not need. Also: ui-sandbox.sh keep now keeps the config too. The server appends spawned sessions and enrolled tokens to it, so regenerating it left the transcripts on disk and the registry empty. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
486842e4aa
commit
8750ff90cb
5 files changed
+97
-10
No files matched your search
+39
-6
@@ -55,6 +55,37 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The phone runs the release build. A debuggable build runs Compose at a
|
||||
# fraction of the speed -- ART keeps the process debugger-friendly and the
|
||||
# compiler leaves its inspection hooks in -- so a frame time measured on one
|
||||
# says little about the app; that cost a day of tuning against the wrong
|
||||
# number. A release build must be signed, and the key is what the phone
|
||||
# recognises the app by, so it lives beside the CA, outside any checkout,
|
||||
# and is generated once here. Switching from an installed debug build means
|
||||
# uninstalling it first: the signatures differ, and Android refuses to
|
||||
# update across them.
|
||||
KEYSTORE="${AI_APP_KEYSTORE:-${XDG_CONFIG_HOME:-$HOME/.config}/ai-app/release.jks}"
|
||||
if [ ! -f "$KEYSTORE" ]; then
|
||||
KEYTOOL="${JAVA_HOME:+$JAVA_HOME/bin/keytool}"
|
||||
KEYTOOL="${KEYTOOL:-keytool}"
|
||||
if ! command -v "$KEYTOOL" >/dev/null 2>&1; then
|
||||
echo "No signing key at $KEYSTORE and no keytool to make one -- set" >&2
|
||||
echo "JAVA_HOME to the JDK Gradle uses, or AI_APP_KEYSTORE to an existing key." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "==> No signing key at $KEYSTORE -- generating one"
|
||||
mkdir -p "$(dirname "$KEYSTORE")"
|
||||
PASSWORD=$(head -c 24 /dev/urandom | base64 | tr -d '/+=')
|
||||
(umask 077 && printf '%s\n' "$PASSWORD" > "$KEYSTORE.password")
|
||||
(umask 077 && "$KEYTOOL" -genkeypair -keystore "$KEYSTORE" -alias ai-app \
|
||||
-keyalg RSA -keysize 2048 -validity 10000 \
|
||||
-storepass "$PASSWORD" -keypass "$PASSWORD" -dname "CN=ai-app" >/dev/null 2>&1)
|
||||
fi
|
||||
AI_APP_KEYSTORE="$KEYSTORE"
|
||||
AI_APP_KEYSTORE_PASSWORD=$(cat "$KEYSTORE.password")
|
||||
export AI_APP_KEYSTORE AI_APP_KEYSTORE_PASSWORD
|
||||
echo "==> Signing with $KEYSTORE"
|
||||
|
||||
# Dev Updater draws a real progress bar from "@@progress done/total" lines,
|
||||
# and ignores anything that isn't exactly that shape. Gradle can't be asked
|
||||
# for this directly: an init script using taskGraph.afterTask is rejected
|
||||
@@ -64,17 +95,17 @@ fi
|
||||
# the total. The build then prints one "> Task :x" line per task as it
|
||||
# goes, so counting those against it is the whole mechanism.
|
||||
#
|
||||
# Task count is not time -- compileDebugKotlin and dexBuilder are most of
|
||||
# Task count is not time -- compileReleaseKotlin and dexBuilder are most of
|
||||
# the wall clock -- so the bar moves unevenly. It is still counted work
|
||||
# rather than a guess at how long last time took.
|
||||
TASKS=$(./gradlew :androidApp:assembleDebug --dry-run --console=plain 2>/dev/null \
|
||||
TASKS=$(./gradlew :androidApp:assembleRelease --dry-run --console=plain 2>/dev/null \
|
||||
| grep -c '^:[A-Za-z:]* SKIPPED' || true)
|
||||
|
||||
echo "==> Building"
|
||||
if [ "${TASKS:-0}" -gt 0 ]; then
|
||||
echo "@@progress 0/$TASKS"
|
||||
DONE=0
|
||||
./gradlew :androidApp:assembleDebug --console=plain 2>&1 | while IFS= read -r line; do
|
||||
./gradlew :androidApp:assembleRelease --console=plain 2>&1 | while IFS= read -r line; do
|
||||
echo "$line"
|
||||
case "$line" in
|
||||
"> Task "*)
|
||||
@@ -86,17 +117,19 @@ if [ "${TASKS:-0}" -gt 0 ]; then
|
||||
# The pipeline's exit status is the shell's, not gradle's, so ask
|
||||
# gradle again rather than reporting a failed build as a success. It is
|
||||
# up to date by now, so this is a second or two.
|
||||
./gradlew :androidApp:assembleDebug --console=plain >/dev/null
|
||||
./gradlew :androidApp:assembleRelease --console=plain >/dev/null
|
||||
else
|
||||
./gradlew :androidApp:assembleDebug
|
||||
./gradlew :androidApp:assembleRelease
|
||||
fi
|
||||
|
||||
APK="$SCRIPT_DIR/androidApp/build/outputs/apk/debug/androidApp-debug.apk"
|
||||
APK="$SCRIPT_DIR/androidApp/build/outputs/apk/release/androidApp-release.apk"
|
||||
echo
|
||||
echo "==> Built $APK"
|
||||
[ -f "$APK" ] && ls -lh "$APK" | awk '{print " " $5}'
|
||||
echo
|
||||
echo "To get it onto the phone: add this project to Dev Updater (or hit"
|
||||
echo "Update on it if it's already there) and install from there."
|
||||
echo "If the phone still has the old debug build, uninstall that first:"
|
||||
echo "it is signed with a different key, so Android will refuse the update."
|
||||
echo "Then start the backend and scan the enrollment QR it prints:"
|
||||
echo " ./server/target/release/ai-server --rotate-token"
|
||||
Reference in new issue
Block a user