Immagine di sistema condivisa

Questa pagina presenta diversi meccanismi che gli OEM Android possono utilizzare per avere un'immagine di sistema condivisa (SSI) tra le linee di prodotti. Propone inoltre una procedura per basare un'SSI di proprietà dell'OEM su un'immagine di sistema generica (GSI) creata con AOSP.

Sfondo

Il framework Android Open Source Project (AOSP) è conforme all'architettura Mainline per mantenere la compatibilità con le versioni precedenti delle implementazioni del fornitore. Ad esempio, un'immagine di sistema generica (GSI) creata a partire dalle origini AOSP di Android 10 può essere eseguita su qualsiasi dispositivo conforme a Treble con Android 8 o versioni successive.

Mainline lo fa dividendo Android in due parti distinte: l'implementazione specifica del fornitore per l'hardware e il framework generico del sistema operativo Android. Ogni componente viene installato in una partizione separata: la partizione del fornitore per il software specifico dell'hardware e la partizione di sistema per il sistema operativo generico. Tra loro viene applicata un'interfaccia con controllo delle versioni, chiamata interfaccia fornitore (VINTF). Questo sistema di partizionamento consente agli OEM di modificare la partizione di sistema senza toccare la partizione del fornitore e viceversa.

Storicamente, i fornitori di SoC e gli OEM hanno modificato pesantemente la versione del framework Android fornita sui dispositivi di consumo (per i dettagli, vedi Ciclo di vita di una release Android). Poiché queste estensioni del framework sono state raramente progettate tenendo presente la compatibilità con le versioni precedenti, le modifiche specifiche del dispositivo hanno aumentato notevolmente la complessità e il costo finanziario dei successivi upgrade del sistema operativo. In Android 10 (livello API 29) e versioni precedenti, l'ecosistema non disponeva di un'architettura chiara e standardizzata che consentisse ai partner di creare estensioni modulari del framework Android.

Questa pagina descrive in che modo i fornitori di SoC e gli OEM possono creare un'immagine di sistema condivisa (SSI). Un'immagine SSI è un'immagine del framework unificata creata a partire dalle origini del sistema operativo Android che può essere riutilizzata su più dispositivi. Mantenendo una compatibilità all'indietro pulita con le implementazioni dei fornitori tramite questa architettura partizionata, un SSI riduce significativamente il costo e la complessità degli upgrade del sistema operativo Android.

Per i dettagli relativi all'implementazione, consulta Passaggi suggeriti per l'SSI basata su GSI. I passaggi sono modulari; a seconda dell'architettura, puoi scegliere di implementare fasi specifiche (ad esempio Passaggio 1: ereditare generic_system.mk per l'immagine di sistema OEM (OEM GSI)) anziché tutte le fasi.

Panoramica di SSI

Con SSI, i componenti software specifici del prodotto e le estensioni OEM vengono inseriti in una nuova partizione /product. I componenti nella partizione /product utilizzano un'interfaccia stabile e ben definita per interagire con i componenti nella partizione /system. Gli OEM possono scegliere di creare un solo SSI o un numero ridotto di SSI da utilizzare in più SKU di dispositivi. Quando viene rilasciata una nuova versione del sistema operativo Android, gli OEM investono una sola volta nell'aggiornamento dei propri SSI all'ultima versione di Android. Possono riutilizzare le SSI per aggiornare più dispositivi senza aggiornare la partizione /product.

Gli OEM e i fornitori di SoC possono creare SSI che includono funzionalità e modifiche personalizzate. I meccanismi e le best practice forniti in questa pagina sono destinati agli OEM per raggiungere questi obiettivi chiave:

  • Riutilizza l'SSI su più SKU di dispositivi.
  • Aggiorna il sistema Android con le estensioni modulari per semplificare gli upgrade del sistema operativo.

L'idea di base di separare i componenti specifici del prodotto nella partizione del prodotto è simile a Mainline, che separa i componenti specifici del SoC nella partizione del fornitore. Un'interfaccia del prodotto (simile a VINTF) consente la comunicazione tra SSI e la partizione del prodotto. Per quanto riguarda SSI, il termine componenti descrive tutte le risorse, i file binari, i testi e le librerie installati nelle immagini, che diventano partizioni.

Partizioni intorno a SSI

La Figura 1 mostra le partizioni intorno a SSI e le interfacce con controllo delle versioni tra le partizioni e le policy sulle interfacce. Questa sezione spiega in dettaglio ciascuna partizione e interfaccia.

