פיתוח חבילות OTA

אפשר להשתמש בכלי ota_from_target_files שמופיע ב-build/make/tools/releasetools כדי ליצור חבילות מלאות ואינקרמנטליות של OTA למכשירים שמשתמשים בעדכוני מערכת מסוג A/B או בעדכוני מערכת מסוג non-A/B. הכלי מקבל כקלט את קובץ target-files.zip שנוצר על ידי מערכת ה-build של Android.

במכשירים עם Android מגרסה 11 ואילך, אפשר ליצור חבילת OTA אחת לכמה מכשירים עם מספרי SKU שונים. כדי לעשות זאת, צריך להגדיר את מכשירי היעד לשימוש בטביעות אצבע דינמיות ולעדכן את המטא-נתונים של OTA כך שיכללו את שם המכשיר ואת טביעת האצבע שלו ברשומות של התנאים המוקדמים והתנאים שלאחר מכן.

ב-Android 8.0 הוצאו משימוש חבילות OTA מבוססות-קובץ למכשירים שאינם מסוג A/B, ובמקום זאת צריך להשתמש בחבילות OTA מבוססות-בלוק. כדי ליצור חבילות OTA מבוססות-בלוקים או מכשירים עם Android מגרסה 7.x ומטה, מעבירים את האפשרות --block לפרמטר ota_from_target_files.

יצירת עדכונים מלאים

עדכון מלא הוא חבילת OTA שמכילה את המצב הסופי המלא של המכשיר (מחיצות המערכת, ההפעלה והשחזור). כל עוד המכשיר יכול לקבל את החבילה ולהחיל אותה, אפשר להתקין את הגרסה באמצעות החבילה, בלי קשר למצב הנוכחי של המכשיר. לדוגמה, הפקודות הבאות משתמשות בכלי הפצה כדי ליצור את הארכיון target-files.zip למכשיר tardis.

. build/envsetup.sh && lunch tardis-eng
mkdir dist_output
make dist DIST_DIR=dist_output

make dist יוצר חבילת OTA מלאה (ב-$OUT). קובץ .zip שנוצר מכיל את כל מה שצריך כדי ליצור חבילות OTA למכשיר tardis. אפשר גם ליצור את ota_from_target_files כקובץ בינארי של Python ולהפעיל אותו כדי ליצור חבילות מלאות או מצטברות.

ota_from_target_files dist_output/tardis-target_files.zip ota_update.zip

הנתיב ota_from_target_files מוגדר ב-$PATH, והקובץ הבינארי של Python שמתקבל נמצא בספרייה out/.

ota_update.zip מוכן עכשיו לשליחה למכשירי בדיקה (הכול חתום באמצעות מפתח הבדיקה). במכשירים של משתמשים, צריך ליצור מפתחות פרטיים משלכם ולהשתמש בהם כמו שמתואר במאמר חתימה על גרסאות להפצה.

יצירת עדכונים מצטברים

עדכון מצטבר הוא חבילת OTA שמכילה תיקונים בינאריים לנתונים שכבר נמצאים במכשיר. חבילות עם עדכונים מצטברים הן בדרך כלל קטנות יותר, כי הן לא צריכות לכלול קבצים שלא השתנו. בנוסף, מכיוון שקבצים שעברו שינוי דומים בדרך כלל מאוד לגרסאות הקודמות שלהם, החבילה צריכה לכלול רק קידוד של ההבדלים בין שני הקבצים.

אפשר להתקין חבילת עדכון מצטבר רק במכשירים שמותקנת בהם גרסת המקור ששימשה ליצירת החבילה. כדי ליצור עדכון מצטבר, צריך את קובץ target_files.zip מהגרסה הקודמת (הגרסה שרוצים לעדכן ממנה) וגם את קובץ target_files.zip מהגרסה החדשה. לדוגמה, הפקודות הבאות משתמשות בכלי הפצה כדי ליצור עדכון מצטבר למכשיר tardis.

ota_from_target_files -i PREVIOUS-tardis-target_files.zip dist_output/tardis-target_files.zip incremental_ota_update.zip

הגרסה הזו דומה מאוד לגרסה הקודמת, וחבילת העדכון המצטבר (incremental_ota_update.zip) קטנה בהרבה מהעדכון המלא המקביל (בערך 1MB במקום 60MB).

