Immagine del sistema condiviso Android

Questa pagina presenta diversi meccanismi che gli OEM di dispositivi Android possono utilizzare per avere la propria immagine di sistema condivisa (SSI) nelle varie linee di prodotto. Propone inoltre una procedura per basare un'immagine di sistema proprietario OEM su un'immagine di sistema generica (GSI) creata con AOSP.

Background

Con Project Treble, Android monolitico è stato suddiviso in due parti: la parte specifica per l'hardware (l'implementazione del fornitore) e la parte del sistema operativo generico (il framework del sistema operativo Android). Il software di ciascun componente è installato in una partizione separata: la partizione del fornitore per il software specifico per l'hardware e la partizione di sistema per il software generico del sistema operativo. Un'interfaccia con versione, chiamata interfaccia del fornitore (VINTF), viene definita e applicata nelle due partizioni. Utilizzando questo sistema di partizione, puoi modificare la partizione di sistema senza modificare la partizione del fornitore e viceversa.

Motivazione

Il codice del framework rilasciato in AOSP è stato conforme all'architettura Treble e ha mantenuto la compatibilità con le implementazioni dei fornitori precedenti. Ad esempio, un'immagine di sistema generica creata da origini AOSP Android 10 può essere eseguita su qualsiasi dispositivo compatibile con Treble con Android 8 o versioni successive. La versione di Android fornita sui dispositivi consumer viene modificata da fornitori di SoC e OEM. (Vedi Ciclo di vita di una release Android.) Queste modifiche ed estensioni apportate al framework non sono state scritte per mantenere la compatibilità con le versioni precedenti, il che si è tradotto in una maggiore complessità e in un costo più elevato per l'upgrade del sistema operativo. Le modifiche e le variazioni specifiche del dispositivo aumentano il costo e la complessità dell'upgrade di una versione del sistema operativo Android.

Prima di Android 11 non esisteva un'architettura chiara che consentisse ai partner di creare estensioni modulari per il framework del sistema operativo Android. Questo documento descrive i passaggi che i fornitori di SoC e gli OEM possono seguire per creare un SSI. Si tratta di un'immagine, generata dalle sorgenti del framework del sistema operativo Android per il riutilizzo su più dispositivi, per mantenere la compatibilità con le implementazioni dei fornitori e per offrire una significativa riduzione della complessità e del costo degli upgrade del sistema operativo Android. Per i passaggi specifici necessari per creare un SSI, consulta la sezione Passaggi suggeriti per gli SSI basati su GSI e tieni presente che non devi necessariamente utilizzare tutti e quattro i passaggi. I passaggi che scegli (ad esempio solo il passaggio 1) dipendono dall'implementazione.

Panoramica dell'SSI

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

Tieni presente che OEM e fornitori di SoC creano SSI che includono tutte le funzionalità e le modifiche personalizzate di cui un OEM ha bisogno. I meccanismi e le best practice forniti in questa pagina sono destinati agli OEM per raggiungere questi obiettivi chiave:

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

L'idea alla base di separare i componenti specifici del prodotto nella partizione del prodotto è simile all'idea di Treble di separare i componenti specifici di SoC nella partizione del fornitore. Un'interfaccia di prodotto (simile a VINTF) consente la comunicazione tra l'SSI e la partizione del prodotto. Tieni presente che, rispetto a SSI, il termine "componenti" descrive tutte le risorse, i binari, i testi, le librerie e così via installati nelle immagini, che diventano essenzialmente partizioni.

Partizioni intorno a SSI

La figura 1 mostra le partizioni relative a SSI e le interfacce con controllo delle versioni tra le partizioni e i criteri delle interfacce. Questa sezione illustra in dettaglio ciascuna delle partizioni e delle interfacce.

Partizioni e interfacce intorno al diagramma di blocchi SSI

