Bên trong gói OTA

Hệ thống tạo tệp nhị phân của trình cập nhật từ bootable/recovery/updater và sử dụng tệp đó trong gói OTA.

Bản thân gói là một tệp .zip (ota_update.zip, incremental_ota_update.zip) chứa tệp nhị phân có thể thực thi META-INF/com/google/android/update-binary .

Trình cập nhật chứa một số hàm tích hợp và trình thông dịch cho tập lệnh có thể mở rộng ngôn ngữ (edify) hỗ trợ các lệnh cho các tác vụ thông thường liên quan đến bản cập nhật. Giao diện của trình cập nhật trong tệp .zip của gói cho một tập lệnh trong tệp META-INF/com/google/android/updater-script.

Lưu ý: Việc dùng tập lệnh chỉnh sửa và/hoặc hàm tích hợp không phổ biến nhưng có thể hữu ích nếu bạn cần gỡ lỗi tệp cập nhật.

Cú pháp edify

Tập lệnh sửa đổi là một biểu thức duy nhất trong đó tất cả giá trị là chuỗi. Các chuỗi trống là false trong ngữ cảnh Boolean và tất cả các chuỗi khác đều là true. Edify hỗ trợ các toán tử sau (với ý nghĩa thông thường):

(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

Chuỗi ký tự bất kỳ a-z, A-Z, 0-9, _, :, /, . không phải là một từ dành riêng thì được coi là giá trị cố định kiểu chuỗi. (Các từ dành riêng là if else rồi đến endif.) Chuỗi văn bản giá trị cố định cũng có thể xuất hiện trong dấu ngoặc kép; đây là cách tạo giá trị có khoảng trắng các ký tự khác không nằm trong tập hợp trên. \n, \t, \", và \\ đóng vai trò là các ký tự thoát trong dấu ngoặc kép \x## cũng vậy.

Phần && và || toán tử ngắn mạch; ở bên phải sẽ không được đánh giá nếu kết quả logic được xác định ở phía bên trái. Các mã sau đây là tương đương:

e1 && e2
if e1 then e2 endif

; toán tử là một điểm trong chuỗi; có nghĩa là đánh giá phần đầu tiên bên trái, sau đó là bên phải. Giá trị của biến này là giá trị của biểu thức bên phải. Dấu chấm phẩy cũng có thể xuất hiện sau một biểu thức, vì vậy, hiệu ứng này mô phỏng các câu lệnh kiểu C:

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

Các hàm tích hợp sẵn

Hầu hết chức năng cập nhật đều nằm trong những hàm có sẵn để thực thi bằng tập lệnh. (Nói đúng ra thì đây là macro chứ không phải là hàm theo nghĩa Lisp, vì các đối số này không cần đánh giá tất cả đối số.) Trừ phi có ghi chú khác, các hàm sẽ trả về true khi thành công và false khi gặp lỗi. Nếu bạn muốn lỗi huỷ bỏ việc thực thi tập lệnh, hãy sử dụng các hàm abort() và/hoặc assert(). Tập hợp các hàm có sẵn trong trình cập nhật cũng có thể được mở rộng để cung cấp chức năng dành riêng cho thiết bị.

abort([msg])
Huỷ thực thi tập lệnh ngay lập tức, với thông báo tuỳ chọn. Nếu người dùng có đã bật màn hình tin nhắn, tin nhắn sẽ xuất hiện trong nhật ký khôi phục và trên màn hình.
assert(expr[, expr, ...])
Đánh giá lần lượt từng trải nghiệm. Nếu giá trị bất kỳ nào là false (sai), sẽ huỷ việc thực thi ngay lập tức bằng thông báo "xác nhận không thành công" và văn bản nguồn của biểu thức không thành công.
apply_patch(src_file, tgt_file, tgt_sha1, tgt_size, patch1_sha1, patch1_blob, [...])
Áp dụng bản vá nhị phân cho src_file để tạo tgt_file. Nếu mục tiêu mong muốn giống với nguồn, hãy chuyển "-" cho tgt_file . tgt_sha1tgt_size là kích thước và hàm băm SHA1 cuối cùng dự kiến của tệp mục tiêu. Phần còn lại đối số phải đi theo cặp: một hàm băm SHA1 (chuỗi hex 40 ký tự) và một blob. Giọt nước là bản vá sẽ được áp dụng khi nội dung hiện tại của tệp nguồn có SHA1 đã cho.

Việc vá lỗi được thực hiện một cách an toàn, đảm bảo tệp đích có hàm băm và kích thước SHA1 mong muốn hoặc hàm này không được động đến—dữ liệu này sẽ không bị để ở trạng thái không thể khôi phục trạng thái trung gian. Nếu quá trình này bị gián đoạn trong quá trình vá, tệp đích có thể bị ở trạng thái trung gian; đã có một bản sao trong phân vùng bộ nhớ đệm. Do đó, hãy bắt đầu lại quá trình cập nhật có thể cập nhật tệp thành công.

Hỗ trợ cú pháp đặc biệt để xử lý nội dung của Thiết bị công nghệ bộ nhớ (MTD) phân vùng dưới dạng tệp, cho phép vá các phân vùng thô như khởi động. Để đọc MTD Bạn phải biết lượng dữ liệu mình muốn đọc vì phân vùng không có khái niệm ở cuối tệp. Bạn có thể sử dụng chuỗi "MTD:partition:size_1:sha1_1:size_2: sha1_2" với tư cách là tên tệp để đọc phân vùng đã cho. Bạn phải chỉ định ít nhất một cặp (size, sha-1); bạn có thể chỉ định nhiều mục nếu có nhiều khả năng đối với nội dung bạn muốn đọc.

apply_patch_check(filename, sha1[, sha1, ...])
Trả về true nếu nội dung của filename hoặc bản sao tạm thời trong phân vùng bộ nhớ đệm (nếu có) có giá trị tổng kiểm SHA1 bằng một trong các giá trị sha1 đã cho. Các giá trị sha1 được chỉ định là 40 chữ số hex. Hàm này khác với sha1_check(read_file(filename), sha1 [, ...]) trong đó biết hãy kiểm tra bản sao phân vùng bộ nhớ đệm, vì vậy, apply_patch_check() sẽ thành công ngay cả khi tệp bị hỏng do một apply_patch() update bị gián đoạn.
apply_patch_space(bytes)
Trả về giá trị true nếu có ít nhất byte dung lượng trống để áp dụng tệp nhị phân bản vá.
concat(expr[, expr, ...])
Đánh giá từng biểu thức và nối các biểu thức đó với nhau. Toán tử + là cú pháp dễ hiểu cho điều này trong trường hợp đặc biệt là hai đối số (nhưng dạng hàm có thể lấy bất kỳ số lượng giá trị nào biểu thức). Biểu thức phải là chuỗi; nó không thể nối các blob.
file_getprop(filename, key)
Đọc tên tệp đã cho, hiểu tên tệp là một tệp thuộc tính (ví dụ: /system/build.prop) và trả về giá trị của khoá đã cho hoặc chuỗi trống nếu không có khoá.
format(fs_type, partition_type, location, fs_size, mount_point)
Định dạng lại một phân vùng nhất định. Các loại phân vùng được hỗ trợ:
  • fs_type="yaffs2" và phân vùng_type="MTD". Vị trí phải là tên của MTD phân vùng; một hệ thống tệp yaffs2 trống được xây dựng ở đó. Các đối số còn lại là không sử dụng.
  • fs_type="ext4" và phân vùng_type="EMMC". Vị trí phải là tệp thiết bị cho phân vùng. Một hệ thống tệp ext4 trống được xây dựng ở đó. Nếu fs_size bằng 0, thì giá trị hệ thống tệp chiếm toàn bộ phân vùng. Nếu fs_size là số dương, thì giá trị hệ thống tệp lấy fs_size byte đầu tiên của phân vùng. Nếu fs_size là một số âm, hệ thống tệp sẽ lấy tất cả trừ byte |fs_size| byte cuối cùng của phân vùng.
  • fs_type="f2fs" và phân vùng_type="EMMC". Vị trí phải là tệp thiết bị cho phân vùng. fs_size phải là một số không âm. Nếu fs_size bằng 0, thì giá trị hệ thống tệp chiếm toàn bộ phân vùng. Nếu fs_size là số dương, thì giá trị hệ thống tệp lấy fs_size byte đầu tiên của phân vùng.
  • upload_point phải là điểm gắn trong tương lai cho hệ thống tệp.
getprop(key)
Trả về giá trị của thuộc tính hệ thống key (hoặc chuỗi trống nếu không được xác định). Các giá trị thuộc tính hệ thống được xác định bằng phân vùng khôi phục không nhất thiết giống với của hệ thống chính. Hàm này trả về giá trị trong quá trình khôi phục.
greater_than_int(a, b)
Trả về true khi và chỉ khi (iff) a (được diễn giải dưới dạng số nguyên) lớn hơn b (được diễn giải dưới dạng số nguyên).
ifelse(cond, e1[, e2])
Đánh giá cond và nếu đúng thì sẽ đánh giá và trả về giá trị e1, nếu không thì hệ thống sẽ đánh giá và trả về e2 (nếu có). Trường "nếu ... khác ... thì ... endif" cấu trúc chỉ là cú pháp dễ hiểu cho hàm này.
is_mounted(mount_point)
Trả về giá trị true nếu có một hệ thống tệp được gắn tại base_point.
is_substring(needle, haystack)
Trả về giá trị true iff needle là chuỗi con của haystack.
less_than_int(a, b)
Trả về true nếuf a (được hiểu là số nguyên) nhỏ hơn b (được hiểu là số nguyên).
mount(fs_type, partition_type, name, mount_point)
Gắn một hệ thống tệp fs_type tại stick_point. partition_type phải là một trong:
  • MTD. Tên là tên của một phân vùng MTD (ví dụ: hệ thống, dữ liệu người dùng; xem /proc/mtd trên thiết bị để xem danh sách đầy đủ).
  • EMMC.

Theo mặc định, quá trình khôi phục không gắn kết bất kỳ hệ thống tệp nào (ngoại trừ thẻ SD nếu người dùng cài đặt thủ công một gói từ thẻ SD); tập lệnh của bạn phải gắn kết bất kỳ mà nó cần sửa đổi.

package_extract_dir(package_dir, dest_dir)
Trích xuất tất cả các tệp từ gói bên dưới package_dir và ghi chúng vào cây tương ứng bên dưới dest_dir. Mọi tệp hiện có đều bị ghi đè.
package_extract_file(package_file[, dest_file])
Trích xuất một package_file duy nhất từ gói cập nhật và ghi nó vào dest_file, ghi đè các tệp hiện có nếu cần. Nếu không có dest_file trả về nội dung của tệp gói dưới dạng blob nhị phân.
read_file(filename)
Đọc filename và trả về nội dung của tệp dưới dạng một blob nhị phân.
run_program(path[, arg, ...])
Thực thi tệp nhị phân tại path, truyền arg. Trả về trạng thái thoát của chương trình.
set_progress(frac)
Đặt vị trí của đồng hồ đo tiến trình trong đoạn được xác định theo dữ liệu gần đây nhất Cuộc gọi show_progress(). frac phải nằm trong khoảng [0.0, 1.0]. Tiến trình mét không bao giờ lùi lại; cố gắng làm như vậy sẽ bị bỏ qua.
sha1_check(blob[, sha1])
Đối số blob là một blob thuộc loại được read_file() trả về hoặc dạng một đối số của package_extract_file() . Không có đối số sha1, hàm này trả về hàm băm SHA1 của blob (dưới dạng chuỗi hex gồm 40 chữ số). Với một hoặc nhiều đối số sha1, hàm này sẽ trả về hàm băm SHA1 nếu hàm này bằng một trong các hoặc chuỗi trống nếu không bằng bất kỳ đối số nào trong số đó.
show_progress(frac, secs)
Tăng đồng hồ đo tiến trình qua frac tiếp theo của độ dài qua secs giây (phải là một số nguyên). secs có thể bằng 0, trong trường hợp này thì định mức là không tự động nâng cao mà bằng cách sử dụng hàm set_progress() được xác định ở trên.
sleep(secs)
Ngủ trong secs giây (phải là một số nguyên).
stdout(expr[, expr, ...])
Đánh giá từng biểu thức và kết xuất giá trị của biểu thức đó vào stdout. Hữu ích khi gỡ lỗi.
tune2fs(device[, arg, …])
Điều chỉnh các tham số có thể điều chỉnh args trên thiết bị.
ui_print([text, ...])
Liên kết tất cả các đối số văn bản và in kết quả ra giao diện người dùng (nơi kết quả sẽ có dạng hiển thị nếu người dùng đã bật màn hình văn bản).
unmount(mount_point)
Ngắt kết nối hệ thống tệp được gắn kết tại stick_point.
wipe_block_device(block_dev, len)
Xoá các byte len của thiết bị khối đã cho block_dev.
wipe_cache()
Làm cho phân vùng bộ nhớ đệm bị xoá ở cuối quá trình cài đặt thành công.
write_raw_image(filename_or_blob, partition)
Ghi hình ảnh trong filename_or_blob vào phân vùng MTD. filename_or_blob có thể là một chuỗi đặt tên một tệp cục bộ hoặc một đối số có giá trị blob chứa dữ liệu cần ghi. Để sao chép tệp từ gói OTA vào một phân vùng, hãy sử dụng: write_raw_image(package_extract_file("zip_filename"), "partition_name");

Lưu ý: Trước Android 4.1, chỉ tên tệp được chấp nhận, vì vậy để hoàn thành Đây là dữ liệu đầu tiên phải được giải nén vào một tệp cục bộ tạm thời.