In OTA-Paketen

Das System erstellt das Updater-Binary aus bootable/recovery/updater und verwendet es in einem OTA-Paket.

Das Paket selbst ist eine ZIP-Datei (ota_update.zip, incremental_ota_update.zip), die die ausführbare Binärdatei META-INF/com/google/android/update-binary enthält.

Updater enthält mehrere integrierte Funktionen und einen Interpreter für eine erweiterbare Scriptingsprache (edify), die Befehle für typische aktualisierungsbezogene Aufgaben unterstützt. Der Updater sucht in der ZIP-Datei des Pakets nach einem Script in der Datei META-INF/com/google/android/updater-script.

Hinweis:Die Verwendung des edify-Scripts und/oder der integrierten Funktionen ist nicht üblich, kann aber hilfreich sein, wenn Sie die Updatedatei debuggen müssen.

Syntax für Edify

Ein edify-Script ist ein einzelner Ausdruck, bei dem alle Werte Strings sind. Leere Strings sind in einem booleschen Kontext false und alle anderen Strings true. Edify unterstützt die folgenden Operatoren (mit den üblichen Bedeutungen):

(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

Beliebiger String aus den Zeichen a–z, A–Z, 0–9, _, :, /, . ist kein reserviertes Wort, wird es als Stringliteral betrachtet. (Reservierte Wörter sind if else und endif.) Stringliterale können auch in doppelten Anführungszeichen erscheinen. So können Werte mit Leerzeichen und anderen Zeichen erstellt werden, die nicht zu den oben genannten gehören. \n, \t, \" und \\ dienen als Escapezeichen in Strings in Anführungszeichen, ebenso wie \x##.

Die Operatoren „&&“ und „||“ führen zu einem Kurzschluss. Die rechte Seite wird nicht ausgewertet, wenn das logische Ergebnis durch die linke Seite bestimmt wird. Folgendes ist äquivalent:

e1 && e2
if e1 then e2 endif

Der Operator „;“ ist ein Sequenzpunkt. Er bedeutet, dass zuerst die linke und dann die rechte Seite ausgewertet wird. Der Wert ist der Wert des Ausdrucks auf der rechten Seite. Ein Semikolon kann auch nach einem Ausdruck stehen, um C-ähnliche Anweisungen zu simulieren:

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

Integrierte Funktionen

Die meisten Aktualisierungsfunktionen sind in den Funktionen enthalten, die von Scripts ausgeführt werden können. Streng genommen handelt es sich dabei um Makros und nicht um Funktionen im Lisp-Sinne, da nicht alle Argumente ausgewertet werden müssen. Sofern nicht anders angegeben, geben Funktionen bei Erfolg true und bei Fehler false zurück. Wenn Fehler die Ausführung des Scripts abbrechen sollen, verwenden Sie die Funktionen abort() und/oder assert(). Die im Updater verfügbaren Funktionen können auch erweitert werden, um gerätespezifische Funktionen bereitzustellen.

abort([msg])
Unterbricht die Ausführung des Scripts sofort mit der optionalen msg. Wenn der Nutzer die Textanzeige aktiviert hat, wird msg im Wiederherstellungsprotokoll und auf dem Bildschirm angezeigt.
assert(expr[, expr, ...])
Hiermit wird jeder expr nacheinander ausgewertet. Wenn einer der Ausdruckswerte falsch ist, wird die Ausführung sofort mit der Meldung „assert failed“ (Behauptung fehlgeschlagen) und dem Quelltext des fehlgeschlagenen Ausdrucks abgebrochen.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
Wendet einen Binär-Patch auf die src_file an, um die tgt_file zu erstellen. Wenn das gewünschte Ziel mit der Quelle identisch ist, geben Sie „-“ für tgt_file an. tgt_sha1 und tgt_size sind der erwartete SHA1-Hash und die Größe der Zieldatei. Die verbleibenden Argumente müssen paarweise vorliegen: ein SHA1-Hash (ein 40-stelliger Hexadezimalstring) und ein Blob. Der Blob ist der Patch, der angewendet wird, wenn der aktuelle Inhalt der Quelldatei die angegebene SHA1-Hash-Technologie hat.

Das Patchen erfolgt auf sichere Weise, sodass die Zieldatei entweder den gewünschten SHA1-Hash und die gewünschte Größe hat oder unverändert bleibt. Sie wird nicht in einem nicht wiederherstellbaren Zwischenstatus belassen. Wenn der Prozess während des Patchens unterbrochen wird, befindet sich die Zieldatei möglicherweise in einem Zwischenstatus. Da sich in der Cachepartition eine Kopie befindet, kann die Datei durch einen Neustart des Updates erfolgreich aktualisiert werden.

Es wird eine spezielle Syntax unterstützt, um den Inhalt von MTD-Partitionen (Memory Technology Device) als Dateien zu behandeln. Dadurch können Rohpartitionen wie die Bootpartition gepatcht werden. Wenn Sie eine MTD-Partition lesen möchten, müssen Sie wissen, wie viele Daten Sie lesen möchten, da die Partition kein End-of-File-Konzept hat. Sie können den String „MTD:partition:size_1:sha1_1:size_2: sha1_2“ als Dateinamen verwenden, um die angegebene Partition zu lesen. Sie müssen mindestens ein Paar (Größe, SHA-1) angeben. Sie können auch mehrere angeben, wenn es mehrere Möglichkeiten gibt, was gelesen werden soll.

apply_patch_check(filename, sha1[, sha1, ...])
Gibt „true“ zurück, wenn der Inhalt von filename oder die temporäre Kopie in der Cachepartition (falls vorhanden) eine SHA1-Prüfsumme hat, die mit einem der angegebenen sha1-Werte übereinstimmt. sha1-Werte werden als 40 Hexadezimalziffern angegeben. Diese Funktion unterscheidet sich von sha1_check(read_file(filename), sha1 [, ...]) dadurch, dass sie die Kopie der Cache-Partition prüft. Daher ist apply_patch_check() auch dann erfolgreich, wenn die Datei durch eine unterbrochene apply_patch() update beschädigt wurde.
apply_patch_space(bytes)
Gibt „wahr“ zurück, wenn mindestens Byte an Auslagerungsbereich für die Anwendung von Binär-Patches verfügbar sind.
concat(expr[, expr, ...])
Hiermit werden alle Ausdrücke ausgewertet und zusammengefügt. Der Operator + ist syntaktischer Sugar für diese Funktion im Spezialfall von zwei Argumenten. Die Funktionsform kann jedoch beliebig viele Ausdrücke annehmen. Die Ausdrücke müssen Strings sein. Blobs können nicht zusammengefügt werden.
file_getprop(filename, key)
Liest den angegebenen Dateinamen, interpretiert ihn als Properties-Datei (z.B. /system/build.prop) und gibt den Wert des angegebenen Schlüssels oder den leeren String zurück, wenn Schlüssel nicht vorhanden ist.
format(fs_type, partition_type, location, fs_size, mount_point)
Formatiert eine bestimmte Partition neu. Unterstützte Partitionstypen:
  • fs_type="yaffs2" und partition_type="MTD". „Location“ muss der Name der MTD-Partition sein. Dort wird ein leeres Yaffs2-Dateisystem erstellt. Die übrigen Argumente werden nicht verwendet.
  • fs_type="ext4" und partition_type="EMMC". Der Speicherort muss die Gerätedatei für die Partition sein. Dort wird ein leeres ext4-Dateisystem erstellt. Wenn fs_size null ist, belegt das Dateisystem die gesamte Partition. Wenn fs_size eine positive Zahl ist, belegt das Dateisystem die ersten fs_size Byte der Partition. Wenn fs_size eine negative Zahl ist, belegt das Dateisystem alle bis auf die letzten |fs_size| Byte der Partition.
  • fs_type="f2fs" and partition_type="EMMC". „Location“ muss die Gerätedatei für die Partition sein. fs_size muss eine positive Zahl sein. Wenn fs_size null ist, belegt das Dateisystem die gesamte Partition. Wenn fs_size eine positive Zahl ist, belegt das Dateisystem die ersten fs_size Byte der Partition.
  • „mount_point“ sollte der zukünftige Bereitstellungspunkt für das Dateisystem sein.
getprop(key)
Gibt den Wert der Systemeigenschaft Schlüssel zurück (oder den leeren String, wenn sie nicht definiert ist). Die Werte der Systemeigenschaften, die von der Wiederherstellungspartition definiert werden, stimmen nicht unbedingt mit denen des Hauptsystems überein. Diese Funktion gibt den Wert bei der Wiederherstellung zurück.
greater_than_int(a, b)
Gibt „wahr“ zurück, wenn a (als Ganzzahl interpretiert) größer als b (als Ganzzahl interpretiert) ist.
ifelse(cond, e1[, e2])
Wertet cond aus und gibt bei „wahr“ den Wert von e1 zurück. Andernfalls wird e2 (falls vorhanden) ausgewertet und zurückgegeben. Das Konstrukt „if…else…then…endif“ ist nur syntaktischer Zucker für diese Funktion.
is_mounted(mount_point)
Gibt „true“ zurück, wenn unter mount_point ein Dateisystem bereitgestellt ist.
is_substring(needle, haystack)
Gibt „wahr“ zurück, wenn needle ein Teilstring von haystack ist.
less_than_int(a, b)
Gibt „wahr“ zurück, wenn a (als Ganzzahl interpretiert) kleiner als b (als Ganzzahl interpretiert) ist.
mount(fs_type, partition_type, name, mount_point)
Hiermit wird ein Dateisystem vom Typ fs_type an mount_point bereitgestellt. partition_type muss einer der folgenden Werte sein:
  • MTD. „Name“ ist der Name einer MTD-Partition (z.B. „system“ oder „userdata“; eine vollständige Liste finden Sie unter /proc/mtd auf dem Gerät).
  • EMMC

Bei der Wiederherstellung werden standardmäßig keine Dateisysteme bereitgestellt (außer der SD-Karte, wenn der Nutzer ein Paket manuell von der SD-Karte installiert). Ihr Script muss alle Partitionen bereitstellen, die geändert werden müssen.

package_extract_dir(package_dir, dest_dir)
Hiermit werden alle Dateien aus dem Paket unter package_dir extrahiert und in den entsprechenden Verzeichnisbaum unter dest_dir geschrieben. Vorhandene Dateien werden überschrieben.
package_extract_file(package_file[, dest_file])
Extrahiert eine einzelne package_file aus dem Update-Paket und schreibt sie in dest_file. Vorhandene Dateien werden dabei gegebenenfalls überschrieben. Ohne das Argument dest_file wird der Inhalt der Paketdatei als Binär-Blob zurückgegeben.
read_file(filename)
Liest filename und gibt den Inhalt als Binär-Blob zurück.
run_program(path[, arg, ...])
Führt die Binärdatei unter path aus und übergibt args. Gibt den Beendigungsstatus des Programms zurück.
set_progress(frac)
Legt die Position des Fortschrittsmessers innerhalb des Chunks fest, der durch den letzten show_progress()-Aufruf definiert wurde. frac muss im Bereich [0.0, 1.0] liegen. Der Fortschrittsbalken bewegt sich nie rückwärts. Versuche, dies zu tun, werden ignoriert.
sha1_check(blob[, sha1])
Das Argument blob ist ein Blob des Typs, der von read_file() zurückgegeben wird, oder die einzeilige Form von package_extract_file() . Ohne sha1-Argumente gibt diese Funktion den SHA1-Hash des Blobs als 40-stelliger Hexadezimalstring zurück. Wenn ein oder mehrere sha1-Argumente übergeben werden, gibt diese Funktion den SHA1-Hash zurück, wenn er mit einem der Argumente übereinstimmt, oder den leeren String, wenn er mit keinem übereinstimmt.
show_progress(frac, secs)
Bewegt den Fortschrittsbalken in den nächsten frac Sekunden (secs, muss eine Ganzzahl sein) um den nächsten frac Teil seiner Länge. secs kann auch 0 sein. In diesem Fall wird der Balken nicht automatisch, sondern mithilfe der oben definierten Funktion set_progress() verschoben.
sleep(secs)
Wartet secs Sekunden (muss eine Ganzzahl sein).
stdout(expr[, expr, ...])
 Bewertet jeden Ausdruck und gibt seinen Wert auf stdout aus. Hilfreich für die Fehlerbehebung.
tune2fs(device[, arg, …])
Passt die anpassbaren Parameter args auf device an.
ui_print([text, ...])
Konkateniert alle text-Argumente und druckt das Ergebnis in der Benutzeroberfläche aus, wo es sichtbar ist, wenn der Nutzer die Textanzeige aktiviert hat.
unmount(mount_point)
Heben Sie die Bereitstellung des Dateisystems auf, das unter mount_point bereitgestellt wurde.
wipe_block_device(block_dev, len)
Löscht die len Byte des angegebenen Blockgeräts block_dev.
wipe_cache()
Die Cache-Partition wird am Ende einer erfolgreichen Installation gelöscht.
write_raw_image(filename_or_blob, partition)
Schreibt das Image in filename_or_blob in die MTD-Partition partition. filename_or_blob kann ein String mit dem Namen einer lokalen Datei oder ein Argument mit Blob-Wert sein, das die zu schreibenden Daten enthält. So kopieren Sie eine Datei aus dem OTA-Paket in eine Partition: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Hinweis:Vor Android 4.1 wurden nur Dateinamen akzeptiert. Daher mussten die Daten zuerst in eine temporäre lokale Datei entpackt werden.