Halaman ini menjelaskan perubahan yang ditambahkan ke AOSP untuk mengurangi perubahan file yang tidak perlu di antara build. Implementator perangkat yang mengelola sistem build mereka sendiri dapat menggunakan informasi ini sebagai panduan untuk mengurangi ukuran update over-the-air (OTA).
Update OTA Android terkadang berisi file yang diubah yang tidak sesuai dengan perubahan kode. Mereka sebenarnya membuat artefak sistem. Hal ini dapat terjadi jika kode yang sama, yang di-build pada waktu yang berbeda, dari direktori yang berbeda, atau di komputer yang berbeda menghasilkan sejumlah besar file yang diubah. File berlebih tersebut akan meningkatkan ukuran patch OTA, dan mempersulit untuk menentukan kode mana yang berubah.
Untuk membuat konten OTA lebih transparan, AOSP menyertakan perubahan sistem build yang dirancang untuk mengurangi ukuran patch OTA. Perubahan file yang tidak perlu di antara build telah dihapus, dan hanya file terkait patch yang terdapat dalam update OTA. AOSP juga menyertakan alat build diff, yang memfilter perubahan file terkait build umum untuk memberikan diff file build yang lebih bersih, dan alat pemetaan blok, yang membantu Anda menjaga alokasi blok tetap konsisten.
Sistem build dapat membuat patch yang tidak perlu besar dengan beberapa cara. Untuk mengurangi hal ini, di Android 8.0 dan yang lebih baru, fitur baru diterapkan untuk mengurangi ukuran patch untuk setiap perbedaan file. Peningkatan yang mengurangi ukuran paket update OTA mencakup hal berikut:
-
Penggunaan ZSTD, algoritma kompresi lossless tujuan umum untuk image
lengkap pada update perangkat non-A/B. ZSTD dapat disesuaikan untuk rasio kompresi
yang lebih tinggi dengan meningkatkan tingkat kompresi. Tingkat kompresi ditetapkan selama waktu
pembuatan OTA dan dapat ditetapkan dengan meneruskan flag
--vabc_compression_param=zstd,$COMPRESSION_LEVEL
-
Meningkatkan ukuran periode kompresi yang digunakan selama OTA. Ukuran jendela kompresi maksimum
dapat ditetapkan dengan menyesuaikan parameter build dalam file
.mk
perangkat. Variabel ini ditetapkan sebagaiPRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
- Penggunaan kompresi ulang Puffin, alat patching deterministik untuk streaming deflate, yang menangani fungsi kompresi dan perbedaan untuk pembuatan update OTA A/B.
-
Perubahan pada penggunaan alat pembuatan delta, seperti cara
library
bsdiff
digunakan untuk mengompresi patch. Di Android 9 dan yang lebih baru, alatbsdiff
memilih algoritma kompresi yang akan memberikan hasil kompresi terbaik untuk patch. -
Peningkatan pada
update_engine
menghasilkan lebih sedikit memori yang digunakan saat patch diterapkan untuk update perangkat A/B.
Bagian berikut membahas berbagai masalah yang memengaruhi ukuran update OTA, solusinya, dan contoh penerapan di AOSP.
Urutan file
Masalah: Sistem file tidak menjamin urutan file saat diminta untuk membuat daftar
file dalam direktori, meskipun biasanya sama untuk checkout yang sama. Alat seperti
ls
mengurutkan hasil secara default, tetapi fungsi karakter pengganti yang digunakan oleh perintah seperti
find
dan make
tidak mengurutkan. Sebelum menggunakan alat ini, Anda harus mengurutkan
output.
Solusi: Saat Anda menggunakan alat seperti find
dan
make
dengan fungsi karakter pengganti, urutkan output perintah ini sebelum menggunakannya. Saat menggunakan $(wildcard)
atau $(shell find)
dalam
file Android.mk
, urutkan juga. Beberapa alat, seperti Java, memang mengurutkan input, jadi
sebelum mengurutkan file, pastikan alat yang Anda gunakan belum melakukannya.
Contoh: Banyak instance diperbaiki dalam sistem build inti menggunakan
makro all-*-files-under
bawaan, yang mencakup
all-cpp-files-under
(karena beberapa definisi tersebar di file make lainnya).
Untuk mengetahui detailnya, lihat hal berikut:
- https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f
- https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410
- https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653
- https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c
Direktori build
Masalah: Mengubah direktori tempat hal-hal dibuat dapat menyebabkan
biner menjadi berbeda. Sebagian besar jalur dalam build Android adalah jalur relatif sehingga
__FILE__
di C/C++ tidak menjadi masalah. Namun, simbol debug mengenkode nama
jalur lengkap secara default, dan .note.gnu.build-id
dihasilkan dari hashing
biner yang telah dihapus sebelumnya, sehingga akan berubah jika simbol debug berubah.
Solusi: AOSP kini membuat jalur debug menjadi relatif. Untuk mengetahui detailnya, lihat CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.
Stempel waktu
Masalah: Stempel waktu dalam output build menyebabkan perubahan file yang tidak perlu. Hal ini kemungkinan terjadi di lokasi berikut:
- Makro
__DATE__/__TIME__/__TIMESTAMP__
dalam kode C atau C++. - Stempel waktu yang disematkan dalam arsip berbasis zip.
Solusi/Contoh: Untuk menghapus stempel waktu dari output build, gunakan petunjuk yang diberikan di bawah ini dalam __DATE__/__TIME__/__TIMESTAMP__ di C/C++. dan Stempel waktu tersemat dalam arsip.
__DATE__/__TIME__/__TIMESTAMP__ di C/C++
Makro ini selalu menghasilkan output yang berbeda untuk build yang berbeda, jadi jangan gunakan makro ini. Berikut beberapa opsi untuk menghilangkan makro ini:
- Hapusnya. Untuk contoh, lihat https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f.
- Untuk mengidentifikasi biner yang berjalan secara unik, baca build-id dari header ELF.
-
Untuk mengetahui kapan OS dibuat, baca
ro.build.date
(ini berfungsi untuk semuanya kecuali build inkremental, yang mungkin tidak memperbarui tanggal ini). Untuk contoh, lihat https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84.
Stempel waktu tersemat dalam arsip (zip, jar)
Android 7.0 memperbaiki masalah stempel waktu tersemat dalam arsip zip dengan menambahkan
-X
ke semua penggunaan perintah zip
. Tindakan ini akan menghapus UID/GID
builder dan stempel waktu Unix yang diperluas dari file zip.
Alat baru, ziptime
(terletak di
/platform/build/+/android16-release/tools/ziptime/
) mereset stempel waktu normal di header zip. Untuk mengetahui detailnya, lihat
file README.
Alat signapk
menetapkan stempel waktu untuk file APK yang dapat bervariasi bergantung pada
zona waktu server. Untuk mengetahui detailnya, lihat CL
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.
Alat signapk
menetapkan stempel waktu untuk file APK yang dapat bervariasi bergantung pada
zona waktu server. Untuk mengetahui detailnya, lihat CL
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.
String versi
Masalah: String versi APK sering kali memiliki BUILD_NUMBER
yang ditambahkan
ke versi hardcode-nya. Meskipun tidak ada yang berubah dalam APK, sebagai hasilnya, APK
akan tetap berbeda.
Solusi: Hapus nomor build dari string versi APK.
Contoh:
- https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27
- https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c
Mengaktifkan komputasi verifikasi di perangkat
Jika dm-verity diaktifkan di perangkat Anda, alat OTA akan otomatis mengambil konfigurasi verity Anda, dan mengaktifkan komputasi verity di perangkat. Hal ini memungkinkan blok verity dihitung di perangkat Android, bukan disimpan sebagai byte mentah dalam paket OTA Anda. Blok Verity dapat menggunakan sekitar 16 MB untuk partisi 2 GB.
Namun, komputasi kebenaran di perangkat dapat memerlukan waktu yang lama. Secara khusus, kode Pengkoreksi
Error Maju dapat memerlukan waktu yang lama. Di perangkat Pixel, proses ini cenderung memerlukan waktu hingga 10
menit. Di perangkat kelas bawah, proses ini dapat memerlukan waktu lebih lama. Jika ingin menonaktifkan komputasi verity
di perangkat, tetapi tetap mengaktifkan dm-verity, Anda dapat melakukannya dengan meneruskan
--disable_fec_computation
ke alat ota_from_target_files
saat
membuat update OTA. Flag ini menonaktifkan komputasi verifikasi di perangkat selama update OTA.
Hal ini akan mengurangi waktu penginstalan OTA, tetapi meningkatkan ukuran paket OTA. Jika perangkat Anda tidak
mengaktifkan dm-verity, meneruskan tanda ini tidak akan berpengaruh.
Alat build yang konsisten
Masalah: Alat yang menghasilkan file yang diinstal harus konsisten (input tertentu harus selalu menghasilkan output yang sama).
Solusi/Contoh: Perubahan diperlukan pada alat build berikut:
- Pembuat file PEMBERITAHUAN. Pembuat file NOTICE diubah untuk membuat koleksi NOTICE yang dapat direproduksi. Lihat CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64.
- Java Android Compiler Kit (Jack). Toolchain Jack memerlukan update untuk menangani perubahan sesekali dalam pengurutan konstruktor yang dihasilkan. Pengakses deterministik untuk konstruktor ditambahkan ke toolchain: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b.
- Kompiler AOT ART (dex2oat). Biner compiler ART menerima update yang menambahkan opsi untuk membuat image deterministik: https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9.
-
File libpac.so (V8). Setiap build membuat file
/system/lib/libpac.so
yang berbeda karena snapshot V8 berubah untuk setiap build. Solusinya adalah menghapus snapshot: https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29. - File pra-dexopt (.odex) aplikasi. File pra-dexopt (.odex) berisi padding yang tidak diinisialisasi pada sistem 64-bit. Hal ini telah diperbaiki: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029.
Menggunakan alat build diff
Untuk kasus saat tidak dapat menghilangkan perubahan file terkait build, AOSP menyertakan
alat build diff,
target_files_diff.py
untuk digunakan dalam membandingkan dua paket file. Alat ini melakukan diff rekursif antara dua
build, yang mengecualikan perubahan file terkait build umum, seperti
- Perubahan yang diharapkan dalam output build (misalnya, karena perubahan nomor build).
- Perubahan karena masalah umum dalam sistem build saat ini.
Untuk menggunakan alat build diff, jalankan perintah berikut:
target_files_diff.py dir1 dir2
dir1
dan dir2
adalah direktori dasar yang berisi file target
yang diekstrak untuk setiap build.
Menjaga konsistensi alokasi blok
Untuk file tertentu, meskipun kontennya tetap sama di antara dua build, blok sebenarnya yang menyimpan data mungkin telah berubah. Akibatnya, updater harus melakukan I/O yang tidak perlu untuk memindahkan blok untuk update OTA.
Dalam update OTA A/B Virtual, I/O yang tidak perlu dapat sangat meningkatkan ruang penyimpanan yang diperlukan untuk menyimpan snapshot copy-on-write. Dalam update OTA non-A/B, memindahkan blok untuk update OTA berkontribusi pada waktu update karena ada lebih banyak I/O karena pemindahan blok.
Untuk mengatasi masalah ini, di Android 7.0, Google memperluas alat make_ext4fs
untuk
menjaga alokasi blok tetap konsisten di seluruh build. Alat make_ext4fs
menerima
flag -d base_fs
opsional yang mencoba mengalokasikan file ke blok yang sama
saat membuat image ext4
. Anda dapat mengekstrak file pemetaan blok (seperti
file peta base_fs
) dari file ZIP file target build sebelumnya. Untuk setiap
partisi ext4
, ada file .map
di
direktori IMAGES
(misalnya, IMAGES/system.map
sesuai dengan
partisi system
). File base_fs
ini kemudian dapat di-check-in dan
ditentukan melalui PRODUCT_<partition>_BASE_FS_PATH
, seperti dalam contoh ini:
PRODUCT_SYSTEM_BASE_FS_PATH := path/to/base_fs_files/base_system.map PRODUCT_SYSTEM_EXT_BASE_FS_PATH := path/to/base_fs_files/base_system_ext.map PRODUCT_VENDOR_BASE_FS_PATH := path/to/base_fs_files/base_vendor.map PRODUCT_PRODUCT_BASE_FS_PATH := path/to/base_fs_files/base_product.map PRODUCT_ODM_BASE_FS_PATH := path/to/base_fs_files/base_odm.map
Meskipun tidak membantu mengurangi ukuran paket OTA secara keseluruhan, hal ini meningkatkan performa update OTA dengan mengurangi jumlah I/O. Untuk update Virtual A/B, update ini secara drastis mengurangi jumlah ruang penyimpanan yang diperlukan untuk menerapkan OTA.
Menghindari update aplikasi
Selain meminimalkan perbedaan build, Anda dapat mengurangi ukuran update OTA dengan mengecualikan update untuk aplikasi yang mendapatkan update melalui app store. APK sering kali terdiri dari sebagian besar berbagai partisi di perangkat. Menyertakan aplikasi versi terbaru yang diupdate oleh app store dalam update OTA dapat berdampak besar pada ukuran paket OTA, dan memberikan sedikit manfaat bagi pengguna. Pada saat pengguna menerima paket OTA, mereka mungkin sudah memiliki aplikasi yang diupdate, atau versi yang lebih baru, yang diterima langsung dari app store.