Questo documento descrive la progettazione di una soluzione di memorizzazione nella cache degli APK per l'installazione rapida di app precaricate su un dispositivo che supporta le partizioni A/B.
Gli OEM possono inserire le app precaricate e quelle più usate nella cache degli APK memorizzata nella partizione B, per lo più vuota, sui nuovi dispositivi con partizioni A/B senza influire sullo spazio dati visibile all'utente. Grazie alla cache degli APK disponibile sul dispositivo, i dispositivi nuovi o di cui è stato ripristinato di recente lo stato di fabbrica sono pronti all'uso quasi immediatamente, senza dover scaricare i file APK da Google Play.
Casi d'uso
- Memorizzare le app precaricate nella partizione B per una configurazione più rapida
- Memorizzare le app più usate nella partizione B per un ripristino più rapido
Prerequisiti
Per utilizzare questa funzionalità, il dispositivo deve:
- Avere installata la release di Android 8.1 (O MR1)
- Avere implementato la partizione A/B
I contenuti precaricati possono essere copiati solo durante il primo avvio. Questo perché sui dispositivi che supportano gli aggiornamenti di sistema A/B, la partizione B non memorizza effettivamente i file immagine di sistema, ma i contenuti precaricati come le risorse demo per la vendita al dettaglio, i file OAT e la cache degli APK. Dopo che le risorse sono state copiate nella partizione /data (durante il primo avvio), la partizione B verrà utilizzata dagli aggiornamenti over-the-air (OTA) per scaricare le versioni aggiornate dell'immagine di sistema.
Pertanto, la cache degli APK non può essere aggiornata tramite OTA; può essere precaricata solo in fabbrica. Il ripristino dei dati di fabbrica influisce solo sulla partizione /data. La partizione B del sistema contiene ancora i contenuti precaricati finché non viene scaricata l'immagine OTA. Dopo il ripristino dei dati di fabbrica, il sistema eseguirà di nuovo il primo avvio. Ciò significa che la memorizzazione nella cache degli APK non è disponibile se l'immagine OTA viene scaricata nella partizione B e poi vengono ripristinati i dati di fabbrica del dispositivo.
Implementazione
Approccio 1. Contenuti nella partizione system_other
Pro: i contenuti precaricati non vengono persi dopo il ripristino dei dati di fabbrica: verranno copiati dalla partizione B dopo un riavvio.
Contro: richiede spazio nella partizione B. L'avvio dopo il ripristino dei dati di fabbrica richiede più tempo per copiare i contenuti precaricati.
Affinché i contenuti precaricati vengano copiati durante il primo avvio, il sistema chiama uno script in /system/bin/preloads_copy.sh. Lo script viene chiamato con un singolo argomento (il percorso del punto di montaggio di sola lettura per la partizione system_b):
Per implementare questa funzionalità, apporta queste modifiche specifiche del dispositivo. Ecco un esempio di Marlin:
- Aggiungi lo script che esegue la copia al
device-common.mkfile (in questo caso,device/google/marlin/device-common.mk), come segue: Trova il codice dello script di esempio all'indirizzo: device/google/marlin/preloads_copy.sh# 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 - Modifica il file
init.common.rcin modo che crei la directory e le sottodirectory/data/preloadsnecessarie: Trova il codice del filemkdir /data/preloads 0775 system systemmkdir /data/preloads/media 0775 system systemmkdir /data/preloads/demo 0775 system systeminitdi esempio all'indirizzo: device/google/marlin/init.common.rc - Definisci un nuovo dominio SELinux nel file
preloads_copy.te: Trova un file di dominio SELinux di esempio all'indirizzo: /device/google/marlin/+/android17-release/sepolicy/preloads_copy.tetype 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;
- Registra il dominio in un nuovo file
:/sepolicy/file_contexts Trova un file di contesti SELinux di esempio all'indirizzo: device/google/marlin/sepolicy/preloads_copy.te/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- Al tempo di compilazione, la directory con i contenuti precaricati deve essere copiata nella partizione
system_other: Questo è un esempio di modifica in un Makefile che consente di copiare le risorse della cache degli APK dal repository Git del fornitore (nel nostro caso vendor/google_devices/marlin/preloads) nella posizione della partizione system_other che verrà copiata in /data/preloads al primo avvio del dispositivo. Questo script viene eseguito al tempo di compilazione per preparare l'immagine system_other. Si prevede che i contenuti precaricati siano disponibili in vendor/google_devices/marlin/preloads. L'OEM è libero di scegliere il nome/percorso effettivo del repository.# 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) - La cache degli APK si trova in
/data/preloads/file_cachee ha il seguente layout: Questa è la struttura finale delle directory sui dispositivi. Gli OEM sono liberi di scegliere qualsiasi approccio di implementazione, purché la struttura finale dei file sia uguale a quella descritta sopra./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Approccio 2. Contenuti nell'immagine dei dati utente caricata in fabbrica
Questo approccio alternativo presuppone che i contenuti precaricati siano già inclusi in
nella directory /data/preloads nella partizione /data.
Pro: funziona subito, senza dover apportare personalizzazioni al dispositivo
per copiare i file al primo avvio. I contenuti si trovano già nella partizione /data.
Contro: i contenuti precaricati vengono persi dopo il ripristino dei dati di fabbrica. Sebbene questo possa essere accettabile per alcuni, potrebbe non funzionare sempre per gli OEM che ripristinano i dati di fabbrica dei dispositivi dopo aver eseguito i controlli di qualità.
È stato aggiunto un nuovo metodo @SystemApi, getPreloadsFileCache(), ad android.content.Context. Restituisce un percorso assoluto a una directory specifica dell'app nella cache precaricata.
È stato aggiunto un nuovo metodo, IPackageManager.deletePreloadsFileCache, che consente di eliminare la directory preloads per recuperare tutto lo spazio. Il metodo può essere chiamato solo dalle app con SYSTEM_UID, ad es. il server di sistema o Impostazioni.
Preparazione dell'app
Solo le app con privilegi possono accedere alla directory della cache preloads. Per questo
accesso, le app devono essere installate nella directory /system/priv-app.
Convalida
- Dopo il primo avvio, il dispositivo deve avere contenuti nella directory
/data/preloads/file_cache. - I contenuti nella directory
file_cache/devono essere eliminati se lo spazio di archiviazione del dispositivo è insufficiente.
Utilizza l'app di esempio ApkCacheTest per testare la cache degli APK.
- Crea l'app eseguendo questo comando dalla directory principale:
make ApkCacheTest - Installa l'app come app con privilegi. Ricorda che solo le app con privilegi possono accedere alla cache degli APK.
Per questa operazione è necessario un dispositivo rooted:
adb root && adb remountadb shell mkdir /system/priv-app/ApkCacheTestadb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/adb shell stop && adb shell start - Se necessario, simula la directory della cache dei file e i relativi contenuti (richiede anche i privilegi di root):
adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetestadb shell restorecon -r /data/preloadsadb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt" - Testa l'app. Dopo aver installato l'app e creato la directory
file_cachedi test, apri l'app ApkCacheTest. Dovrebbe mostrare un filetest.txte i relativi contenuti. Consulta questo screenshot per vedere come vengono visualizzati questi risultati nell'interfaccia utente.
Figura 1. Risultati di ApkCacheTest.