Внутри OTA-пакетов

Система создает двоичный файл обновления из bootable/recovery/updater и использует его в пакете OTA.

Сам пакет представляет собой ZIP-файл ( ota_update.zip , incremental_ota_update.zip ), содержащий исполняемый двоичный файл META-INF/com/google/android/update-binary .

Программа обновления содержит несколько встроенных функций и интерпретатор для расширяемого языка сценариев ( edify ), который поддерживает команды для типичных задач, связанных с обновлением. Программа обновления ищет в ZIP-файле пакета скрипт в файле META-INF/com/google/android/updater-script .

Примечание. Использование сценария edify и/или встроенных функций не является обычным действием, но может быть полезно, если вам нужно отладить файл обновления.

Научить синтаксису

Сценарий назидания представляет собой одно выражение, в котором все значения являются строками. Пустые строки являются ложными в логическом контексте, а все остальные строки являются истинными . Edify поддерживает следующие операторы (с обычными значениями):

(expr )
 expr + expr  # string concatenation, not integer addition
 expr == expr
 expr != expr
 expr && expr
 expr || expr
 ! expr
 if expr then expr endif
 if expr then expr else expr endif
 function_name(expr, expr,...)
 expr; expr

Любая строка символов az, AZ, 0-9, _, :, /, . это не зарезервированное слово считается строковым литералом. (Зарезервированные слова имеют вид if else then endif. ) Строковые литералы также могут заключаться в двойные кавычки; вот как создавать значения с пробелами и другими символами, не входящими в указанный выше набор. \n, \t, \", и \\ служат экранами в строках в кавычках, как и \x ## .

&& и || операторы замыкаются накоротко; правая часть не оценивается, если логический результат определяется левой стороной. Следующие эквивалентны:

e1 && e2
if e1 then e2 endif

; оператор является точкой следования; это означает сначала оценить левую сторону, а затем правую. Его значением является значение выражения в правой части. Точка с запятой также может стоять после выражения, поэтому эффект имитирует операторы в стиле C:

prepare();
do_other_thing("argument");
finish_up();

Встроенные функции

Большая часть функций обновления содержится в функциях, доступных для выполнения сценариями. (Строго говоря, это макросы , а не функции в смысле Лиспа, поскольку им не нужно вычислять все свои аргументы.) Если не указано иное, функции возвращают true в случае успеха и false в случае ошибки. Если вы хотите, чтобы ошибки прервали выполнение скрипта, используйте функции abort() и/или assert() . Набор функций, доступных в программе обновления, также может быть расширен для предоставления функций, специфичных для конкретного устройства .

abort([ msg ])
Немедленно прерывает выполнение скрипта с помощью необязательного msg . Если пользователь включил отображение текста, сообщение появляется в журнале восстановления и на экране.
assert( expr [, expr , ...])
Оценивает каждое выражение по очереди. Если какое-либо из них ложно, немедленно прерывает выполнение с сообщением "assert failed" и исходным текстом ошибочного выражения.
apply_patch( src_file , tgt_file , tgt_sha1 , tgt_size , patch1_sha1 , patch1_blob , [...])
Применяет двоичный патч к src_file для создания tgt_file . Если желаемая цель совпадает с источником, передайте «-» для tgt_file . tgt_sha1 и tgt_size — ожидаемый окончательный хэш SHA1 и размер целевого файла. Остальные аргументы должны быть представлены парами: хэш SHA1 (шестнадцатеричная строка из 40 символов) и большой двоичный объект. Большой двоичный объект — это исправление, которое будет применяться, когда текущее содержимое исходного файла имеет заданный SHA1.

Исправление выполняется безопасным способом, гарантирующим, что целевой файл либо имеет желаемый хэш SHA1 и размер, либо не будет изменен — он не останется в невосстановимом промежуточном состоянии. Если процесс прерывается во время исправления, целевой файл может находиться в промежуточном состоянии; копия существует в разделе кеша, поэтому перезапуск обновления может успешно обновить файл.

Поддерживается специальный синтаксис для обработки содержимого разделов Memory Technology Device (MTD) как файлов, что позволяет исправлять необработанные разделы, такие как загрузочные. Чтобы прочитать раздел MTD, вы должны знать, сколько данных вы хотите прочитать, поскольку раздел не имеет понятия конца файла. Вы можете использовать строку «MTD: partition : size_1 : sha1_1 : size_2 : sha1_2 » в качестве имени файла для чтения данного раздела. Вы должны указать хотя бы одну пару (size, sha-1) ; вы можете указать более одного, если есть несколько вариантов того, что вы ожидаете прочитать.

