Apakah Google telah menggunakan OTA A/B di perangkat apa pun?
Ya. Nama pemasaran untuk update A/B adalah update yang lancar. Ponsel Pixel dan Pixel XL
dari Oktober 2016 dikirimkan dengan A/B, dan semua Chromebook menggunakan
implementasi update_engine
A/B yang sama. Implementasi kode platform yang diperlukan bersifat publik di Android 7.1 dan
yang lebih tinggi.
Mengapa OTA A/B lebih baik?
OTA A/B memberikan pengalaman pengguna yang lebih baik saat melakukan update. Pengukuran dari update keamanan bulanan menunjukkan bahwa fitur ini telah terbukti berhasil: Mulai Mei 2017, 95% pemilik Pixel menjalankan update keamanan terbaru setelah satu bulan dibandingkan dengan 87% pengguna Nexus, dan pengguna Pixel mengupdate lebih cepat daripada pengguna Nexus. Kegagalan untuk mengupdate blok selama OTA tidak lagi menyebabkan perangkat tidak dapat melakukan booting; hingga image sistem baru berhasil melakukan booting, Android mempertahankan kemampuan untuk kembali ke image sistem yang berfungsi sebelumnya.
Apa yang dimaksud dengan system_other?
Aplikasi disimpan dalam file .apk, yang sebenarnya adalah arsip ZIP. Setiap file .apk memiliki satu atau beberapa file .dex di dalamnya yang berisi bytecode Dalvik portabel. File .odex (.dex yang dioptimalkan) berada secara terpisah dari file .apk dan dapat berisi kode mesin khusus untuk perangkat. Jika file .odex tersedia, Android dapat menjalankan aplikasi dengan kecepatan kompilasi sebelumnya tanpa harus menunggu kode dikompilasi setiap kali aplikasi diluncurkan. File .odex tidak mutlak diperlukan: Android sebenarnya dapat menjalankan kode .dex secara langsung melalui interpretasi atau kompilasi Just-In-Time (JIT), tetapi file .odex memberikan kombinasi kecepatan peluncuran dan kecepatan runtime terbaik jika ruang tersedia.
Contoh: Untuk installed-files.txt dari Nexus 6P yang menjalankan Android 7.1 dengan total ukuran image sistem 2628 MiB (2755792836 byte), pengelompokan kontributor terbesar untuk keseluruhan ukuran image sistem menurut jenis file adalah sebagai berikut:
.odex | 1391770312 byte | 50,5% |
.apk | 846878259 byte | 30,7% |
.so (kode C/C++ native) | 202162479 byte | 7,3% |
File .oat/gambar .art | 163892188 byte | 5,9% |
Font | 38952361 byte | 1,4% |
Data lokalitas icu | 27468687 byte | 0,9% |
Angka ini juga serupa untuk perangkat lain, sehingga pada perangkat Nexus/Pixel, file .odex memerlukan
sekitar setengah partisi sistem. Artinya, kita dapat terus menggunakan ext4, tetapi menulis
file .odex ke partisi B di pabrik, lalu menyalinnya ke /data
saat
booting pertama. Penyimpanan sebenarnya yang digunakan dengan ext4 A/B identik dengan SquashFS A/B, karena jika
kita menggunakan SquashFS, kita akan mengirimkan file .odex yang telah dioptimalkan di system_a, bukan
system_b.
Bukankah menyalin file .odex ke /data berarti ruang yang disimpan di /system akan hilang di /data?
Kurang tepat. Di Pixel, sebagian besar ruang yang digunakan oleh file .odex adalah untuk aplikasi, yang biasanya
ada di /data
. Aplikasi ini menggunakan update Google Play, sehingga file .apk dan .odex
di image sistem tidak digunakan selama sebagian besar masa pakai perangkat. File tersebut dapat dikecualikan
sepenuhnya dan diganti dengan file .odex kecil yang berbasis profil saat pengguna benar-benar menggunakan setiap
aplikasi (sehingga tidak memerlukan ruang untuk aplikasi yang tidak digunakan pengguna). Untuk mengetahui detailnya, lihat presentasi The Evolution of Art di Google I/O 2016.
Perbandingan ini sulit dilakukan karena beberapa alasan utama:
-
Aplikasi yang diupdate oleh Google Play selalu memiliki file .odex di
/data
segera setelah menerima update pertamanya. - Aplikasi yang tidak dijalankan pengguna sama sekali tidak memerlukan file .odex.
- Kompilasi berbasis profil menghasilkan file .odex yang lebih kecil daripada kompilasi ahead-of-time (karena yang pertama hanya mengoptimalkan kode yang penting untuk performa).
Untuk mengetahui detail tentang opsi penyesuaian yang tersedia untuk OEM, lihat Mengonfigurasi ART.
Bukankah ada dua salinan file .odex di /data?
Prosesnya sedikit lebih rumit ... Setelah image sistem baru ditulis, dex2oat versi
baru dijalankan terhadap file .dex baru untuk membuat file .odex baru. Hal ini
terjadi saat sistem lama masih berjalan, sehingga file .odex lama dan baru berada di
/data
secara bersamaan.
Kode di OtaDexoptService (frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java
) memanggil getAvailableSpace
sebelum mengoptimalkan setiap paket untuk menghindari pengisian
/data
yang berlebihan. Perhatikan bahwa tersedia di sini masih konservatif: ini adalah jumlah
ruang yang tersisa sebelum mencapai nilai minimum ruang sistem yang biasa (diukur sebagai
persentase dan jumlah byte). Jadi, jika /data
penuh, tidak akan ada dua salinan
setiap file .odex. Kode yang sama juga memiliki BULK_DELETE_THRESHOLD: Jika perangkat hampir mengisi
ruang yang tersedia (seperti yang baru saja dijelaskan), file .odex milik aplikasi
yang tidak digunakan akan dihapus. Ini adalah kasus lain tanpa dua salinan setiap file .odex.
Dalam kasus terburuk saat /data
benar-benar penuh, update akan menunggu hingga
perangkat dimulai ulang ke sistem baru dan tidak lagi memerlukan file .odex sistem lama. PackageManager menangani hal ini: (frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215
). Setelah sistem baru berhasil di-booting, installd
(frameworks/native/+/main/cmds/installd/dexopt.cpp#2422
) dapat menghapus file .odex yang digunakan oleh sistem lama, sehingga mengembalikan perangkat ke
status stabil dengan hanya satu salinan.
Jadi, meskipun /data
mungkin berisi dua salinan dari semua file .odex,
(a) hal ini bersifat sementara dan (b) hanya terjadi jika Anda memiliki banyak ruang kosong di
/data
. Kecuali selama update, hanya ada satu salinan. Selain itu, sebagai bagian dari
fitur keandalan umum ART, ART tidak akan pernah mengisi /data
dengan file .odex (karena hal itu juga akan menjadi masalah pada sistem non-A/B).
Apakah semua penulisan/penyalinan ini tidak meningkatkan keausan flash?
Hanya sebagian kecil flash yang ditulis ulang: update sistem Pixel lengkap menulis sekitar 2,3 GiB. (Aplikasi juga dikompilasi ulang, tetapi hal ini juga berlaku untuk non-A/B.) Secara tradisional, OTA penuh berbasis blok menulis jumlah data yang serupa, sehingga tingkat keausan flash akan serupa.
Apakah mem-flash dua partisi sistem akan meningkatkan waktu flashing pabrik?
Tidak. Ukuran gambar sistem Pixel tidak bertambah (hanya membagi ruang di dua partisi).
Apakah menyimpan file .odex di B tidak akan memperlambat proses booting ulang setelah reset data pabrik?
Ya. Jika Anda benar-benar telah menggunakan perangkat, mengambil OTA, dan melakukan reset data pabrik, mulai ulang pertama akan lebih lambat dari biasanya (1m40d vs 40d di Pixel XL) karena
file .odex akan hilang dari B setelah OTA pertama sehingga tidak dapat disalin ke
/data
. Itulah konsekuensinya.
Reset data pabrik seharusnya merupakan operasi yang jarang dilakukan jika dibandingkan dengan booting reguler sehingga waktu yang diperlukan
tidak terlalu penting. (Hal ini tidak memengaruhi pengguna atau peninjau yang mendapatkan perangkat dari
pabrik, karena dalam hal ini partisi B tersedia.) Penggunaan compiler JIT berarti kita
tidak perlu mengompilasi ulang semuanya, jadi tidak seburuk yang Anda bayangkan. Anda juga
dapat menandai aplikasi sebagai memerlukan kompilasi terlebih dahulu menggunakan
coreApp="true"
dalam manifes: (frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23
). Hal ini saat ini digunakan oleh system_server
karena tidak diizinkan untuk JIT karena
alasan keamanan.
Apakah menyimpan file .odex di /data, bukan /system, tidak akan memperlambat proses mulai ulang setelah OTA?
Tidak. Seperti yang dijelaskan di atas, dex2oat baru dijalankan saat image sistem lama masih berjalan untuk membuat file yang akan diperlukan oleh sistem baru. Update tidak dianggap tersedia hingga pekerjaan tersebut selesai.
Dapatkah (haruskah) kami mengirimkan perangkat A/B 32 GiB? 16GiB? 8GiB?
32 GiB berfungsi dengan baik seperti yang telah dibuktikan di Pixel, dan 320 MiB dari 16 GiB berarti pengurangan sebesar 2%. Demikian pula, 320 MiB dari 8 GiB adalah pengurangan sebesar 4%. Jelas A/B bukan pilihan yang direkomendasikan di perangkat dengan 4 GiB, karena overhead 320 MiB hampir 10% dari total ruang yang tersedia.
Apakah AVB2.0 memerlukan OTA A/B?
Tidak. Booting Terverifikasi Android selalu memerlukan update berbasis blok, tetapi tidak harus update A/B.
Apakah OTA A/B memerlukan AVB2.0?
Tidak.
Apakah OTA A/B merusak perlindungan rollback AVB2.0?
Tidak. Ada beberapa kebingungan di sini karena jika sistem A/B gagal melakukan booting ke image sistem baru, sistem tersebut akan (setelah beberapa percobaan ulang yang ditentukan oleh bootloader Anda) otomatis kembali ke image sistem "sebelumnya". Namun, poin utamanya di sini adalah bahwa "sebelumnya" dalam arti A/B sebenarnya masih merupakan image sistem "saat ini". Segera setelah perangkat berhasil mem-booting image baru, perlindungan rollback akan aktif dan memastikan Anda tidak dapat kembali. Namun, hingga Anda benar-benar berhasil mem-booting image baru, perlindungan rollback tidak menganggapnya sebagai image sistem saat ini.
Jika Anda menginstal update saat sistem berjalan, bukankah itu akan memperlambat prosesnya?
Dengan update non-A/B, tujuannya adalah menginstal update secepat mungkin karena pengguna menunggu dan tidak dapat menggunakan perangkat saat update diterapkan. Dengan update A/B, hal sebaliknya berlaku; karena pengguna masih menggunakan perangkat mereka, dampak sekecil mungkin adalah sasarannya, sehingga update sengaja dibuat lambat. Melalui logika di klien update sistem Java (yang untuk Google adalah GmsCore, paket inti yang disediakan oleh GMS), Android juga mencoba memilih waktu saat pengguna tidak menggunakan perangkat mereka sama sekali. Platform ini mendukung menjeda/melanjutkan update, dan klien dapat menggunakannya untuk menjeda update jika pengguna mulai menggunakan perangkat dan melanjutkannya saat perangkat tidak ada aktivitas lagi.
Ada dua fase saat melakukan OTA, yang ditampilkan dengan jelas di UI sebagai Langkah 1 dari 2 dan Langkah 2 dari 2 di bawah status progres. Langkah 1 sesuai dengan penulisan blok data, sedangkan langkah 2 adalah pra-kompilasi file .dex. Kedua fase ini sangat berbeda dalam hal dampak performa. Fase pertama adalah I/O sederhana. Hal ini memerlukan sedikit resource (RAM, CPU, I/O) karena hanya menyalin blok secara perlahan.
Fase kedua menjalankan dex2oat untuk melakukan prakompilasi image sistem baru. Hal ini jelas memiliki batas persyaratan yang kurang jelas karena mengompilasi aplikasi yang sebenarnya. Selain itu, jelas ada lebih banyak pekerjaan yang terlibat dalam mengompilasi aplikasi besar dan kompleks daripada aplikasi kecil dan sederhana; sedangkan pada fase 1 tidak ada blok disk yang lebih besar atau lebih kompleks daripada yang lain.
Prosesnya mirip dengan saat Google Play menginstal update aplikasi di latar belakang sebelum menampilkan notifikasi 5 aplikasi diupdate, seperti yang telah dilakukan selama bertahun-tahun.
Bagaimana jika pengguna benar-benar menunggu update?
Implementasi saat ini di GmsCore tidak membedakan antara update latar belakang dan update yang dimulai pengguna, tetapi dapat melakukannya pada masa mendatang. Jika pengguna secara eksplisit meminta update untuk diinstal atau sedang melihat layar progres update, kami akan memprioritaskan pekerjaan update dengan asumsi bahwa mereka secara aktif menunggu update selesai.
Apa yang terjadi jika ada kegagalan dalam menerapkan update?
Dengan update non-A/B, jika update gagal diterapkan, pengguna biasanya akan dibiarkan dengan perangkat yang tidak dapat digunakan. Satu-satunya pengecualian adalah jika kegagalan terjadi sebelum aplikasi dimulai (misalnya, karena paket gagal diverifikasi). Dengan update A/B, kegagalan untuk menerapkan update tidak memengaruhi sistem yang sedang berjalan. Pembaruan dapat dicoba lagi nanti.