Внутри 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 — это одно выражение, в котором все значения являются строками. Пустые строки являются ложными в логическом контексте, а все остальные строки — истинными . 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 , ...])
Оценивает каждое выражение по очереди. Если какое-либо из них имеет значение false, немедленно прерывает выполнение с сообщением «assert error» и исходным текстом ошибочного выражения.
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: раздел : size_1 : sha1_1 : size_2 : sha1_2 » в качестве имени файла для чтения данного раздела. Вы должны указать хотя бы одну пару (размер, 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" и part_type="MTD". Местоположение должно быть именем раздела MTD; там создается пустая файловая система yaffs2. Остальные аргументы не используются.
  • fs_type="ext4" и раздел_type="EMMC". Местоположение должно быть файлом устройства для раздела. Там создается пустая файловая система ext4. Если fs_size равен нулю, файловая система занимает весь раздел. Если fs_size — положительное число, файловая система принимает первые байты fs_size раздела. Если fs_size — отрицательное число, файловая система принимает все, кроме последнего |fs_size| байт раздела.
  • fs_type="f2fs" и раздел_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, если файловая система смонтирована в точке_монтирования .
is_substring( needle , haystack )
Возвращает true, если и только если Needle является подстрокой Haystack .
less_than_int( a , b )
Возвращает true, если a (интерпретируется как целое число) меньше b (интерпретируется как целое число).
mount( fs_type , partition_type , name , mount_point )
Монтирует файловую систему fs_type в точке монтирования . Тип_раздела должен быть одним из:
  • МТД . Имя — это имя раздела MTD (например, system, userdata; полный список см. в /proc/mtd на устройстве).
  • ЭММК.

Восстановление по умолчанию не монтирует никакие файловые системы (кроме 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 ])
Аргумент blob — это большой двоичный объект типа, возвращаемого 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 )
Отключает файловую систему, смонтированную в точке_монтирования .
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 может быть строкой, именующей локальный файл, или аргументом с большим двоичным значением, содержащим данные для записи. Чтобы скопировать файл из пакета OTA в раздел, используйте: write_raw_image(package_extract_file("zip_filename"), "partition_name");

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