В Android 10 поддерживаются динамические разделы – система разделов пользовательского пространства, которая позволяет создавать, изменять и удалять разделы во время беспроводных обновлений.
На этой странице описывается, как клиенты OTA изменяют размер динамических разделов во время обновления для устройств, отличных от A/B.
На устройствах, не поддерживающих A/B-обновления, беспроводное обновление динамических разделов выполняется с помощью файла updater из пакета обновления.
Обновить устройства для запуска
Этот раздел относится к устройствам без A/B-обновлений, которые поставляются с поддержкой динамических разделов и обновляются с Android 10 до более поздних версий.
Как создавать пакеты обновлений
Пакеты беспроводного обновления создаются с помощью скрипта ota_from_target_files, расположенного в каталоге build/make/tools/releasetools. По умолчанию скрипт создает пакет, который обновляет разделы system и vendor. Если есть дополнительные динамические разделы, например product, product_services или odm, их обновления должны быть сгенерированы в коде, предназначенном для определенного устройства.
Чтобы сгенерировать обновления, в расширенном модуле Python реализуйте функции FullOTA_GetBlockDifferences() и IncrementalOTA_GetBlockDifferences(). Эти две функции возвращают список объектов BlockDifference, каждый из которых описывает патч обновления, который будет применен к разделу. Разделы, возвращаемые этими двумя функциями, не должны изменяться вручную или проверяться в других местах, например в *_InstallBegin() или *_InstallEnd().
Пример создания обновления:
# device/yoyodyne/tardis/releasetools.py import os from common import BlockDifference, EmptyImage, GetUserImage # The joined list of user image partitions of source and target builds. # - Items should be added to the list if new dynamic partitions are added. # - Items should not be removed from the list even if dynamic partitions are # deleted. When generating an incremental OTA package, this script needs to # know that an image is present in source build but not in target build. USERIMAGE_PARTITIONS = [ "product", "odm", ] def GetUserImages(input_tmp, input_zip): return {partition: GetUserImage(partition, input_tmp, input_zip) for partition in USERIMAGE_PARTITIONS if os.path.exists(os.path.join(input_tmp, "IMAGES", partition + ".img"))} def FullOTA_GetBlockDifferences(info): images = GetUserImages(info.input_tmp, info.input_zip) return [BlockDifference(partition, image) for partition, image in images.items()] def IncrementalOTA_GetBlockDifferences(info): source_images = GetUserImages(info.source_tmp, info.source_zip) target_images = GetUserImages(info.target_tmp, info.target_zip) # Use EmptyImage() as a placeholder for partitions that will be deleted. for partition in source_images: target_images.setdefault(partition, EmptyImage()) # Use source_images.get() because new partitions are not in source_images. return [BlockDifference(partition, target_image, source_images.get(partition)) for partition, target_image in target_images.items()]
Обновить поток
В скрипт edify добавляются следующие функции:
unmap_partition(name)- Отменить сопоставление раздела, если оно выполнено, в противном случае ничего не делать.
- Возвращает строку
tв случае успеха или пустую строку в случае ошибки.
map_partition(name)- Если раздел ещё не сопоставлен, сопоставьте его.
- Возвращает абсолютный путь к сопоставленному блочному устройству в случае успеха или пустую строку в случае ошибки.
update_dynamic_partitions(op_list)- Применить к метаданным динамического раздела список операций, при необходимости отменив сопоставление разделов.
-
Возвращает
tпри успешном выполнении или пустую строку при неудачном.
Аргумент op_list для update_dynamic_partitions указывает на файл в пакете обновлений. Каждая строка в файле соответствует одной операции. Если какая-либо операция завершится неудачно, функция update_dynamic_partitions немедленно вернет пустую строку. Доступны следующие операции:
resize partition-name size- Отмените сопоставление раздела, а затем измените его размер до size.
remove partition_name- Отмените сопоставление раздела, а затем удалите его.
add partition-name group-name- Добавьте в указанную группу новую группу товаров.
- Прервать, если группа не существует или сегмент уже существует.
move partition-name group-name- Переместить раздел в указанную группу.
- Прервать выполнение, если группа или раздел не существуют.
-
add_group group-name maximum-size- Добавить группу с указанным названием и максимальным размером.
- Прервать, если группа уже существует.
- Значение maximum_size, равное 0, означает, что размер разделов в группе не ограничен. Чтобы убедиться, что разделы в группе не превышают доступное пространство на устройстве, требуется дополнительное тестирование.
-
resize_group group-name maximum-size- Изменить размер группы до указанного максимального значения.
- Прервать, если группа не существует.
- Если значение maximum_size равно 0, то ограничений на размер разделов в группе нет. Чтобы убедиться, что разделы в группе не превышают доступное пространство на устройстве, требуется дополнительное тестирование.
remove_group group-name- Удалить группу.
- Прервать работу, если в группе есть разделы.
remove_all_groups- Отмените сопоставление всех разделов с менеджером устройств.
- Удалите все разделы и группы.
Дополнительное беспроводное обновление
При добавочном беспроводном обновлении используется следующая логика:
- Уменьшить или удалить разделы или переместить их из группы (чтобы было достаточно места для уменьшения групп).
- Уменьшать группы (чтобы было достаточно места для роста групп).
- Увеличить группы (чтобы было достаточно места для увеличения/добавления разделов).
- Увеличить разделы/добавить разделы/переместить разделы в новую группу
Значение update-script генерируется по следующей логике:
for each shrinking partition:
block_image_update(map_partition(name), …)
update_dynamic_partitions(op_list)
for each growing / adding partition:
block_image_update(map_partition(name), …)
Файл op_list для update_dynamic_partitions генерируется по следующей логике:
for each deleting partition:
remove
for each partition that changes groups:
move to "default"
for each shrinking partition:
resize
for each shrinking / removing group:
resize_group / remove_group
for each growing / adding group:
resize_group / add_group
for each adding partition:
add
for each growing / adding partition:
resize
for each partition that changes groups:
move to target groupПолный образ OTA
Полные беспроводные обновления выполняются по следующей логике:
- Удалите все существующие группы и разделы.
- Добавить группы
- Добавить разделы
update-script генерируется по следующей логике:
update_dynamic_partitions(op_list)
for each adding partition:
block_image_update(map_partition(name), …)
Файл op_list для update_dynamic_partitions создается по следующей логике:
remove_all_groups
for each adding group:
add_group
for each adding partition:
add
for each adding partition:
resize