Partizioni e interfacce intorno al diagramma a blocchi SSI

Figura 1. Partizioni e interfacce intorno a SSI.

Immagini e partizioni

Le informazioni in questa sezione distinguono i termini immagine e partizione.

  • Un'immagine è un software concettuale che può essere aggiornato in modo indipendente.
  • Una partizione è una posizione di archiviazione fisica che può essere aggiornata in modo indipendente.

Le sezioni della Figura 1 sono definite come segue:

  • SSI:un'immagine comune a un OEM, che può esistere su più dispositivi. Non ha componenti specifici per l'hardware o il prodotto. Tutto ciò che è contenuto in un determinato SSI è, per definizione, condiviso tra tutti i dispositivi che lo utilizzano. L'SSI è composto da una singola immagine /system o da un'immagine /system e dalle partizioni /system_ext.

  • Immagine prodotto:una raccolta di componenti specifici per prodotto o dispositivo che rappresentano personalizzazioni ed estensioni OEM del sistema operativo Android. Inserisci i componenti specifici del SoC nella partizione /vendor. I fornitori di SoC possono anche utilizzare la partizione /product per i componenti appropriati, ad esempio quelli indipendenti dal SoC. Ad esempio, se un fornitore di SoC fornisce un componente indipendente dal SoC ai propri clienti OEM (che è facoltativo spedire con il prodotto), il fornitore di SoC può inserire questo componente nell'immagine prodotto. La posizione di un componente è determinata dal suo scopo e non dalla sua proprietà.

  • Immagine del fornitore:una raccolta di componenti specifici del SoC.

  • Immagine ODM:una raccolta di componenti specifici della scheda non forniti dal SoC. In genere, il fornitore del SoC è proprietario dell'immagine del fornitore, mentre il produttore del dispositivo è proprietario dell'immagine ODM. Quando non è presente una partizione /odm separata, le immagini del fornitore del SoC e dell'ODM vengono unite nella partizione /vendor.

La partizione /system_ext

La partizione /system_ext è facoltativa. Utilizza questa partizione per eventuali funzionalità ed estensioni personalizzate strettamente accoppiate a componenti basati su AOSP. Si presume che questa partizione sia l'estensione specifica dell'OEM della partizione /system, senza un'interfaccia definita nelle due partizioni. I componenti nella partizione /system_ext possono effettuare chiamate API private nella partizione /system, mentre i componenti nella partizione /system possono effettuare chiamate API private nella partizione /system_ext.

Poiché le due partizioni sono strettamente accoppiate, vengono entrambe aggiornate insieme quando viene rilasciata una nuova versione di Android. Una partizione /system_ext creata per la release precedente di Android non deve essere compatibile con la partizione /system nella release successiva di Android.

Per installare un modulo nella partizione /system_ext, aggiungi system_ext_specific: true al file Android.bp. Sui dispositivi che non hanno una partizione /system_ext, installa questi moduli nella sottodirectory ./system_ext della partizione /system.

Cronologia:l'obiettivo di progettazione originale della partizione /system_ext era quello di inserire tutti i componenti specifici dell'OEM, indipendentemente dal fatto che siano comuni, nella partizione /product. Tuttavia, spostarli tutti contemporaneamente non era fattibile, soprattutto quando alcuni componenti presentavano un alto accoppiamento con la partizione /system. Per spostare un componente con alto accoppiamento nella partizione /product, è necessario estendere l'interfaccia del prodotto. Ciò spesso richiedeva un refactoring esteso del componente stesso, il che richiedeva molto tempo e impegno. La partizione /system_ext è nata come luogo per ospitare temporaneamente i componenti che non sono pronti per essere spostati nella partizione /product. L'obiettivo dell'SSI era quello di eliminare alla fine la partizione /system_ext.

Tuttavia, la partizione /system_ext è utile per mantenere la partizione /system il più vicino possibile ad AOSP. Con SSI, la maggior parte dello sforzo di upgrade è dedicata ai componenti nelle partizioni /system e /system_ext. Quando l'immagine di sistema viene creata da origini il più simili possibile a quelle di AOSP, puoi concentrare lo sforzo di upgrade sull'immagine system_ext.

Interfacce tra le immagini

