Questo documento descrive la progettazione di una soluzione di memorizzazione nella cache degli APK per l'installazione rapida delle app precaricate su un dispositivo che supporta le partizioni A/B.
Gli OEM possono inserire app precaricate e popolari nella cache APK archiviata nella partizione B per lo più vuota sui nuovi dispositivi con partizione A/B senza influire sullo spazio dati rivolto agli utenti. Avendo una cache APK disponibile sul dispositivo, i dispositivi nuovi o su cui è stato eseguito di recente il ripristino dei dati di fabbrica sono pronti per l'uso quasi immediatamente, senza dover scaricare i file APK da Google Play.
Casi d'uso
- Memorizza le app precaricate nella partizione B per una configurazione più rapida
- Memorizza le app più utilizzate nella partizione B per un ripristino più rapido
Prerequisiti
Per utilizzare questa funzionalità, il dispositivo deve avere:
- È installata la release Android 8.1 (O MR1)
- Partizione A/B implementata
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 delle immagini di sistema, ma contenuti precaricati come risorse demo per la vendita al dettaglio, file OAT e la cache APK. Dopo che le risorse sono state copiate nella partizione /data (questo avviene al 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 APK non può essere aggiornata tramite OTA; può essere precaricata solo in fabbrica. Il ripristino dei dati di fabbrica interessa solo la partizione /data. La partizione B del sistema contiene ancora i contenuti precaricati fino a quando 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 dell'APK non è disponibile se l'immagine OTA viene scaricata nella partizione B e poi il dispositivo viene ripristinato alle impostazioni di fabbrica.
Implementazione
Approccio 1. Contenuti sulla partizione system_other
Vantaggio: i contenuti preinstallati non vengono persi dopo il ripristino dei dati di fabbrica, ma vengono copiati dalla partizione B dopo il riavvio.
Con: richiede spazio nella partizione B. L'avvio dopo il ripristino dei dati di fabbrica richiede un tempo aggiuntivo per copiare i contenuti pre caricati.
Affinché i pre-caricamenti 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 (percorso al punto di montaggio di sola lettura per la partizione system_b
):
Per implementare questa funzionalità, apporta le seguenti modifiche specifiche del dispositivo. Ecco un example da Marlin:
- Aggiungi lo script che esegue la copia al file
device-common.mk
(in questo casodevice/google/marlin/device-common.mk
), come segue: Puoi trovare il codice sorgente 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.rc
in modo che crei la directory e le sottodirectory/data/preloads
necessarie: Puoi trovare un esempio di codice sorgente del filemkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
all'indirizzo: device/google/marlin/init.common.rc - Definisci un nuovo dominio SELinux nel file
preloads_copy.te
: Puoi trovare un file di dominio SELinux di esempio all'indirizzo: /device/google/marlin/+/main/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 Puoi trovare 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 momento della compilazione, la directory con i contenuti precaricati deve essere copiata nella
partizione
system_other
: Questo è un esempio di modifica in un file Makefile che consente di copiare le risorse della cache APK dal repository Git del fornitore (nel nostro caso era vendor/google_devices/marlin/preloads) alla posizione nella partizione system_other che in seguito verrà copiata in /data/preloads quando il dispositivo si avvia per la prima volta. Questo script viene eseguito in fase 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/il percorso del repository effettivo.# 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 APK si trova in
/data/preloads/file_cache
e ha il seguente layout: Questa è la struttura di directory finale sui dispositivi. Gli OEM sono liberi di scegliere qualsiasi approccio di implementazione, a condizione che la struttura del file finale segua quella descritta sopra./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Approccio 2. Contenuti sull'immagine data dell'utente visualizzata in fabbrica
Questo approccio alternativo presuppone che i contenuti precaricati siano già inclusi nella directory /data/preloads
della partizione /data
.
Vantaggio: funziona subito, non è necessario apportare personalizzazioni al dispositivo per copiare i file al primo avvio. I contenuti sono già nella
partizione /data
.
Svantaggio: i contenuti preinstallati vengono persi dopo un ripristino dei dati di fabbrica. Anche se questo potrebbe essere accettabile per alcuni, potrebbe non funzionare sempre per gli OEM che ripristinano i dati di fabbrica dei dispositivi dopo aver eseguito ispezioni di controllo qualità.
È stato aggiunto un nuovo metodo @SystemApi, getPreloadsFileCache()
, a
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 dei pre-caricamenti 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 dei precaricamenti. Per questo accesso, le app devono essere installate nella directory /system/priv-app
.
Convalida
- Dopo il primo avvio, il dispositivo dovrebbe avere contenuti nella directory
/data/preloads/file_cache
. - I contenuti nella directory
file_cache/
devono essere eliminati se lo spazio di archiviazione del dispositivo è in esaurimento.
Utilizza l'app di esempio ApkCacheTest per testare la cache APK.
- Compila l'app eseguendo questo comando dalla directory principale:
make ApkCacheTest
- Installa l'app come app privilegiata. Ricorda che solo le app privilegiate possono accedere alla cache APK.
Per farlo, è necessario 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
- Simula la directory della cache dei file e i relativi contenuti, se necessario (sono richiesti anche i privilegi di 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"
- Testa l'app. Dopo aver installato l'app e creato la directory di test
file_cache
, apri l'app ApkCacheTest. Dovresti visualizzare un filetest.txt
e i relativi contenuti. Guarda questo screenshot per vedere come vengono visualizzati questi risultati nell'interfaccia utente.
Figura 1. Risultati di ApkCacheTest.