Caching APK

Dokumen ini menjelaskan desain solusi cache APK untuk penginstalan cepat aplikasi yang dimuat sebelumnya pada perangkat yang mendukung partisi A/B.

OEM dapat menempatkan pramuat dan aplikasi populer di cache APK yang disimpan di sebagian besar partisi B yang kosong pada perangkat yang dipartisi A/B baru tanpa memengaruhi ruang data yang dihadapi pengguna. Dengan memiliki cache APK yang tersedia di perangkat, perangkat baru atau yang baru saja disetel ulang ke setelan pabrik siap digunakan segera, tanpa perlu mengunduh file APK dari Google Play.

Gunakan kasus

  • Simpan aplikasi yang dimuat sebelumnya di partisi B untuk pengaturan yang lebih cepat
  • Simpan aplikasi populer di partisi B untuk pemulihan lebih cepat

Prasyarat

Untuk menggunakan fitur ini, perangkat membutuhkan:

  • Android 8.1 (O MR1) rilis diinstal
  • Partisi A/B diimplementasikan

Konten yang dimuat sebelumnya hanya dapat disalin selama boot pertama. Ini karena pada perangkat yang mendukung pembaruan sistem A/B, partisi B sebenarnya tidak menyimpan file gambar sistem, melainkan konten yang dimuat sebelumnya seperti sumber daya demo ritel, file OAT, dan cache APK. Setelah sumber daya disalin ke partisi /data (ini terjadi pada boot pertama), partisi B akan digunakan oleh pembaruan over-the-air (OTA) untuk mengunduh versi terbaru dari citra sistem.

Oleh karena itu, cache APK tidak dapat diperbarui melalui OTA; itu hanya dapat dimuat sebelumnya di pabrik. Reset pabrik hanya memengaruhi partisi /data. Partisi sistem B masih memiliki konten yang dimuat sebelumnya hingga gambar OTA diunduh. Setelah reset pabrik, sistem akan melalui boot pertama lagi. Ini berarti cache APK tidak tersedia jika gambar OTA diunduh ke partisi B, dan kemudian perangkat dikembalikan ke setelan pabrik.

Penerapan

Pendekatan 1. Konten pada partisi system_other

Pro : Konten yang dimuat sebelumnya tidak hilang setelah reset pabrik - konten akan disalin dari partisi B setelah reboot.

Con : Membutuhkan ruang pada partisi B. Boot setelah reset pabrik memerlukan waktu tambahan untuk menyalin konten yang dimuat sebelumnya.

Agar pramuat dapat disalin selama boot pertama, sistem akan memanggil skrip di /system/bin/preloads_copy.sh . Skrip dipanggil dengan satu argumen (jalur ke titik pemasangan hanya-baca untuk partisi system_b ):

Untuk menerapkan fitur ini, buat perubahan khusus perangkat ini. Berikut adalah contoh dari Marlin:

  1. Tambahkan skrip yang melakukan penyalinan ke file device-common.mk (dalam hal ini, device/google/marlin/device-common.mk ), seperti:
    # Script that copies preloads directory from system_other to data partition
    PRODUCT_COPY_FILES += \
        device/google/marlin/preloads_copy.sh:system/bin/preloads_copy.sh
    
    Temukan contoh sumber skrip di: device/google/marlin /preloads_copy.sh
  2. Edit file init.common.rc untuk membuatnya membuat direktori /data/preloads dan subdirektori yang diperlukan:
    mkdir /data/preloads 0775 system system
    mkdir /data/preloads/media 0775 system system
    mkdir /data/preloads/demo 0775 system system
    
    Temukan contoh sumber file init di: device/google/marlin/init.common.rc
  3. Tentukan domain SELinux baru di file preloads_copy.te : preloads_copy.te
    type preloads_copy, domain, coredomain;
    type preloads_copy_exec, exec_type, vendor_file_type, file_type;
    
    init_daemon_domain(preloads_copy)
    
    allow preloads_copy shell_exec:file rx_file_perms;
    allow preloads_copy toolbox_exec:file rx_file_perms;
    allow preloads_copy preloads_data_file:dir create_dir_perms;
    allow preloads_copy preloads_data_file:file create_file_perms;
    allow preloads_copy preloads_media_file:dir create_dir_perms;
    allow preloads_copy preloads_media_file:file create_file_perms;
    
    # Allow to copy from /postinstall
    allow preloads_copy system_file:dir r_dir_perms;
    
    Temukan contoh file domain SELinux di: /device/google/marlin/+/master/sepolicy/preloads_copy.te
  4. Daftarkan domain di yang baru /sepolicy/file_contexts file: l10n
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Temukan contoh file konteks SELinux di: device/google/marlin/sepolicy/preloads_copy.te
  5. Pada waktu pembuatan, direktori dengan konten yang dimuat sebelumnya harus disalin ke partisi system_other : l10n
    # Copy contents of preloads directory to system_other partition
    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,vendor/google_devices/marlin/preloads,system_other/preloads)
    
    Ini adalah contoh perubahan Makefile yang memungkinkan penyalinan sumber daya cache APK dari repositori Git vendor (dalam kasus kami adalah vendor/google_devices/ marlin/preloads) ke lokasi pada partisi system_other yang nantinya akan disalin ke /data/preloads saat perangkat melakukan booting pertama kali. Skrip ini berjalan pada waktu pembuatan untuk menyiapkan gambar system_other. Itu mengharapkan konten yang dimuat sebelumnya tersedia di vendor/google_devices/marlin/preloads. OEM bebas memilih nama/jalur repositori yang sebenarnya.
  6. Cache APK terletak di /data/preloads/file_cache dan memiliki tata letak berikut:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    Ini adalah struktur direktori terakhir pada perangkat. OEM bebas memilih pendekatan implementasi apa pun selama struktur file akhir mereplikasi yang dijelaskan di atas.