הפצה של חבילה מצטברת רק למכשירים שמופעלת בהם בדיוק אותה גרסת build קודמת ששימשה כנקודת התחלה של החבילה המצטברת. צריך להפעיל את התמונות ב-PREVIOUS-tardis-target_files.zip או ב-PREVIOUS-tardis-img.zip (שניהם נוצרו באמצעות make dist, כדי להפעיל אותם באמצעות fastboot update), במקום את התמונות בספרייה PRODUCT_OUT (שנוצרו באמצעות make, כדי להפעיל אותן באמצעות fastboot flashall). ניסיון להתקין את החבילה המצטברת במכשיר עם גרסה אחרת יוביל לשגיאת התקנה. אם ההתקנה נכשלת, המכשיר נשאר באותו מצב פעולה (מריץ את המערכת הישנה). החבילה בודקת את המצב הקודם של כל הקבצים שהיא מעדכנת לפני שהיא משנה אותם, כך שהמכשיר לא נשאר במצב של שדרוג חלקי.

כדי לספק את חוויית המשתמש הטובה ביותר, מומלץ להציע עדכון מלא כל 3-4 עדכונים מצטברים. כך המשתמשים יכולים להתעדכן בגרסה האחרונה ולמנוע רצף ארוך של עדכונים מצטברים.

יצירת חבילות OTA לכמה מק"טים

‫Android 11 ואילך תומך בשימוש בחבילת OTA אחת למספר מכשירים עם מק"טים שונים. כדי לעשות זאת, צריך להגדיר את מכשירי היעד לשימוש בטביעות אצבע דינמיות ולעדכן את המטא-נתונים של ה-OTA (באמצעות כלי OTA) כך שיכללו את שם המכשיר ואת טביעת האצבע ברשומות של התנאים לפני ואחרי.

מידע על מק"טים

הפורמט של מק"ט הוא וריאציה של שילוב ערכי פרמטר build, ובדרך כלל הוא קבוצת משנה לא מוצהרת של הפרמטרים הנוכחיים build_fingerprint. יצרני ציוד מקורי יכולים להשתמש בכל שילוב של פרמטרים לבנייה שאושרו על ידי CDD עבור מק"ט, וגם להשתמש בתמונה אחת עבור המק"טים האלה. לדוגמה, למק"ט הבא יש כמה וריאציות:

SKU = <product><device><modifierA><modifierB><modifierC>
  • modifierA היא רמת המכשיר (למשל Pro,‏ Premium או Plus)
  • modifierB הוא וריאציית החומרה (כמו רדיו)
  • modifierC הוא האזור, שיכול להיות כללי (כמו NA,‏ EMEA או CHN) או ספציפי למדינה או לשפה (כמו JPN,‏ ENG או CHN)

יצרני ציוד מקורי רבים משתמשים בקובץ אימג' יחיד לכמה מק"טים, ואז גוזרים את שם המוצר הסופי ואת טביעת האצבע של המכשיר בזמן הריצה אחרי שהמכשיר מופעל. התהליך הזה מפשט את תהליך הפיתוח של הפלטפורמה, ומאפשר למכשירים עם התאמות אישיות קלות אבל שמות מוצר שונים לשתף תמונות משותפות (כמו tardis ו-tardispro).

שימוש בטביעות אצבע דינמיות

טביעת אצבע היא שרשור מוגדר של פרמטרים של build, כמו ro.product.brand, ro.product.name ו-ro.product.device. טביעת האצבע של המכשיר נגזרת מטביעת האצבע של מחיצת המערכת ומשמשת כמזהה ייחודי של התמונות (והבייטים) שפועלות במכשיר. כדי ליצור טביעת אצבע דינמית, משתמשים בלוגיקה דינמית בקובץ build.prop של המכשיר כדי לקבל את הערך של משתני טוען האתחול בזמן אתחול המכשיר, ואז משתמשים בנתונים האלה כדי ליצור טביעת אצבע דינמית למכשיר.

