System tworzy binarne dane aktualizacji na podstawie bootable/recovery/updater
i używa ich w pakiecie OTA.
ota_update.zip
,
incremental_ota_update.zip
), który zawiera plik wykonywalny binarny
META-INF/com/google/android/update-binary
.
Updater zawiera kilka wbudowanych funkcji i interpretator rozszerzalnego języka skryptowego (edify), który obsługuje polecenia do typowych zadań związanych z aktualizacją. Aktualizator szuka skryptu w pliku META-INF/com/google/android/updater-script
w pliku ZIP pakietu.
Uwaga: używanie skryptu edify lub wbudowanych funkcji nie jest częstą czynnością, ale może być przydatne, jeśli chcesz debugować plik aktualizacji.
Edytowanie składni
Skrypt edyfikujący to pojedynczy wyrażenie, w którym wszystkie wartości są ciągami znaków. Pusty ciąg znaków jest w kontekście wartości logicznej fałszem, a wszystkie inne ciągi znaków są prawdą. Edify obsługuje te operatory (z ich zwykłym znaczeniem):
(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 a-z, A-Z, 0-9, _, :, /, . nie jest słowem zastrzeżonym, jest uważany za literał ciągu znaków. (Zarezerwowane słowa to if else i endif). Wartości dosłowne typu string mogą też być podawane w podwójnych cudzysłowach. W ten sposób można tworzyć wartości zawierające spacje i inne znaki, które nie należą do podanego powyżej zbioru. \n, \t, \" i \\ służą do ucieczki w cudzysłowach, podobnie jak \x##.
Operatory && i || działają na zasadzie krótkiego spięcia. Prawa strona nie jest oceniana, jeśli wynik logiczny jest określany przez lewą stronę. Te elementy są równoważne:
e1 && e2 if e1 then e2 endif
Operator ; to punkt sekwencyjny, który oznacza, że najpierw należy sprawdzić lewą, a potem prawą stronę. Jego wartość jest wartością wyrażenia po prawej stronie. Kropka z przecinkiem może też występować po wyrażeniu, aby efekt symulował instrukcje w stylu C:
prepare(); do_other_thing("argument"); finish_up();
Wbudowane funkcje
Większość funkcji aktualizacji znajduje się w funkcjach dostępnych do wykonania przez skrypty.
(ściśle rzecz biorąc, są to makra, a nie funkcje w rozumieniu języka Lisp, ponieważ nie muszą one 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 kończyły wykonywanie skryptu, użyj funkcji abort()
lub assert()
. Zestaw funkcji dostępnych w aktualizatorze może zostać rozszerzony o funkcje związane z konkretnym urządzeniem.
abort([msg])
- Natychmiast przerywa wykonywanie skryptu, przekazując opcjonalny komunikat msg. Jeśli użytkownik włączył wyświetlanie tekstu, w logu odzyskiwania i na ekranie pojawi się komunikat msg.
-
assert(expr[, expr, ...])
- Ocenia po kolei każdą wartość expr. Jeśli którykolwiek z nich ma wartość fałsz, natychmiast przerywa wykonanie, wyświetlając komunikat „assert failed” (odrzucenie) i tekst źródłowy nieudanego wyrażenia.
-
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
-
Stosuje binarne poprawki do pliku src_file, aby wygenerować plik tgt_file. Jeśli żądany element docelowy jest taki sam jak źródło, w parametrze tgt_file podaj wartość „-”. tgt_sha1 i tgt_size to oczekiwany końcowy ciąg znaków identyfikatora SHA1 i rozmiar pliku docelowego. Pozostałe argumenty muszą występować w parach: szyfr SHA1 (40-znakowy ciąg szesnastkowy) i blob. Blob to poprawka, która zostanie zastosowana, gdy bieżąca zawartość pliku źródłowego ma podany identyfikator SHA1.
Aktualizacja jest przeprowadzana w bezpieczny sposób, który gwarantuje, że plik docelowy będzie miał odpowiedni ciąg znaków identyfikatora SHA1 i odpowiednią wielkość lub nie zostanie zmieniony – nie będzie w stanie pośrednim, z którego nie można by odzyskać danych. Jeśli proces zostanie przerwany podczas instalowania poprawek, plik docelowy może być w stan przejściowym. Jego kopia znajduje się w partycji pamięci podręcznej, więc ponowne uruchomienie aktualizacji może spowodować zaktualizowanie pliku.
Obsługiwana jest specjalna składnia, która pozwala traktować zawartość partycji urządzenia z pamięcią technologiczną (MTD) jako pliki, co umożliwia łatanie partycji nieprzetworzonych, takich jak partycja rozruchu. Aby odczytać partycję MTD, musisz wiedzieć, ile danych chcesz odczytać, ponieważ partycja nie zawiera informacji o końcu pliku. Aby odczytać daną partycję, możesz użyć ciągu „MTD:partition:size_1:sha1_1:size_2: sha1_2" jako nazwy pliku. Musisz określić co najmniej jedną parę (size, sha-1). Możesz określić więcej niż jedną parę, jeśli istnieje kilka możliwości odczytu.
-
apply_patch_check(filename, sha1[, sha1, ...])
- Zwraca wartość true, jeśli zawartość filename lub tymczasowa kopia na partycji pamięci podręcznej (jeśli jest obecna) ma sumę kontrolną SHA1 równą jednej z podanych wartości sha1.
Wartości sha1 są podawane jako 40 cyfr szesnastkowych. Ta funkcja różni się od funkcji
sha1_check(read_file(filename), sha1 [, ...])
tym, że potrafi sprawdzić kopię partycji pamięci podręcznej, więc funkcjaapply_patch_check()
zakończy się powodzeniem, nawet jeśli plik został uszkodzony przez przerwany procesapply_patch() update
. apply_patch_space(bytes)
- Zwraca wartość „prawda”, jeśli co najmniej bajtów miejsca na dysku jest dostępne na potrzeby stosowania poprawek binarnych.
-
concat(expr[, expr, ...])
- Wyznacza wartość każdego wyrażenia i konkatenuje je. Operator + jest cukierkiem składniczym dla tej funkcji w przypadku szczególnym 2 argumentów (ale forma funkcji może przyjmować dowolną liczbę wyrażeń). Wyrażenia muszą być ciągami znaków; nie można ich łączyć z blobami.
-
file_getprop(filename, key)
-
Odczytuje podany filename, interpretuje go jako plik właściwości (np.
/system/build.prop
), i zwraca wartość podanego key lub pusty ciąg znaków , jeśli key nie jest obecny. -
format(fs_type, partition_type, location, fs_size, mount_point)
- Sformatuj partycję. Obsługiwane typy partycji:
- fs_type="yaffs2" i partition_type="MTD". Lokalizacja musi być nazwą partycji MTD. Tam tworzy się pusty system plików yaffs2. Pozostałe argumenty nie są używane.
- fs_type="ext4" i partition_type="EMMC". Lokalizacja musi być plikiem urządzenia na partycji. Tworzony jest tam pusty system plików ext4. Jeśli wartość fs_size wynosi 0, system plików zajmuje całą partycję. Jeśli fs_size jest liczbą dodatnią, system plików bierze pierwsze fs_size bajtów partycji. Jeśli fs_size to liczba ujemna, system plików zabiera wszystkie bajty oprócz ostatnich |fs_size| bajtów partycji.
- fs_type="f2fs" i partition_type="EMMC". Lokalizacja musi być plikiem urządzenia na partycji. Wartość fs_size musi być liczbą nieujemną. Jeśli wartość fs_size wynosi 0, system plików zajmuje całą partycję. Jeśli fs_size jest liczbą dodatnią, system plików bierze pierwsze fs_size bajtów partycji.
- Wartość mount_point powinna być przyszłym punktem podłączenia do systemu plików.
getprop(key)
- Zwraca wartość właściwości systemowej key (lub pusty ciąg znaków, jeśli nie jest zdefiniowana). Wartości właściwości systemu zdefiniowane przez partycję odzyskiwania nie muszą być takie same jak w systemie głównym. Ta funkcja zwraca wartość w recovery.
-
greater_than_int(a, b)
- Zwraca wartość prawda, jeśli i tylko jeśli a (interpretowana jako liczba całkowita) jest większa od b (interpretowana jako liczba całkowita).
-
ifelse(cond, e1[, e2])
- Analizuje warunek cond i jeśli jest on prawdziwy, zwraca wartość elementu e1, a w przeciwnym razie zwraca element e2 (jeśli jest obecny). Konstrukcja „if ... else ... then ... endif” to tylko element składniowy tej funkcji.
is_mounted(mount_point)
- Zwraca wartość „true” (prawda), jeśli w mount_point zamontowano system plików.
-
is_substring(needle, haystack)
- Zwraca wartość „True” (Prawda), jeśli ciąg znaków needle jest podciągiem ciągu znaków haystack.
-
less_than_int(a, b)
- Zwraca wartość „prawda”, jeśli a (interpretowana jako liczba całkowita) jest mniejsza niż b (interpretowana jako liczba całkowita).
-
mount(fs_type, partition_type, name, mount_point)
-
Podłącza system plików fs_type w mount_point. Wartość partition_type musi być równa jednej z tych wartości:
-
MTD. Nazwa to nazwa partycji MTD (np. system, userdata; pełna lista znajduje się na urządzeniu w miejscu
/proc/mtd
). - EMMC
Domyślnie funkcja przywracania nie montuje żadnych systemów plików (z wyjątkiem karty SD, jeśli użytkownik ręcznie instaluje pakiet z karty SD). Skrypt musi zamontować wszystkie partycje, które musi zmodyfikować.
-
MTD. Nazwa to nazwa partycji MTD (np. system, userdata; pełna lista znajduje się na urządzeniu w miejscu
-
package_extract_dir(package_dir, dest_dir)
- Wyodrębnia wszystkie pliki z pakietu w katalogu package_dir i zapisuje je w odpowiednim drzewie w katalogu dest_dir. Wszystkie istniejące pliki zostaną zastąpione.
-
package_extract_file(package_file[, dest_file])
- Wyodrębnia z pakietu aktualizacji pojedynczy plik package_file i zapisuje go w pliku dest_file, w razie potrzeby zastępując istniejące pliki. Bez argumentu dest_file zwraca zawartość pliku pakietu jako binarne blob.
read_file(filename)
- Odczytuje nazwa_pliku i zwraca jego zawartość jako binarne bloby.
-
run_program(path[, arg, ...])
- Uruchamia plik binarny w ścieżce path, przekazując argumenty arg. Zwraca stan wyjścia z programu.
set_progress(frac)
- Ustawia pozycję licznika postępu w kawałku zdefiniowanym przez ostatnie wywołanie funkcji
show_progress()
. Wartość frac musi mieścić się w zakresie [0,0, 1,0]. Wskaźnik postępu nigdy nie przesuwa się wstecz; próby wykonania tej czynności są ignorowane. -
sha1_check(blob[, sha1])
- Argument blob to blob typu zwracanego przez funkcję
read_file()
lub formę jednoargumentową funkcjipackage_extract_file()
. Jeśli nie podasz argumentu sha1, funkcja zwróci skrót SHA1 bloba (jako 40-cyfrowy ciąg szesnastkowy). Jeśli podano co najmniej 1 argument sha1, funkcja zwraca hasz SHA1, jeśli jest on równy jednemu z argumentów, lub pusty ciąg znaków, jeśli nie jest równy żadnemu z argumentów. -
show_progress(frac, secs)
-
Przesuwa licznik postępu o następny frac jego długości w sekundy (musi być liczbą całkowitą). Wartość sekundy może wynosić 0, co oznacza, że licznik nie jest przesuwany automatycznie, ale za pomocą funkcji
set_progress()
zdefiniowanej powyżej. sleep(secs)
- Pauza trwa sekundy sekund (musi być liczbą całkowitą).
-
stdout(expr[, expr, ...])
- Oblicza każdy wyrażenie i wypisuje jego wartość na wyjściu standardowym. Przydatne podczas debugowania.
-
tune2fs(device[, arg, …])
- Dostosowuje parametry args na urządzeniu.
ui_print([text, ...])
- Łączy wszystkie argumenty text i wypisuje wynik w interfejsie (gdzie będzie widoczny, jeśli użytkownik włączył wyświetlanie tekstu).
unmount(mount_point)
- Odłącza system plików zamontowany w mount_point.
-
wipe_block_device(block_dev, len)
- Wymazuje len bajtów z danego blokowego urządzenia block_dev.
wipe_cache()
- Spowoduje wyczyszczenie partycji pamięci podręcznej po pomyślnej instalacji.
-
write_raw_image(filename_or_blob, partition)
-
Zapisywanie obrazu w filename_or_blob na partycji MTD.
filename_or_blob może być ciągiem znaków z nazwą pliku lokalnego lub argumentem o wartości blob zawierającym dane do zapisania. Aby skopiować plik z pliku OTA do partycji, użyj:
write_raw_image(package_extract_file("zip_filename"), "partition_name");
Uwaga: przed Androidem 4.1 akceptowane były tylko nazwy plików, więc aby to osiągnąć, dane musiały zostać najpierw rozpakowane do tymczasowego pliku lokalnego.