diff --git a/execute-all.sh b/execute-all.sh index 6012955f..95e4264d 100755 --- a/execute-all.sh +++ b/execute-all.sh @@ -25,6 +25,9 @@ readonly DOWNLOAD_SCRIPT="$SCRIPTS_ROOT/scripts/download-nexus-image.sh" # Helper script to extract system & vendor images data readonly EXTRACT_SCRIPT="$SCRIPTS_ROOT/scripts/extract-factory-images.sh" +# Helper script to extract ota data +readonly OTA_SCRIPT="$SCRIPTS_ROOT/scripts/extract-ota.sh" + # Helper script to generate "proprietary-blobs.txt" file readonly GEN_BLOBS_LIST_SCRIPT="$SCRIPTS_ROOT/scripts/gen-prop-blobs-list.sh" @@ -341,6 +344,7 @@ USE_FUSEEXT2=false FORCE_VIMG=false JAVA_FOUND=false TIMESTAMP="" +OTA=false # Compatibility check_bash_version @@ -477,6 +481,7 @@ if [ ! -d "$OUT_BASE" ]; then fi FACTORY_IMGS_DATA="$OUT_BASE/factory_imgs_data" FACTORY_IMGS_R_DATA="$OUT_BASE/factory_imgs_repaired_data" +OTA_DATA="$OUT_BASE/ota_data" echo "[*] Setting output base to '$OUT_BASE'" # Download images if not provided @@ -502,17 +507,59 @@ if [[ "$INPUT_IMG" == "" ]]; then echo "[-] Images download failed" abort 1 } - factoryImgArchive="$(find "$OUT_BASE" -iname "*$DEV_ALIAS*$BUILDID*.tgz" -or \ - -iname "*$DEV_ALIAS*$BUILDID*.zip" | head -1)" + factoryImgArchive="$(find "$OUT_BASE" -iname "*$DEV_ALIAS*$BUILDID-factory*.tgz" -or \ + -iname "*$DEV_ALIAS*$BUILDID-factory*.zip" | head -1)" else factoryImgArchive="$INPUT_IMG" fi +readonly OTA_IMGS_LIST="$(jqIncRawArrayTop "ota-partitions" "$CONFIG_FILE")" +if [[ "$OTA_IMGS_LIST" != "" ]]; then + OTA=true +fi + +if [ "$OTA" = true ]; then +OtaArchive="" +if [[ "$INPUT_IMG" == "" ]]; then + + # Factory image alias for devices with naming incompatibilities with AOSP + if [[ "$DEVICE" == "flounder" && "$DEV_ALIAS" == "" ]]; then + echo "[-] Building for flounder requires setting the device alias option - 'volantis' or 'volantisg'" + abort 1 + fi + if [[ "$DEV_ALIAS" == "" ]]; then + DEV_ALIAS="$DEVICE" + fi + + __extraArgs="" + if [ $AUTO_TOS_ACCEPT = true ]; then + __extraArgs="--yes" + fi + + $DOWNLOAD_SCRIPT --device "$DEVICE" --alias "$DEV_ALIAS" \ + --buildID "$BUILDID" --output "$OUT_BASE" $__extraArgs --ota || { + echo "[-] OTA download failed" + abort 1 + } + OtaArchive="$(find "$OUT_BASE" -iname "*$DEV_ALIAS*ota-$BUILDID*.tgz" -or \ + -iname "*$DEV_ALIAS*ota-$BUILDID*.zip" | head -1)" +else + OtaArchive="$INPUT_IMG" +fi +fi + if [[ "$factoryImgArchive" == "" ]]; then echo "[-] Failed to locate factory image archive" abort 1 fi +if [ "$OTA" = true ]; then +if [[ "$OtaArchive" == "" ]]; then + echo "[-] Failed to locate OTA archive" + abort 1 +fi +fi + # Clear old data if present & extract data from factory images if [ -d "$FACTORY_IMGS_DATA" ]; then # Previous run might have been with --keep which keeps the mount-points. Check @@ -531,6 +578,12 @@ else mkdir -p "$FACTORY_IMGS_DATA" fi +if [ -d "$OTA_DATA" ]; then + rm -rf "${OTA_DATA:?}"/* +else + mkdir -p "$OTA_DATA" +fi + EXTRACT_SCRIPT_ARGS=(--input "$factoryImgArchive" --output "$FACTORY_IMGS_DATA") if [ "$USE_DEBUGFS" = true ]; then @@ -544,6 +597,15 @@ $EXTRACT_SCRIPT "${EXTRACT_SCRIPT_ARGS[@]}" --conf-file "$CONFIG_FILE" || { abort 1 } +if [ "$OTA" = true ]; then +OTA_SCRIPT_ARGS=(--input "$OtaArchive" --output "$OTA_DATA") + +$OTA_SCRIPT "${OTA_SCRIPT_ARGS[@]}" --conf-file "$CONFIG_FILE" || { + echo "[-] OTA data extract failed" + abort 1 +} +fi + # system.img contents are different between Nexus & Pixel SYSTEM_ROOT="$FACTORY_IMGS_DATA/system" if [[ -d "$FACTORY_IMGS_DATA/system/system" && -f "$FACTORY_IMGS_DATA/system/system/build.prop" ]]; then @@ -690,6 +752,9 @@ if [[ -f "$FACTORY_IMGS_DATA/product_partition_size" ]]; then fi # Make radio files available to vendor generate script +if [[ -d "$OTA_DATA/radio" ]]; then + cp -r "$OTA_DATA/radio" "$FACTORY_IMGS_DATA/" +fi ln -s "$FACTORY_IMGS_DATA/radio" "$FACTORY_IMGS_R_DATA/radio" VGEN_SCRIPT_EXTRA_ARGS=(--conf-type "$CONFIG_TYPE") @@ -721,6 +786,7 @@ if [ "$KEEP_DATA" = false ]; then fi rm -rf "$FACTORY_IMGS_DATA" rm -rf "$FACTORY_IMGS_R_DATA" + rm -rf "$OTA_DATA" fi # If output dir is not AOSP SRC root print some user messages, otherwise the diff --git a/scripts/constants.sh b/scripts/constants.sh index 51026770..6311b93c 100644 --- a/scripts/constants.sh +++ b/scripts/constants.sh @@ -19,7 +19,8 @@ declare -ra SUPPORTED_DEVICES=( # URLs to download factory images from readonly NID_URL="https://google.com" -readonly GURL="https://developers.google.com/android/nexus/images" +readonly GURL="https://developers.google.com/android/images" +readonly GURL2="https://developers.google.com/android/ota" readonly TOSURL="https://developers.google.com/profile/acknowledgeNotification" # oatdump dependencies URLs as compiled from AOSP matching API levels diff --git a/scripts/download-nexus-image.sh b/scripts/download-nexus-image.sh index a1fc1d44..ef694104 100755 --- a/scripts/download-nexus-image.sh +++ b/scripts/download-nexus-image.sh @@ -26,6 +26,7 @@ cat <<_EOF -b|--buildID : BuildID string (e.g. MMB29P) -o|--output : Path to save images archived -y|--yes : Default accept Google ToS + --ota : Download OTA instead of factory image _EOF abort 1 } @@ -82,6 +83,7 @@ DEV_ALIAS="" BUILDID="" OUTPUT_DIR="" AUTO_TOS_ACCEPT=false +OTA=false while [[ $# -gt 0 ]] do @@ -106,6 +108,9 @@ do -y|--yes) AUTO_TOS_ACCEPT=true ;; + --ota) + OTA=true + ;; *) echo "[-] Invalid argument '$1'" usage @@ -148,22 +153,38 @@ done # Accept news ToS page accept_tos -xsrf_token=$(curl -L -b "$COOKIE_FILE" --silent "$GURL" | \ +if [ "$OTA" = true ]; then + URL="$GURL2" +else + URL="$GURL" +fi +xsrf_token=$(curl -L -b "$COOKIE_FILE" --silent "$URL" | \ grep -io "" | \ cut -d '"' -f4) -response=$(curl -b "$COOKIE_FILE" -X POST -d "notification_id=wall-nexus-image-tos" \ - -H "X_XSRFToken: $xsrf_token" --write-out "%{http_code}" --output /dev/null \ - --silent "$TOSURL") +if [ "$OTA" = true ]; then + response=$(curl -b "$COOKIE_FILE" -X POST -d "notification_id=wall-nexus-ota-tos" \ + -H "X_XSRFToken: $xsrf_token" --write-out "%{http_code}" --output /dev/null \ + --silent "$TOSURL") +else + response=$(curl -b "$COOKIE_FILE" -X POST -d "notification_id=wall-nexus-image-tos" \ + -H "X_XSRFToken: $xsrf_token" --write-out "%{http_code}" --output /dev/null \ + --silent "$TOSURL") +fi if [[ "$response" != "200" ]]; then echo "[-] Nexus ToS accept request failed" abort 1 fi # Then retrieve the index page -url=$(curl -L -b "$COOKIE_FILE" --silent -H "X_XSRFToken: $xsrf_token" "$GURL" | \ - grep -i " [target_dir] [partition.img] + : file extracted from the OTA zip file or the OTA zip file + : output directory for the extracted file + : name of partition to be extracted +``` + +## Example + +``` +$ python extract_android_ota_payload.py marlin-ota-opm4.171019.021.d1-fd6998a5.zip /tmp/ +Extracting 'boot.img' +Extracting 'system.img' +Extracting 'vendor.img' +... +Extracting 'modem.img' +``` + +## Dependencies + +``` +python-protobuf +``` diff --git a/scripts/extract_android_ota_payload/extract_android_ota_payload.py b/scripts/extract_android_ota_payload/extract_android_ota_payload.py new file mode 100644 index 00000000..1ef304ec --- /dev/null +++ b/scripts/extract_android_ota_payload/extract_android_ota_payload.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python + +import hashlib +import os +import os.path +import shutil +import struct +import subprocess +import sys +import zipfile + +# protobufs compiled with protoc 2.5.0 are not compatible with python3 +if sys.version_info[0] != 2: + raise Exception("Python 2.x is required") + +# from https://android.googlesource.com/platform/system/update_engine/+/refs/heads/master/scripts/update_payload/ +import update_metadata_pb2 + +PROGRAMS = [ 'bzcat', 'xzcat' ] + +BRILLO_MAJOR_PAYLOAD_VERSION = 2 + +class PayloadError(Exception): + pass + +class Payload(object): + class _PayloadHeader(object): + _MAGIC = 'CrAU' + + def __init__(self): + self.version = None + self.manifest_len = None + self.metadata_signature_len = None + self.size = None + + def ReadFromPayload(self, payload_file): + magic = payload_file.read(4) + if magic != self._MAGIC: + raise PayloadError('Invalid payload magic: %s' % magic) + self.version = struct.unpack('>Q', payload_file.read(8))[0] + self.manifest_len = struct.unpack('>Q', payload_file.read(8))[0] + self.size = 20 + self.metadata_signature_len = 0 + if self.version != BRILLO_MAJOR_PAYLOAD_VERSION: + raise PayloadError('Unsupported payload version (%d)' % self.version) + self.size += 4 + self.metadata_signature_len = struct.unpack('>I', payload_file.read(4))[0] + + def __init__(self, payload_file): + self.payload_file = payload_file + self.header = None + self.manifest = None + self.data_offset = None + self.metadata_signature = None + self.metadata_size = None + + def _ReadManifest(self): + return self.payload_file.read(self.header.manifest_len) + + def _ReadMetadataSignature(self): + self.payload_file.seek(self.header.size + self.header.manifest_len) + return self.payload_file.read(self.header.metadata_signature_len); + + def ReadDataBlob(self, offset, length): + self.payload_file.seek(self.data_offset + offset) + return self.payload_file.read(length) + + def Init(self): + self.header = self._PayloadHeader() + self.header.ReadFromPayload(self.payload_file) + manifest_raw = self._ReadManifest() + self.manifest = update_metadata_pb2.DeltaArchiveManifest() + self.manifest.ParseFromString(manifest_raw) + metadata_signature_raw = self._ReadMetadataSignature() + if metadata_signature_raw: + self.metadata_signature = update_metadata_pb2.Signatures() + self.metadata_signature.ParseFromString(metadata_signature_raw) + self.metadata_size = self.header.size + self.header.manifest_len + self.data_offset = self.metadata_size + self.header.metadata_signature_len + +def decompress_payload(command, data, size, hash): + p = subprocess.Popen([command, '-'], stdout=subprocess.PIPE, stdin=subprocess.PIPE) + r = p.communicate(data)[0] + if len(r) != size: + print("Unexpected size %d %d" % (len(r), size)) + elif hashlib.sha256(data).digest() != hash: + print("Hash mismatch") + return r + +def parse_payload(payload_f, partition, out_f): + BLOCK_SIZE = 4096 + for operation in partition.operations: + e = operation.dst_extents[0] + data = payload_f.ReadDataBlob(operation.data_offset, operation.data_length) + out_f.seek(e.start_block * BLOCK_SIZE) + if operation.type == update_metadata_pb2.InstallOperation.REPLACE: + out_f.write(data) + elif operation.type == update_metadata_pb2.InstallOperation.REPLACE_XZ: + r = decompress_payload('xzcat', data, e.num_blocks * BLOCK_SIZE, operation.data_sha256_hash) + out_f.write(r) + elif operation.type == update_metadata_pb2.InstallOperation.REPLACE_BZ: + r = decompress_payload('bzcat', data, e.num_blocks * BLOCK_SIZE, operation.data_sha256_hash) + out_f.write(r) + else: + raise PayloadError('Unhandled operation type (%d)' % operation.type) + +def main(filename, output_dir, partition): + if filename.endswith('.zip'): + print("Extracting 'payload.bin' from OTA file...") + ota_zf = zipfile.ZipFile(filename) + payload_file = open(ota_zf.extract('payload.bin', output_dir)) + else: + payload_file = file(filename) + + payload = Payload(payload_file) + payload.Init() + + for p in payload.manifest.partitions: + name = p.partition_name + '.img' + if (partition is not None and name != partition): + continue + print("Extracting '%s'" % name) + fname = os.path.join(output_dir, name) + out_f = open(fname, 'w') + try: + parse_payload(payload, p, out_f) + except PayloadError as e: + print('Failed: %s' % e) + out_f.close() + os.unlink(fname) + +if __name__ == '__main__': + try: + filename = sys.argv[1] + except: + print('Usage: %s payload.bin [output_dir] [partition.img]' % sys.argv[0]) + sys.exit() + + try: + output_dir = sys.argv[2] + except IndexError: + output_dir = os.getcwd() + + try: + partition = sys.argv[3] + except IndexError: + try: + partition = sys.argv[2] + except IndexError: + partition = None + + if partition is not None and not partition.endswith('.img'): + partition = None + + if output_dir.endswith('.img'): + output_dir = os.getcwd() + + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + main(filename, output_dir, partition) diff --git a/scripts/extract_android_ota_payload/requirements.txt b/scripts/extract_android_ota_payload/requirements.txt new file mode 100644 index 00000000..08a9c737 --- /dev/null +++ b/scripts/extract_android_ota_payload/requirements.txt @@ -0,0 +1 @@ +protobuf>=2.5.0 diff --git a/scripts/extract_android_ota_payload/update_metadata_pb2.py b/scripts/extract_android_ota_payload/update_metadata_pb2.py new file mode 100644 index 00000000..595f2f62 --- /dev/null +++ b/scripts/extract_android_ota_payload/update_metadata_pb2.py @@ -0,0 +1,631 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: update_metadata.proto + +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='update_metadata.proto', + package='chromeos_update_engine', + serialized_pb='\n\x15update_metadata.proto\x12\x16\x63hromeos_update_engine\"1\n\x06\x45xtent\x12\x13\n\x0bstart_block\x18\x01 \x01(\x04\x12\x12\n\nnum_blocks\x18\x02 \x01(\x04\"z\n\nSignatures\x12@\n\nsignatures\x18\x01 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x1a*\n\tSignature\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\x0c\"+\n\rPartitionInfo\x12\x0c\n\x04size\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"w\n\tImageInfo\x12\r\n\x05\x62oard\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x15\n\rbuild_channel\x18\x05 \x01(\t\x12\x15\n\rbuild_version\x18\x06 \x01(\t\"\xe6\x03\n\x10InstallOperation\x12;\n\x04type\x18\x01 \x02(\x0e\x32-.chromeos_update_engine.InstallOperation.Type\x12\x13\n\x0b\x64\x61ta_offset\x18\x02 \x01(\r\x12\x13\n\x0b\x64\x61ta_length\x18\x03 \x01(\r\x12\x33\n\x0bsrc_extents\x18\x04 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\nsrc_length\x18\x05 \x01(\x04\x12\x33\n\x0b\x64st_extents\x18\x06 \x03(\x0b\x32\x1e.chromeos_update_engine.Extent\x12\x12\n\ndst_length\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_sha256_hash\x18\x08 \x01(\x0c\x12\x17\n\x0fsrc_sha256_hash\x18\t \x01(\x0c\"\xa5\x01\n\x04Type\x12\x0b\n\x07REPLACE\x10\x00\x12\x0e\n\nREPLACE_BZ\x10\x01\x12\x08\n\x04MOVE\x10\x02\x12\n\n\x06\x42SDIFF\x10\x03\x12\x0f\n\x0bSOURCE_COPY\x10\x04\x12\x11\n\rSOURCE_BSDIFF\x10\x05\x12\x08\n\x04ZERO\x10\x06\x12\x0b\n\x07\x44ISCARD\x10\x07\x12\x0e\n\nREPLACE_XZ\x10\x08\x12\x0c\n\x08PUFFDIFF\x10\t\x12\x11\n\rBROTLI_BSDIFF\x10\n\"\xa6\x03\n\x0fPartitionUpdate\x12\x16\n\x0epartition_name\x18\x01 \x02(\t\x12\x17\n\x0frun_postinstall\x18\x02 \x01(\x08\x12\x18\n\x10postinstall_path\x18\x03 \x01(\t\x12\x17\n\x0f\x66ilesystem_type\x18\x04 \x01(\t\x12M\n\x17new_partition_signature\x18\x05 \x03(\x0b\x32,.chromeos_update_engine.Signatures.Signature\x12\x41\n\x12old_partition_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x41\n\x12new_partition_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12<\n\noperations\x18\x08 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x1c\n\x14postinstall_optional\x18\t \x01(\x08\"\xc4\x05\n\x14\x44\x65ltaArchiveManifest\x12\x44\n\x12install_operations\x18\x01 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12K\n\x19kernel_install_operations\x18\x02 \x03(\x0b\x32(.chromeos_update_engine.InstallOperation\x12\x18\n\nblock_size\x18\x03 \x01(\r:\x04\x34\x30\x39\x36\x12\x19\n\x11signatures_offset\x18\x04 \x01(\x04\x12\x17\n\x0fsignatures_size\x18\x05 \x01(\x04\x12>\n\x0fold_kernel_info\x18\x06 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_kernel_info\x18\x07 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fold_rootfs_info\x18\x08 \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12>\n\x0fnew_rootfs_info\x18\t \x01(\x0b\x32%.chromeos_update_engine.PartitionInfo\x12\x39\n\x0eold_image_info\x18\n \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x39\n\x0enew_image_info\x18\x0b \x01(\x0b\x32!.chromeos_update_engine.ImageInfo\x12\x18\n\rminor_version\x18\x0c \x01(\r:\x01\x30\x12;\n\npartitions\x18\r \x03(\x0b\x32\'.chromeos_update_engine.PartitionUpdateB\x02H\x03') + + + +_INSTALLOPERATION_TYPE = _descriptor.EnumDescriptor( + name='Type', + full_name='chromeos_update_engine.InstallOperation.Type', + filename=None, + file=DESCRIPTOR, + values=[ + _descriptor.EnumValueDescriptor( + name='REPLACE', index=0, number=0, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='REPLACE_BZ', index=1, number=1, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='MOVE', index=2, number=2, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='BSDIFF', index=3, number=3, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SOURCE_COPY', index=4, number=4, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='SOURCE_BSDIFF', index=5, number=5, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='ZERO', index=6, number=6, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='DISCARD', index=7, number=7, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='REPLACE_XZ', index=8, number=8, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='PUFFDIFF', index=9, number=9, + options=None, + type=None), + _descriptor.EnumValueDescriptor( + name='BROTLI_BSDIFF', index=10, number=10, + options=None, + type=None), + ], + containing_type=None, + options=None, + serialized_start=712, + serialized_end=877, +) + + +_EXTENT = _descriptor.Descriptor( + name='Extent', + full_name='chromeos_update_engine.Extent', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='start_block', full_name='chromeos_update_engine.Extent.start_block', index=0, + number=1, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='num_blocks', full_name='chromeos_update_engine.Extent.num_blocks', index=1, + number=2, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=49, + serialized_end=98, +) + + +_SIGNATURES_SIGNATURE = _descriptor.Descriptor( + name='Signature', + full_name='chromeos_update_engine.Signatures.Signature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='version', full_name='chromeos_update_engine.Signatures.Signature.version', index=0, + number=1, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='data', full_name='chromeos_update_engine.Signatures.Signature.data', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value="", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=180, + serialized_end=222, +) + +_SIGNATURES = _descriptor.Descriptor( + name='Signatures', + full_name='chromeos_update_engine.Signatures', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='signatures', full_name='chromeos_update_engine.Signatures.signatures', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[_SIGNATURES_SIGNATURE, ], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=100, + serialized_end=222, +) + + +_PARTITIONINFO = _descriptor.Descriptor( + name='PartitionInfo', + full_name='chromeos_update_engine.PartitionInfo', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='size', full_name='chromeos_update_engine.PartitionInfo.size', index=0, + number=1, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hash', full_name='chromeos_update_engine.PartitionInfo.hash', index=1, + number=2, type=12, cpp_type=9, label=1, + has_default_value=False, default_value="", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=224, + serialized_end=267, +) + + +_IMAGEINFO = _descriptor.Descriptor( + name='ImageInfo', + full_name='chromeos_update_engine.ImageInfo', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='board', full_name='chromeos_update_engine.ImageInfo.board', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='key', full_name='chromeos_update_engine.ImageInfo.key', index=1, + number=2, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='channel', full_name='chromeos_update_engine.ImageInfo.channel', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='version', full_name='chromeos_update_engine.ImageInfo.version', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='build_channel', full_name='chromeos_update_engine.ImageInfo.build_channel', index=4, + number=5, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='build_version', full_name='chromeos_update_engine.ImageInfo.build_version', index=5, + number=6, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=269, + serialized_end=388, +) + + +_INSTALLOPERATION = _descriptor.Descriptor( + name='InstallOperation', + full_name='chromeos_update_engine.InstallOperation', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='type', full_name='chromeos_update_engine.InstallOperation.type', index=0, + number=1, type=14, cpp_type=8, label=2, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='data_offset', full_name='chromeos_update_engine.InstallOperation.data_offset', index=1, + number=2, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='data_length', full_name='chromeos_update_engine.InstallOperation.data_length', index=2, + number=3, type=13, cpp_type=3, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='src_extents', full_name='chromeos_update_engine.InstallOperation.src_extents', index=3, + number=4, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='src_length', full_name='chromeos_update_engine.InstallOperation.src_length', index=4, + number=5, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='dst_extents', full_name='chromeos_update_engine.InstallOperation.dst_extents', index=5, + number=6, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='dst_length', full_name='chromeos_update_engine.InstallOperation.dst_length', index=6, + number=7, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='data_sha256_hash', full_name='chromeos_update_engine.InstallOperation.data_sha256_hash', index=7, + number=8, type=12, cpp_type=9, label=1, + has_default_value=False, default_value="", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='src_sha256_hash', full_name='chromeos_update_engine.InstallOperation.src_sha256_hash', index=8, + number=9, type=12, cpp_type=9, label=1, + has_default_value=False, default_value="", + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + _INSTALLOPERATION_TYPE, + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=391, + serialized_end=877, +) + + +_PARTITIONUPDATE = _descriptor.Descriptor( + name='PartitionUpdate', + full_name='chromeos_update_engine.PartitionUpdate', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='partition_name', full_name='chromeos_update_engine.PartitionUpdate.partition_name', index=0, + number=1, type=9, cpp_type=9, label=2, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='run_postinstall', full_name='chromeos_update_engine.PartitionUpdate.run_postinstall', index=1, + number=2, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='postinstall_path', full_name='chromeos_update_engine.PartitionUpdate.postinstall_path', index=2, + number=3, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='filesystem_type', full_name='chromeos_update_engine.PartitionUpdate.filesystem_type', index=3, + number=4, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=unicode("", "utf-8"), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='new_partition_signature', full_name='chromeos_update_engine.PartitionUpdate.new_partition_signature', index=4, + number=5, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='old_partition_info', full_name='chromeos_update_engine.PartitionUpdate.old_partition_info', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='new_partition_info', full_name='chromeos_update_engine.PartitionUpdate.new_partition_info', index=6, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='operations', full_name='chromeos_update_engine.PartitionUpdate.operations', index=7, + number=8, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='postinstall_optional', full_name='chromeos_update_engine.PartitionUpdate.postinstall_optional', index=8, + number=9, type=8, cpp_type=7, label=1, + has_default_value=False, default_value=False, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=880, + serialized_end=1302, +) + + +_DELTAARCHIVEMANIFEST = _descriptor.Descriptor( + name='DeltaArchiveManifest', + full_name='chromeos_update_engine.DeltaArchiveManifest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='install_operations', full_name='chromeos_update_engine.DeltaArchiveManifest.install_operations', index=0, + number=1, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='kernel_install_operations', full_name='chromeos_update_engine.DeltaArchiveManifest.kernel_install_operations', index=1, + number=2, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='block_size', full_name='chromeos_update_engine.DeltaArchiveManifest.block_size', index=2, + number=3, type=13, cpp_type=3, label=1, + has_default_value=True, default_value=4096, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='signatures_offset', full_name='chromeos_update_engine.DeltaArchiveManifest.signatures_offset', index=3, + number=4, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='signatures_size', full_name='chromeos_update_engine.DeltaArchiveManifest.signatures_size', index=4, + number=5, type=4, cpp_type=4, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='old_kernel_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_kernel_info', index=5, + number=6, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='new_kernel_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_kernel_info', index=6, + number=7, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='old_rootfs_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_rootfs_info', index=7, + number=8, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='new_rootfs_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_rootfs_info', index=8, + number=9, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='old_image_info', full_name='chromeos_update_engine.DeltaArchiveManifest.old_image_info', index=9, + number=10, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='new_image_info', full_name='chromeos_update_engine.DeltaArchiveManifest.new_image_info', index=10, + number=11, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='minor_version', full_name='chromeos_update_engine.DeltaArchiveManifest.minor_version', index=11, + number=12, type=13, cpp_type=3, label=1, + has_default_value=True, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='partitions', full_name='chromeos_update_engine.DeltaArchiveManifest.partitions', index=12, + number=13, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + extension_ranges=[], + serialized_start=1305, + serialized_end=2013, +) + +_SIGNATURES_SIGNATURE.containing_type = _SIGNATURES; +_SIGNATURES.fields_by_name['signatures'].message_type = _SIGNATURES_SIGNATURE +_INSTALLOPERATION.fields_by_name['type'].enum_type = _INSTALLOPERATION_TYPE +_INSTALLOPERATION.fields_by_name['src_extents'].message_type = _EXTENT +_INSTALLOPERATION.fields_by_name['dst_extents'].message_type = _EXTENT +_INSTALLOPERATION_TYPE.containing_type = _INSTALLOPERATION; +_PARTITIONUPDATE.fields_by_name['new_partition_signature'].message_type = _SIGNATURES_SIGNATURE +_PARTITIONUPDATE.fields_by_name['old_partition_info'].message_type = _PARTITIONINFO +_PARTITIONUPDATE.fields_by_name['new_partition_info'].message_type = _PARTITIONINFO +_PARTITIONUPDATE.fields_by_name['operations'].message_type = _INSTALLOPERATION +_DELTAARCHIVEMANIFEST.fields_by_name['install_operations'].message_type = _INSTALLOPERATION +_DELTAARCHIVEMANIFEST.fields_by_name['kernel_install_operations'].message_type = _INSTALLOPERATION +_DELTAARCHIVEMANIFEST.fields_by_name['old_kernel_info'].message_type = _PARTITIONINFO +_DELTAARCHIVEMANIFEST.fields_by_name['new_kernel_info'].message_type = _PARTITIONINFO +_DELTAARCHIVEMANIFEST.fields_by_name['old_rootfs_info'].message_type = _PARTITIONINFO +_DELTAARCHIVEMANIFEST.fields_by_name['new_rootfs_info'].message_type = _PARTITIONINFO +_DELTAARCHIVEMANIFEST.fields_by_name['old_image_info'].message_type = _IMAGEINFO +_DELTAARCHIVEMANIFEST.fields_by_name['new_image_info'].message_type = _IMAGEINFO +_DELTAARCHIVEMANIFEST.fields_by_name['partitions'].message_type = _PARTITIONUPDATE +DESCRIPTOR.message_types_by_name['Extent'] = _EXTENT +DESCRIPTOR.message_types_by_name['Signatures'] = _SIGNATURES +DESCRIPTOR.message_types_by_name['PartitionInfo'] = _PARTITIONINFO +DESCRIPTOR.message_types_by_name['ImageInfo'] = _IMAGEINFO +DESCRIPTOR.message_types_by_name['InstallOperation'] = _INSTALLOPERATION +DESCRIPTOR.message_types_by_name['PartitionUpdate'] = _PARTITIONUPDATE +DESCRIPTOR.message_types_by_name['DeltaArchiveManifest'] = _DELTAARCHIVEMANIFEST + +class Extent(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _EXTENT + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.Extent) + +class Signatures(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + + class Signature(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _SIGNATURES_SIGNATURE + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.Signatures.Signature) + DESCRIPTOR = _SIGNATURES + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.Signatures) + +class PartitionInfo(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _PARTITIONINFO + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.PartitionInfo) + +class ImageInfo(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _IMAGEINFO + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.ImageInfo) + +class InstallOperation(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _INSTALLOPERATION + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.InstallOperation) + +class PartitionUpdate(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _PARTITIONUPDATE + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.PartitionUpdate) + +class DeltaArchiveManifest(_message.Message): + __metaclass__ = _reflection.GeneratedProtocolMessageType + DESCRIPTOR = _DELTAARCHIVEMANIFEST + + # @@protoc_insertion_point(class_scope:chromeos_update_engine.DeltaArchiveManifest) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), 'H\003') +# @@protoc_insertion_point(module_scope) diff --git a/scripts/generate-vendor.sh b/scripts/generate-vendor.sh index c6964ca3..29e9abd8 100755 --- a/scripts/generate-vendor.sh +++ b/scripts/generate-vendor.sh @@ -167,6 +167,13 @@ copy_radio_files() { cp "$inDir/radio/$img.img" "$outDir/radio/" done fi + + if [[ "$VENDOR" == "google" && "$OTA_IMGS_LIST" != "" ]]; then + for img in "${OTA_IMGS[@]}" + do + cp "$inDir/radio/$img.img" "$outDir/radio/" + done + fi } extract_blobs() { @@ -393,6 +400,13 @@ gen_board_vendor_mk() { echo "\$(call add-radio-file,radio/$img.img)" done fi + + if [[ "$VENDOR" == "google" && "$OTA_IMGS_LIST" != "" ]]; then + for img in "${OTA_IMGS[@]}" + do + echo "\$(call add-radio-file,radio/$img.img)" + done + fi } >> "$ANDROID_BOARD_VENDOR_MK" } @@ -987,6 +1001,10 @@ update_ab_ota_partitions() { do echo " $partition \\" done + for partition in "${OTA_IMGS[@]}" + do + echo " $partition \\" + done } >> "$outMk" strip_trail_slash_from_file "$outMk" } @@ -1181,6 +1199,7 @@ readonly DEVICE_VENDOR_CONFIG="$(jqIncRawArray "$API_LEVEL" "$CONFIG_TYPE" "devi readonly EXTRA_MODULES="$(jqIncRawArray "$API_LEVEL" "$CONFIG_TYPE" "new-modules" "$CONFIG_FILE")" readonly FORCE_MODULES="$(jqIncRawArray "$API_LEVEL" "$CONFIG_TYPE" "forced-modules" "$CONFIG_FILE")" readonly EXTRA_IMGS_LIST="$(jqIncRawArrayTop "extra-partitions" "$CONFIG_FILE")" +readonly OTA_IMGS_LIST="$(jqIncRawArrayTop "ota-partitions" "$CONFIG_FILE")" # Populate the array with the APK that need to maintain their signature readarray -t PSIG_BC_FILES < <( @@ -1207,6 +1226,9 @@ BUILD_ID=$(get_build_id "$INPUT_DIR/system/build.prop") if [[ "$EXTRA_IMGS_LIST" != "" ]]; then readarray -t EXTRA_IMGS < <(echo "$EXTRA_IMGS_LIST") fi +if [[ "$OTA_IMGS_LIST" != "" ]]; then + readarray -t OTA_IMGS < <(echo "$OTA_IMGS_LIST") +fi echo "[*] Generating '$DEVICE' vendor blobs"