#!/bin/bash # # A script for testing imgdiff/applypatch. It takes two full OTA # packages as arguments. It generates (on the host) patches for all # the zip/jar/apk files they have in common, as well as boot and # recovery images. It then applies the patches on the device (or # emulator) and checks that the resulting file is correct. EMULATOR_PORT=5580 # set to 0 to use a device instead USE_EMULATOR=0 # where on the device to do all the patching. WORK_DIR=/data/local/tmp START_OTA_PACKAGE=$1 END_OTA_PACKAGE=$2 # ------------------------ tmpdir=$(mktemp -d) if [ "$USE_EMULATOR" == 1 ]; then emulator -wipe-data -noaudio -no-window -port $EMULATOR_PORT & pid_emulator=$! ADB="adb -s emulator-$EMULATOR_PORT " else ADB="adb -d " fi echo "waiting to connect to device" $ADB wait-for-device # run a command on the device; exit with the exit status of the device # command. run_command() { $ADB shell "$@" \; echo \$? | awk '{if (b) {print a}; a=$0; b=1} END {exit a}' } testname() { echo echo "$1"... testname="$1" } fail() { echo echo FAIL: $testname echo [ "$open_pid" == "" ] || kill $open_pid [ "$pid_emulator" == "" ] || kill $pid_emulator exit 1 } sha1() { sha1sum $1 | awk '{print $1}' } size() { stat -c %s $1 | tr -d '\n' } cleanup() { # not necessary if we're about to kill the emulator, but nice for # running on real devices or already-running emulators. testname "removing test files" run_command rm $WORK_DIR/applypatch run_command rm $WORK_DIR/source run_command rm $WORK_DIR/target run_command rm $WORK_DIR/patch [ "$pid_emulator" == "" ] || kill $pid_emulator rm -rf $tmpdir } $ADB push $ANDROID_PRODUCT_OUT/system/bin/applypatch $WORK_DIR/applypatch patch_and_apply() { local fn=$1 shift unzip -p $START_OTA_PACKAGE $fn > $tmpdir/source unzip -p $END_OTA_PACKAGE $fn > $tmpdir/target imgdiff "$@" $tmpdir/source $tmpdir/target $tmpdir/patch bsdiff $tmpdir/source $tmpdir/target $tmpdir/patch.bs echo "patch for $fn is $(size $tmpdir/patch) [of $(size $tmpdir/target)] ($(size $tmpdir/patch.bs) with bsdiff)" echo "$fn $(size $tmpdir/patch) of $(size $tmpdir/target) bsdiff $(size $tmpdir/patch.bs)" >> /tmp/stats.txt $ADB push $tmpdir/source $WORK_DIR/source || fail "source push failed" run_command rm /data/local/tmp/target $ADB push $tmpdir/patch $WORK_DIR/patch || fail "patch push failed" run_command /data/local/tmp/applypatch /data/local/tmp/source \ /data/local/tmp/target $(sha1 $tmpdir/target) $(size $tmpdir/target) \ $(sha1 $tmpdir/source):/data/local/tmp/patch \ || fail "applypatch of $fn failed" $ADB pull /data/local/tmp/target $tmpdir/result diff -q $tmpdir/target $tmpdir/result || fail "patch output not correct!" } # --------------- basic execution ---------------------- for i in $((zipinfo -1 $START_OTA_PACKAGE; zipinfo -1 $END_OTA_PACKAGE) | \ sort | uniq -d | egrep -e '[.](apk|jar|zip)$'); do patch_and_apply $i -z done patch_and_apply boot.img patch_and_apply system/recovery.img # --------------- cleanup ---------------------- cleanup echo echo PASS echo