Figura 1. Partizioni e interfacce per l'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 nella Figura 1 sono definite come segue:

  • SSI: l'SSI è l'immagine comune a un OEM e può essere presente su più dispositivi. Non sono presenti componenti specifici per hardware o per prodotto. Per definizione, tutto ciò che è contenuto in un determinato SSI è condiviso tra tutti i dispositivi che lo utilizzano. L'SSI è composto da una singola /system immagine o da un /system e dalle partizioni /system_ext, come mostrato nella Figura 1.

    • La partizione /system contiene componenti basati su AOSP, mentre /system_ext, se implementato, contiene estensioni e componenti di OEM e fornitori di SoC strettamente accoppiati ai componenti AOSP. Ad esempio, una libreria del framework Java OEM che fornisce API personalizzate per le app dell'OEM è più adatta alla partizione /system_ext rispetto alla partizione /system. I contenuti per le partizioni /system e /system_ext vengono generati dalle sorgenti Android modificate dall'OEM.

    • La partizione /system_ext è facoltativa, ma è consigliabile utilizzarla per eventuali funzionalità ed estensioni personalizzate strettamente integrate con i componenti basati su AOSP. Questa distinzione ti aiuta a identificare le modifiche da apportare per spostare questi componenti dalla partizione /system_ext alla partizione /product per un determinato periodo di tempo.

  • Prodotto: una raccolta di componenti specifici per prodotto o dispositivo che rappresentano le personalizzazioni e le estensioni OEM del sistema operativo Android. Inserisci i componenti specifici per l'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 ai propri clienti OEM un componente indipendente dall'SoC (che può essere spedito con il prodotto), può inserire questo componente nell'immagine del prodotto. La posizione di un componente non è determinata dalla sua proprietà, ma dal suo scopo.

  • Fornitore:una raccolta di componenti specifici per SoC.

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

