המערכת יוצרת את קובץ העדכון הבינארי מ-bootable/recovery/updater
ומשתמשת בו בחבילת OTA.
ota_update.zip
, incremental_ota_update.zip
) שמכיל את קובץ הבינארי להפעלה META-INF/com/google/android/update-binary
.
Updater מכיל כמה פונקציות מובנות ומתרגם לשפת סקריפטים נרחבת (edify) שתומכת בפקודות למשימות נפוצות שקשורות לעדכון. הכלי Updater מחפש קובץ סקריפט בקובץ ה-zip של החבילה, בקובץ META-INF/com/google/android/updater-script
.
הערה: השימוש בסקריפט edify או בפונקציות המובנות הוא לא פעילות נפוצה, אבל הוא יכול להיות שימושי אם צריך לנפות באגים בקובץ העדכון.
שיפור התחביר
סקריפט edify הוא ביטוי יחיד שבו כל הערכים הם מחרוזות. מחרוזות ריקות הן false בהקשר בוליאני, וכל שאר המחרוזות הן true. ב-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
כל מחרוזת של התווים a-z, A-Z, 0-9, _, :, /, . שלא היא מילה שמורה, נחשבת למחרוזת לטינית. (המילים השמורות הן if else ואז endif.) מחרוזות לינאריות יכולות להופיע גם במירכאות כפולות. כך יוצרים ערכים עם רווחים לבנים ותווים אחרים שלא נכללים בקבוצה שלמעלה. תווים כמו \n, \t, \" ו-\\ משמשים כתוויות בריחה (escape) במחרוזות במירכאות, כמו גם \x##.
אופרטורי && ו-|| מבצעים קיצור דרך (short-circuiting). הצד הימני לא מחושב אם התוצאה הלוגית נקבעת על ידי הצד הימני. האפשרויות הבאות זהות:
e1 && e2 if e1 then e2 endif
האופרטור ; הוא נקודת רצף. המשמעות היא שקודם צריך להעריך את הצד שמואל ואז את הצד הימני. הערך שלו הוא הערך של הביטוי בצד שמאל. פסיק נקודה יכול להופיע גם אחרי ביטוי, כך שהאפקט מדמה הצהרות בסגנון C:
prepare(); do_other_thing("argument"); finish_up();
פונקציות מובנות
רוב הפונקציונליות של העדכונים נכללת בפונקציות שזמינות להרצה על ידי סקריפטים.
(במובן המדויק, אלה מאקרוסים ולא פונקציות במובן של Lisp, כי אין צורך להעריך את כל הארגומנטים שלהם). אלא אם צוין אחרת, הפונקציות מחזירות את הערך true אם הפעולה בוצעה בהצלחה ואת הערך false אם נוצרה שגיאה. אם רוצים שהפעלת הסקריפט תבוטל אם מתרחשות שגיאות, צריך להשתמש בפונקציות abort()
ו/או assert()
. אפשר גם להרחיב את קבוצת הפונקציות הזמינות ב-updater כדי לספק פונקציונליות ספציפית למכשיר.
abort([msg])
- ביטול מיידי של ביצוע הסקריפט, עם הפרמטר האופציונלי msg. אם המשתמש הפעיל את הצגת הטקסט, הערך msg יופיע ביומן השחזור ובמסך.
-
assert(expr[, expr, ...])
- הפונקציה מבצעת הערכה של כל expr בתורו. אם אחד מהם הוא false, הפונקציה מפסיקה את הביצוע באופן מיידי עם ההודעה "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 תווים) ו-blob. ה-blob הוא התיקון שצריך להחיל כשה-SHA1 של התוכן הנוכחי של קובץ המקור הוא זה שצוין.
תיקון הבאגים מתבצע באופן בטוח, כך שאפשר להבטיח שלקובץ היעד יהיה הגיבוב והגודל הרצויים של SHA1, או שהוא לא ישתנה – הוא לא יישאר במצב ביניים שלא ניתן לשחזור. אם התהליך מופסק במהלך תיקון הבאגים, ייתכן שקובץ היעד יהיה במצב ביניים. יש עותק במחיצה של המטמון, כך שניתן יהיה להפעיל מחדש את העדכון כדי לעדכן את הקובץ.
יש תמיכה בסינטקס מיוחד לטיפול בתוכן של מחיצות של מכשיר טכנולוגיית זיכרון (MTD) בתור קבצים, שמאפשר תיקון של מחיצות גולמיות כמו אתחול. כדי לקרוא מחיצה מסוג MTD, צריך לדעת כמה נתונים רוצים לקרוא כי אין במחיצה סימן לסוף הקובץ. אפשר להשתמש במחרוזת "MTD:partition:size_1:sha1_1:size_2: sha1_2" בתור שם הקובץ כדי לקרוא את המחיצה הנתונה. צריך לציין לפחות זוג אחד של (size, sha-1). אפשר לציין יותר מזוג אחד אם יש כמה אפשרויות למה שציפיתם לקרוא.
-
apply_patch_check(filename, sha1[, sha1, ...])
-
הפונקציה מחזירה את הערך true אם לתוכן של filename או של העותק הזמני במחיצה של המטמון (אם הוא קיים) יש סיכום SHA1 שווה לאחד מערכי sha1 שצוינו.
הערכים של sha1 מצוינים כ-40 ספרות הקסדצימליות. הפונקציה הזו שונה מ-
sha1_check(read_file(filename), sha1 [, ...])
בכך שהיא יודעת לבדוק את העותק במחיצה של המטמון, כך ש-apply_patch_check()
תצליח גם אם הקובץ פגום בגללapply_patch() update
שהופסק. apply_patch_space(bytes)
- הפונקציה מחזירה את הערך True אם יש לפחות בייטים של שטח מחיקה זמין להחלת תיקוני באגים בינאריים.
-
concat(expr[, expr, ...])
- הערכה של כל ביטוי ושרשור שלהם. אופרטור ה-+ הוא תכונה נוחה לשימוש (syntactic sugar) של הפונקציה הזו במקרה המיוחד של שני ארגומנטים (אבל טופס הפונקציה יכול להכיל כל מספר של ביטויים). הביטויים חייבים להיות מחרוזות. אי אפשר לשרשר blobs.
-
file_getprop(filename, key)
-
קורא את filename שצוין, מפרש אותו כקובץ מאפיינים (למשל
/system/build.prop
) ומחזיר את הערך של key שצוין, או את המחרוזת הריקה אם key לא קיים. -
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" and partition_type="EMMC". המיקום חייב להיות קובץ המכשיר של המחיצה. הערך של fs_size חייב להיות מספר לא שלילי. אם הערך של fs_size הוא אפס, מערכת הקבצים תופסת את כל המחיצה. אם fs_size הוא מספר חיובי, מערכת הקבצים תשתמש ב-fs_size הבייטים הראשונים של המחיצה.
- mount_point צריכה להיות נקודת הטעינה העתידית של מערכת הקבצים.
getprop(key)
- פונקציה שמחזירה את הערך של מאפיין המערכת key (או את המחרוזת הריקה, אם הוא לא מוגדר). ערכי מאפייני המערכת שמוגדרים על ידי מחיצת השחזור לא בהכרח זהים לערכי המערכת הראשית. הפונקציה הזו מחזירה את הערך בתהליך השחזור.
-
greater_than_int(a, b)
- הפונקציה מחזירה את הערך true אם ורק אם (iff) הערך של a (שמתפרש כמספר שלם) גדול מהערך של b (שמתפרש כמספר שלם).
-
ifelse(cond, e1[, e2])
- הפונקציה בוחנת את cond, ואם הערך שלה הוא true, היא מחשבת ומחזירה את הערך של e1. אחרת, היא מחשבת ומחזירה את הערך של e2 (אם הוא קיים). המבנה if ... else ... then ... endif הוא רק תכונה פונקציונלית לשיפור התחביר של הפונקציה הזו.
is_mounted(mount_point)
- הפונקציה מחזירה את הערך true אם יש מערכת קבצים שמוצמדת ל-mount_point.
-
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 ב-mount_point. הערך של partition_type חייב להיות אחד מהערכים הבאים:
-
MTD. Name הוא השם של מחיצה ב-MTD (למשל, system, userdata. רשימה מלאה מופיעה בקובץ
/proc/mtd
במכשיר). - EMMC
ברירת המחדל של תהליך השחזור היא לא לחבר מערכת קבצים כלשהי (חוץ מכרטיס ה-SD, אם המשתמש מבצע התקנה ידנית של חבילה מכרטיס ה-SD). הסקריפט צריך לחבר את כל המחיצות שהוא צריך לשנות.
-
MTD. Name הוא השם של מחיצה ב-MTD (למשל, system, userdata. רשימה מלאה מופיעה בקובץ
-
package_extract_dir(package_dir, dest_dir)
- חילוץ כל הקבצים מהחבילה מתחת ל-package_dir וכתיבה שלהם בעץ התואם מתחת ל-dest_dir. קבצים קיימים יימחקו.
-
package_extract_file(package_file[, dest_file])
- חילוץ קובץ package_file יחיד מחבילת העדכון וכתיבה שלו בקובץ dest_file, עם כתיבה מחדש של קבצים קיימים במקרה הצורך. בלי הארגומנט dest_file, הפונקציה מחזירה את תוכן קובץ החבילה כ-blob בינארי.
read_file(filename)
- קורא את filename ומחזיר את התוכן שלו כ-blob בינארי.
-
run_program(path[, arg, ...])
- הפעלת קובץ הבינארי ב-path, עם העברת args. הפונקציה מחזירה את סטטוס היציאה של התוכנית.
set_progress(frac)
-
מגדיר את המיקום של מדד ההתקדמות בתוך הרצף שמוגדר על ידי הקריאה האחרונה של
show_progress()
. הערך של frac חייב להיות בטווח [0.0, 1.0]. מדד ההתקדמות אף פעם לא חוזר לאחור, והמערכת מתעלמת מניסיונות לגרום לו לעשות זאת. -
sha1_check(blob[, sha1])
-
הארגומנט blob הוא blob מהסוג שהפונקציה
read_file()
מחזירה, או הטופס שלpackage_extract_file()
עם ארגומנט אחד. בלי ארגומנטי sha1, הפונקציה הזו מחזירה את גיבוב ה-SHA1 של ה-blob (כמחרוזת 16-תווית מרובע). עם ארגומנט sha1 אחד או יותר, הפונקציה הזו מחזירה את גיבוב ה-SHA1 אם הוא שווה לאחד מהארגומנטים, או את המחרוזת הריקה אם הוא לא שווה לאף אחד מהם. -
show_progress(frac, secs)
-
מקדמת את מד ההתקדמות ב-frac הבא של האורך שלו במהלך secs שניות (חייב להיות מספר שלם). הערך של secs יכול להיות 0, ובמקרה כזה מד ההתקדמות לא מתקדם באופן אוטומטי אלא באמצעות הפונקציה
set_progress()
שהוגדרה למעלה. sleep(secs)
- הפעולה נכנסת למצב שינה למשך secs שניות (חייב להיות מספר שלם).
-
stdout(expr[, expr, ...])
- מעריכה כל ביטוי ומעבירה את הערך שלו ל-stdout. שימושיים לניפוי באגים.
-
tune2fs(device[, arg, …])
- משנה את הפרמטרים הניתנים לשינוי args ב-device.
ui_print([text, ...])
- מחברת את כל הארגומנטים של 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, המערכת קיבלה רק שמות של קבצים, ולכן כדי לעשות זאת היה צריך קודם לפתוח את הנתונים בקובץ מקומי זמני.