Bản cập nhật hệ thống động (DSU) cho phép bạn tạo hình ảnh hệ thống Android để người dùng có thể tải xuống từ Internet và dùng thử mà không có nguy cơ làm hỏng hình ảnh hệ thống hiện tại. Tài liệu này mô tả cách hỗ trợ DSU.
Yêu cầu về kernel
Xem phần Triển khai phân vùng động để biết các yêu cầu về hạt nhân.
Ngoài ra, DSU dựa vào tính năng nhân bản đồ thiết bị (dm-verity) để xác minh hình ảnh hệ thống Android. Vì vậy, bạn phải bật các cấu hình hạt nhân sau:
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
Yêu cầu về phân vùng
Kể từ Android 11, DSU yêu cầu phân vùng /data
sử dụng hệ thống tệp F2FS hoặc ext4. F2FS mang lại hiệu suất tốt hơn và được khuyên dùng, nhưng sự khác biệt không đáng kể.
Dưới đây là một số ví dụ về thời gian cập nhật hệ thống động trên thiết bị Pixel:
- Sử dụng F2FS:
- 109 giây, người dùng 8G, hệ thống 867M, loại hệ thống tệp: F2FS: encryption=aes-256-xts:aes-256-cts
- 104 giây, 8G người dùng, 867M hệ thống, loại hệ thống tệp: F2FS: mã hoá=băng
- Sử dụng định dạng ext4:
- 135 giây, người dùng 8G, hệ thống 867M, loại hệ thống tệp: ext4: mã hoá=aes-256-xts:aes-256-cts
Nếu mất nhiều thời gian hơn trên nền tảng của mình, bạn nên kiểm tra xem cờ gắn kết có chứa bất kỳ cờ nào tạo chế độ ghi "đồng bộ hoá" hay không, hoặc bạn có thể chỉ định cờ "không đồng bộ" một cách rõ ràng để có hiệu suất tốt hơn.
Phân vùng metadata
(16 MB trở lên) là bắt buộc để lưu trữ dữ liệu liên quan đến các hình ảnh đã cài đặt. Bạn phải gắn trong quá trình gắn giai đoạn đầu tiên.
Phân vùng userdata
phải sử dụng hệ thống tệp F2FS hoặc ext4. Khi sử dụng F2FS, hãy thêm tất cả bản vá liên quan đến F2FS có trong nhân hệ điều hành Android phổ biến.
DSU được phát triển và kiểm thử bằng kernel/common 4.9. Bạn nên sử dụng nhân 4.9 trở lên cho tính năng này.
Cách hoạt động của lớp trừu tượng phần cứng (HAL) của nhà cung cấp
Weaver HAL
Weaver HAL cung cấp một số lượng khe cố định để lưu trữ khoá người dùng. DSU chiếm thêm 2 khe khoá. Nếu có HAL Weaver, nhà sản xuất thiết bị gốc (OEM) cần có đủ khe cho hình ảnh hệ thống chung (GSI) và hình ảnh máy chủ.
HAL (Lớp trừu tượng phần cứng) cho người trực điện thoại
HAL HAL (Lớp trừu tượng phần cứng) cần hỗ trợ các giá trị USER_ID
lớn, vì GSI bù cho các UID sang HAL bằng +1000000.
Xác minh quy trình khởi động
Nếu bạn muốn hỗ trợ khởi động Hình ảnh GSI dành cho nhà phát triển ở trạng thái ĐÃ KHOÁ mà không cần vô hiệu hoá tính năng khởi động đã xác minh, hãy thêm khoá GSI dành cho nhà phát triển bằng cách thêm dòng sau vào tệp device/<device_name>/device.mk
:
$(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk)
Bảo vệ chống khôi phục
Khi sử dụng DSU, hình ảnh hệ thống Android đã tải xuống phải mới hơn hình ảnh hệ thống hiện tại trên thiết bị. Bạn có thể thực hiện việc này bằng cách so sánh các cấp độ bản vá bảo mật trong phần Xác minh quy trình khởi động của Android (AVB) phần mô tả thuộc tính AVB của cả hai ảnh hệ thống: Prop: com.android.build.system.security_patch ->
'2019-04-05'
.
Đối với các thiết bị không sử dụng AVB, hãy đưa cấp bản vá bảo mật của hình ảnh hệ thống hiện tại vào lệnh cmdline nhân hệ điều hành hoặc bootconfig bằng trình tải khởi động: androidboot.system.security_patch=2019-04-05
.
Yêu cầu về phần cứng
Khi bạn khởi chạy một phiên bản DSU, hai tệp tạm thời sẽ được phân bổ:
- Một phân vùng logic để lưu trữ
GSI.img
(1~1,5 G) - Phân vùng
/data
trống 8 GB làm hộp cát để chạy GSI
Bạn nên dành ít nhất 10 GB dung lượng trống trước khi khởi chạy một thực thể DSU. DSU cũng hỗ trợ việc phân bổ từ thẻ SD. Khi có thẻ SD, thẻ này sẽ có mức độ ưu tiên cao nhất để phân bổ. Khả năng hỗ trợ thẻ SD là rất quan trọng đối với các thiết bị hiệu suất thấp hơn có thể không có đủ bộ nhớ trong. Khi có thẻ SD, hãy đảm bảo bạn chưa lắp thẻ. DSU không hỗ trợ thẻ SD được nhận dạng.
Giao diện người dùng có sẵn
Bạn có thể chạy DSU bằng adb
, một ứng dụng của Nhà sản xuất thiết bị gốc (OEM) hoặc trình tải DSU bằng một lần nhấp (trong Android 11 trở lên).
Chạy DSU bằng adb
Để chạy DSU bằng adb, hãy nhập các lệnh sau:
$ simg2img out/target/product/.../system.img system.raw
$ gzip -c system.raw > system.raw.gz
$ adb push system.raw.gz /storage/emulated/0/Download
$ adb shell am start-activity \
-n com.android.dynsystem/com.android.dynsystem.VerificationActivity \
-a android.os.image.action.START_INSTALL \
-d file:///storage/emulated/0/Download/system.raw.gz \
--el KEY_SYSTEM_SIZE $(du -b system.raw|cut -f1) \
--el KEY_USERDATA_SIZE 8589934592
Chạy DSU bằng một ứng dụng
Điểm truy cập chính đến DSU là API android.os.image.DynamicSystemClient.java
:
public class DynamicSystemClient {
...
...
/**
* Start installing DynamicSystem from URL with default userdata size.
*
* @param systemUrl A network URL or a file URL to system image.
* @param systemSize size of system image.
*/
public void start(String systemUrl, long systemSize) {
start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
}
Bạn phải đóng gói/cài đặt trước ứng dụng này trên thiết bị. Vì DynamicSystemClient
là một API hệ thống, nên bạn không thể tạo ứng dụng bằng API SDK thông thường và không thể phát hành ứng dụng đó trên Google Play. Mục đích của ứng dụng này là:
- Tìm nạp danh sách hình ảnh và URL tương ứng bằng giao thức do nhà cung cấp xác định.
- So khớp hình ảnh trong danh sách với thiết bị và hiển thị hình ảnh tương thích để người dùng chọn.
Gọi
DynamicSystemClient.start
như sau:DynamicSystemClient aot = new DynamicSystemClient(...) aot.start( ...URL of the selected image..., ...uncompressed size of the selected image...);
URL này trỏ đến một tệp hình ảnh hệ thống được nén bằng gzip, không thưa thớt. Bạn có thể tạo tệp này bằng các lệnh sau:
$ simg2img ${OUT}/system.img ${OUT}/system.raw
$ gzip ${OUT}/system.raw
$ ls ${OUT}/system.raw.gz
Tên tệp phải theo định dạng sau:
<android version>.<lunch name>.<user defined title>.raw.gz
Ví dụ:
o.aosp_taimen-userdebug.2018dev.raw.gz
p.aosp_taimen-userdebug.2018dev.raw.gz
Trình tải DSU bằng một lần nhấp
Android 11 giới thiệu trình tải DSU một lần nhấp, là một giao diện người dùng trong phần cài đặt dành cho nhà phát triển.
Hình 1. Khởi chạy trình tải DSU
Khi nhà phát triển nhấp vào nút Trình tải DSU, trình tải này sẽ tìm nạp một chỉ số mô tả JSON DSU được định cấu hình trước từ web và hiển thị tất cả hình ảnh có thể áp dụng trong trình đơn nổi. Chọn một hình ảnh để bắt đầu cài đặt DSU và tiến trình sẽ hiển thị trên thanh thông báo.
Hình 2. Tiến trình cài đặt hình ảnh DSU
Theo mặc định, trình tải DSU tải một bộ mô tả JSON có chứa hình ảnh GSI. Các phần sau đây minh hoạ cách tạo các gói DSU do OEM ký và tải các gói đó từ trình tải DSU.
Cờ tính năng
Tính năng DSU nằm trong cờ tính năng settings_dynamic_android
. Trước khi sử dụng DSU, hãy đảm bảo bạn đã bật cờ tính năng tương ứng.
Hình 3. Bật cờ tính năng
Giao diện người dùng cờ tính năng có thể không dùng được trên thiết bị đang chạy bản dựng người dùng. Trong trường hợp này, hãy sử dụng lệnh adb
:
$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1
Nhà cung cấp lưu trữ hình ảnh hệ thống trên GCE (không bắt buộc)
Một trong những vị trí lưu trữ hình ảnh hệ thống có thể là bộ chứa Google Compute Engine (GCE). Quản trị viên phát hành sử dụng bảng điều khiển bộ nhớ GCP để thêm/xoá/thay đổi hình ảnh hệ thống đã phát hành.
Hình ảnh phải có thể truy cập công khai, như minh hoạ dưới đây:
Hình 4. Quyền truy cập công khai trong GCE
Bạn có thể xem quy trình công khai một mục trong tài liệu về Google Cloud.
DSU nhiều phân vùng trong tệp ZIP
Kể từ Android 11, DSU có thể có nhiều phân vùng. Ví dụ: nó có thể chứa product.img
ngoài system.img
. Khi thiết bị khởi động, giai đoạn đầu tiên init
sẽ phát hiện các phân vùng DSU đã cài đặt và tạm thời thay thế phân vùng trên thiết bị khi DSU đã cài đặt được bật. Gói DSU có thể chứa một phân vùng không có phân vùng tương ứng trên thiết bị.
Hình 5. Quy trình DSU có nhiều phân vùng
DSU do OEM ký
Để đảm bảo tất cả hình ảnh chạy trên thiết bị đều được nhà sản xuất thiết bị uỷ quyền, tất cả hình ảnh trong gói DSU đều phải được ký. Ví dụ: giả sử có một gói DSU chứa hai hình ảnh phân vùng như bên dưới:
dsu.zip {
- system.img
- product.img
}
Cả system.img
và product.img
đều phải được ký bằng khoá OEM trước khi được đưa vào tệp ZIP. Thông thường, bạn nên sử dụng một thuật toán bất đối xứng, chẳng hạn như RSA, trong đó khoá bí mật được dùng để ký gói và khoá công khai được dùng để xác minh gói. Ổ đĩa ram giai đoạn đầu tiên phải bao gồm khoá công khai được ghép nối, ví dụ: /avb/*.avbpubkey
. Nếu thiết bị đã sử dụng AVB, thì quy trình ký hiện có là đủ. Các phần sau đây minh hoạ quy trình ký và nêu bật vị trí của khoá công khai AVB dùng để xác minh hình ảnh trong gói DSU.
Chỉ số mô tả JSON DSU
Phần mô tả JSON DSU mô tả các gói DSU. Lớp này hỗ trợ 2 dữ liệu gốc.
Trước tiên, dữ liệu gốc include
bao gồm các mã mô tả JSON bổ sung hoặc chuyển hướng trình tải DSU đến một vị trí mới. Ví dụ:
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
Tiếp theo, dữ liệu gốc image
được dùng để mô tả các gói DSU đã phát hành. Bên trong dữ liệu gốc của hình ảnh, có một số thuộc tính:
Thuộc tính
name
vàdetails
là các chuỗi xuất hiện trên hộp thoại để người dùng chọn.Các thuộc tính
cpu_api
,vndk
vàos_version
được dùng để kiểm tra khả năng tương thích như được mô tả trong phần tiếp theo.Thuộc tính
pubkey
không bắt buộc mô tả khoá công khai ghép nối với khoá bí mật dùng để ký gói DSU. Khi được chỉ định, dịch vụ DSU có thể kiểm tra xem thiết bị có khoá dùng để xác minh gói DSU hay không. Việc này giúp tránh việc cài đặt một gói DSU không nhận dạng được, chẳng hạn như cài đặt DSU do OEM-A ký cho một thiết bị do OEM-B tạo.Thuộc tính không bắt buộc
tos
trỏ đến một tệp văn bản mô tả điều khoản dịch vụ của gói DSU tương ứng. Khi nhà phát triển chọn một gói DSU có thuộc tính điều khoản dịch vụ được chỉ định, hộp thoại hiển thị trong Hình 6 sẽ mở ra, yêu cầu nhà phát triển chấp nhận điều khoản dịch vụ trước khi cài đặt gói DSU.Hình 6. Hộp thoại Điều khoản dịch vụ
Để tham khảo, dưới đây là phần mô tả JSON của DSU cho GSI:
{
"images":[
{
"name":"GSI+GMS x86",
"os_version":"10",
"cpu_abi": "x86",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
"uri":"https://.../gsi/gsi_gms_x86-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI+GMS ARM64",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
"uri":"https://.../gsi/gsi_gms_arm64-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI ARM64",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"uri":"https://.../gsi/aosp_arm64-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI x86_64",
"os_version":"10",
"cpu_abi": "x86_64",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"uri":"https://.../gsi/aosp_x86_64-exp-QP1A.190711.020.C4-5928301.zip"
}
]
}
Quản lý khả năng tương thích
Một số thuộc tính được dùng để chỉ định khả năng tương thích giữa gói DSU và thiết bị cục bộ:
cpu_api
là một chuỗi mô tả cấu trúc thiết bị. Thuộc tính này là bắt buộc và được so sánh với thuộc tính hệ thốngro.product.cpu.abi
. Các giá trị này phải khớp chính xác.os_version
là một số nguyên không bắt buộc chỉ định một bản phát hành Android. Ví dụ: đối với Android 10,os_version
là10
và đối với Android 11,os_version
là11
. Khi bạn chỉ định thuộc tính này, thuộc tính đó phải bằng hoặc lớn hơn thuộc tính hệ thốngro.system.build.version.release
. Quy trình kiểm tra này dùng để ngăn việc khởi động hình ảnh GSI của Android 10 trên thiết bị của nhà cung cấp Android 11 (hiện không được hỗ trợ). Cho phép khởi động hình ảnh GSI Android 11 trên thiết bị Android 10.vndk
là một mảng không bắt buộc chỉ định tất cả VNDK có trong gói DSU. Khi được chỉ định, trình tải DSU sẽ kiểm tra xem số được trích xuất từ thuộc tính hệ thốngro.vndk.version
có được đưa vào hay không.
Thu hồi khoá DSU để bảo mật
Trong trường hợp cực kỳ hiếm khi cặp khoá RSA dùng để ký hình ảnh DSU bị xâm phạm, bạn nên cập nhật ramdisk càng sớm càng tốt để xoá khoá bị xâm phạm. Ngoài việc cập nhật phân vùng khởi động, bạn có thể chặn các khoá bị xâm phạm bằng cách sử dụng danh sách thu hồi khoá DSU (danh sách khoá bị cấm) từ một URL HTTPS.
Danh sách thu hồi khoá DSU chứa danh sách các khoá công khai AVB đã thu hồi. Trong quá trình cài đặt DSU, các khoá công khai bên trong hình ảnh DSU sẽ được xác thực bằng danh sách thu hồi. Nếu chúng tôi phát hiện hình ảnh có chứa khoá công khai đã thu hồi, thì quá trình cài đặt DSU sẽ dừng lại.
URL danh sách thu hồi khoá phải là URL HTTPS để đảm bảo độ bảo mật và được chỉ định trong một chuỗi tài nguyên:
frameworks/base/packages/DynamicSystemInstallationService/res/values/strings.xml@key_revocation_list_url
Giá trị của chuỗi là https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json
, đây là danh sách thu hồi cho các khoá GSI do Google phát hành. Chuỗi tài nguyên này có thể được che phủ và tuỳ chỉnh để những OEM sử dụng tính năng DSU có thể cung cấp và duy trì danh sách cấm chính của riêng họ. Đây là một cách để OEM chặn một số khoá công khai nhất định mà không cần cập nhật hình ảnh ổ đĩa ram của thiết bị.
Định dạng của danh sách thu hồi là:
{
"entries":[
{
"public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
"status":"REVOKED",
"reason":"Key revocation test key"
},
{
"public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
"status":"REVOKED",
"reason":"Key revocation test key"
}
]
}
public_key
là chuỗi đại diện SHA-1 của khoá đã thu hồi, ở định dạng được mô tả trong phần tạo khoá xuất bản AVB.status
cho biết trạng thái thu hồi của khoá. Hiện tại, giá trị duy nhất được hỗ trợ làREVOKED
.reason
là một chuỗi không bắt buộc mô tả lý do thu hồi.
Quy trình DSU
Phần này mô tả cách thực hiện một số quy trình cấu hình DSU.
Tạo một cặp khoá mới
Sử dụng lệnh openssl
để tạo cặp khoá riêng tư/công khai RSA ở định dạng .pem
(ví dụ: có kích thước 2048 bit):
$ openssl genrsa -out oem_cert_pri.pem 2048
$ openssl rsa -in oem_cert_pri.pem -pubout -out oem_cert_pub.pem
Bạn có thể không truy cập được khoá riêng tư và khoá này chỉ được lưu trữ trong một mô-đun bảo mật phần cứng (HSM). Trong trường hợp này, có thể có chứng chỉ khoá công khai x509 sau khi tạo khoá. Hãy xem phần Thêm khoá công khai ghép nối vào ramdisk để biết hướng dẫn tạo khoá công khai AVB từ chứng chỉ x509.
Cách chuyển đổi chứng chỉ x509 sang định dạng PEM:
$ openssl x509 -pubkey -noout -in oem_cert_pub.x509.pem > oem_cert_pub.pem
Bỏ qua bước này nếu chứng chỉ đã là tệp PEM.
Thêm mã pubkey ghép nối vào ổ đĩa RAM
Bạn phải đặt oem_cert.avbpubkey
trong /avb/*.avbpubkey
để xác minh gói DSU đã ký. Trước tiên, hãy chuyển đổi khoá công khai ở định dạng PEM sang định dạng khoá công khai AVB:
$ avbtool extract_public_key --key oem_cert_pub.pem --output oem_cert.avbpubkey
Sau đó, hãy đưa khoá công khai vào ramdisk giai đoạn đầu bằng các bước sau.
Thêm một mô-đun tạo sẵn để sao chép
avbpubkey
. Ví dụ: thêmdevice/<company>/<board>/oem_cert.avbpubkey
vàdevice/<company>/<board>/avb/Android.mk
với nội dung như sau:include $(CLEAR_VARS) LOCAL_MODULE := oem_cert.avbpubkey LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := $(LOCAL_MODULE) ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true) LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb else LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb endif include $(BUILD_PREBUILT)
Làm cho mục tiêu droidcore phụ thuộc vào
oem_cert.avbpubkey
đã thêm:droidcore: oem_cert.avbpubkey
Tạo thuộc tính AVB pubkey trong phần mô tả JSON
oem_cert.avbpubkey
ở định dạng nhị phân khoá công khai AVB. Sử dụng SHA-1 để giúp mã này có thể đọc được trước khi đưa vào chỉ số mô tả JSON:
$ sha1sum oem_cert.avbpubkey | cut -f1 -d ' '
3e62f2be9d9d813ef5........866ac72a51fd20
Đây sẽ là nội dung của thuộc tính pubkey
của phần mô tả JSON.
"images":[
{
...
"pubkey":"3e62f2be9d9d813ef5........866ac72a51fd20",
...
},
Ký gói DSU
Sử dụng một trong các phương thức sau để ký gói DSU:
Phương pháp 1: Sử dụng lại cấu phần phần mềm do quy trình ký AVB ban đầu tạo để tạo gói DSU. Một cách khác là trích xuất hình ảnh đã ký từ gói phát hành và sử dụng hình ảnh đã trích xuất để trực tiếp tạo tệp ZIP.
Phương thức 2: Sử dụng các lệnh sau để ký các phân vùng DSU nếu có khoá riêng tư. Mỗi
img
trong gói DSU (tệp ZIP) được ký riêng:$ key_len=$(openssl rsa -in oem_cert_pri.pem -text | grep Private-Key | sed -e 's/.*(\(.*\) bit.*/\1/') $ for partition in system product; do avbtool add_hashtree_footer \ --image ${OUT}/${partition}.img \ --partition_name ${partition} \ --algorithm SHA256_RSA${key_len} \ --key oem_cert_pri.pem done
Để biết thêm thông tin về cách thêm add_hashtree_footer
bằng avbtool
, hãy xem phần Sử dụng avbtool.
Xác minh gói DSU trên thiết bị
Bạn nên xác minh tất cả hình ảnh cục bộ dựa trên khoá công khai ghép nối bằng các lệnh sau:
for partition in system product; do
avbtool verify_image --image ${OUT}/${partition}.img --key oem_cert_pub.pem
done
Kết quả đầu ra dự kiến sẽ có dạng như sau:
Verifying image dsu/system.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/system.img
: Successfully verified sha1 hashtree of dsu/system.img for image of 898494464 bytes
Verifying image dsu/product.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/product.img
: Successfully verified sha1 hashtree of dsu/product.img for image of 905830400 bytes
Tạo một gói DSU
Ví dụ sau đây tạo một gói DSU chứa system.img
và product.img
:
dsu.zip {
- system.img
- product.img
}
Sau khi cả hai hình ảnh đã được ký, hãy sử dụng lệnh sau để tạo tệp ZIP:
$ mkdir -p dsu
$ cp ${OUT}/system.img dsu
$ cp ${OUT}/product.img dsu
$ cd dsu && zip ../dsu.zip *.img && cd -
Tuỳ chỉnh DSU một lần nhấp
Theo mặc định, trình tải DSU trỏ đến siêu dữ liệu của hình ảnh GSI là https://...google.com/.../gsi-src.json
.
OEM có thể ghi đè danh sách bằng cách xác định thuộc tính persist.sys.fflag.override.settings_dynamic_system.list
trỏ đến chỉ số mô tả JSON của riêng họ. Ví dụ: OEM có thể cung cấp siêu dữ liệu JSON bao gồm GSI cũng như hình ảnh thuộc quyền sở hữu riêng của OEM như sau:
{
"include": ["https://dl.google.com/.../gsi-src.JSON"]
"images":[
{
"name":"OEM image",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"...",
"vndk":[
27,
28,
29
],
"spl":"...",
"pubkey":"",
"uri":"https://.../....zip"
},
}
Nhà sản xuất thiết bị gốc (OEM) có thể tạo chuỗi siêu dữ liệu DSU đã xuất bản như trong Hình 7.
Hình 7. Tạo chuỗi siêu dữ liệu DSU đã xuất bản