Skip to content

Commit a8ba778

Browse files
committed
Harden APK installs and cache emulator wipe
1 parent abdbce6 commit a8ba778

File tree

1 file changed

+101
-24
lines changed

1 file changed

+101
-24
lines changed

scripts/build-android-app.sh

Lines changed: 101 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ configure_avd() {
741741
fi
742742
declare -A settings=(
743743
["hw.ramSize"]=3072
744-
["disk.dataPartition.size"]=4096M
744+
["disk.dataPartition.size"]=8192M
745745
["hw.bluetooth"]=no
746746
["hw.camera.back"]=none
747747
["hw.camera.front"]=none
@@ -917,6 +917,9 @@ dump_emulator_diagnostics() {
917917
log_instrumentation_state() {
918918
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path android | sed 's/^/[build-android-app] pm path android: /' || true
919919

920+
local runtime_pkg="${RUNTIME_PACKAGE:-$PACKAGE_NAME}"
921+
local test_pkg="${TEST_RUNTIME_PACKAGE:-${runtime_pkg}.test}"
922+
920923
local instrumentation_list
921924
instrumentation_list="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list instrumentation 2>/dev/null || true)"
922925
if [ -n "$instrumentation_list" ]; then
@@ -926,23 +929,23 @@ log_instrumentation_state() {
926929
fi
927930

928931
local have_test_apk=0
929-
if "$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "${PACKAGE_NAME}.test" >/dev/null 2>&1; then
932+
if [ -n "$test_pkg" ] && "$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "$test_pkg" >/dev/null 2>&1; then
930933
have_test_apk=1
931-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "${PACKAGE_NAME}.test" \
934+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "$test_pkg" \
932935
| sed 's/^/[build-android-app] test-apk: /'
933936
else
934-
ba_log "Test APK for ${PACKAGE_NAME}.test not yet installed on $EMULATOR_SERIAL"
937+
ba_log "Test APK for $test_pkg not yet installed on $EMULATOR_SERIAL"
935938
fi
936939

937940
local package_regex package_list package_matches
938-
package_regex="${PACKAGE_NAME//./\.}"
941+
package_regex="${runtime_pkg//./\.}"
939942
package_list="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list packages 2>/dev/null || true)"
940943
if [ -n "$package_list" ]; then
941944
package_matches="$(printf '%s\n' "$package_list" | grep -E "${package_regex}|${package_regex}\.test" || true)"
942945
if [ -n "$package_matches" ]; then
943946
printf '%s\n' "$package_matches" | sed 's/^/[build-android-app] package: /'
944947
else
945-
ba_log "Packages matching $PACKAGE_NAME not yet installed on $EMULATOR_SERIAL"
948+
ba_log "Packages matching $runtime_pkg not yet installed on $EMULATOR_SERIAL"
946949
fi
947950
else
948951
ba_log "Package manager returned no packages on $EMULATOR_SERIAL"
@@ -962,7 +965,7 @@ collect_instrumentation_crash() {
962965
: >"$crash_log"
963966

964967
if "$ADB_BIN" -s "$EMULATOR_SERIAL" shell logcat -d -t 2000 >"$log_tmp" 2>/dev/null; then
965-
if grep -E "FATAL EXCEPTION|AndroidRuntime|Process: ${PACKAGE_NAME}(\\.test)?|Abort message:" "$log_tmp" >"$filtered_tmp" 2>/dev/null; then
968+
if grep -E "FATAL EXCEPTION|AndroidRuntime|Process: ${RUNTIME_PACKAGE}(\\.test)?|Abort message:" "$log_tmp" >"$filtered_tmp" 2>/dev/null; then
966969
if [ -s "$filtered_tmp" ]; then
967970
while IFS= read -r line; do
968971
echo "[build-android-app] crash: $line"
@@ -1043,15 +1046,24 @@ EMULATOR_SERIAL="emulator-$EMULATOR_PORT"
10431046

10441047
EMULATOR_LOG="$GRADLE_PROJECT_DIR/emulator.log"
10451048
ba_log "Starting headless Android emulator $AVD_NAME on port $EMULATOR_PORT"
1049+
EMULATOR_ADDITIONAL_ARGS=()
1050+
WIPE_SENTINEL="$AVD_HOME/.${AVD_NAME}.wiped"
1051+
if [ ! -f "$WIPE_SENTINEL" ]; then
1052+
EMULATOR_ADDITIONAL_ARGS+=(-wipe-data)
1053+
fi
10461054
ANDROID_AVD_HOME="$AVD_HOME" "$EMULATOR_BIN" -avd "$AVD_NAME" -port "$EMULATOR_PORT" \
10471055
-no-window -no-snapshot -gpu swiftshader_indirect -no-audio -no-boot-anim \
10481056
-accel off -no-accel -camera-back none -camera-front none -skip-adb-auth \
1049-
-feature -Vulkan -netfast -memory 3072 >"$EMULATOR_LOG" 2>&1 &
1057+
-feature -Vulkan -netfast -memory 3072 "${EMULATOR_ADDITIONAL_ARGS[@]}" >"$EMULATOR_LOG" 2>&1 &
10501058
EMULATOR_PID=$!
10511059
trap stop_emulator EXIT
10521060

10531061
sleep 5
10541062

1063+
if [ ! -f "$WIPE_SENTINEL" ]; then
1064+
touch "$WIPE_SENTINEL" 2>/dev/null || true
1065+
fi
1066+
10551067
detect_emulator_serial() {
10561068
local deadline current_devices serial existing
10571069
deadline=$((SECONDS + 180))
@@ -1179,20 +1191,64 @@ if [ "$ASSEMBLE_EXIT_CODE" -ne 0 ]; then
11791191
fi
11801192

11811193
adb_install_retry() {
1182-
local serial="$1" apk="$2" tries=5
1194+
local serial="$1" apk="$2" tries=3
11831195
local attempt
1196+
11841197
for attempt in $(seq 1 "$tries"); do
11851198
if command -v timeout >/dev/null 2>&1; then
1186-
timeout 120 "$ADB_BIN" -s "$serial" install -r -t "$apk" && return 0
1199+
if timeout 120 "$ADB_BIN" -s "$serial" install -r -t --no-incremental "$apk"; then
1200+
return 0
1201+
fi
11871202
else
1188-
"$ADB_BIN" -s "$serial" install -r -t "$apk" && return 0
1203+
if "$ADB_BIN" -s "$serial" install -r -t --no-incremental "$apk"; then
1204+
return 0
1205+
fi
11891206
fi
11901207
if [ "$attempt" -lt "$tries" ]; then
11911208
ba_log "install retry $attempt/$tries for $(basename "$apk")"
11921209
"$ADB_BIN" -s "$serial" wait-for-device
11931210
sleep 3
11941211
fi
11951212
done
1213+
1214+
ba_log "Falling back to push+pm install for $(basename "$apk")"
1215+
local remote_tmp="/data/local/tmp/$(basename "$apk")"
1216+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
1217+
if ! "$ADB_BIN" -s "$serial" push "$apk" "$remote_tmp" >/dev/null 2>&1; then
1218+
ba_log "Failed to push $(basename "$apk") to $remote_tmp" >&2
1219+
return 1
1220+
fi
1221+
1222+
if command -v timeout >/dev/null 2>&1; then
1223+
if timeout 180 "$ADB_BIN" -s "$serial" shell pm install -r -t -g "$remote_tmp"; then
1224+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
1225+
return 0
1226+
fi
1227+
else
1228+
if "$ADB_BIN" -s "$serial" shell pm install -r -t -g "$remote_tmp"; then
1229+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
1230+
return 0
1231+
fi
1232+
fi
1233+
1234+
local size
1235+
size=$(stat -c%s "$apk" 2>/dev/null || wc -c <"$apk")
1236+
if [ -n "$size" ]; then
1237+
ba_log "Attempting size-piped install for $(basename "$apk")"
1238+
if command -v timeout >/dev/null 2>&1; then
1239+
if timeout 180 "$ADB_BIN" -s "$serial" shell "cat '$remote_tmp' | pm install -r -t -g -S $size"; then
1240+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
1241+
return 0
1242+
fi
1243+
else
1244+
if "$ADB_BIN" -s "$serial" shell "cat '$remote_tmp' | pm install -r -t -g -S $size"; then
1245+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
1246+
return 0
1247+
fi
1248+
fi
1249+
fi
1250+
1251+
"$ADB_BIN" -s "$serial" shell rm -f "$remote_tmp" >/dev/null 2>&1 || true
11961252
return 1
11971253
}
11981254

@@ -1281,20 +1337,41 @@ if [ -d "$ANDROID_SDK_ROOT/build-tools" ]; then
12811337
done < <(find "$ANDROID_SDK_ROOT/build-tools" -maxdepth 1 -mindepth 1 -type d | sort -Vr)
12821338
fi
12831339

1340+
RUNTIME_PACKAGE="$PACKAGE_NAME"
12841341
if [ -n "$AAPT_BIN" ] && [ -x "$AAPT_BIN" ]; then
12851342
APK_PACKAGE="$($AAPT_BIN dump badging "$APP_APK" 2>/dev/null | awk -F"'" '/^package: name=/{print $2; exit}')"
12861343
if [ -n "$APK_PACKAGE" ]; then
12871344
ba_log "aapt reported application package: $APK_PACKAGE"
12881345
if [ "$APK_PACKAGE" != "$PACKAGE_NAME" ]; then
12891346
ba_log "WARNING: APK package ($APK_PACKAGE) differs from Codename One package ($PACKAGE_NAME)" >&2
12901347
fi
1348+
RUNTIME_PACKAGE="$APK_PACKAGE"
12911349
else
12921350
ba_log "WARN: Unable to extract application package using $AAPT_BIN" >&2
12931351
fi
12941352
else
12951353
ba_log "WARN: aapt binary not found under $ANDROID_SDK_ROOT/build-tools; skipping APK package verification" >&2
12961354
fi
12971355

1356+
TEST_RUNTIME_PACKAGE="${RUNTIME_PACKAGE}.test"
1357+
RUNTIME_STUB_FQCN="${RUNTIME_PACKAGE}.${MAIN_NAME}Stub"
1358+
1359+
ba_log "Preparing device for APK installation"
1360+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell getprop sys.boot_completed >/dev/null 2>&1 || true
1361+
1362+
SESSION_IDS="$($ADB_BIN -s "$EMULATOR_SERIAL" shell cmd package list sessions 2>/dev/null | awk '{print $1}' | sed 's/sessionId=//g' || true)"
1363+
if [ -n "$SESSION_IDS" ]; then
1364+
while IFS= read -r sid; do
1365+
[ -z "$sid" ] && continue
1366+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package abort-session "$sid" >/dev/null 2>&1 || true
1367+
done <<<"$SESSION_IDS"
1368+
fi
1369+
1370+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm uninstall "$RUNTIME_PACKAGE" >/dev/null 2>&1 || true
1371+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm uninstall "$TEST_RUNTIME_PACKAGE" >/dev/null 2>&1 || true
1372+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package bg-dexopt-job >/dev/null 2>&1 || true
1373+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell rm -f /data/local/tmp/*.apk >/dev/null 2>&1 || true
1374+
12981375
ba_log "Installing app APK: $APP_APK"
12991376
if ! adb_install_retry "$EMULATOR_SERIAL" "$APP_APK"; then
13001377
dump_emulator_diagnostics
@@ -1310,34 +1387,34 @@ if ! adb_install_retry "$EMULATOR_SERIAL" "$TEST_APK"; then
13101387
fi
13111388

13121389
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list instrumentation | sed "s/^/[build-android-app] instrumentation: /" || true
1313-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list packages | grep -E "${PACKAGE_NAME//./\.}|${PACKAGE_NAME//./\.}\.test" | sed "s/^/[build-android-app] package: /" || true
1314-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package resolve-activity --brief "$PACKAGE_NAME/$FQCN" | sed "s/^/[build-android-app] resolve-stub (pre-test): /" || true
1390+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list packages | grep -E "${RUNTIME_PACKAGE//./\.}|${RUNTIME_PACKAGE//./\.}\.test" | sed "s/^/[build-android-app] package: /" || true
1391+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package resolve-activity --brief "$RUNTIME_PACKAGE/$RUNTIME_STUB_FQCN" | sed "s/^/[build-android-app] resolve-stub (pre-test): /" || true
13151392

1316-
APP_PACKAGE_PATH="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "$PACKAGE_NAME" 2>/dev/null | tr -d '\r' || true)"
1393+
APP_PACKAGE_PATH="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "$RUNTIME_PACKAGE" 2>/dev/null | tr -d '\r' || true)"
13171394
if [ -n "$APP_PACKAGE_PATH" ]; then
13181395
printf '%s\n' "$APP_PACKAGE_PATH" | sed 's/^/[build-android-app] app-apk: /'
13191396
else
1320-
ba_log "App package $PACKAGE_NAME not yet reported by pm path on $EMULATOR_SERIAL"
1397+
ba_log "App package $RUNTIME_PACKAGE not yet reported by pm path on $EMULATOR_SERIAL"
13211398
fi
13221399

1323-
TEST_PACKAGE_PATH="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "${PACKAGE_NAME}.test" 2>/dev/null | tr -d '\r' || true)"
1400+
TEST_PACKAGE_PATH="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm path "$TEST_RUNTIME_PACKAGE" 2>/dev/null | tr -d '\r' || true)"
13241401
if [ -n "$TEST_PACKAGE_PATH" ]; then
13251402
printf '%s\n' "$TEST_PACKAGE_PATH" | sed 's/^/[build-android-app] test-apk: /'
13261403
else
1327-
ba_log "Test package ${PACKAGE_NAME}.test not yet reported by pm path on $EMULATOR_SERIAL"
1404+
ba_log "Test package $TEST_RUNTIME_PACKAGE not yet reported by pm path on $EMULATOR_SERIAL"
13281405
fi
13291406

13301407
log_instrumentation_state
13311408

13321409
RUNNER="$(
13331410
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list instrumentation \
13341411
| tr -d '\r' \
1335-
| grep -F "(target=$PACKAGE_NAME)" \
1412+
| grep -F "(target=$RUNTIME_PACKAGE)" \
13361413
| head -n1 \
13371414
| sed -E 's/^instrumentation:([^ ]+).*/\1/'
13381415
)"
13391416
if [ -z "$RUNNER" ]; then
1340-
ba_log "No instrumentation runner found for $PACKAGE_NAME"
1417+
ba_log "No instrumentation runner found for $RUNTIME_PACKAGE"
13411418
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell pm list instrumentation | sed 's/^/[build-android-app] instrumentation: /'
13421419
dump_emulator_diagnostics
13431420
stop_emulator
@@ -1350,7 +1427,7 @@ LAUNCH_RESOLVE_OUTPUT="$("$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package reso
13501427
if [ -n "$LAUNCH_RESOLVE_OUTPUT" ]; then
13511428
printf '%s\n' "$LAUNCH_RESOLVE_OUTPUT" | sed 's/^/[build-android-app] resolve-launch: /'
13521429
fi
1353-
STUB_ACTIVITY_FQCN="$PACKAGE_NAME/$FQCN"
1430+
STUB_ACTIVITY_FQCN="$RUNTIME_PACKAGE/$RUNTIME_STUB_FQCN"
13541431
STUB_RESOLVE_OUTPUT="$(
13551432
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell cmd package resolve-activity --brief "$STUB_ACTIVITY_FQCN" 2>&1 || true
13561433
)"
@@ -1366,8 +1443,8 @@ if [[ "$STUB_RESOLVE_OUTPUT" == *"No activity found"* ]] || [ -z "$STUB_RESOLVE_
13661443
exit 1
13671444
fi
13681445

1369-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell am force-stop "$PACKAGE_NAME" >/dev/null 2>&1 || true
1370-
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell am force-stop "${PACKAGE_NAME}.test" >/dev/null 2>&1 || true
1446+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell am force-stop "$RUNTIME_PACKAGE" >/dev/null 2>&1 || true
1447+
"$ADB_BIN" -s "$EMULATOR_SERIAL" shell am force-stop "$TEST_RUNTIME_PACKAGE" >/dev/null 2>&1 || true
13711448

13721449
UI_TEST_TIMEOUT_SECONDS="${UI_TEST_TIMEOUT_SECONDS:-900}"
13731450
if ! [[ "$UI_TEST_TIMEOUT_SECONDS" =~ ^[0-9]+$ ]] || [ "$UI_TEST_TIMEOUT_SECONDS" -le 0 ]; then
@@ -1422,10 +1499,10 @@ fi
14221499
copy_device_file() {
14231500
local src="$1"
14241501
local dest="$2"
1425-
if ! "$ADB_BIN" -s "$EMULATOR_SERIAL" shell run-as "$PACKAGE_NAME" ls "$src" >/dev/null 2>&1; then
1502+
if ! "$ADB_BIN" -s "$EMULATOR_SERIAL" shell run-as "$RUNTIME_PACKAGE" ls "$src" >/dev/null 2>&1; then
14261503
return 1
14271504
fi
1428-
if "$ADB_BIN" -s "$EMULATOR_SERIAL" exec-out run-as "$PACKAGE_NAME" cat "$src" >"$dest"; then
1505+
if "$ADB_BIN" -s "$EMULATOR_SERIAL" exec-out run-as "$RUNTIME_PACKAGE" cat "$src" >"$dest"; then
14291506
return 0
14301507
fi
14311508
rm -f "$dest"

0 commit comments

Comments
 (0)