Update otapreopt_script to support Async Pre-reboot Dexopt.
Bug: 377557749
Test: -
1. system/update_engine/scripts/update_device.py out/dist/$TARGET_PRODUCT-ota-$USER.zip
2. adb shell cmd jobscheduler run android 27873781
Change-Id: I4fc7c4a08516bc48a69cfe7e01402838b27dfdea
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index b7ad331..5690e2f 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -23,6 +23,9 @@
TARGET_SLOT="$1"
STATUS_FD="$2"
+# "1" if the script is triggered by the `UpdateEngine.triggerPostinstall` API. Empty otherwise.
+TRIGGERED_BY_API="$3"
+
# Maximum number of packages/steps.
MAXIMUM_PACKAGES=1000
@@ -53,25 +56,43 @@
# A source that infinitely emits arbitrary lines.
# When connected to STDIN of another process, this source keeps STDIN open until
# the consumer process closes STDIN or this script dies.
+# In practice, the pm command keeps consuming STDIN, so we don't need to worry
+# about running out of buffer space.
function infinite_source {
while echo .; do
sleep 1
done
}
+if [[ "$TRIGGERED_BY_API" = "1" ]]; then
+ # During OTA installation, the script is called the first time, and
+ # `TRIGGERED_BY_API` can never be "1". `TRIGGERED_BY_API` being "1" means this
+ # is the second call to this script, through the
+ # `UpdateEngine.triggerPostinstall` API.
+ # When we reach here, it means Pre-reboot Dexopt is enabled in asynchronous
+ # mode and the job scheduler determined that it's the time to run the job.
+ # Start Pre-reboot Dexopt now and wait for it to finish.
+ infinite_source | pm art on-ota-staged --start
+ exit $?
+fi
+
PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 3 )); then
# Delegate to Pre-reboot Dexopt, a feature of ART Service.
# ART Service decides what to do with this request:
# - If Pre-reboot Dexopt is disabled or unsupported, the command returns
- # non-zero. This is always the case if the current system is Android 14 or
- # earlier.
+ # non-zero.
+ # This is always the case if the current system is Android 14 or earlier.
# - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
- # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
- # not. This is the default behavior if the current system is Android 15.
- # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
- # an asynchronous job and returns 0 immediately. The job will then run by the
- # job scheduler when the device is idle and charging.
+ # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds
+ # or not.
+ # This is the default behavior if the current system is Android 15.
+ # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command
+ # schedules an asynchronous job and returns 0 immediately.
+ # Later, when the device is idle and charging, the job will be run by the
+ # job scheduler. It will call this script again through the
+ # `UpdateEngine.triggerPostinstall` API, with `TRIGGERED_BY_API` being "1".
+ # This is always the case if the current system is Android 16 or later.
if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
# Handled by Pre-reboot Dexopt.
exit 0