Interfacce tra immagini

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

  • Interfaccia del fornitore (VINTF): VINTF è l'interfaccia per i componenti che si trovano nelle immagini del fornitore e dell'ODM. I componenti nelle immagini del prodotto e del 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. Questo valore è stato originariamente definito in Project treble, che suddivide le immagini in partizioni di sistema e del fornitore. L'interfaccia viene descritta utilizzando i seguenti meccanismi:

    • HIDL (l'HAL passthrough è disponibile solo per i moduli system e system_ext)
    • AIDL stabile
    • Configurazioni
      • API System Properties
      • API dello schema del file di configurazione
    • VNDK
    • API SDK Android
    • Libreria SDK Java
  • Interfacce dei prodotti: l'interfaccia del prodotto è l'interfaccia tra l'SSI e l'immagine del prodotto. La definizione di un'interfaccia stabile disaccoppia i componenti del prodotto dai componenti di sistema in un SSI. L'interfaccia del prodotto richiede le stesse interfacce stabili di VINTF. Tuttavia, per i dispositivi che vengono lanciati con Android 11 e versioni successive vengono applicate solo le API VNDK e SDK Android.

Attivare SSI in Android 11

Questa sezione spiega come utilizzare le nuove funzionalità implementate per supportare gli SSI in Android 11.

La partizione /system_ext

La partizione /system_ext è stata introdotta in Android 11 come partizione facoltativa. È il luogo per i componenti non AOSP che hanno un accoppiamento stretto con i componenti definiti da AOSP nella partizione /system. Si presume che la partizione /system_ext sia l'estensione specifica dell'OEM per la partizione /system, senza un'interfaccia definita tra le due partizioni. I componenti della partizione /system_ext possono effettuare chiamate API private nella partizione /system, mentre i componenti della partizione /system possono effettuare chiamate API private nella partizione /system_ext.

Poiché le due partizioni sono strettamente accoppiate, l'upgrade di entrambe le partizioni viene eseguito 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. Per i dispositivi che non dispongono di una partizione /system_ext, installa questi moduli nella sottodirectory ./system_ext della partizione /system.

Cronologia

Ecco alcune informazioni sulla partizione /system_ext. L'obiettivo del progetto era collocare tutti i componenti specifici dell'OEM, indipendentemente dal fatto che siano comuni, nella partizione /product. Tuttavia, non era possibile spostarli tutti contemporaneamente, soprattutto se alcuni componenti erano strettamente accoppiati con la partizione /system. Per spostare un componente strettamente accoppiato nella partizione /product, l'interfaccia del prodotto deve essere estesa. Ciò spesso richiedeva un ampio refactoring del componente stesso, cosa che richiede molto tempo e impegno. La partition /system_ext è stata creata inizialmente per ospitare temporaneamente i componenti non pronti per essere spostati nella partition /product. L'obiettivo dell'SSI era eliminare definitivamente la partizione /system_ext.

Tuttavia, la partizione /system_ext è utile per mantenere la partizione /system il più vicina possibile ad AOSP. Con SSI, la maggior parte dell'impegno per l'upgrade viene speso per i componenti nelle partizioni /system e /system_ext. Quando l'immagine di sistema viene creata da origini il più simili possibile a quelle in AOSP, puoi concentrare l'operazione di upgrade sull'immagine system_ext.

Scompila i componenti dalle partizioni /system e /system_ext nella partizione /product

Android 9 ha introdotto una partizione /product associata alla partizione /system. I moduli nella partizione /product utilizzano le risorse di sistema senza alcuna limitazione e viceversa. Per rendere possibile SSI in Android 10, i componenti del prodotto vengono suddivisi nelle partizioni /system_ext e /product. La partizione /system_ext non deve rispettare le limitazioni relative all'utilizzo dei componenti di sistema che la partizione /system_ext aveva in Android 9./product A partire da Android 10, la partizione /product deve essere sganciata dalla partizione /system e deve utilizzare interfacce stabili delle partizioni /system e /system_ext.

Lo scopo principale della partizione /system_ext è estendere le funzionalità di sistema, piuttosto che installare moduli di prodotti in bundle, come descritto nella sezione /system_ext partition. Per farlo, rimuovi i moduli specifici del prodotto e spostali nella partizione /product. Il disaccoppiamento dei moduli specifici del prodotto rende /system_ext comune ai dispositivi. Per maggiori dettagli, vedi Creare una partizione /system_ext comune.

Per separare la partizione /product dai componenti di sistema, la partizione /product deve avere lo stesso criterio di applicazione della partizione /vendor già divisa in Project Treble.

A partire da Android 11, le interfacce native e Java per la partizione /product vengono applicate come descritto di seguito. Per maggiori informazioni, consulta Applicazione delle interfacce di partizione del prodotto.

  • Interfacce native:i moduli nativi nella partizione /product devono essere scommessi dalle altre partizioni. Le uniche dipendenze consentite dai moduli del prodotto sono alcune librerie VNDK (incluso LLNDK) dalla partizione /system. Le librerie JNI su cui dipendono le app del 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 le librerie SDK Java nella partizione /system o /system_ext. Puoi definire librerie SDK Java per le API personalizzate.

Passaggi suggeriti per l'SSI basata su GSI

Partizioni suggerite per gli SSI basati su GSI

Figura 2. Partizioni suggerite per SSI basato su GSI

Un'immagine di sistema generica (GSI) è l'immagine di sistema creata direttamente da AOSP. Viene utilizzato per i test di conformità di Treble (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 su cui è installata la versione richiesta di Android.

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

Questa sezione fornisce una guida per gli 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 sorgenti AOSP, possono sostituire l'immagine di sistema che creano con la GSI fornita da AOSP. Tuttavia, gli OEM non devono raggiungere il passaggio finale (usando GSI così com'è) in una volta sola.

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

Se eredita generic_system.mk (che in Android 11 era mainline_system.mk e rinominata generic_system.mk in AOSP), l'immagine di sistema (GSI OEM) include tutti i file di cui dispone il GSI di AOSP. Questi file possono essere modificati dagli OEM, in modo che la GSI dell'OEM possa contenere i file proprietari dell'OEM oltre ai file GSI AOSP. Tuttavia, gli OEM non sono autorizzati a modificare il file generic_system.mk stesso.

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

Figura 3. Ereditarietà di generiche_system.mk per l'immagine di sistema dell'OEM.

Passaggio 2: Assicurati che la GSI OEM abbia lo stesso elenco di file della GSI AOSP

In questa fase la GSI dell'OEM non può avere file aggiuntivi. I file di proprietà dell'OEM devono essere spostati nelle partizioni system_ext o product.

Spostare i file aggiunti dall'immagine del sistema OEM

Figura 4. Spostare i file aggiunti dall'immagine del sistema di gestione degli OEM

Passaggio 3: Definisci una lista consentita per limitare i file modificati nel GSI OEM

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

Se esegui periodicamente lo strumento compare_images con il parametro allowlist, puoi monitorare le differenze al di fuori dell'elenco consentito. In questo modo non è necessario apportare ulteriori modifiche al GSI dell'OEM.

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

Figura 5. Definisci una lista consentita per ridurre l'elenco dei file modificati nel GSI dell'OEM

Passaggio 4: Assicurati che il GSI OEM abbia gli stessi binari del 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 nel GSI OEM o inviare le modifiche in upstream ad AOSP in modo che il GSI AOSP le includa.

Assicurati che GSI OEM abbia gli stessi binari di GSI AOSP

Figura 6. Assicurarsi che il GSI OEM abbia gli stessi binari del GSI AOSP

Definire l'SSI per gli OEM

Proteggere la partizione /system al momento della compilazione

Per evitare modifiche specifiche del prodotto nella partizione /system e definire il GSI dell'OEM, gli OEM possono utilizzare una macro makefile denominata require-artifacts-in-path per impedire qualsiasi dichiarazione dei moduli di sistema dopo la chiamata della macro. Consulta l'esempio di creazione del file makefile e attivazione del controllo del percorso degli elementi.

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 il GSI dell'OEM comune a tutti i prodotti dell'OEM. Questa procedura è per la definizione del GSI OEM e può essere indipendente dai passaggi per il GSI AOSP.

Applicare le interfacce dei prodotti

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

Rendi comune la partizione /system_ext

La partizione /system_ext potrebbe essere diversa da un dispositivo all'altro, perché può avere moduli specifici per il 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 suggerimenti per rendere comune la partizione /system_ext.

Esporre le API nascoste nella partizione di sistema

Molte app specifiche del 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 il dispositivo nella partizione del prodotto, rimuovi l'utilizzo delle API nascoste.

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

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

Includi il superset di tutti gli APK e salta alcune installazioni di pacchetti per ogni dispositivo

Alcuni pacchetti forniti in bundle con il sistema non sono comuni a tutti i dispositivi. Separare il raggruppamento di questi moduli APK per spostarli nel prodotto o nella partizione del fornitore può essere difficile. Come soluzione provvisoria, gli OEM possono fare in modo che l'SSI includa tutti i moduli, quindi escludere quelli indesiderati utilizzando una proprietà SKU (ro.boot.hardware.sku). Per utilizzare il filtro, gli OEM sovrappongono le risorse del framework config_disableApkUnlessMatchedSku_skus_list e config_disableApksUnlessMatchedSku_apk_list.

Per impostazioni più precise, dichiara un broadcast receiver che disabilita i pacchetti non necessari. Il ricevitore di trasmissione chiama setApplicationEnabledSetting per disattivare il pacchetto quando riceve il messaggio ACTION_BOOT_COMPLETED.

Definire RRO anziché utilizzare l'overlay delle risorse statiche

Un overlay di risorse statiche manipola i pacchetti sovrapposti. Tuttavia, può impedire la definizione di un SSI, quindi assicurati che le proprietà per l'RRO siano attivate e impostate correttamente. Impostando le proprietà come segue, gli OEM possono avere tutti gli overlay generati automaticamente come RRO.

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

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

Domande frequenti

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 modificare generic_system.mk (mainline_system.mk) per un GSI OEM?

No, ma gli OEM possono definire un nuovo makefile per un GSI OEM che eredita il file generic_system.mk e utilizza invece il nuovo file makefile. Per un esempio, consulta Applicare le interfacce di partizione del prodotto.

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

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