Mengurangi ukuran OTA

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 sebagai PRODUCT_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, alat bsdiff 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:

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:

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:

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:

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.