1#!/bin/bash 2# 3# Copyright (C) 2020 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# 18# This script creates the final boot image profile (suitable to include in the platform build). 19# The input to the script are: 20# 1) the boot.zip file which contains the boot classpath and system server jars. 21# This file can be obtained from running `m dist` or by configuring the device with 22# the `art/tools/boot-image-profile-configure-device.sh` script. 23# 2) the preloaded classes denylist which specify what clases should not be preloaded 24# in Zygote. Usually located in usually in frameworks/base/config/preloaded-classes-denylist 25# 3) a list of raw boot image profiles extracted from devices. An example how to do that is 26# by running `art/tools/boot-image-profile-extract-profile.sh` script. 27# 28# It is strongly recommended that you make use of extensive critical user journeys flows in order 29# to capture the raw boot image profiles described in #3. 30# 31# NOTE: by default, the script uses default arguments for producing the boot image profiles. 32# You might want to adjust the default generation arguments based on the shape of profile 33# and based on the metrics that matter for each product. 34# 35 36if [[ -z "$ANDROID_BUILD_TOP" ]]; then 37 echo "You must run on this after running envsetup.sh and launch target" 38 exit 1 39fi 40 41if [[ "$#" -lt 4 ]]; then 42 echo "Usage $0 <output-dir> <boot.zip-location> <preloaded-denylist-location> <profile-input1> <profile-input2> ... <profman args>" 43 echo "Without any profman args the script will use defaults." 44 echo "Example: $0 output-dir boot.zip frameworks/base/config/preloaded-classes-denylist android1.prof android2.prof" 45 echo " $0 output-dir boot.zip frameworks/base/config/preloaded-classes-denylist android.prof --profman-arg --upgrade-startup-to-hot=true" 46 echo "preloaded-deny-list-location is usually frameworks/base/config/preloaded-classes-denylist" 47 exit 1 48fi 49 50echo "Creating work dir" 51WORK_DIR=/tmp/android-bcp 52mkdir -p "$WORK_DIR" 53 54OUT_DIR="$1" 55BOOT_ZIP="$2" 56PRELOADED_DENYLIST="$3" 57shift 3 58 59# Read the profile input args. 60profman_profile_input_args=() 61while [[ "$#" -ge 1 ]] && [[ ! "$1" = '--profman-arg' ]]; do 62 profman_profile_input_args+=("--profile-file=$1") 63 shift 64done 65 66# Read the profman args. 67profman_args=() 68while [[ "$#" -ge 2 ]] && [[ "$1" = '--profman-arg' ]]; do 69 profman_args+=("$2") 70 shift 2 71done 72 73OUT_BOOT_PROFILE="$OUT_DIR"/boot-image-profile.txt 74OUT_PRELOADED_CLASSES="$OUT_DIR"/preloaded-classes 75OUT_SYSTEM_SERVER="$OUT_DIR"/art-profile 76 77echo "Changing dirs to the build top" 78cd "$ANDROID_BUILD_TOP" 79 80echo "Unziping boot.zip" 81BOOT_UNZIP_DIR="$WORK_DIR"/boot-dex 82BOOT_JARS="$BOOT_UNZIP_DIR"/dex_bootjars_input 83SYSTEM_SERVER_JAR="$BOOT_UNZIP_DIR"/system/framework/services.jar 84 85unzip -o "$BOOT_ZIP" -d "$BOOT_UNZIP_DIR" 86 87echo "Processing boot image jar files" 88jar_args=() 89for entry in "$BOOT_JARS"/* 90do 91 jar_args+=("--apk=$entry") 92done 93profman_args+=("${jar_args[@]}") 94 95echo "Running profman for boot image profiles" 96# NOTE: 97# You might want to adjust the default generation arguments based on the data 98# For example, to update the selection thresholds you could specify: 99# --method-threshold=10 \ 100# --class-threshold=10 \ 101# --preloaded-class-threshold=10 \ 102# --special-package=android:1 \ 103# --special-package=com.android.systemui:1 \ 104# The threshold is percentage of total aggregation, that is, a method/class is 105# included in the profile only if it's used by at least x% of the packages. 106# (from 0% - include everything to 100% - include only the items that 107# are used by all packages on device). 108# The --special-package allows you to give a prioriority to certain packages, 109# meaning, if the methods is used by that package then the algorithm will use a 110# different selection thresholds. 111# (system server is identified as the "android" package) 112profman \ 113 --generate-boot-image-profile \ 114 "${profman_profile_input_args[@]}" \ 115 --out-profile-path="$OUT_BOOT_PROFILE" \ 116 --out-preloaded-classes-path="$OUT_PRELOADED_CLASSES" \ 117 --preloaded-classes-denylist="$PRELOADED_DENYLIST" \ 118 --special-package=android:1 \ 119 --special-package=com.android.systemui:1 \ 120 "${profman_args[@]}" 121 122echo "Done boot image profile" 123 124echo "Running profman for system server" 125# For system server profile we want to include everything usually 126# We also don't have a preloaded-classes file for it, so we ignore the argument. 127profman \ 128 --generate-boot-image-profile \ 129 "${profman_profile_input_args[@]}" \ 130 --out-profile-path="$OUT_SYSTEM_SERVER" \ 131 --apk="$SYSTEM_SERVER_JAR" \ 132 --method-threshold=0 \ 133 --class-threshold=0 134 135echo "Done system server" 136 137echo "" 138echo "Boot profile methods+classes count: $(wc -l $OUT_BOOT_PROFILE)" 139echo "Preloaded classes count: $(wc -l $OUT_PRELOADED_CLASSES)" 140echo "System server profile methods+classes count: $(wc -l $OUT_SYSTEM_SERVER)" 141 142CLEAN_UP="${CLEAN_UP:-true}" 143if [[ "$CLEAN_UP" = "true" ]]; then 144 rm -rf "$WORK_DIR" 145fi 146