Esistono due interfacce principali per le immagini di fornitori e prodotti relative a SSI:

  • Vendor Interface (VINTF): VINTF è l'interfaccia per i componenti che risiedono nelle immagini del fornitore e dell'ODM. I componenti nelle immagini di prodotto e di sistema possono interagire con le immagini del fornitore e dell'ODM solo tramite questa interfaccia. Ad esempio, un'immagine del fornitore non può dipendere da una parte privata dell'immagine di sistema e viceversa. Questa interfaccia è definita nell'architettura Treble (ora parte dell'architettura Mainline più ampia), che suddivide le immagini in partizioni di sistema e del fornitore. L'interfaccia è descritta utilizzando i seguenti meccanismi:

    • HIDL (Passthrough HAL è disponibile solo per i moduli system e system_ext)
    • AIDL stabile
    • Configurazioni
      • API System Properties
      • API schema file di configurazione
    • VNDK
    • API SDK Android
    • Libreria SDK Java
  • Interfacce prodotto: l'interfaccia prodotto è l'interfaccia tra SSI e l'immagine del prodotto. La definizione di un'interfaccia stabile disaccoppia i componenti del prodotto dai componenti del sistema in un'SSI.

Abilita SSI

Questa sezione spiega come supportare l'SSI in Android 11 e versioni successive.

Separare i componenti

Per separare la partizione /product dai componenti di sistema, la partizione /product deve avere la stessa policy di applicazione della partizione /vendor che è già stata separata con Mainline.

  • Interfacce integrate:i moduli integrati nella partizione /product devono essere separati dalle altre partizioni. Le uniche dipendenze consentite dai moduli del prodotto sono alcune librerie VNDK (inclusa LLNDK) della partizione /system. Le librerie JNI da cui dipendono le app prodotto devono essere librerie NDK.
  • Interfacce Java:i moduli Java (app) nella partizione /product non possono utilizzare API nascoste perché sono instabili. Questi moduli devono utilizzare solo API pubbliche e API di sistema della partizione /system e librerie dell'SDK Java nella partizione /system o /system_ext. Puoi definire librerie SDK Java per API personalizzate.

Applicare le interfacce dei prodotti

Per assicurarsi che la partizione /product sia separata, gli OEM possono fare in modo che i loro dispositivi applichino le interfacce di prodotto impostando PRODUCT_PRODUCT_VNDK_VERSION:= current per i moduli integrati e PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true per i moduli Java. Queste variabili vengono impostate automaticamente se PRODUCT_SHIPPING_API_LEVEL del dispositivo è maggiore o uguale a 30. Per informazioni dettagliate, consulta Imporre interfacce di partizione dei prodotti.

Passaggi suggeriti per l'SSI basata su GSI

Partizioni suggerite per l'indicizzazione semantica basata su GSI

Figura 2. Partizioni suggerite per l'indicizzazione lato server basata su GSI.

Un'immagine di sistema generica (GSI) è l'immagine di sistema creata direttamente da AOSP. Viene utilizzato per i test di conformità (ad esempio CTS-on-GSI) e come piattaforma di riferimento che gli sviluppatori di app possono utilizzare per testare la compatibilità delle loro app quando non dispongono di un dispositivo reale con la versione richiesta di Android.

Gli OEM possono anche utilizzare GSI per creare la propria SSI. Come spiegato in Immagini e partizioni, SSI è costituita dall'immagine di sistema per i componenti definiti da AOSP e dall'immagine system_ext per i componenti definiti dall'OEM. Quando GSI viene utilizzata come immagine system, l'OEM può concentrarsi sull'immagine system_ext per l'upgrade.

Questa sezione fornisce indicazioni agli OEM che vogliono modularizzare le proprie personalizzazioni nelle partizioni /system_ext e /product utilizzando un'immagine di sistema AOSP o quasi AOSP. Se gli OEM creano l'immagine di sistema dalle origini AOSP, possono sostituire l'immagine di sistema che creano con la GSI fornita da AOSP. Tuttavia, gli OEM non devono raggiungere il passaggio finale (utilizzando GSI così com'è) in una sola volta.

Passaggio 1: ereditare generic_system.mk per l'immagine di sistema OEM (GSI OEM)

Ereditando generic_system.mk (denominato mainline_system.mk in Android 11 e rinominato generic_system.mk in AOSP), l'immagine di sistema (OEM GSI) include tutti i file della GSI AOSP. Questi file possono essere modificati dagli OEM, in modo che la GSI OEM possa contenere i file proprietari OEM oltre ai file GSI AOSP.

