Support non-flattened APEXes in the sync script.

Using OVERRIDE_TARGET_FLATTEN_APEX in a full platform tree isn't
straightforward any more.

Test: art/tools/buildbot-build.sh --target && \
      art/tools/buildbot-teardown-device.sh && \
      art/tools/buildbot-cleanup-device.sh && \
      art/tools/buildbot-setup-device.sh && \
      art/tools/buildbot-sync.sh
Test: art/tools/buildbot-sync.sh
Change-Id: I4f189b22ccbd5cdf066052253e2df8a9fb7d1452
diff --git a/tools/buildbot-sync.sh b/tools/buildbot-sync.sh
index 0e79883..00b745c 100755
--- a/tools/buildbot-sync.sh
+++ b/tools/buildbot-sync.sh
@@ -16,6 +16,8 @@
 
 # Push ART artifacts and its dependencies to a chroot directory for on-device testing.
 
+set -e
+
 if [ -t 1 ]; then
   # Color sequences if terminal is a tty.
   red='\033[0;31m'
@@ -44,29 +46,23 @@
   exit 1
 fi
 
-if [[ "$(build/soong/soong_ui.bash --dumpvar-mode TARGET_FLATTEN_APEX)" != "true" ]]; then
-  echo -e "${red}This script only works when  APEX packages are flattened, but the build" \
-    "configuration is set up to use non-flattened APEX packages.${nc}"
-  echo -e "${magenta}You can force APEX flattening by setting the environment variable" \
-    "\`OVERRIDE_TARGET_FLATTEN_APEX\` to \"true\" before starting the build and running this" \
-    "script.${nc}"
-  exit 1
-fi
-
 
 # Sync relevant product directories
 # ---------------------------------
 
-sync_dir() {
-  local dir=${1}
-  echo -e "${green}Syncing $dir directory...${nc}"
-  adb shell mkdir -p "$ART_TEST_CHROOT/$dir"
-  adb push "$ANDROID_PRODUCT_OUT/$dir" "$ART_TEST_CHROOT/"
-}
-
-sync_dir system
-sync_dir linkerconfig
-sync_dir data
+(
+  cd $ANDROID_PRODUCT_OUT
+  for dir in system/* linkerconfig data; do
+    [ -d $dir ] || continue
+    if [ $dir == system/apex ]; then
+      # We sync the APEXes later.
+      continue
+    fi
+    echo -e "${green}Syncing $dir directory...${nc}"
+    adb shell mkdir -p "$ART_TEST_CHROOT/$dir"
+    adb push $dir "$ART_TEST_CHROOT/$(dirname $dir)"
+  done
+)
 
 # Overwrite the default public.libraries.txt file with a smaller one that
 # contains only the public libraries pushed to the chroot directory.
@@ -79,26 +75,28 @@
 # APEX packages activation.
 # -------------------------
 
+adb shell mkdir -p "$ART_TEST_CHROOT/apex"
+
 # Manually "activate" the flattened APEX $1 by syncing it to /apex/$2 in the
 # chroot. $2 defaults to $1.
-#
-# TODO: Handle the case of build targets using non-flatted APEX packages.
-# As a workaround, one can run `export OVERRIDE_TARGET_FLATTEN_APEX=true` before building
-# a target to have its APEX packages flattened.
 activate_apex() {
   local src_apex=${1}
   local dst_apex=${2:-${src_apex}}
+
+  # Unpack the .apex file in the product directory, but if we already see a
+  # directory we assume buildbot-build.sh has already done it for us and just
+  # use it.
+  src_apex_path=$ANDROID_PRODUCT_OUT/system/apex/${src_apex}
+  if [ ! -d $src_apex_path ]; then
+    echo -e "${green}Extracting APEX ${src_apex}.apex...${nc}"
+    mkdir -p $src_apex_path
+    $ANDROID_HOST_OUT/bin/deapexer --debugfs_path $ANDROID_HOST_OUT/bin/debugfs_static \
+      extract ${src_apex_path}.apex $src_apex_path
+  fi
+
   echo -e "${green}Activating APEX ${src_apex} as ${dst_apex}...${nc}"
-  # We move the files from `/system/apex/${src_apex}` to `/apex/${dst_apex}` in
-  # the chroot directory, instead of simply using a symlink, as Bionic's linker
-  # relies on the real path name of a binary (e.g.
-  # `/apex/com.android.art/bin/dex2oat`) to select the linker configuration.
-  adb shell mkdir -p "$ART_TEST_CHROOT/apex"
   adb shell rm -rf "$ART_TEST_CHROOT/apex/${dst_apex}"
-  # Use use mv instead of cp, as cp has a bug on fugu NRD90R where symbolic
-  # links get copied with odd names, eg: libcrypto.so -> /system/lib/libcrypto.soe.sort.so
-  adb shell mv "$ART_TEST_CHROOT/system/apex/${src_apex}" "$ART_TEST_CHROOT/apex/${dst_apex}" \
-    || exit 1
+  adb push $src_apex_path "$ART_TEST_CHROOT/apex/${dst_apex}"
 }
 
 # "Activate" the required APEX modules.