ระบบจะสร้างไบนารีโปรแกรมอัปเดตจาก bootable/recovery/updater
และใช้ไบนารีดังกล่าวในแพ็กเกจ OTA
ota_update.zip
,
incremental_ota_update.zip
) ที่มีไบนารีที่เรียกใช้ได้
META-INF/com/google/android/update-binary
Updater มีฟังก์ชันในตัวหลายรายการและโปรแกรมแปลภาษาสคริปต์แบบขยายได้ (edify) ที่รองรับคําสั่งสําหรับงานทั่วไปที่เกี่ยวข้องกับการอัปเดต โปรแกรมอัปเดตจะค้นหาสคริปต์ในไฟล์ META-INF/com/google/android/updater-script
ในไฟล์ .zip ของแพ็กเกจ
หมายเหตุ: การใช้สคริปต์ edify และ/หรือฟังก์ชันในตัวไม่ใช่กิจกรรมทั่วไป แต่อาจมีประโยชน์ในกรณีที่คุณต้องแก้ไขข้อบกพร่องของไฟล์อัปเดต
ไวยากรณ์ Edify
สคริปต์ edify คือนิพจน์เดียวที่ค่าทั้งหมดเป็นสตริง สตริงว่างจะเป็นเท็จในบริบทบูลีน และสตริงอื่นๆ ทั้งหมดจะเป็นจริง 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 then endif) สตริงตัวอักษรล้วนอาจปรากฏในเครื่องหมายคำพูดคู่ด้วย ซึ่งเป็นวิธีสร้างค่าที่มีเว้นวรรคและอักขระอื่นๆ ที่ไม่ได้อยู่ในชุดข้างต้น \n, \t, \" และ \\ ทำหน้าที่เป็นอักขระหลีกภายในสตริงที่มีเครื่องหมายคำพูด เช่นเดียวกับ \x##
โอเปอเรเตอร์ && และ || จะใช้การลัดวงจร ระบบจะไม่ประเมินด้านขวาหากผลลัพธ์เชิงตรรกะถูกกำหนดโดยด้านซ้าย รายการต่อไปนี้มีความหมายเหมือนกัน
e1 && e2 if e1 then e2 endif
โอเปอเรเตอร์ ; คือจุดเริ่มต้นของรายการ ซึ่งหมายความว่าให้ประเมินด้านซ้ายก่อนแล้วจึงประเมินด้านขวา ค่าของตัวแปรคือค่าของนิพจน์ด้านขวา เซมิโคลอนยังปรากฏหลังจากนิพจน์ได้ด้วยเพื่อให้ผลลัพธ์จำลองคำสั่งสไตล์ C ดังนี้
prepare(); do_other_thing("argument"); finish_up();
ฟังก์ชันในตัว
ฟังก์ชันการอัปเดตส่วนใหญ่อยู่ในฟังก์ชันที่ใช้สคริปต์เรียกใช้ได้
(อย่างเคร่งครัดแล้ว คำสั่งเหล่านี้คือมาโคร ไม่ใช่ฟังก์ชันในความหมายของ Lisp เนื่องจากไม่จำเป็นต้องประเมินอาร์กิวเมนต์ทั้งหมด) ฟังก์ชันจะแสดงผล true เมื่อดำเนินการสำเร็จ และ false เมื่อเกิดข้อผิดพลาด เว้นแต่จะระบุไว้เป็นอย่างอื่น หากต้องการให้ข้อผิดพลาดหยุดการเรียกใช้สคริปต์ ให้ใช้ฟังก์ชัน abort()
และ/หรือ assert()
ชุดฟังก์ชันที่มีให้ใช้งานในโปรแกรมอัปเดตยังขยายการให้บริการฟังก์ชันการทำงานเฉพาะอุปกรณ์ได้ด้วย
abort([msg])
- หยุดการดำเนินการของสคริปต์ทันที โดยมี msg (ไม่บังคับ) หากผู้ใช้เปิดการแสดงข้อความไว้ msg จะปรากฏในบันทึกการกู้คืนและบนหน้าจอ
-
assert(expr[, expr, ...])
- ประเมิน expr แต่ละรายการตามลําดับ หากมีรายการใดเป็นเท็จ ระบบจะหยุดการดําเนินการทันทีพร้อมข้อความ "การยืนยันไม่สําเร็จ" และข้อความต้นฉบับของนิพจน์ที่ไม่สําเร็จ
-
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 และขนาดที่ต้องการ หรือจะไม่ถูกแตะต้อง ไฟล์จะไม่อยู่ในสถานะกลางที่กู้คืนไม่ได้ หากกระบวนการขัดจังหวะระหว่างการแพตช์ ไฟล์เป้าหมายอาจอยู่ในสถานะกลางๆ เนื่องจากมีสำเนาอยู่ในพาร์ติชันแคช การเริ่มการอัปเดตอีกครั้งจึงอัปเดตไฟล์ได้สำเร็จ
ระบบรองรับไวยากรณ์พิเศษเพื่อจัดการเนื้อหาของพาร์ติชัน Memory Technology Device (MTD) เป็นไฟล์ ซึ่งช่วยให้สามารถแก้ไขพาร์ติชัน RAW เช่น พาร์ติชันสำหรับบูตได้ หากต้องการอ่านพาร์ติชัน MTD คุณต้องทราบปริมาณข้อมูลที่คุณต้องการอ่าน เนื่องจากพาร์ติชันไม่มีแนวคิดเกี่ยวกับจุดสิ้นสุดของไฟล์ คุณสามารถใช้สตริง MTD:partition:size_1:sha1_1:size_2:sha1_2" เป็นชื่อไฟล์เพื่ออ่านพาร์ติชันที่ระบุ คุณต้องระบุคู่ (size, sha-1) อย่างน้อย 1 คู่ โดยระบุได้มากกว่า 1 คู่หากมีสิ่งที่คุณคาดหวังจะอ่านได้หลายรายการ
-
apply_patch_check(filename, sha1[, sha1, ...])
-
แสดงผลเป็น "จริง" หากเนื้อหาของ filename หรือสำเนาชั่วคราวในพาร์ติชันแคช (หากมี) มีการตรวจสอบผลรวม SHA1 เท่ากับค่า sha1 ที่ระบุ
ค่า sha1 จะระบุเป็นเลขฐานสิบหก 40 หลัก ฟังก์ชันนี้แตกต่างจาก
sha1_check(read_file(filename), sha1 [, ...])
ตรงที่รู้ว่าต้องตรวจสอบสำเนาพาร์ติชันแคช ดังนั้นapply_patch_check()
จึงจะดำเนินการสำเร็จแม้ว่าไฟล์จะเสียหายเนื่องจากapply_patch() update
ถูกขัดจังหวะ apply_patch_space(bytes)
- แสดงผลเป็น "จริง" หากมีพื้นที่ว่างสำหรับใช้แพตช์ไบนารีอย่างน้อย bytes
-
concat(expr[, expr, ...])
- ประเมินนิพจน์แต่ละรายการและต่อเชื่อมเข้าด้วยกัน ตัวดำเนินการ + คือรูปแบบคำสั่งที่ช่วยให้เขียนโค้ดได้ง่ายขึ้นสำหรับฟังก์ชันนี้ในกรณีที่มีอาร์กิวเมนต์ 2 รายการ (แต่รูปแบบฟังก์ชันใช้นิพจน์ได้เท่าใดก็ได้) นิพจน์ต้องเป็นสตริง และต้องไม่ต่อบล็อกข้อมูล
-
file_getprop(filename, key)
-
อ่านชื่อไฟล์ที่ระบุ ตีความเป็นไฟล์พร็อพเพอร์ตี้ (เช่น
/system/build.prop
) และแสดงผลค่าของคีย์ที่ระบุ หรือสตริงว่างหากไม่มีคีย์ -
format(fs_type, partition_type, location, fs_size, mount_point)
-
ฟอร์แมตพาร์ติชันที่ระบุใหม่ ประเภทพาร์ติชันที่รองรับ
- fs_type="yaffs2" and partition_type="MTD" ตำแหน่งต้องเป็นชื่อของพาร์ติชัน MTD ระบบจะสร้างระบบไฟล์ yaffs2 ว่างไว้ที่นั่น อาร์กิวเมนต์ที่เหลือจะไม่ได้ใช้
- fs_type="ext4" and partition_type="EMMC" ตำแหน่งต้องเป็นไฟล์อุปกรณ์สำหรับพาร์ติชัน ระบบจะสร้างระบบไฟล์ ext4 เปล่าในนั้น หาก fs_size เป็น 0 ระบบไฟล์จะกินพื้นที่ทั้งพาร์ติชัน หาก fs_size เป็นจำนวนบวก ระบบไฟล์จะใช้ไบต์ fs_size แรกของพาร์ติชัน หาก fs_size เป็นจำนวนลบ ระบบไฟล์จะใช้พื้นที่ทั้งหมดยกเว้นไบต์ |fs_size| สุดท้ายของพาร์ติชัน
- fs_type="f2fs" and partition_type="EMMC" ตำแหน่งต้องเป็นไฟล์อุปกรณ์ของพาร์ติชัน fs_size ต้องเป็นตัวเลขที่ไม่ใช่ค่าลบ หาก fs_size เป็น 0 ระบบไฟล์จะกินพื้นที่ทั้งพาร์ติชัน หาก fs_size เป็นจำนวนบวก ระบบไฟล์จะใช้ไบต์ fs_size แรกของพาร์ติชัน
- mount_point ควรเป็นจุดต่อเชื่อมในอนาคตสำหรับระบบไฟล์
getprop(key)
- แสดงผลค่าของพร็อพเพอร์ตี้ระบบ key (หรือสตริงว่างเปล่า หากไม่ได้กําหนด) ค่าพร็อพเพอร์ตี้ของระบบที่กำหนดโดยพาร์ติชันการกู้คืนไม่จำเป็นต้องเหมือนกับค่าของพร็อพเพอร์ตี้ของระบบหลัก ฟังก์ชันนี้จะแสดงผลค่าในการกู้คืน
-
greater_than_int(a, b)
- แสดงผลเป็น "จริง" เฉพาะในกรณีที่ a (ตีความว่าเป็นจำนวนเต็ม) มากกว่า b (ตีความว่าเป็นจำนวนเต็ม)
-
ifelse(cond, e1[, e2])
- จะประเมิน cond และหากเป็นจริงจะประเมินและแสดงค่าของ e1 หากไม่เป็นจริงจะประเมินและแสดงค่าของ e2 (หากมี) รูปแบบ "if ... else ... then ... endif" เป็นเพียงรูปแบบคำสั่งสำหรับฟังก์ชันนี้
is_mounted(mount_point)
- แสดงผลเป็น "จริง" หากมีระบบไฟล์ที่ต่อเชื่อมที่ mount_point
-
is_substring(needle, haystack)
- แสดงค่า "จริง" เฉพาะในกรณีที่ needle เป็นสตริงย่อยของ haystack
-
less_than_int(a, b)
- แสดงผลเป็น "จริง" เฉพาะในกรณีที่ a (ตีความว่าเป็นจำนวนเต็ม) น้อยกว่า b (ตีความว่าเป็นจำนวนเต็ม)
-
mount(fs_type, partition_type, name, mount_point)
-
ต่อเชื่อมระบบไฟล์ fs_type ที่ mount_point โดย partition_type ต้องเป็นค่าใดค่าหนึ่งต่อไปนี้
-
MTD ชื่อคือชื่อของพาร์ติชัน MTD (เช่น system, userdata ดูรายการทั้งหมดได้ใน
/proc/mtd
บนอุปกรณ์) - EMMC
การกู้คืนจะไม่มาสก์ระบบไฟล์ใดๆ โดยค่าเริ่มต้น (ยกเว้นการ์ด SD หากผู้ใช้ติดตั้งแพ็กเกจจากการ์ด SD ด้วยตนเอง) สคริปต์ของคุณจะต้องมาสก์พาร์ติชันที่ต้องแก้ไข
-
MTD ชื่อคือชื่อของพาร์ติชัน 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 ระบบจะแสดงผลเนื้อหาของไฟล์แพ็กเกจเป็นบล็อกไบนารี
read_file(filename)
- อ่าน filename และแสดงผลเนื้อหาเป็นบล็อกไบนารี
-
run_program(path[, arg, ...])
- เรียกใช้ไบนารีที่ path โดยส่ง arg แสดงสถานะการออกของโปรแกรม
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 ความยาว 40 หลัก) เมื่อใช้อาร์กิวเมนต์ sha1 อย่างน้อย 1 รายการ ฟังก์ชันนี้จะแสดงผลแฮช 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 ทั้งหมดเข้าด้วยกันและพิมพ์ผลลัพธ์ไปยัง UI (ซึ่งจะแสดงหากผู้ใช้เปิดการแสดงข้อความไว้)
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 ลงใน partition ของ MTD
filename_or_blob อาจเป็นสตริงที่ระบุชื่อไฟล์ในเครื่องหรืออาร์กิวเมนต์ที่มีค่าประเภท Blob ซึ่งมีข้อมูลที่เขียน หากต้องการคัดลอกไฟล์จากแพ็กเกจ OTA ไปยังพาร์ติชัน ให้ใช้คำสั่งต่อไปนี้
write_raw_image(package_extract_file("zip_filename"), "partition_name");
หมายเหตุ: ก่อน Android 4.1 ระบบยอมรับเฉพาะชื่อไฟล์ ดังนั้นจึงต้องแตกไฟล์เป็นไฟล์ชั่วคราวในเครื่องก่อน