@@ -497,6 +497,106 @@ wait_for_package_service() {
497497 return 1
498498}
499499
500+ wait_for_api_level () {
501+ local serial=" $1 "
502+ local timeout=" ${API_LEVEL_TIMEOUT_SECONDS:- 600} "
503+ local per_try=" ${API_LEVEL_PER_TRY_TIMEOUT_SECONDS:- 5} "
504+ if ! [[ " $timeout " =~ ^[0-9]+$ ]] || [ " $timeout " -le 0 ]; then
505+ timeout=600
506+ fi
507+ if ! [[ " $per_try " =~ ^[0-9]+$ ]] || [ " $per_try " -le 0 ]; then
508+ per_try=5
509+ fi
510+
511+ local deadline=$(( SECONDS + timeout))
512+ local last_log=$SECONDS
513+ local sdk=" "
514+
515+ while [ $SECONDS -lt $deadline ]; do
516+ if sdk=" $( timeout " $per_try " " $ADB_BIN " -s " $serial " shell getprop ro.build.version.sdk 2> /dev/null | tr -d ' \r' | tr -d ' \n' ) " ; then
517+ if [[ " $sdk " =~ ^[0-9]+$ ]]; then
518+ ba_log " Device API level is $sdk "
519+ return 0
520+ fi
521+ fi
522+ if [ $(( SECONDS - last_log)) -ge 10 ]; then
523+ ba_log " Waiting for ro.build.version.sdk on $serial "
524+ last_log=$SECONDS
525+ fi
526+ sleep 2
527+ done
528+
529+ ba_log " ro.build.version.sdk not available after ${timeout} s" >&2
530+ return 1
531+ }
532+
533+ dump_emulator_diagnostics () {
534+ " $ADB_BIN " -s " $EMULATOR_SERIAL " shell getprop | sed ' s/^/[build-android-app] getprop: /' || true
535+ " $ADB_BIN " -s " $EMULATOR_SERIAL " shell logcat -d -t 2000 \
536+ | grep -v -E ' com\\.android\\.bluetooth|BtGd|bluetooth' \
537+ | tail -n 200 | sed ' s/^/[build-android-app] logcat: /' || true
538+ }
539+
540+ log_instrumentation_state () {
541+ " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm path android \
542+ | sed ' s/^/[build-android-app] pm path android: /' || true
543+
544+ local instrumentation_list
545+ instrumentation_list=" $( " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm list instrumentation 2> /dev/null || true) "
546+ if [ -n " $instrumentation_list " ]; then
547+ printf ' %s\n' " $instrumentation_list " | sed ' s/^/[build-android-app] instrumentation: /'
548+ else
549+ ba_log " No instrumentation targets reported on $EMULATOR_SERIAL before installation"
550+ fi
551+
552+ local have_test_apk=0
553+ if " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm path " ${PACKAGE_NAME} .test" > /dev/null 2>&1 ; then
554+ have_test_apk=1
555+ " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm path " ${PACKAGE_NAME} .test" \
556+ | sed ' s/^/[build-android-app] test-apk: /'
557+ else
558+ ba_log " Test APK for ${PACKAGE_NAME} .test not yet installed on $EMULATOR_SERIAL "
559+ fi
560+
561+ local package_regex package_list package_matches
562+ package_regex=" ${PACKAGE_NAME// ./ \. } "
563+ package_list=" $( " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm list packages 2> /dev/null || true) "
564+ if [ -n " $package_list " ]; then
565+ package_matches=" $( printf ' %s\n' " $package_list " | grep -E " ${package_regex} |${package_regex} \.test" || true) "
566+ if [ -n " $package_matches " ]; then
567+ printf ' %s\n' " $package_matches " | sed ' s/^/[build-android-app] package: /'
568+ else
569+ ba_log " Packages matching $PACKAGE_NAME not yet installed on $EMULATOR_SERIAL "
570+ fi
571+ else
572+ ba_log " Package manager returned no packages on $EMULATOR_SERIAL "
573+ fi
574+
575+ local instrumentation_target instrumentation_line
576+ instrumentation_target=" "
577+ if [ -n " $instrumentation_list " ]; then
578+ instrumentation_line=" $( printf ' %s\n' " $instrumentation_list " | awk -v pkg=' ${PACKAGE_NAME}.test' ' $0 ~ pkg {print; exit}' ) "
579+ if [ -n " $instrumentation_line " ]; then
580+ instrumentation_target=" ${instrumentation_line# instrumentation: } "
581+ instrumentation_target=" ${instrumentation_target%% * } "
582+ else
583+ instrumentation_target=" $( printf ' %s\n' " $instrumentation_list " | awk -F' ' ' /^instrumentation:/{print $1}' | head -n1) "
584+ instrumentation_target=" ${instrumentation_target# instrumentation: } "
585+ fi
586+ fi
587+
588+ if [ -n " $instrumentation_target " ] && [ " $have_test_apk " -eq 1 ]; then
589+ " $ADB_BIN " -s " $EMULATOR_SERIAL " shell am instrument -w -r \
590+ -e log true \
591+ " $instrumentation_target " \
592+ 2>&1 | sed ' s/^/[build-android-app] am instrument: /'
593+ elif [ -n " $instrumentation_target " ]; then
594+ ba_log " Instrumentation target $instrumentation_target available but test APK missing; skipping am instrument dry run"
595+ else
596+ ba_log " Skipping am instrument dry run; no instrumentation target detected on $EMULATOR_SERIAL "
597+ fi
598+ }
599+
500600stop_emulator () {
501601 if [ -n " ${EMULATOR_SERIAL:- } " ]; then
502602 " $ADB_BIN " -s " $EMULATOR_SERIAL " emu kill > /dev/null 2>&1 || true
@@ -619,46 +719,68 @@ if [ "$POST_BOOT_GRACE" -gt 0 ]; then
619719fi
620720
621721if ! wait_for_package_service " $EMULATOR_SERIAL " ; then
622- " $ADB_BIN " -s " $EMULATOR_SERIAL " shell getprop | sed ' s/^/[build-android-app] getprop: /' || true
623- " $ADB_BIN " -s " $EMULATOR_SERIAL " shell logcat -d -t 2000 \
624- | grep -v -E ' com\.android\.bluetooth|BtGd|bluetooth' \
625- | tail -n 200 | sed ' s/^/[build-android-app] logcat: /' || true
722+ dump_emulator_diagnostics
626723 stop_emulator
627724 exit 1
628725fi
629726
630- " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm path android \
631- | sed ' s/^/[build-android-app] pm path android: /' || true
632- INSTRUMENTATION_LIST=" $( " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm list instrumentation 2> /dev/null || true) "
633- if [ -n " $INSTRUMENTATION_LIST " ]; then
634- printf ' %s\n' " $INSTRUMENTATION_LIST " | sed ' s/^/[build-android-app] instrumentation: /'
635- else
636- ba_log " No instrumentation targets reported on $EMULATOR_SERIAL before installation"
727+ if ! wait_for_api_level " $EMULATOR_SERIAL " ; then
728+ dump_emulator_diagnostics
729+ stop_emulator
730+ exit 1
637731fi
638732
639- PACKAGE_REGEX=" ${PACKAGE_NAME// ./ \\ .} "
640- PACKAGE_LIST=" $( " $ADB_BIN " -s " $EMULATOR_SERIAL " shell pm list packages 2> /dev/null || true) "
641- if [ -n " $PACKAGE_LIST " ]; then
642- PACKAGE_MATCHES=" $( printf ' %s\n' " $PACKAGE_LIST " | grep -E " ${PACKAGE_REGEX} |${PACKAGE_REGEX} \\ .test" || true) "
643- if [ -n " $PACKAGE_MATCHES " ]; then
644- printf ' %s\n' " $PACKAGE_MATCHES " | sed ' s/^/[build-android-app] package: /'
645- else
646- ba_log " Packages matching $PACKAGE_NAME not yet installed on $EMULATOR_SERIAL "
647- fi
648- else
649- ba_log " Package manager returned no packages on $EMULATOR_SERIAL "
733+ " $ADB_BIN " kill-server > /dev/null 2>&1 || true
734+ " $ADB_BIN " start-server > /dev/null 2>&1 || true
735+ " $ADB_BIN " -s " $EMULATOR_SERIAL " wait-for-device
736+ export ANDROID_SERIAL=" $EMULATOR_SERIAL "
737+
738+ INSTALL_TIMEOUT_SECONDS=" ${INSTALL_TIMEOUT_SECONDS:- 600} "
739+ if ! [[ " $INSTALL_TIMEOUT_SECONDS " =~ ^[0-9]+$ ]] || [ " $INSTALL_TIMEOUT_SECONDS " -le 0 ]; then
740+ INSTALL_TIMEOUT_SECONDS=600
650741fi
651742
652- INSTRUMENTATION_TARGET=" $( printf ' %s\n' " $INSTRUMENTATION_LIST " | awk -F' ' ' /instrumentation/{print $2}' | head -n1) "
653- if [ -n " $INSTRUMENTATION_TARGET " ]; then
654- " $ADB_BIN " -s " $EMULATOR_SERIAL " shell am instrument -w -r \
655- -e log true \
656- " $INSTRUMENTATION_TARGET " \
657- 2>&1 | sed ' s/^/[build-android-app] am instrument: /'
743+ INSTALL_CMD=(
744+ " ./gradlew"
745+ " --no-daemon"
746+ " installDebug"
747+ " installDebugAndroidTest"
748+ )
749+ if command -v timeout > /dev/null 2>&1 ; then
750+ ba_log " Installing app and androidTest APKs with external timeout of ${INSTALL_TIMEOUT_SECONDS} s"
751+ INSTALL_CMD=(" timeout" " $INSTALL_TIMEOUT_SECONDS " " ${INSTALL_CMD[@]} " )
658752else
659- ba_log " Skipping am instrument dry run; no instrumentation target detected on $EMULATOR_SERIAL "
753+ ba_log " timeout command not found; running install tasks without external watchdog "
660754fi
661755
756+ GRADLE_INSTALL_LOG=" $GRADLE_PROJECT_DIR /gradle-ui-install.log"
757+ set +e
758+ (
759+ cd " $GRADLE_PROJECT_DIR "
760+ " ${INSTALL_CMD[@]} " | tee " $GRADLE_INSTALL_LOG "
761+ exit " ${PIPESTATUS[0]} "
762+ )
763+ INSTALL_EXIT_CODE=$?
764+ set -e
765+
766+ if [ -f " $GRADLE_INSTALL_LOG " ]; then
767+ cp " $GRADLE_INSTALL_LOG " " $FINAL_ARTIFACT_DIR /ui-test-install.log"
768+ ba_log " Gradle install log saved to $FINAL_ARTIFACT_DIR /ui-test-install.log"
769+ fi
770+
771+ if [ " $INSTALL_EXIT_CODE " -ne 0 ]; then
772+ ba_log " Gradle install tasks exited with status $INSTALL_EXIT_CODE "
773+ stop_emulator
774+ exit 1
775+ fi
776+
777+ log_instrumentation_state
778+
779+ " $ADB_BIN " kill-server > /dev/null 2>&1 || true
780+ " $ADB_BIN " start-server > /dev/null 2>&1 || true
781+ " $ADB_BIN " -s " $EMULATOR_SERIAL " wait-for-device
782+ export ANDROID_SERIAL=" $EMULATOR_SERIAL "
783+
662784UI_TEST_TIMEOUT_SECONDS=" ${UI_TEST_TIMEOUT_SECONDS:- 900} "
663785if ! [[ " $UI_TEST_TIMEOUT_SECONDS " =~ ^[0-9]+$ ]] || [ " $UI_TEST_TIMEOUT_SECONDS " -le 0 ]; then
664786 ba_log " Invalid UI_TEST_TIMEOUT_SECONDS=$UI_TEST_TIMEOUT_SECONDS provided; falling back to 900"
0 commit comments