1#!/bin/bash 2 3# Copyright 2024 Google Inc. All rights reserved. 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# apply_update.sh: Script to update the device in incremental way 18 19# Ensure OUT directory exists 20if [ -z "$OUT" ]; then 21 echo "Error: OUT environment variable not set." >&2 22 exit 1 23fi 24 25DEVICE_PATH="/data/verity-hash" 26HOST_PATH="$OUT/verity-hash" 27 28# Create the log file path 29log_file="$HOST_PATH/snapshot.log" 30 31# Function to log messages to both console and log file 32log_message() { 33 message="$1" 34 echo "$message" # Print to stdout 35 echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$log_file" # Append to log file with timestamp 36} 37 38# Function to check for create_snapshot and build if needed 39ensure_create_snapshot() { 40 if ! command -v create_snapshot &> /dev/null; then 41 log_message "create_snapshot not found. Building..." 42 m create_snapshot 43 if [[ $? -ne 0 ]]; then 44 log_message "Error: Failed to build create_snapshot." 45 exit 1 46 fi 47 fi 48} 49 50ensure_create_snapshot 51 52# Function to flash static partitions 53flash_static_partitions() { 54 local wipe_flag="$1" 55 local flash_bootloader="$2" 56 57 if (( flash_bootloader )); then 58 fastboot flash bootloader "$OUT"/bootloader.img 59 fastboot reboot bootloader 60 sleep 1 61 fastboot flash radio "$OUT"/radio.img 62 fastboot reboot bootloader 63 sleep 1 64 fi 65 fastboot flashall --exclude-dynamic-partitions --disable-super-optimization --skip-reboot 66 67 if (( wipe_flag )); then 68 log_message "Wiping device..." 69 fastboot -w 70 fi 71 fastboot reboot 72} 73 74# Function to display the help message 75show_help() { 76 cat << EOF 77Usage: $0 [OPTIONS] 78 79This script updates an Android device with incremental flashing, optionally wiping data and flashing static partitions. 80 81Options: 82 --skip-static-partitions Skip flashing static partitions (bootloader, radio, boot, vbmeta, dtbo and other static A/B partitions). 83 * Requires manual update of static partitions on both A/B slots 84 *before* using this flag. 85 * Speeds up the update process and development iteration. 86 * Ideal for development focused on the Android platform (AOSP, 87 git_main). 88 * Safe usage: First update static partitions on both slots, then 89 use this flag for faster development iterations. 90 Ex: 91 1: Run this on both the slots - This will update the kernel and other static partitions: 92 $fastboot flashall --exclude-dynamic-partitions --disable-super-optimization --skip-reboot 93 94 2: Update bootloader on both the slots: 95 $fastboot flash bootloader $OUT/bootloader.img --slot=all 96 97 3: Update radio on both the slots: 98 $fastboot flash radio $OUT/radio.img --slot=all 99 Now, the script can safely use this flag for update purpose. 100 101 --wipe Wipe user data during the update. 102 --boot_snapshot Boot the device off snapshots - No data wipe is supported 103 To revert back to original state - `adb shell snapshotctl revert-snapshots` 104 --help Display this help message. 105 106Environment Variables: 107 OUT Path to the directory containing build output. 108 This is required for the script to function correctly. 109 110Examples: 111 <Development workflow for any project in the platform and build with 'm' to create the images> 112 113 Update the device: 114 $0 115 116 Update the device, but skip flashing static partitions (see above for the usage): 117 $0 --skip-static-partitions 118 119 Update the device and wipe user data: 120 $0 --wipe 121 122 Display this help message: 123 $0 --help 124EOF 125} 126 127skip_static_partitions=0 128boot_snapshot=0 129flash_bootloader=1 130wipe_flag=0 131help_flag=0 132 133# Parse arguments 134for arg in "$@"; do 135 case "$arg" in 136 --skip-static-partitions) 137 skip_static_partitions=1 138 ;; 139 --wipe) 140 wipe_flag=1 141 ;; 142 --skip_bootloader) 143 flash_bootloader=0 144 ;; 145 --boot_snapshot) 146 boot_snapshot=1 147 ;; 148 --help) 149 help_flag=1 150 ;; 151 *) 152 echo "Unknown argument: $arg" >&2 153 help_flag=1 154 ;; 155 esac 156done 157 158# Check if help flag is set 159if (( help_flag )); then 160 show_help 161 exit 0 162fi 163 164rm -rf $HOST_PATH 165 166adb root 167adb wait-for-device 168 169adb shell rm -rf $DEVICE_PATH 170adb shell mkdir -p $DEVICE_PATH 171 172echo "Extracting device source hash from dynamic partitions" 173adb shell snapshotctl dump-verity-hash $DEVICE_PATH 174adb pull -q $DEVICE_PATH $OUT/ 175 176log_message "Entering directory:" 177 178# Navigate to the verity-hash directory 179cd "$HOST_PATH" || { log_message "Error: Could not navigate to $HOST_PATH"; exit 1; } 180 181pwd 182 183# Iterate over all .pb files using a for loop 184for pb_file in *.pb; do 185 # Extract the base filename without the .pb extension 186 base_filename="${pb_file%.*}" 187 188 # Construct the source and target file names 189 source_file="$pb_file" 190 target_file="$OUT/$base_filename.img" 191 192 # Construct the create_snapshot command using an array 193 snapshot_args=( 194 "create_snapshot" 195 "--source" "$source_file" 196 "--target" "$target_file" 197 "--merkel_tree" 198 ) 199 200 # Log the command about to be executed 201 log_message "Running: ${snapshot_args[*]}" 202 203 "${snapshot_args[@]}" >> "$log_file" 2>&1 & 204done 205 206log_message "Waiting for snapshot patch creation" 207 208# Wait for all background processes to complete 209wait $(jobs -p) 210 211log_message "Snapshot patches created successfully" 212 213adb push -q $HOST_PATH/*.patch $DEVICE_PATH 214 215log_message "Applying update" 216 217if (( boot_snapshot)); then 218 adb shell snapshotctl map-snapshots $DEVICE_PATH 219elif (( wipe_flag )); then 220 adb shell snapshotctl apply-update $DEVICE_PATH -w 221else 222 adb shell snapshotctl apply-update $DEVICE_PATH 223fi 224 225if (( skip_static_partitions )); then 226 log_message "Rebooting device - Skipping flashing static partitions" 227 adb reboot 228else 229 log_message "Rebooting device to bootloader" 230 adb reboot bootloader 231 log_message "Waiting to enter fastboot bootloader" 232 flash_static_partitions "$wipe_flag" "$flash_bootloader" 233fi 234 235log_message "Update completed" 236