Pendekatan 2. Konten pada gambar data pengguna di-flash di pabrik

Pendekatan alternatif ini mengasumsikan bahwa konten yang dimuat sebelumnya sudah disertakan dalam direktori /data/preloads pada partisi /data .

Pro : Bekerja di luar kotak - tidak perlu membuat penyesuaian perangkat untuk menyalin file pada boot pertama. Konten sudah ada di partisi /data .

Con : Konten yang dimuat sebelumnya hilang setelah reset pabrik. Meskipun ini mungkin dapat diterima untuk beberapa orang, ini mungkin tidak selalu berhasil untuk OEM yang menyetel ulang perangkat ke pabrik setelah melakukan inspeksi kontrol kualitas.

Metode @SystemApi baru, getPreloadsFileCache() , telah ditambahkan ke android.content.Context . Ini mengembalikan jalur absolut ke direktori khusus aplikasi di cache yang dimuat sebelumnya.

Metode baru, IPackageManager.deletePreloadsFileCache , ditambahkan yang memungkinkan penghapusan direktori pramuat untuk mendapatkan kembali semua ruang. Metode ini hanya dapat dipanggil oleh aplikasi dengan SYSTEM_UID, yaitu server sistem atau Pengaturan.

Persiapan aplikasi

Hanya aplikasi istimewa yang dapat mengakses direktori cache pramuat. Untuk akses itu, aplikasi harus diinstal di direktori /system/priv-app .

Validasi

  • Setelah boot pertama, perangkat harus memiliki konten di direktori /data/preloads/file_cache .
  • Konten dalam direktori file_cache/ harus dihapus jika penyimpanan perangkat hampir habis.

Gunakan contoh aplikasi ApkCacheTest untuk menguji cache APK.

  1. Bangun aplikasi dengan menjalankan perintah ini dari direktori root:
    make ApkCacheTest
    
  2. Instal aplikasi sebagai aplikasi istimewa. (Ingat, hanya aplikasi istimewa yang dapat mengakses cache APK.) Ini membutuhkan perangkat yang di-rooting:
    adb root && adb remount
    adb shell mkdir /system/priv-app/ApkCacheTest
    adb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/
    adb shell stop && adb shell start
    
  3. Simulasikan direktori cache file dan kontennya jika diperlukan (juga memerlukan hak akses root):
    adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetest
    adb shell restorecon -r /data/preloads
    adb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt"
    
  4. Uji aplikasi. Setelah menginstal aplikasi dan membuat direktori test file_cache , buka aplikasi ApkCacheTest. Seharusnya menunjukkan satu file test.txt dan isinya. Lihat tangkapan layar ini untuk melihat bagaimana hasil ini muncul di antarmuka pengguna.

    Gambar 1. Hasil ApkCacheTest