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 82ART_JARS="$BOOT_UNZIP_DIR"/dex_artjars_input 83BOOT_JARS="$BOOT_UNZIP_DIR"/dex_bootjars_input 84SYSTEM_SERVER_JAR="$BOOT_UNZIP_DIR"/system/framework/services.jar 85 86unzip -o "$BOOT_ZIP" -d "$BOOT_UNZIP_DIR" 87 88echo "Processing boot image jar files" 89jar_args=() 90for entry in "$ART_JARS"/* 91do 92 jar_args+=("--apk=$entry") 93done 94for entry in "$BOOT_JARS"/* 95do 96 jar_args+=("--apk=$entry") 97done 98profman_args+=("${jar_args[@]}") 99 100echo "Running profman for boot image profiles" 101# NOTE: 102# You might want to adjust the default generation arguments based on the data 103# For example, to update the selection thresholds you could specify: 104# --method-threshold=10 \ 105# --class-threshold=10 \ 106# --preloaded-class-threshold=10 \ 107# --special-package=android:1 \ 108# --special-package=com.android.systemui:1 \ 109# The threshold is percentage of total aggregation, that is, a method/class is 110# included in the profile only if it's used by at least x% of the packages. 111# (from 0% - include everything to 100% - include only the items that 112# are used by all packages on device). 113# The --special-package allows you to give a prioriority to certain packages, 114# meaning, if the methods is used by that package then the algorithm will use a 115# different selection thresholds. 116# (system server is identified as the "android" package) 117profman \ 118 --generate-boot-image-profile \ 119 "${profman_profile_input_args[@]}" \ 120 --out-profile-path="$OUT_BOOT_PROFILE" \ 121 --out-preloaded-classes-path="$OUT_PRELOADED_CLASSES" \ 122 --preloaded-classes-denylist="$PRELOADED_DENYLIST" \ 123 --special-package=android:1 \ 124 --special-package=com.android.systemui:1 \ 125 "${profman_args[@]}" 126 127echo "Done boot image profile" 128 129echo "Running profman for system server" 130# For system server profile we want to include everything usually 131# We also don't have a preloaded-classes file for it, so we ignore the argument. 132profman \ 133 --generate-boot-image-profile \ 134 "${profman_profile_input_args[@]}" \ 135 --out-profile-path="$OUT_SYSTEM_SERVER" \ 136 --apk="$SYSTEM_SERVER_JAR" \ 137 --method-threshold=0 \ 138 --class-threshold=0 139 140echo "Done system server" 141 142echo "" 143echo "Boot profile methods+classes count: $(wc -l $OUT_BOOT_PROFILE)" 144echo "Preloaded classes count: $(wc -l $OUT_PRELOADED_CLASSES)" 145echo "System server profile methods+classes count: $(wc -l $OUT_SYSTEM_SERVER)" 146 147CLEAN_UP="${CLEAN_UP:-true}" 148if [[ "$CLEAN_UP" = "true" ]]; then 149 rm -rf "$WORK_DIR" 150fi 151