לדוגמה, כדי להשתמש בטביעות אצבע דינמיות במכשירי tardis ו-tardispro, צריך לעדכן את הקבצים הבאים כמו שמוצג בהמשך.

  • מעדכנים את הקובץ odm/etc/build_std.prop כך שיכיל את השורה הבאה.

    ro.odm.product.device=tardis
    
  • מעדכנים את הקובץ odm/etc/build_pro.prop כך שיכיל את השורה הבאה.

    ro.odm.product.device=tardispro
    
  • מעדכנים את הקובץ odm/etc/build.prop כך שיכיל את השורות הבאות.

    ro.odm.product.device=tardis
    import /odm/etc/build_${ro.boot.product.hardware.sku}.prop
    

השורות האלה מגדירות באופן דינמי את שם המכשיר, טביעת האצבע והערכים של ro.build.fingerprint על סמך הערך של מאפיין טוען האתחול ro.boot.product.hardware.sku (שהוא לקריאה בלבד).

עדכון המטא-נתונים של חבילת OTA

חבילת OTA מכילה קובץ מטא-נתונים (META-INF/com/android/metadata) שמתאר את החבילה, כולל התנאי המוקדם והתנאי שלאחר מכן של חבילת ה-OTA. לדוגמה, הקוד הבא הוא קובץ המטא-נתונים של חבילת OTA שמיועדת למכשיר tardis.

post-build=google/tardis/tardis:11/RP1A.200521.001/6516341:userdebug/dev-keys
post-build-incremental=6516341
post-sdk-level=30
post-security-patch-level=2020-07-05
post-timestamp=1590026334
pre-build=google/tardis/tardis:11/RP1A.200519.002.A1/6515794:userdebug/dev-keys
pre-build-incremental=6515794
pre-device=tardis

הערכים pre-device,‏ pre-build-incremental ו-pre-build מגדירים את המצב שבו המכשיר צריך להיות לפני שאפשר להתקין את חבילת ה-OTA. הערכים של post-build-incremental ושל post-build מגדירים את המצב שאליו המכשיר אמור להגיע אחרי התקנת חבילת ה-OTA. הערכים של השדות pre- ו-post- נגזרים ממאפייני הבנייה התואמים הבאים.

  • הערך pre-device נגזר ממאפיין ה-build‏ ro.product.device.
  • הערכים של pre-build-incremental ו-post-build-incremental נגזרים ממאפיין ה-build‏ ro.build.version.incremental.
  • הערכים של pre-build ו-post-build נגזרים ממאפיין הבנייה ro.build.fingerprint.

במכשירים עם Android מגרסה 11 ואילך, אפשר להשתמש בדגל --boot_variable_file בכלי OTA כדי לציין נתיב לקובץ שמכיל את הערכים של משתני זמן הריצה שמשמשים ליצירת טביעת האצבע הדינמית של המכשיר. לאחר מכן, הנתונים משמשים לעדכון המטא-נתונים של OTA כדי לכלול את שם המכשיר ואת טביעת האצבע בתנאים pre- ו-post- (באמצעות התו | כתו מפריד). לדגל --boot_variable_file יש את התחביר והתיאור הבאים.

  • תחביר: --boot_variable_file <path>
  • תיאור: מציין נתיב לקובץ שמכיל את הערכים האפשריים של מאפייני ro.boot.*. המאפיין הזה משמש לחישוב טביעות האצבע האפשריות בזמן הריצה, כשחלק מהמאפיינים של ro.product.* מוחלפים על ידי הצהרת הייבוא. בכל שורה בקובץ צריך להיות נכס אחד, והפורמט של כל שורה הוא: prop_name=value1,value2.

לדוגמה, אם הנכס הוא ro.boot.product.hardware.sku=std,pro, המטא-נתונים של OTA למכשירים tardis ו-tardispro מוצגים כמו בדוגמה הבאה.

post-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-build=google/tardis/tardis:11/<suffix>|google/tardis/tardispro:11/<suffix>
pre-device=tardis|tardispro

כדי לתמוך בפונקציונליות הזו במכשירים עם Android 10, אפשר לעיין בהטמעה לדוגמה. רשימת השינויים הזו מנתחת באופן מותנה את ההצהרות import בקובץ build.prop, מה שמאפשר לזהות שינויים במאפיינים ולשקף אותם במטא-נתונים הסופיים של ה-OTA.