Memorizzazione nella cache dell'APK

Questo documento descrive la progettazione di una soluzione di memorizzazione nella cache di APK per una rapida installazione di app precaricate su un dispositivo che supporta le partizioni A/B.

Gli OEM possono inserire precaricamenti e app popolari nella cache degli APK, memorizzate nella maggior parte partizione B vuota sui nuovi dispositivi partizionati A/B senza conseguenze in qualsiasi spazio dati rivolto agli utenti. Avendo a disposizione una cache dell'APK sul dispositivo, nuovi i dispositivi sottoposti a ripristino di fabbrica di recente sono pronti per essere utilizzati quasi immediatamente, senza dover scaricare file APK da Google Play.

Casi d'uso

  • Archivia le app precaricate nella partizione B per una configurazione più rapida
  • Archivia le app popolari nella partizione B per un ripristino più rapido

Prerequisiti

Per utilizzare questa funzionalità, il dispositivo deve avere:

  • Versione di Android 8.1 (O MR1) installata
  • Partizione A/B implementata

I contenuti precaricati possono essere copiati solo al primo avvio. Il motivo è che dispositivi che supportano gli aggiornamenti di sistema A/B, la partizione B non memorizza file immagine di sistema, ma contenuti precaricati come risorse demo retail, i file OAT e la cache dell'APK. Dopo che le risorse sono state copiate in /data (questo avviene al primo avvio), la partizione B sarà utilizzata dall'interfaccia over-the-air (OTA) aggiornamenti per scaricare le versioni aggiornate dell'immagine di sistema.

Di conseguenza, la cache dell'APK non può essere aggiornata tramite OTA. può essere precaricato in una fabbrica. Il ripristino dei dati di fabbrica interessa solo la partizione /data. Il sistema B la partizione include ancora i contenuti precaricati fino al download dell'immagine OTA. Dopo il ripristino dei dati di fabbrica, il sistema esegue di nuovo il primo avvio. Ciò significa che l'APK la memorizzazione nella cache non è disponibile se l'immagine OTA viene scaricata sulla partizione B e vengono ripristinati i dati di fabbrica del dispositivo.

Implementazione

Approccio 1. Contenuti attivati partizione system_other

Pro: i contenuti precaricati non vengono persi dopo il ripristino dei dati di fabbrica: verrà copiata dalla partizione B dopo un riavvio.

Svantaggio: richiede spazio sulla partizione B. Avviare dopo il ripristino dei dati di fabbrica richiede più tempo per copiare contenuti precaricati.

Affinché i precaricamenti vengano copiati durante il primo avvio, il sistema chiama uno script a /system/bin/preloads_copy.sh. Lo script viene chiamato con una singola (percorso al punto di montaggio di sola lettura per system_b partizione di Compute Engine):

Per implementare questa funzionalità, apporta queste modifiche specifiche per dispositivo. Ecco un esempio da Marlin:

  1. Aggiungi lo script che esegue la copia a device-common.mk (in questo caso, device/google/marlin/device-common.mk), in questo modo:
    # 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
    
    Puoi trovare l'origine dello script di esempio all'indirizzo: device/google/marlin/preloads_copy.sh
  2. Modifica il file init.common.rc per creare il directory e sottodirectory /data/preloads necessarie:
    mkdir /data/preloads 0775 system system
    mkdir /data/preloads/media 0775 system system
    mkdir /data/preloads/demo 0775 system system
    
    Puoi trovare il codice sorgente init di esempio all'indirizzo: device/google/marlin/init.common.rc
  3. Definisci un nuovo dominio SELinux nel 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;
    
    Puoi trovare un esempio di file di dominio SELinux all'indirizzo: /device/google/marlin/+/main/sepolicy/preloads_copy.te
  4. Registra il dominio in un nuovo /sepolicy/file_contexts file:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    Trova un file di contesti SELinux di esempio all'indirizzo: device/google/marlin/sepolicy/preloads_copy.te
  5. In fase di creazione, la directory con i contenuti precaricati deve essere copiata system_other partizione:
    # 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)
    
    Questo è un esempio di modifica in un Makefile che consente di copiare la cache dell'APK risorse dal repository Git del fornitore (nel nostro caso fornitore/google_devices/marlin/preloads) nella posizione sulla partizione system_other che verrà poi copiato in /data/preloads quando il dispositivo si avvia per il primo nel tempo. Questo script viene eseguito al momento della build per preparare l'immagine system_other. Prevede contenuti precaricati in modo da renderli disponibili su Vendor/google_devices/marlin/preloads. OEM può scegliere liberamente il nome/percorso del repository.
  6. La cache dell'APK si trova in /data/preloads/file_cache e ha il seguente layout:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    Questa è la struttura di directory finale sui dispositivi. Gli OEM sono liberi di scegliere qualsiasi approccio all'implementazione purché la struttura finale del file replica uno descritto sopra.

Approccio 2. Contenuti sui dati utente l'immagine è stata visualizzata in fabbrica

Questo approccio alternativo presuppone che i contenuti precaricati siano già inclusi in nella directory /data/preloads sulla partizione /data.

Pro: funziona subito, non è necessario realizzare un dispositivo per copiare i file al primo avvio. I contenuti si trovano già nella /data partizione.

Svantaggio: i contenuti precaricati vanno persi dopo un ripristino dei dati di fabbrica. Mentre potrebbe essere accettabile per alcuni, non sempre funziona per gli OEM che resettare i dispositivi dopo aver effettuato ispezioni del controllo qualità.

Un nuovo metodo @SystemApi, getPreloadsFileCache(), è stato aggiunto a android.content.Context. Restituisce un percorso assoluto a specifica dell'app nella cache precaricata.

È stato aggiunto un nuovo metodo, IPackageManager.deletePreloadsFileCache che consente di eliminare la directory di precaricamento per recuperare tutto lo spazio. Il metodo può Essere chiamato solo dalle app con SYSTEM_UID, ovvero il server di sistema o Impostazioni.

Preparazione dell'app

Solo le app con privilegi possono accedere alla directory della cache di precaricamento. Per questo le app devono essere installate nella directory /system/priv-app.

Convalida

  • Dopo il primo avvio, il dispositivo dovrebbe avere i contenuti nella Directory /data/preloads/file_cache.
  • I contenuti nella directory file_cache/ devono essere eliminati se lo spazio di archiviazione del dispositivo sta per esaurirsi.

Utilizza l'esempio di ApkCacheTest app per testare la cache dell'APK.

  1. Crea l'app eseguendo questo comando dalla directory principale:
    make ApkCacheTest
    
  2. Installare l'app come app con privilegi. Tieni presente che solo le app con privilegi possono accedere alla cache dell'APK. Richiede un dispositivo rooted:
    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. Simula la directory della cache del file e i suoi contenuti, se necessario (richiedendo anche i privilegi 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. Testa l'app. Dopo aver installato l'app e creato la directory di test file_cache, apri l'app ApkCacheTest. Dovrebbe essere visualizzato un file test.txt e i relativi contenuti. Guarda questo screenshot per vedere come vengono visualizzati questi risultati nell'interfaccia utente.

    Figura 1. Risultati di ApkCacheTest.