Mengurangi ukuran OTA

Halaman ini menjelaskan perubahan yang ditambahkan ke AOSP untuk mengurangi perubahan file yang tidak perlu di antara build. Implementor perangkat yang mengelola sistem build mereka sendiri dapat menggunakan informasi ini sebagai panduan untuk mengurangi ukuran update melalui udara (OTA).

Update OTA Android terkadang berisi file yang diubah yang tidak sesuai dengan perubahan kode. Sebenarnya, ini adalah artefak sistem build. Hal ini dapat terjadi saat kode yang sama, yang dibuat pada waktu yang berbeda, dari direktori yang berbeda, atau di komputer yang berbeda menghasilkan sejumlah besar file yang diubah. File berlebih tersebut meningkatkan ukuran patch OTA, dan menyulitkan 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 dihilangkan, dan hanya file terkait patch yang disertakan dalam update OTA. AOSP juga menyertakan alat perbedaan build, yang memfilter perubahan file terkait build umum untuk memberikan perbedaan file build yang lebih bersih, dan alat pemetaan blok, yang membantu Anda menjaga konsistensi alokasi blok.

Sistem build dapat membuat patch yang terlalu besar dengan beberapa cara. Untuk mengurangi masalah ini, di Android 8.0 dan yang lebih tinggi, 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 tanpa kehilangan data untuk tujuan umum, untuk gambar 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 tanda --vabc_compression_param=zstd,$COMPRESSION_LEVEL
  • Meningkatkan ukuran jendela kompresi yang digunakan selama OTA. Ukuran jendela kompresi maksimum dapat ditetapkan dengan menyesuaikan parameter build di file .mk perangkat. Variabel ini ditetapkan sebagai PRODUCT_VIRTUAL_AB_COMPRESSION_FACTOR := 262144
  • Penggunaan rekompresi Puffin, alat patching deterministik untuk aliran deflate, yang menangani fungsi kompresi dan diff untuk pembuatan update OTA A/B.
  • Perubahan pada penggunaan alat pembuatan delta, seperti cara penggunaan library bsdiff 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 implementasi di AOSP.

Urutan file

Masalah: Sistem file tidak menjamin urutan file saat diminta untuk menampilkan 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 outputnya.

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, mengurutkan 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 mengetahui detailnya, lihat referensi berikut:

Membangun direktori

Masalah: Mengubah direktori tempat sesuatu dibangun 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 jalur file lengkap secara default, dan .note.gnu.build-id dihasilkan dari hashing biner yang telah di-strip, sehingga akan berubah jika simbol debug berubah.

Solusi: AOSP kini membuat jalur debug 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 akan 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 di __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 menghapus UID/GID builder dan stempel waktu Unix yang diperpanjang 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 yang dikodekan secara permanen. Meskipun tidak ada perubahan lain dalam APK, sebagai akibatnya, APK akan tetap berbeda.

Solusi: Hapus nomor build dari string versi APK.

Contoh:

Mengaktifkan komputasi veritas di perangkat

Jika dm-verity diaktifkan di perangkat Anda, alat OTA akan otomatis mengambil konfigurasi verifikasi Anda, dan mengaktifkan komputasi verifikasi di perangkat. Hal ini memungkinkan blok verity dihitung di perangkat Android, bukan disimpan sebagai byte mentah dalam paket OTA Anda. Blok verifikasi dapat menggunakan sekitar 16 MB untuk partisi 2 GB.

Namun, menghitung verity di perangkat dapat memakan waktu lama. Secara khusus, kode Koreksi error Penerusan dapat memakan waktu yang lama. Di perangkat Pixel, biasanya perlu waktu hingga 10 menit. Di perangkat kelas bawah, proses ini dapat memerlukan waktu lebih lama. Jika Anda ingin menonaktifkan komputasi verifikasi 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. Tanda ini menonaktifkan komputasi veritas di perangkat selama update OTA. Hal ini mengurangi waktu penginstalan OTA, tetapi meningkatkan ukuran paket OTA. Jika dm-verity tidak diaktifkan di perangkat Anda, meneruskan tanda ini tidak akan berpengaruh.

Alat build yang konsisten

Masalah: Alat yang menghasilkan file terinstal harus konsisten (input tertentu harus selalu menghasilkan output yang sama).

Solusi/Contoh: Perubahan diperlukan dalam alat build berikut:

Menggunakan alat perbedaan build

Untuk kasus yang tidak memungkinkan penghapusan perubahan file terkait build, AOSP menyertakan alat perbedaan build, target_files_diff.py untuk digunakan dalam membandingkan dua paket file. Alat ini melakukan diff 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 umum dalam sistem build saat ini.

Untuk menggunakan alat perbedaan build, 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 isinya 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-blok tersebut untuk update OTA.

Dalam update OTA A/B Virtual, I/O yang tidak perlu dapat meningkatkan ruang penyimpanan yang diperlukan secara signifikan 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 akibat pemindahan blok.

Untuk mengatasi masalah ini, di Android 7.0, Google memperluas alat make_ext4fs untuk mempertahankan konsistensi alokasi blok 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 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 A/B Virtual, ruang penyimpanan yang diperlukan untuk menerapkan OTA akan berkurang secara drastis.

Menghindari mengupdate aplikasi

Selain meminimalkan perbedaan build, Anda dapat mengurangi ukuran update OTA dengan mengecualikan update untuk aplikasi yang mendapatkan update melalui toko aplikasi. APK sering kali terdiri dari sebagian besar berbagai partisi di perangkat. Menyertakan versi terbaru aplikasi 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.