• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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