Penyimpanan cache APK

Dokumen ini menjelaskan desain solusi cache APK untuk penginstalan cepat aplikasi bawaan di perangkat yang mendukung partisi A/B.

OEM dapat menempatkan pramuat dan aplikasi populer dalam cache APK yang sebagian besar partisi B kosong di perangkat baru yang dipartisi A/B tanpa memengaruhi setiap ruang data yang berhadapan dengan pengguna. Dengan memiliki cache APK yang tersedia di perangkat, baru atau perangkat yang baru saja dikembalikan ke setelan pabrik siap digunakan seketika, tanpa perlu mendownload file APK dari Google Play.

Kasus penggunaan

  • Simpan aplikasi yang dipramuat di partisi B untuk penyiapan yang lebih cepat
  • Simpan aplikasi populer di partisi B untuk pemulihan yang lebih cepat

Prasyarat

Untuk menggunakan fitur ini, perangkat memerlukan:

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

Konten yang dipramuat hanya dapat disalin selama booting pertama. Hal ini karena pada yang mendukung update sistem A/B, partisi B sebenarnya tidak file image sistem, tetapi konten yang dimuat sebelumnya seperti resource demo promo, File OAT dan cache APK. Setelah resource disalin ke /data partisi (ini terjadi saat booting pertama), partisi B akan digunakan oleh over-the-air (OTA) update untuk mendownload image sistem versi terbaru.

Oleh karena itu, cache APK tidak dapat diupdate melalui OTA; hanya dapat dipramuat di pabrik. Reset ke setelan pabrik hanya memengaruhi partisi /data. Sistem B masih memiliki konten yang dipramuat hingga {i>image <i}OTA diunduh. Setelah mereset ke setelan pabrik, sistem akan melakukan booting pertama lagi. Artinya APK {i>caching<i} tidak tersedia jika {i>image<i} OTA diunduh ke partisi B, dan maka perangkat akan direset ke setelan pabrik.

Implementasi

Pendekatan 1. Konten aktif partisi sistem_lainnya

Kelebihan: Konten yang dipramuat tidak hilang setelah direset ke setelan pabrik - konten akan disalin dari partisi B setelah {i>reboot<i}.

Kekurangan: Memerlukan ruang di partisi B. Booting setelah reset ke setelan pabrik memerlukan waktu tambahan untuk menyalin konten yang dipramuat.

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

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

  1. Tambahkan skrip yang melakukan penyalinan ke device-common.mk (dalam kasus ini, device/google/marlin/device-common.mk), seperti ini:
    # 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/pramuats_copy.sh
  2. Edit file init.common.rc agar file tersebut membuat direktori dan subdirektori /data/preloads 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 dalam file 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/+/main/sepolicy/previews_copy.te
  4. Daftarkan domain di /sepolicy/file_contexts baru file:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Temukan contoh file konteks SELinux di: device/google/marlin/sepolicy/pramuats_copy.te
  5. Pada waktu build, direktori dengan konten yang dipramuat harus disalin ke Partisi system_other:
    # 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 pada Makefile yang memungkinkan penyalinan cache APK sumber daya dari repositori Git vendor (dalam kasus kami itu vendor/google_devices/marlin/preemptibles) ke lokasi di partisi system_other yang nantinya akan disalin ke {i> /data/previews<i} saat perangkat melakukan {i>booting<i} untuk baik. Skrip ini berjalan pada waktu build untuk menyiapkan image system_other. Diharapkan konten yang dipramuat akan tersedia di vendor/google_devices/marlin/pramuats. OEM kita 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 akhir pada perangkat. OEM bebas memilih pendekatan implementasi apa pun, selama struktur file akhir mereplikasi sebagaimana dijelaskan di atas.

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

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

Kelebihan: Dapat langsung digunakan - tidak perlu membuat perangkat khusus untuk menyalin file saat booting pertama. Konten sudah ada di Partisi /data.

Kekurangan: Konten yang dipramuat akan hilang setelah direset ke setelan pabrik. Meskipun langkah ini mungkin dapat diterima, dan mungkin tidak selalu berhasil untuk OEM yang mengatur ulang perangkat setelah melakukan pemeriksaan kendali mutu.

Metode @SystemApi baru, getPreloadsFileCache(), ditambahkan ke android.content.Context. Operator ini mengembalikan jalur absolut ke direktori khusus aplikasi dalam cache yang dipramuat.

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

Persiapan aplikasi

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

Validasi

  • Setelah booting pertama, perangkat seharusnya memiliki konten di Direktori /data/preloads/file_cache.
  • Konten dalam direktori file_cache/ harus dihapus jika perangkat hampir kehabisan ruang penyimpanan.

Gunakan contoh ApkCacheTest untuk menguji cache APK.

  1. Bangun aplikasi dengan menjalankan perintah ini dari direktori root:
    make ApkCacheTest
    
  2. Instal aplikasi sebagai aplikasi dengan hak istimewa. (Ingat, hanya aplikasi dengan hak istimewa yang dapat mengakses cache APK.) Tindakan ini memerlukan perangkat yang telah di-root:
    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 istimewa 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 file_cache pengujian, buka aplikasi ApkCacheTest. Seharusnya satu file test.txt dan isinya akan ditampilkan. Lihat screenshot ini untuk melihat bagaimana hasil ini muncul di antarmuka pengguna.

    Gambar 1. Hasil ApkCacheTest.