Wewnątrz pakietów OTA

System tworzy plik binarny aktualizatora z bootable/recovery/updater i używa go w pakiecie OTA.

Sam pakiet to plik .zip ( ota_update.zip , incremental_ota_update.zip ) zawierający wykonywalny plik binarny META-INF/com/google/android/update-binary .

Updater zawiera kilka wbudowanych funkcji i interpreter rozszerzalnego języka skryptowego ( edify ), który obsługuje polecenia typowe zadania związane z aktualizacją. Aktualizator szuka w pliku .zip pakietu skryptu w pliku META-INF/com/google/android/updater-script .

Uwaga: Korzystanie ze skryptu edify i/lub funkcji wbudowanych nie jest częstą czynnością, ale może być pomocne, jeśli chcesz debugować plik aktualizacji.

Edytuj składnię

Skrypt edify to pojedyncze wyrażenie, w którym wszystkie wartości są ciągami znaków. Puste ciągi są fałszywe w kontekście logicznym, a wszystkie inne ciągi są prawdziwe . Edify obsługuje następujące operatory (o zwykłym znaczeniu):

(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

Dowolny ciąg znaków az, AZ, 0-9, _, :, /, . które nie jest słowem zastrzeżonym, jest uważane za literał łańcuchowy. (Słowa zastrzeżone to if else to endif. ) Literały łańcuchowe mogą także pojawiać się w cudzysłowie; w ten sposób można tworzyć wartości zawierające białe znaki i inne znaki, których nie ma w powyższym zestawie. \n, \t, \" i \\ służą jako znaki specjalne w obrębie ciągów znaków w cudzysłowie, podobnie jak \x ## .

&& i || operatorzy powodują zwarcie; prawa strona nie jest oceniana, jeśli wynik logiczny jest określony przez lewą stronę. Następujące są równoważne:

e1 && e2
if e1 then e2 endif

; operator jest punktem sekwencji; oznacza to ocenę najpierw lewej, a potem prawej strony. Jego wartością jest wartość wyrażenia po prawej stronie. Średnik może również pojawić się po wyrażeniu, więc efekt symuluje instrukcje w stylu C:

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

Wbudowane funkcje

Większość funkcji aktualizacji zawarta jest w funkcjach dostępnych do wykonania przez skrypty. (Ściśle mówiąc, są to raczej makra niż funkcje w sensie Lisp, ponieważ nie muszą oceniać wszystkich swoich argumentów.) O ile nie zaznaczono inaczej, funkcje zwracają wartość true w przypadku powodzenia i false w przypadku błędu. Jeśli chcesz, aby błędy przerwały wykonanie skryptu, użyj funkcji abort() i/lub assert() . Zestaw funkcji dostępnych w aktualizatorze można również rozszerzyć, aby zapewnić funkcjonalność specyficzną dla urządzenia .

abort([ msg ])
Natychmiast przerywa wykonywanie skryptu, z opcjonalnym msg . Jeśli użytkownik włączył wyświetlanie tekstu, komunikat msg pojawi się w dzienniku odzyskiwania i na ekranie.
assert( expr [, expr , ...])
Oblicza po kolei każde wyrażenie . Jeśli którakolwiek z nich ma wartość false, natychmiast przerywa wykonywanie z komunikatem „twierdzenie nie powiodło się” i tekstem źródłowym wyrażenia, które nie powiodło się.
apply_patch( src_file , tgt_file , tgt_sha1 , tgt_size , patch1_sha1 , patch1_blob , [...])
Stosuje łatkę binarną do pliku src , aby utworzyć plik tgt . Jeśli żądany cel jest taki sam jak źródło, przekaż „-” dla tgt_file . tgt_sha1 i tgt_size to oczekiwany końcowy skrót SHA1 i rozmiar pliku docelowego. Pozostałe argumenty muszą występować w parach: skrót SHA1 (40-znakowy ciąg szesnastkowy) i obiekt typu blob. Obiekt blob to łatka, którą należy zastosować, gdy bieżąca zawartość pliku źródłowego ma podany SHA1.

Łatanie odbywa się w bezpieczny sposób, który gwarantuje, że plik docelowy albo będzie miał żądany skrót i rozmiar SHA1, albo pozostanie nienaruszony — nie pozostanie w niemożliwym do odzyskania stanie pośrednim. Jeśli proces zostanie przerwany podczas instalowania łatki, plik docelowy może znajdować się w stanie pośrednim; kopia istnieje na partycji pamięci podręcznej, więc ponowne uruchomienie aktualizacji może pomyślnie zaktualizować plik.

Obsługiwana jest specjalna składnia, która pozwala traktować zawartość partycji Memory Technology Device (MTD) jako pliki, umożliwiając łatanie surowych partycji, takich jak boot. Aby odczytać partycję MTD, musisz wiedzieć, ile danych chcesz odczytać, ponieważ partycja nie ma pojęcia końca pliku. Możesz użyć ciągu „MTD: partycja : rozmiar_1 : sha1_1 : rozmiar_2 : sha1_2 ” jako nazwy pliku, aby odczytać podaną partycję. Musisz określić co najmniej jedną parę (rozmiar, sha-1) ; możesz określić więcej niż jedną, jeśli istnieje wiele możliwości tego, co spodziewasz się przeczytać.

apply_patch_check( filename , sha1 [, sha1 , ...])
Zwraca wartość true, jeśli zawartość nazwy pliku lub tymczasowej kopii w partycji pamięci podręcznej (jeśli istnieje) ma sumę kontrolną SHA1 równą jednej z podanych wartości sha1 . wartości sha1 są określone jako 40 cyfr szesnastkowych. Funkcja ta różni się od funkcji sha1_check(read_file( filename ), sha1 [, ...]) tym, że wie, jak sprawdzić kopię partycji pamięci podręcznej, więc apply_patch_check() zakończy się sukcesem, nawet jeśli plik został uszkodzony przez przerwaną apply_patch() update .
apply_patch_space( bytes )
Zwraca wartość true, jeśli dostępna jest co najmniej bajtowa przestrzeń podstawowa do zastosowania poprawek binarnych.
concat( expr [, expr , ...])
Ocenia każde wyrażenie i łączy je. Operator + jest cukrem syntaktycznym dla tej funkcji w szczególnym przypadku dwóch argumentów (ale forma funkcji może przyjmować dowolną liczbę wyrażeń). Wyrażenia muszą być ciągami znaków; nie może łączyć obiektów blob.
file_getprop( filename , key )
Odczytuje podaną nazwę pliku , interpretuje ją jako plik właściwości (np. /system/build.prop ) i zwraca wartość podanego klucza lub pusty ciąg znaków, jeśli klucz nie istnieje.
format( fs_type , partition_type , location , fs_size , mount_point )
Ponownie formatuje daną partycję. Obsługiwane typy partycji:
  • fs_type="yaffs2" i partycji_type="MTD". Lokalizacja musi być nazwą partycji MTD; tworzony jest tam pusty system plików yaffs2. Pozostałe argumenty są niewykorzystane.
  • fs_type="ext4" i partycji_type="EMMC". Lokalizacja musi być plikiem urządzenia dla partycji. Konstruowany jest tam pusty system plików ext4. Jeśli fs_size wynosi zero, system plików zajmuje całą partycję. Jeśli fs_size jest liczbą dodatnią, system plików pobiera pierwsze bajty fs_size partycji. Jeśli rozmiar_fs jest liczbą ujemną, system plików pobiera wszystko oprócz ostatniego |rozmiar_fs| bajtów partycji.
  • fs_type="f2fs" i ​​partycji_type="EMMC". Lokalizacja musi być plikiem urządzenia dla partycji. fs_size musi być liczbą nieujemną. Jeśli fs_size wynosi zero, system plików zajmuje całą partycję. Jeśli fs_size jest liczbą dodatnią, system plików pobiera pierwsze bajty fs_size partycji.
  • punkt_montowania powinien być przyszłym punktem montowania systemu plików.
getprop( key )
Zwraca wartość klucza właściwości systemowej (lub pusty ciąg znaków, jeśli nie jest zdefiniowany). Wartości właściwości systemu zdefiniowane przez partycję odzyskiwania niekoniecznie są takie same, jak te w systemie głównym. Ta funkcja zwraca wartość w trakcie odzyskiwania.
greater_than_int( a , b )
Zwraca wartość true wtedy i tylko wtedy, gdy (iff) a (interpretowane jako liczba całkowita) jest większe niż b (interpretowane jako liczba całkowita).
ifelse( cond , e1 [, e2 ])
Ocenia warunek i jeśli jest prawdziwy, ocenia i zwraca wartość e1 , w przeciwnym razie ocenia i zwraca e2 (jeśli istnieje). Konstrukt „if… else… then… endif” jest po prostu cukrem syntaktycznym dla tej funkcji.
is_mounted( mount_point )
Zwraca wartość true, jeśli istnieje system plików zamontowany w punkcie_montowania .
is_substring( needle , haystack )
Zwraca wartość true, jeśli igła jest podciągiem haystack .
less_than_int( a , b )
Zwraca wartość true, jeśli a (interpretowane jako liczba całkowita) jest mniejsze niż b (interpretowane jako liczba całkowita).
mount( fs_type , partition_type , name , mount_point )
Montuje system plików typu fs w punkcie_montowania . typ_partycji musi być jednym z:
  • MTD . Nazwa to nazwa partycji MTD (np. system, dane użytkownika; pełna lista znajduje się /proc/mtd na urządzeniu).
  • EMMC.

Odzyskiwanie domyślnie nie montuje żadnego systemu plików (z wyjątkiem karty SD, jeśli użytkownik dokonuje ręcznej instalacji pakietu z karty SD); Twój skrypt musi zamontować wszystkie partycje, które musi zmodyfikować.

package_extract_dir( package_dir , dest_dir )
Wyodrębnia wszystkie pliki z pakietu znajdującego się pod katalog_pakietu i zapisuje je w odpowiednim drzewie pod katalog_dest . Wszelkie istniejące pliki zostaną nadpisane.
package_extract_file( package_file [, dest_file ])
Wyodrębnia pojedynczy plik_pakietu z pakietu aktualizacji i zapisuje go w pliku docelowym , w razie potrzeby zastępując istniejące pliki. Bez argumentu dest_file zwraca zawartość pliku pakietu jako binarny obiekt BLOB.
read_file( filename )
Odczytuje nazwę pliku i zwraca jego zawartość jako binarny obiekt BLOB.
run_program( path [, arg , ...])
Wykonuje plik binarny w path , przekazując argument s. Zwraca status wyjścia programu.
set_progress( frac )
Ustawia pozycję miernika postępu w fragmencie zdefiniowanym przez ostatnie wywołanie show_progress() . frac musi należeć do zakresu [0,0, 1,0]. Wskaźnik postępu nigdy nie cofa się; próby nakłonienia go do tego są ignorowane.
sha1_check( blob [, sha1 ])
Argument blob to obiekt typu blob zwracany przez read_file() lub jednoargumentową formę package_extract_file() . Bez argumentów sha1 ta funkcja zwraca skrót SHA1 obiektu BLOB (jako 40-cyfrowy ciąg szesnastkowy). W przypadku jednego lub większej liczby argumentów sha1 funkcja ta zwraca skrót SHA1, jeśli jest równy jednemu z argumentów, lub pusty ciąg znaków, jeśli nie jest równy żadnemu z nich.
show_progress( frac , secs )
Przesuwa licznik postępu o następny ułamek jego długości w sekundach (musi być liczbą całkowitą). secs może wynosić 0, w takim przypadku licznik nie jest zwiększany automatycznie, ale poprzez użycie zdefiniowanej powyżej funkcji set_progress() .
sleep( secs )
Usypia przez sekundy (musi być liczbą całkowitą).
stdout( expr [, expr , ...])
Ocenia każde wyrażenie i zrzuca jego wartość na standardowe wyjście. Przydatne do debugowania.
tune2fs( device [, arg , …])
Dostosowuje parametry przestrajalne args na urządzeniu .
ui_print([ text , ...])
Łączy wszystkie argumenty tekstowe i wypisuje wynik w interfejsie użytkownika (gdzie będzie widoczny, jeśli użytkownik włączył wyświetlanie tekstu).
unmount( mount_point )
Odmontowuje system plików zamontowany w punkcie_montowania .
wipe_block_device( block_dev , len )
Czyści bajty len danego urządzenia blokowego block_dev .
wipe_cache()
Powoduje wyczyszczenie partycji pamięci podręcznej po pomyślnej instalacji.
write_raw_image( filename_or_blob , partition )
Zapisuje obraz w pliku nazwa_pliku_lub_blob na partycji MTD. nazwa_pliku_lub_blob może być ciągiem nazywającym plik lokalny lub argumentem o wartości typu blob zawierającym dane do zapisania. Aby skopiować plik z pakietu OTA na partycję, użyj: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Uwaga: przed wersją Androida 4.1 akceptowane były tylko nazwy plików, więc aby to osiągnąć, dane trzeba było najpierw rozpakować do tymczasowego pliku lokalnego.