Ereditare `generic_system.mk` per l'immagine di sistema OEM

Figura 3. Eredita generic_system.mk per l'immagine di sistema dell'OEM.

Passaggio 2: fai in modo che la GSI OEM abbia lo stesso elenco di file della GSI AOSP

In questa fase, la GSI OEM non può contenere file aggiuntivi, quindi sposta i file proprietari dell'OEM nelle partizioni system_ext o product.

Spostamento dei file aggiunti al di fuori della GSI OEM

Figura 4. Sposta i file aggiunti al di fuori della GSI OEM.

Passaggio 3: definisci una lista consentita per limitare i file modificati nella GSI OEM

Per controllare i file modificati, gli OEM possono utilizzare lo strumento compare_images e confrontare la GSI AOSP con la GSI OEM. Ottieni la GSI AOSP dal target lunch AOSP generic_system_*.

Eseguendo periodicamente lo strumento compare_images con il parametro allowlist, puoi monitorare le differenze al di fuori dell'elenco consentito. Ciò impedisce ulteriori modifiche alla GSI OEM.

Definisci una lista consentita per ridurre l'elenco dei file modificati in OEM GSI

Figura 5. Definisci la lista consentita per ridurre l'elenco dei file modificati nella GSI OEM.

Passaggio 4: fai in modo che la GSI OEM abbia gli stessi file binari della GSI AOSP

La pulizia della lista consentita consente agli OEM di utilizzare la GSI AOSP come immagine di sistema per i propri prodotti. Per ripulire la lista consentita, gli OEM possono abbandonare le modifiche nella GSI OEM o trasferirle a AOSP in modo che la GSI AOSP includa le modifiche.

Fare in modo che la GSI OEM abbia gli stessi file binari della GSI AOSP

Figura 6. Fai in modo che la GSI OEM abbia gli stessi file binari della GSI AOSP.

Definisci SSI

Gli OEM possono utilizzare le seguenti indicazioni per definire la propria SSI.

Proteggere la partizione /system al tempo di compilazione

Per evitare modifiche specifiche del prodotto nella partizione /system e definire la GSI OEM, gli OEM possono utilizzare una macro makefile chiamata require-artifacts-in-path per impedire qualsiasi dichiarazione di moduli di sistema dopo la chiamata della macro. Consulta l'esempio nel Passaggio 1: crea il makefile e abilita il controllo del percorso dell'artefatto.

Gli OEM possono definire un elenco per consentire l'installazione temporanea di moduli specifici del prodotto nella partizione /system. Tuttavia, l'elenco deve essere vuoto per rendere la GSI OEM comune a tutti i prodotti dell'OEM. Questa procedura serve a definire la GSI OEM e può essere indipendente dai passaggi per la GSI AOSP.

Rendere comune la partizione /system_ext

La partizione /system_ext potrebbe variare a seconda dei dispositivi, perché può contenere moduli specifici del dispositivo e inclusi nel sistema. Poiché l'SSI è costituito da partizioni /system e /system_ext, le differenze nella partizione /system_ext impediscono agli OEM di definire un'SSI. Gli OEM possono avere il proprio SSI e condividerlo tra più dispositivi rimuovendo eventuali differenze e rendendo comune la partizione /system_ext.

Questa sezione fornisce consigli per rendere comune la partizione /system_ext.

Esporre le API nascoste nella partizione di sistema

Molte app specifiche per prodotto non possono essere installate nella partizione del prodotto perché utilizzano API nascoste, che sono vietate nella partizione del prodotto. Per spostare le app specifiche per dispositivo nella partizione del prodotto, rimuovi l'utilizzo delle API nascoste.

Il modo migliore per rimuovere le API nascoste dalle app è trovare API pubbliche o di sistema alternative per sostituirle. Se non ci sono API per sostituire le API nascoste, gli OEM possono contribuire ad AOSP per definire le nuove API di sistema per i loro dispositivi.

In alternativa, gli OEM possono definire API personalizzate creando una propria libreria SDK Java nella partizione /system_ext. Questa libreria può utilizzare API nascoste nella partizione di sistema e può fornire le API alle app nella partizione del prodotto o del fornitore. Gli OEM devono bloccare le API rivolte al prodotto per la compatibilità con le versioni precedenti.

Sostituzione della disattivazione delle app specifiche per SKU

