Halaman ini menjelaskan perubahan yang ditambahkan ke AOSP untuk mengurangi perubahan file yang tidak perlu antar build. Implementer perangkat yang memelihara sistem build mereka sendiri dapat menggunakan informasi ini sebagai panduan untuk mengurangi ukuran update over-the-air (OTA) mereka.
Pembaruan Android OTA terkadang berisi file yang diubah yang tidak sesuai dengan perubahan kode. Mereka benar-benar membangun artefak sistem. 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 seperti itu meningkatkan ukuran tambalan OTA, dan membuatnya sulit untuk menentukan 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 terkandung dalam pembaruan OTA. AOSP juga menyertakan alat diff build , yang menyaring perubahan file terkait build umum 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 besar yang tidak perlu dalam beberapa cara. Untuk mengurangi hal ini, di Android 8.0 dan yang lebih tinggi, fitur baru diterapkan untuk mengurangi ukuran patch untuk setiap perbedaan file. Perbaikan yang mengurangi ukuran paket pembaruan OTA meliputi:
- Penggunaan Brotli , algoritme kompresi lossless tujuan umum untuk gambar penuh pada pembaruan perangkat non-A/B. Brotli dapat disesuaikan untuk mengoptimalkan kompresi. Pada pembaruan yang lebih besar yang terdiri dari dua atau lebih blok dalam sistem file (misalnya,
system.img
), produsen perangkat atau mitra dapat menambahkan algoritme kompresi mereka sendiri, dan dapat menggunakan algoritme kompresi yang berbeda pada blok yang berbeda dari pembaruan yang sama. - Penggunaan kompresi ulang Puffin , alat tambalan deterministik untuk mengempiskan aliran, yang menangani fungsi kompresi dan perbedaan untuk pembuatan pembaruan OTA A/B.
- Perubahan penggunaan alat generasi delta, seperti bagaimana perpustakaan
bsdiff
digunakan untuk mengompresi patch. Di Android 9 dan yang lebih tinggi, alatbsdiff
memilih algoritme kompresi yang akan memberikan hasil kompresi terbaik untuk tambalan. - Penyempurnaan pada
update_engine
menghasilkan lebih sedikit memori yang digunakan saat patch diterapkan untuk pembaruan perangkat A/B. - Perbaikan untuk memisahkan file zip besar untuk pembaruan OTA berbasis blok. Mode di
imgdiff
membagi file APK berukuran besar, berdasarkan nama entri. Ini menghasilkan tambalan yang lebih kecil dibandingkan dengan memisahkan file secara linier dan menggunakan alatbsdiff
untuk mengompresnya.
Bagian berikut membahas berbagai masalah yang memengaruhi ukuran pembaruan OTA, solusinya, dan contoh penerapan di AOSP.
Urutan berkas
Masalah : Sistem file tidak menjamin urutan file ketika diminta untuk daftar file dalam direktori, meskipun umumnya 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 output.
Solusi : Saat Anda menggunakan alat seperti find
and 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 diperbaiki dalam 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 binari berbeda. Sebagian besar jalur di Android build adalah jalur relatif sehingga __FILE__
di C/C++ tidak menjadi masalah. Namun, simbol debug mengkodekan nama path lengkap secara default, dan .note.gnu.build-id
dihasilkan dari hashing biner yang telah dilucuti, 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 dalam output build menghasilkan perubahan file yang tidak perlu. Ini mungkin terjadi di lokasi berikut:
-
__DATE__/__TIME__/__TIMESTAMP__
makro dalam kode C atau C++. - Stempel waktu tertanam dalam arsip berbasis zip.
Solusi/Contoh: Untuk menghapus stempel waktu dari output build, gunakan instruksi yang diberikan di bawah ini pada __DATE__/__TIME__/__TIMESTAMP__ di C/C++. dan cap waktu Tertanam dalam arsip .
__DATE__/__TIME__/__TIMESTAMP__ dalam C/C++
Makro ini selalu menghasilkan output yang berbeda untuk build yang berbeda, jadi jangan menggunakannya. Berikut adalah beberapa opsi untuk menghilangkan makro ini:
- Hapus mereka. Sebagai 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 tambahan, yang mungkin tidak memperbarui tanggal ini). Sebagai contoh, lihat https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84 .
Stempel waktu yang disematkan dalam arsip (zip, jar)
Android 7.0 memperbaiki masalah cap waktu yang disematkan di arsip zip dengan menambahkan -X
ke semua penggunaan perintah zip
. Ini menghapus UID/GID dari builder dan stempel waktu Unix yang diperpanjang dari file zip.
Alat baru, ziptime
(terletak di /platform/build/+/master/tools/ziptime/
) mengatur ulang cap waktu normal di header zip. Untuk detailnya, lihat file README .
Alat signapk
menyetel stempel waktu untuk file APK yang dapat 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 lain dalam APK, akibatnya, APK akan tetap berbeda.
Solusi: Hapus nomor build dari string versi APK.
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 perhitungan kebenaran di perangkat
Jika dm-verity diaktifkan di perangkat Anda, maka alat OTA secara otomatis mengambil konfigurasi verity Anda, dan mengaktifkan penghitungan verity di perangkat. Ini memungkinkan blok verity untuk 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 di perangkat bisa memakan waktu lama. Secara khusus, kode koreksi Kesalahan Teruskan dapat memakan waktu lama. Pada perangkat piksel, prosesnya cenderung memakan waktu hingga 10 menit. Pada perangkat kelas bawah, ini bisa memakan waktu lebih lama. Jika Anda ingin menonaktifkan perhitungan verity pada perangkat, tetapi masih mengaktifkan dm-verity, Anda dapat melakukannya dengan meneruskan --disable_fec_computation
ke alat ota_from_target_files
saat membuat pembaruan OTA. Bendera ini menonaktifkan perhitungan kebenaran pada perangkat selama pembaruan OTA. Ini mengurangi waktu instalasi OTA, tetapi meningkatkan ukuran paket OTA. Jika perangkat Anda tidak mengaktifkan dm-verity, meneruskan tanda ini tidak akan berpengaruh.
Alat pembuatan yang konsisten
Masalah: Alat yang menghasilkan file yang diinstal harus konsisten (input yang diberikan harus selalu menghasilkan output yang sama).
Solusi/Contoh: Perubahan diperlukan pada alat pembangunan 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 Kompilator Android Java (Jack) . Toolchain Jack memerlukan pembaruan untuk menangani perubahan sesekali dalam pemesanan konstruktor yang dihasilkan. Aksesor 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 aplikasi pra-dexopt'd (.odex) . File pra-dexopt'd (.odex) berisi padding yang tidak diinisialisasi pada sistem 64-bit. Ini diperbaiki: https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029 .
Menggunakan 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 terkait build umum, seperti:
- Perubahan yang diharapkan dalam output build (misalnya, karena perubahan nomor build).
- Perubahan karena masalah yang diketahui 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 diekstraksi untuk setiap build.
Menjaga alokasi blok tetap konsisten
Untuk file tertentu, meskipun isinya tetap sama di 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 OTA A/B Virtual, I/O yang tidak perlu dapat sangat 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 pergerakan 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 gambar 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 diperiksa 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 ini tidak membantu mengurangi ukuran paket OTA secara keseluruhan, ini meningkatkan kinerja pembaruan OTA dengan mengurangi jumlah I/O. Untuk pembaruan A/B Virtual, 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 dapat 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 versi yang lebih baru, yang diterima langsung dari toko aplikasi.