apply_patch_check( filename , sha1 [, sha1 , ...])
Возвращает true, если содержимое имени файла или временная копия в разделе кеша (если есть) имеют контрольную сумму SHA1, равную одному из заданных значений sha1 . Значения sha1 задаются как 40 шестнадцатеричных цифр. Эта функция отличается от sha1_check(read_file( filename ), sha1 [, ...]) тем, что она знает, что нужно проверить копию раздела кеша, поэтому apply_patch_check() завершится успешно, даже если файл был поврежден прерванным apply_patch() update .
apply_patch_space( bytes )
Возвращает true, если для применения двоичных исправлений доступно не менее байтов свободного пространства.
concat( expr [, expr , ...])
Оценивает каждое выражение и объединяет их. Оператор + является синтаксическим сахаром для этой функции в особом случае двух аргументов (но форма функции может принимать любое количество выражений). Выражения должны быть строками; он не может объединять большие двоичные объекты.
file_getprop( filename , key )
Читает заданное имя файла , интерпретирует его как файл свойств (например, /system/build.prop ) и возвращает значение заданного ключа или пустую строку, если ключ отсутствует.
format( fs_type , partition_type , location , fs_size , mount_point )
Переформатирует заданный раздел. Поддерживаемые типы разделов:
  • fs_type="yaffs2" и partition_type="MTD". Расположение должно быть именем раздела MTD; там создается пустая файловая система yaffs2. Остальные аргументы не используются.
  • fs_type="ext4" и partition_type="EMMC". Местоположение должно быть файлом устройства для раздела. Там создается пустая файловая система ext4. Если fs_size равен нулю, файловая система занимает весь раздел. Если fs_size — положительное число, файловая система берет первые байты fs_size раздела. Если fs_size отрицательное число, файловая система берет все, кроме последнего |fs_size| байт раздела.
  • fs_type="f2fs" и partition_type="EMMC". Местоположение должно быть файлом устройства для раздела. fs_size должен быть неотрицательным числом. Если fs_size равен нулю, файловая система занимает весь раздел. Если fs_size — положительное число, файловая система берет первые байты fs_size раздела.
  • mount_point должна быть будущей точкой монтирования файловой системы.
getprop( key )
Возвращает значение ключа системного свойства (или пустую строку, если оно не определено). Значения системных свойств, определенные разделом восстановления, не обязательно совпадают со значениями основной системы. Эта функция возвращает значение в рекавери.
greater_than_int( a , b )
Возвращает true тогда и только тогда, когда (iff) a (интерпретируется как целое число) больше, чем b (интерпретируется как целое число).
ifelse( cond , e1 [, e2 ])
Вычисляет cond и, если оно истинно, оценивает и возвращает значение e1 , в противном случае оценивает и возвращает e2 (если имеется). Конструкция "if...else...then...endif" является просто синтаксическим сахаром для этой функции.
is_mounted( mount_point )
Возвращает true, если в точке mount_point смонтирована файловая система.
is_substring( needle , haystack )
Возвращает true, если иголка является подстрокой стога сена .
less_than_int( a , b )
Возвращает true, если a (интерпретируется как целое число) меньше, чем b (интерпретируется как целое число).
mount( fs_type , partition_type , name , mount_point )
Монтирует файловую систему fs_type в mount_point . partition_type должен быть одним из:
  • МТД . Имя — это имя раздела MTD (например, system, userdata; полный список см. в /proc/mtd на устройстве).
  • ЭМС.

Recovery не монтирует никакие файловые системы по умолчанию (кроме SD-карты, если пользователь выполняет ручную установку пакета с SD-карты); ваш сценарий должен смонтировать все разделы, которые необходимо изменить.

package_extract_dir( package_dir , dest_dir )
Извлекает все файлы из пакета под package_dir и записывает их в соответствующее дерево под dest_dir . Любые существующие файлы перезаписываются.
package_extract_file( package_file [, dest_file ])
Извлекает один файл package_file из пакета обновления и записывает его в файл dest_file , при необходимости перезаписывая существующие файлы. Без аргумента dest_file возвращает содержимое файла пакета в виде двоичного большого двоичного объекта.
read_file( filename )
Считывает имя файла и возвращает его содержимое в виде двоичного двоичного объекта.
run_program( path [, arg , ...])
Выполняет двоичный файл по пути , передавая arg s. Возвращает статус выхода программы.
set_progress( frac )
Устанавливает позицию индикатора прогресса в чанке, определяемом самым последним show_progress() . frac должен быть в диапазоне [0.0, 1.0]. Индикатор прогресса никогда не движется назад; попытки заставить это сделать игнорируются.
sha1_check( blob [, sha1 ])
Аргумент большого двоичного объекта — это большой двоичный объект типа, возвращаемого read_file() , или формой с одним аргументом функции package_extract_file() . Без аргументов sha1 эта функция возвращает хэш SHA1 большого двоичного объекта (в виде 40-значной шестнадцатеричной строки). С одним или несколькими аргументами sha1 эта функция возвращает хэш SHA1, если он равен одному из аргументов, или пустую строку, если он не равен ни одному из них.
show_progress( frac , secs )
Продвигает индикатор прогресса по следующему фрагменту его длины в секундах (должно быть целым числом). secs может быть равно 0, и в этом случае счетчик увеличивается не автоматически, а с помощью функции set_progress() , определенной выше.
sleep( secs )
Спит в течение секунд секунд (должно быть целым числом).
stdout( expr [, expr , ...])
Оценивает каждое выражение и выводит его значение на стандартный вывод. Полезно для отладки.
tune2fs( device [, arg , …])
Настраивает настраиваемые параметры args на устройстве .
ui_print([ text , ...])
Объединяет все текстовые аргументы и выводит результат в пользовательский интерфейс (где он будет виден, если пользователь включил отображение текста).
unmount( mount_point )
Размонтирует файловую систему, смонтированную в mount_point .
wipe_block_device( block_dev , len )
Стирает байты len данного блочного устройства block_dev .
wipe_cache()
Вызывает очистку раздела кеша в конце успешной установки.
write_raw_image( filename_or_blob , partition )
Записывает образ в filename_or_blob в раздел MTD. filename_or_blob может быть строкой, именующей локальный файл, или аргументом со значением blob, содержащим данные для записи. Чтобы скопировать файл из пакета OTA в раздел, используйте: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Примечание. До Android 4.1 принимались только имена файлов, поэтому для этого данные сначала нужно было распаковать во временный локальный файл.