Android 16 ha ritirato e rimosso il meccanismo legacy per disattivare selettivamente gli APK in base allo SKU hardware utilizzando overlay delle risorse del framework (config_disableApksUnlessMatchedSku_apk_list e config_disableApkUnlessMatchedSku_skus_list). Per maggiori dettagli, consulta aosp/3444399.

La sostituzione consigliata è l'utilizzo della configurazione di sistema install-in-user-type all'interno di directory specifiche per SKU. Questo approccio impedisce l'installazione del pacchetto per qualsiasi utente di uno SKU specifico, anziché disabilitarlo dopo l'installazione.

  1. Includi tutti gli APK (il superset di tutte le potenziali app per tutti gli SKU nell'immagine di sistema) nell'immagine, in genere nella partizione /product.

  2. Assicurati che lo SKU del dispositivo sia impostato correttamente nella proprietà di sistema ro.boot.hardware.sku (utilizzata dal sistema per identificare lo SKU del dispositivo al momento dell'avvio).

  3. Crea sottodirectory sysconfig specifiche per SKU in /product/etc/sysconfig/ utilizzando la convenzione di denominazione sku_<SKU_NAME>. Il sistema carica automaticamente le configurazioni dalla directory che corrisponde alla proprietà ro.boot.hardware.sku. Percorso di esempio: /product/etc/sysconfig/sku_basic_model/.

  4. Configura la prevenzione dell'installazione di app. All'interno della directory specifica dello SKU, crea un file di configurazione XML (ad esempio, disabled_apps.xml) e utilizza il tag <do-not-install-in> per escludere pacchetti specifici.

Esempio XML (/product/etc/sysconfig/sku_basic_model/disabled_apps.xml):

<?xml version="1.0" encoding="utf-8"?>
<config>
    <!-- Prevents this package from being installed for ANY user on this SKU -->
    <install-in-user-type package="com.example.premium.feature.app" >
        <do-not-install-in user-type="FULL" />
        <do-not-install-in user-type="SYSTEM" />
    </install-in-user-type>
</config>

Ecco un confronto tra i due metodi:

Funzionalità Android 15 e versioni precedenti Android 16 e versioni successive
Metodo di configurazione Overlay delle risorse del framework File XML SystemConfig
Logic location config.xml (overlay risorsa) /product/etc/sysconfig/sku_<name>/
Risultato Disabilita l'app utilizzando PackageManager Impedisce l'installazione dell'app per l'utente
Robustezza Può essere riattivato dai servizi di sistema Il pacchetto non viene mai installato per l'utente

Per i casi che richiedono un controllo più granulare (ovvero la disattivazione di un'app normalmente installata per impostazione predefinita in tutti gli SKU), Android supporta anche i tag disabled-in-sku e enabled-in-sku-override in sysconfig:

  • <disabled-in-sku package="com.example.app" /> disattiva l'app a livello globale.

  • <enabled-in-sku-override package="com.example.app" /> riattiva l'app per uno SKU specifico quando viene inserita nella directory sku_<name> corrispondente.

Definisci RRO anziché utilizzare l'overlay di risorse statiche

Una risorsa statica sovrapposta manipola i pacchetti sovrapposti. Tuttavia, può ostacolare la definizione di un'SSI, quindi assicurati che le proprietà per RRO siano attive e impostate correttamente. Impostando le proprietà come segue, gli OEM possono avere tutte le overlay generate automaticamente come RRO.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

Se è necessaria una configurazione dettagliata, definisci manualmente un RRO anziché affidarti a uno generato automaticamente. Per informazioni dettagliate, vedi Modificare il valore delle risorse di un'app in fase di runtime. Gli OEM possono anche definire RRO condizionali che dipendono dalle proprietà di sistema utilizzando gli attributi android:requiredSystemPropertyName e android:requiredSystemPropertyValue.

Domande frequenti

Di seguito sono riportate le domande frequenti su SSI.

Posso definire più SSI?

Dipende dalla comunanza e dalle caratteristiche dei dispositivi (o del gruppo di dispositivi). Gli OEM possono provare a rendere comune la partizione system_ext, come descritto in Rendere comune la partizione system_ext. Se un gruppo di dispositivi presenta molte differenze, è meglio definire più SSI.

Posso rimuovere da generic_system.mk i moduli che sono in conflitto con la mia implementazione?

No. GSI ha un insieme minimo di moduli avviabili e testabili. Se ritieni che un modulo non sia essenziale, segnala un bug per aggiornare il file generic_system.mk.