Halaman ini menjelaskan perubahan yang ditambahkan ke AOSP untuk mengurangi perubahan file yang tidak perlu antar build. Implementasi perangkat yang mengelola sistem build mereka sendiri dapat menggunakan informasi ini sebagai panduan untuk mengurangi ukuran pembaruan over-the-air (OTA).
Pembaruan OTA Android terkadang berisi file yang diubah yang tidak sesuai dengan perubahan kode. Mereka sebenarnya membangun artefak sistem. Hal ini dapat terjadi ketika kode yang sama, dibuat pada waktu yang berbeda, dari direktori yang berbeda, atau pada mesin yang berbeda menghasilkan sejumlah besar file yang diubah. File berlebih tersebut meningkatkan ukuran patch OTA, dan mempersulit penentuan kode mana yang diubah.
Untuk membuat konten OTA lebih transparan, AOSP menyertakan perubahan sistem build yang dirancang untuk mengurangi ukuran patch OTA. Perubahan file yang tidak perlu antar build telah dihilangkan, dan hanya file terkait patch yang terdapat dalam pembaruan OTA. AOSP juga menyertakan alat build diff , yang memfilter perubahan umum pada file terkait build untuk memberikan perbedaan file build yang lebih bersih, dan alat pemetaan blok , yang membantu Anda menjaga alokasi blok tetap konsisten.
Sistem build dapat membuat patch berukuran besar yang tidak perlu dengan beberapa cara. Untuk memitigasi hal ini, di Android 8.0 dan lebih tinggi, fitur baru diterapkan untuk mengurangi ukuran patch untuk setiap perbedaan file. Perbaikan yang mengurangi ukuran paket pembaruan OTA meliputi hal berikut:
- Penggunaan Brotli , algoritma kompresi lossless dengan tujuan umum untuk gambar penuh pada pembaruan perangkat non-A/B. Brotli dapat dikustomisasi untuk mengoptimalkan kompresi. Pada pembaruan yang lebih besar yang terdiri dari dua atau lebih blok dalam sistem file (misalnya,
system.img
), produsen atau mitra perangkat dapat menambahkan algoritma kompresi mereka sendiri, dan dapat menggunakan algoritma kompresi yang berbeda pada blok berbeda dari pembaruan yang sama. - Penggunaan kompresi ulang Puffin , alat patching deterministik untuk aliran deflate, yang menangani fungsi kompresi dan diff untuk pembuatan pembaruan A/B OTA.
- Perubahan pada penggunaan alat generasi delta, seperti bagaimana perpustakaan
bsdiff
digunakan untuk mengompresi patch. Di Android 9 dan lebih tinggi, alatbsdiff
memilih algoritma kompresi yang akan memberikan hasil kompresi terbaik untuk sebuah patch. - Perbaikan pada
update_engine
menghasilkan lebih sedikit memori yang dikonsumsi saat patch diterapkan untuk pembaruan perangkat A/B. - Perbaikan pada pemisahan file zip besar untuk pembaruan OTA berbasis blok. Mode di
imgdiff
membagi file APK berukuran besar, berdasarkan nama entri. Ini menghasilkan patch yang lebih kecil dibandingkan dengan memisahkan file secara linear dan menggunakan alatbsdiff
untuk mengompresnya.
Bagian berikut membahas berbagai masalah yang mempengaruhi ukuran pembaruan OTA, solusinya, dan contoh implementasi di AOSP.
Urutan berkas
Masalah : Sistem file tidak menjamin urutan file ketika dimintai daftar file dalam direktori, meskipun biasanya sama untuk checkout yang sama. Alat seperti ls
mengurutkan hasil secara default, tetapi fungsi wildcard yang digunakan oleh perintah seperti find
dan make
tidak mengurutkan. Sebelum menggunakan alat ini, Anda harus mengurutkan hasilnya.
Solusi : Saat Anda menggunakan alat seperti find
dan make
dengan fungsi wildcard, urutkan output dari perintah ini sebelum menggunakannya. Saat menggunakan $(wildcard)
atau $(shell find)
di file Android.mk
, urutkan juga. Beberapa alat, seperti Java, melakukan pengurutan input, jadi sebelum Anda mengurutkan file, pastikan alat yang Anda gunakan belum melakukannya.
Contoh: Banyak instance yang diperbaiki di sistem build inti menggunakan makro all-*-files-under
bawaan, yang mencakup all-cpp-files-under
(karena beberapa definisi tersebar di makefile lain). Untuk detailnya, lihat berikut ini:
- 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
Bangun direktori
Masalah: Mengubah direktori tempat sesuatu dibangun dapat menyebabkan binernya berbeda. Sebagian besar jalur di build Android adalah jalur relatif sehingga __FILE__
di C/C++ tidak menjadi masalah. Namun, simbol debug mengkodekan nama jalur lengkap secara default, dan .note.gnu.build-id
dihasilkan dari hashing biner yang telah dilucuti sebelumnya, sehingga akan berubah jika simbol debug berubah.
Solusi: AOSP sekarang membuat jalur debug menjadi relatif. Untuk detailnya, lihat CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02 .
Stempel waktu
Masalah: Stempel waktu pada keluaran build mengakibatkan perubahan file yang tidak perlu. Hal ini mungkin terjadi di lokasi berikut:
- Makro
__DATE__/__TIME__/__TIMESTAMP__
dalam kode C atau C++. - Stempel waktu tertanam dalam arsip berbasis zip.
Solusi/Contoh: Untuk menghapus stempel waktu dari keluaran build, gunakan instruksi yang diberikan di bawah ini di __DATE__/__TIME__/__TIMESTAMP__ di C/C++. dan Stempel waktu yang tertanam dalam arsip .
__DATE__/__TIME__/__TIMESTAMP__ dalam C/C++
Makro ini selalu menghasilkan keluaran berbeda untuk build berbeda, jadi jangan gunakan makro tersebut. Berikut beberapa opsi untuk menghilangkan makro tersebut:
- Hapus mereka. Sebagai contoh, lihat https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f .
- Untuk mengidentifikasi biner yang sedang berjalan secara unik, baca build-id dari header ELF.
- Untuk mengetahui kapan OS dibuat, baca
ro.build.date
(ini berfungsi untuk semua hal kecuali versi tambahan, yang mungkin tidak memperbarui tanggal ini). Sebagai contoh, lihat https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84 .
Stempel waktu yang tertanam dalam arsip (zip, jar)
Android 7.0 memperbaiki masalah stempel waktu yang tertanam dalam arsip zip dengan menambahkan -X
ke semua penggunaan perintah zip
. Ini menghapus UID/GID pembuat dan stempel waktu Unix yang diperluas dari file zip.
Alat baru, ziptime
(terletak di /platform/build/+/main/tools/ziptime/
) menyetel ulang stempel waktu normal di header zip. Untuk detailnya, lihat file README .
Alat signapk
menetapkan stempel waktu untuk file APK yang mungkin bervariasi tergantung pada zona waktu server. Untuk 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 hardcodenya. Meskipun tidak ada perubahan apa pun pada APK, akibatnya APK tersebut 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
Aktifkan komputasi kebenaran pada perangkat
Jika dm-verity diaktifkan pada perangkat Anda, maka alat OTA secara otomatis mengambil konfigurasi verity Anda, dan mengaktifkan komputasi verity pada perangkat. Hal ini memungkinkan blok verity dihitung pada perangkat Android, alih-alih disimpan sebagai byte mentah dalam paket OTA Anda. Blok Verity dapat menggunakan sekitar 16MB untuk partisi 2GB.
Namun, menghitung kebenaran pada perangkat dapat memakan waktu lama. Secara khusus, kode koreksi Kesalahan Teruskan dapat memakan waktu lama. Pada perangkat piksel, proses ini cenderung memerlukan waktu hingga 10 menit. Pada perangkat kelas bawah, proses ini bisa memakan waktu lebih lama. Jika Anda ingin menonaktifkan komputasi veritas pada perangkat, namun tetap mengaktifkan dm-verity, Anda dapat melakukannya dengan meneruskan --disable_fec_computation
ke alat ota_from_target_files
saat membuat pembaruan OTA. Tanda ini menonaktifkan komputasi kebenaran pada perangkat selama pembaruan OTA. Ini mengurangi waktu instalasi OTA, namun meningkatkan ukuran paket OTA. Jika perangkat Anda tidak mengaktifkan dm-verity, meneruskan tanda ini tidak akan berpengaruh.
Alat pembangunan yang konsisten
Masalah: Alat yang menghasilkan file yang terinstal harus konsisten (input yang diberikan harus selalu menghasilkan output yang sama).
Solusi/Contoh: Perubahan diperlukan pada alat build berikut:
- PEMBERITAHUAN pembuat file . Pembuat file NOTICE diubah untuk membuat koleksi NOTICE yang dapat direproduksi. Lihat CL: https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64 .
- Kit Kompiler Java Android (Jack) . Toolchain Jack memerlukan pembaruan untuk menangani perubahan sesekali dalam pemesanan konstruktor yang dihasilkan. Pengakses deterministik untuk konstruktor telah ditambahkan ke rantai alat: https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b .
- Kompiler ART AOT (dex2oat) . Biner kompiler ART menerima pembaruan yang menambahkan opsi untuk membuat gambar 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 aplikasi (.odex) . File pra-dexopt (.odex) berisi padding yang tidak diinisialisasi pada sistem 64-bit. Ini telah diperbaiki: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029 .
Gunakan alat build diff
Untuk kasus di mana tidak mungkin untuk menghilangkan perubahan file terkait build, AOSP menyertakan alat build diff, target_files_diff.py
untuk digunakan dalam membandingkan dua paket file. Alat ini melakukan perbedaan rekursif antara dua build, tidak termasuk perubahan file umum terkait build, seperti
- Perubahan yang diharapkan pada output build (misalnya, karena perubahan nomor build).
- Perubahan karena masalah umum pada 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 diekstraksi untuk setiap build.
Jaga agar alokasi blok tetap konsisten
Untuk file tertentu, meskipun isinya tetap sama antara dua build, blok sebenarnya yang menyimpan data mungkin telah berubah. Akibatnya, pembaru harus melakukan I/O yang tidak perlu untuk memindahkan blok untuk pembaruan OTA.
Dalam pembaruan Virtual A/B OTA, I/O yang tidak perlu dapat meningkatkan ruang penyimpanan yang diperlukan untuk menyimpan snapshot copy-on-write. Dalam pembaruan OTA non-A/B, memindahkan blok untuk pembaruan OTA berkontribusi pada waktu pembaruan karena ada lebih banyak I/O karena perpindahan blok.
Untuk mengatasi masalah ini, di Android 7.0 Google memperluas alat make_ext4fs
untuk menjaga konsistensi alokasi blok di seluruh build. Alat make_ext4fs
menerima flag opsional -d base_fs
yang mencoba mengalokasikan file ke blok yang sama saat membuat gambar ext4
. Anda dapat mengekstrak file pemetaan blok (seperti file peta base_fs
) dari file zip file target build sebelumnya. Untuk setiap partisi ext4
, terdapat file .map
di direktori IMAGES
(misalnya, IMAGES/system.map
sesuai dengan partisi system
). File base_fs
ini kemudian dapat didaftarkan 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 hal ini tidak membantu mengurangi ukuran paket OTA secara keseluruhan, hal ini meningkatkan kinerja pembaruan OTA dengan mengurangi jumlah I/O. Untuk pembaruan Virtual A/B, ini secara drastis mengurangi jumlah ruang penyimpanan yang diperlukan untuk menerapkan OTA.
Hindari memperbarui aplikasi
Selain meminimalkan perbedaan build, Anda dapat mengurangi ukuran pembaruan OTA dengan mengecualikan pembaruan untuk aplikasi yang mendapatkan pembaruan melalui toko aplikasi. APK sering kali merupakan bagian penting dari berbagai partisi pada perangkat. Menyertakan versi terbaru aplikasi yang diperbarui oleh toko aplikasi dalam pembaruan OTA mungkin berdampak besar pada paket OTA, dan memberikan sedikit manfaat bagi pengguna. Pada saat pengguna menerima paket OTA, mereka mungkin sudah memiliki aplikasi yang diperbarui, atau bahkan versi yang lebih baru, yang diterima langsung dari toko aplikasi.