Update boot image profile generation scripts

The old script is not longer suitable. It is replace by two scripts:
- one that can configure the device to capture boot image profiles
- and the second, which can process the raw boot image profiles
  obtained after running CUJs and transform it to the expected build
  system format.

Note that boot-image-profile-generate.sh should be invoked with
arguments based on the ammount of executed  CUJs and the shape of
profile data. Some defaults are provided but these might not be
the best in all cases.

Test: run the scripts and check the data
Bug: 152574358
Change-Id: Ic814f22591d8861e7224f8deadbcc21427f94333
diff --git a/tools/boot-image-profile-generate.sh b/tools/boot-image-profile-generate.sh
new file mode 100755
index 0000000..e21048e
--- /dev/null
+++ b/tools/boot-image-profile-generate.sh
@@ -0,0 +1,152 @@
+#!/bin/bash
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+# This script creates the final boot image profile (suitable to include in the platform build).
+# The input to the script are:
+#   1) the boot.zip file which contains the boot classpath and system server jars.
+#      This file can be obtained from running `m dist` or by configuring the device with
+#      the `art/tools/boot-image-profile-configure-device.sh` script.
+#   2) the preloaded classes blacklist which specify what clases should not be preloaded
+#      in Zygote. Usually located in usually in frameworks/base/config/preloaded-classes-blacklist
+#   3) a list of raw boot image profiles extracted from devices. An example how to do that is
+#      by running `art/tools/boot-image-profile-extract-profile.sh` script.
+#
+# It is strongly recommended that you make use of extensive critical user journeys flows in order
+# to capture the raw boot image profiles described in #3.
+#
+# NOTE: by default, the script uses default arguments for producing the boot image profiles.
+# You might want to adjust the default generation arguments based on the shape of profile
+# and based on the metrics that matter for each product.
+#
+
+if [[ -z "$ANDROID_BUILD_TOP" ]]; then
+  echo "You must run on this after running envsetup.sh and launch target"
+  exit 1
+fi
+
+if [[ "$#" -lt 4 ]]; then
+  echo "Usage $0 <output-dir> <boot.zip-location> <preloaded-blacklist-location> <profile-input1> <profile-input2> ... <profman args>"
+  echo "Without any profman args the script will use defaults."
+  echo "Example: $0 output-dir boot.zip frameworks/base/config/preloaded-classes-blacklist android1.prof android2.prof"
+  echo "         $0 output-dir boot.zip frameworks/base/config/preloaded-classes-blacklist android.prof --profman-arg --upgrade-startup-to-hot=true"
+  echo "preloaded.black-list is usually in frameworks/base/config/preloaded-classes-blacklist"
+  exit 1
+fi
+
+echo "Creating work dir"
+WORK_DIR=/tmp/android-bcp
+mkdir -p "$WORK_DIR"
+
+OUT_DIR="$1"
+BOOT_ZIP="$2"
+PRELOADED_BLACKLIST="$3"
+shift 3
+
+IN
+
+# Read the profile input args.
+profman_profile_input_args=()
+while [[ "$#" -ge 1 ]] && [[ ! "$1" = '--profman-arg' ]]; do
+  profman_profile_input_args+=("--profile-file=$1")
+  shift
+done
+
+# Read the profman args.
+profman_args=()
+while [[ "$#" -ge 2 ]] && [[ "$1" = '--profman-arg' ]]; do
+  profman_args+=("$2")
+  shift 2
+done
+
+OUT_BOOT_PROFILE="$OUT_DIR"/boot-image-profile.txt
+OUT_PRELOADED_CLASSES="$OUT_DIR"/preloaded-classes
+OUT_SYSTEM_SERVER="$OUT_DIR"/art-profile
+
+echo "Changing dirs to the build top"
+cd "$ANDROID_BUILD_TOP"
+
+echo "Unziping boot.zip"
+BOOT_UNZIP_DIR="$WORK_DIR"/boot-dex
+ART_JARS="$BOOT_UNZIP_DIR"/dex_artjars_input
+BOOT_JARS="$BOOT_UNZIP_DIR"/dex_bootjars_input
+SYSTEM_SERVER_JAR="$BOOT_UNZIP_DIR"/system/framework/services.jar
+
+unzip -o "$BOOT_ZIP" -d "$BOOT_UNZIP_DIR"
+
+echo "Processing boot image jar files"
+jar_args=()
+for entry in "$ART_JARS"/*
+do
+  jar_args+=("--apk=$entry")
+done
+for entry in "$BOOT_JARS"/*
+do
+  jar_args+=("--apk=$entry")
+done
+profman_args+=("${jar_args[@]}")
+
+echo "Running profman for boot image profiles"
+# NOTE:
+# You might want to adjust the default generation arguments based on the data
+# For example, to update the selection thresholds you could specify:
+#  --method-threshold=10 \
+#  --class-threshold=10 \
+#  --preloaded-class-threshold=10 \
+#  --special-package=android:1 \
+#  --special-package=com.android.systemui:1 \
+# The threshold is percentage of total aggregation, that is, a method/class is
+# included in the profile only if it's used by at least x% of the packages.
+# (from 0% - include everything to 100% - include only the items that
+# are used by all packages on device).
+# The --special-package allows you to give a prioriority to certain packages,
+# meaning, if the methods is used by that package then the algorithm will use a
+# different selection thresholds.
+# (system server is identified as the "android" package)
+profman \
+  --generate-boot-image-profile \
+  "${profman_profile_input_args[@]}" \
+  --out-profile-path="$OUT_BOOT_PROFILE" \
+  --out-preloaded-classes-path="$OUT_PRELOADED_CLASSES" \
+  --preloaded-classes-blacklist="$PRELOADED_BLACKLIST" \
+  --special-package=android:1 \
+  --special-package=com.android.systemui:1 \
+  "${profman_args[@]}"
+
+echo "Done boot image profile"
+
+echo "Running profman for system server"
+# For system server profile we want to include everything usually
+# We also don't have a preloaded-classes file for it, so we ignore the argument.
+profman \
+  --generate-boot-image-profile \
+  "${profman_profile_input_args[@]}" \
+  --out-profile-path="$OUT_SYSTEM_SERVER" \
+  --apk="$SYSTEM_SERVER_JAR" \
+  --method-threshold=0 \
+  --class-threshold=0
+
+echo "Done system server"
+
+echo ""
+echo "Boot profile methods+classes count:          $(wc -l $OUT_BOOT_PROFILE)"
+echo "Preloaded classes count:                     $(wc -l $OUT_PRELOADED_CLASSES)"
+echo "System server profile methods+classes count: $(wc -l $OUT_SYSTEM_SERVER)"
+
+CLEAN_UP="${CLEAN_UP:-true}"
+if [[ "$CLEAN_UP" = "true" ]]; then
+  rm -rf "$WORK_DIR"
+fi
\ No newline at end of file