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 precaricamenti e app popolari nella cache APK archiviata nella partizione B quasi vuota sui nuovi dispositivi con partizioni A/B senza influire su alcuno spazio dati rivolto agli utenti. Grazie a 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 file APK da Google Play.
Casi d'uso
- Memorizza 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:
- Release di Android 8.1 (O MR1) installata
- 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 i file immagine 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 al download dell'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, ma vengono copiati dalla partizione B dopo il 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 precaricamenti 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 del punto di montaggio di sola lettura per la partizione system_b
):
Per implementare questa funzionalità, apporta le seguenti modifiche specifiche per il dispositivo. Ecco un esempio di Marlin:
- Aggiungi lo script che esegue la copia al file
device-common.mk
(in questo caso,device/google/marlin/device-common.mk
), come segue: Trova 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: Trova l'origine del filemkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
di 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/+/android16-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 momento della compilazione, la directory con i contenuti precaricati deve essere copiata nella partizione
system_other
: Questo è un esempio di modifica di un Makefile che consente di copiare le risorse della cache APK dal repository Git del fornitore (nel nostro caso vendor/google_devices/marlin/preloads) nella posizione della partizione system_other che verrà successivamente copiata in /data/preloads all'avvio del dispositivo 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 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 APK si trova in
/data/preloads/file_cache
e 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 replichi quella descritta sopra./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Approccio 2. Contenuti sull'immagine dei dati utente flashata in fabbrica
Questo approccio alternativo presuppone che i contenuti precaricati siano già inclusi nella
directory /data/preloads
nella partizione /data
.
Pro: funziona subito, non è necessario personalizzare il dispositivo per copiare i file al primo avvio. I contenuti si trovano già nella partizione /data
.
Svantaggio: i contenuti precaricati vengono persi dopo il 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 precaricamenti per recuperare tutto lo spazio. Il metodo può
essere chiamato solo da app con SYSTEM_UID, ovvero 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.
- 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 APK.
Per questo è 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 (richiede 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. Dovrebbe mostrare un filetest.txt
e i relativi contenuti. Consulta questo screenshot per vedere come vengono visualizzati i risultati nell'interfaccia utente.
Figura 1. Risultati di ApkCacheTest.