Rimuovi pacchetti per l'utente di sistema

Questa pagina descrive come migliorare le prestazioni identificando e rimuovendo i pacchetti non necessari per l'utente di sistema.

Disattiva i pacchetti non necessari

In Automotive, l'utente del sistema è headless, il che significa che non è destinato all'utilizzo o all'accesso diretto da parte di una persona. Di conseguenza, molte app e servizi non devono essere eseguiti nell'utente di sistema e possono essere disattivati per migliorare le prestazioni. Pertanto, è disponibile un'opzione per rimuovere le app non necessarie per l'utente di sistema (utente 0).

In questa pagina vengono trattati due tipi di utenti:

  • SISTEMA. Sempre Utente 0
  • COMPLETO. Utente destinato all'uso da parte di una persona (utente non di sistema), Utente 10+

Android 11

In Android 11, modifica la configurazione di config_userTypePackageWhitelistMode. I flag possono essere combinati. In questo caso, 5 equivale a 1 più 4 (una combinazione di flag 1 e 4).

Segnala Descrizione
0 Disattiva la lista consentita. Installa tutti i pacchetti di sistema; nessun logging.
1 Applica. Installa i pacchetti di sistema solo se sono inclusi nella lista consentita.
2 Registra i pacchetti non inclusi nella lista consentita.
4 Qualsiasi pacchetto non menzionato nel file della lista consentita è inserito implicitamente nella lista consentita per tutti gli utenti.
8 Uguale a 4 per l'utente del sistema.
16 Ignorare gli OTA. Non installare pacchetti di sistema durante le OTA.

Considera questi scenari comuni:

  • Per abilitare una funzionalità per una lista consentita completa, 1 (completamente applicata)
  • Per attivare una funzionalità per una lista consentita incompleta, 5
  • Per attivare una funzionalità per l'utente SYSTEM per semplificare lo sviluppo locale, 9 (lista consentita implicita)
  • Per disattivare una funzionalità come se non fosse mai stata attivata, 16
  • Per disattivare una funzionalità e annullare tutti gli effetti precedenti, 0

Installa il file XML nella directory sysconfig del dispositivo (si tratta della stessa directory che contiene il file makefile (.mk) utilizzato per creare l'immagine di sistema per il dispositivo). Quando assegni un nome al file XML, includi la posizione in cui il pacchetto è definito nella compilazione, ad esempio preinstalled-packages-product-car-CAR_PRODUCT_NAME.xml.

<!- this package will be installed for both FULL and SYSTEM user -->
    <install-in-user-type package="com.android.bluetooth"->
        <install-in user-type="FULL" /->
        <install-in user-type="SYSTEM" /->
    </install-in-user-type->

<!- this package will only be installed for both FULL user -->
    <install-in-user-type package="com.android.car.calendar"->
        <install-in user-type="FULL" >
    </install-in-user-type->

Android 9 e Android 10

Per configurare questa funzionalità in Android 9 e Android 10:

  1. Sovrapponi il file di configurazione config_systemUserPackagesBlacklistSupported di frameworks/base/core/res/res/values/config.xml e impostalo su true. Quando la funzionalità è attiva, per impostazione predefinita, tutti i pacchetti devono essere installati sia per l'utente del sistema sia per l'utente COMPLETO.
  2. Crea un file config.xml che elenca i pacchetti da disattivare per l'utente di sistema, ad esempio:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
  3. Aggiungi una riga a device.mk per copiare il file nella cartella di destinazione system/etc/sysconfig/ del dispositivo, ad esempio:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Verifica il risultato

Per verificare il risultato, esegui:

$ adb shell dumpsys user | grep PACKAGE_SUBSTRING
$ adb shell pm list packages --user USER_ID PACKAGE_SUBSTRING
$ adb shell cmd user report-system-user-package-whitelist-problems

Edificio

Per determinare se un pacchetto deve essere installato nell'utente di sistema, esamina il file AndroidManifest.xml del pacchetto situato nella directory principale del codice sorgente del progetto, inclusi gli attributi e i componenti dell'app, che includono tutte le attività, i servizi, i ricevitori di trasmissione e i fornitori di contenuti. Per scoprire di più, consulta Panoramica del file manifest dell'app.

Disattivare il flusso di lavoro dei pacchetti

Figura 1. Disabilita flusso di lavoro dei pacchetti.

Livello 1, a livello di app

1. Verificare se l'app (o i componenti dell'app) è dichiarata come singleton

Se l'app è un singleton, il sistema la esegue nell'utente di sistema. È probabile che l'app sia stata progettata per essere multiutente. Per scoprire di più sulle app multiutente, consulta Creare app multiutente.

  1. Controlla il file manifest Android per android:singleUser="true".
  2. Se true, aggiungi alla lista consentita. Obbligatorio per l'utente di sistema.
  3. Se false, continua. Controlla altri criteri prima di procedere con la rimozione.

2. Verificare se l'app richiede l'accesso allo spazio di archiviazione protetto

Molti servizi di avvio del sistema si basano spesso sullo spazio di archiviazione criptato del dispositivo (DE) anziché su quello criptato delle credenziali (CE). Inoltre, le app di sistema che sono consapevoli dell'avvio diretto si basano anche sull'archiviazione criptata del dispositivo. Per scoprire di più sulle app sensibili all'avvio diretto, vedi Supportare l'avvio diretto nelle app di sistema.

  1. Controlla il manifest di Android per android:defaultToDeviceProtectedStorage="true", che è necessario per numerosi servizi di avvio di sistema.
  2. Se true, inserisci nella lista consentita.
  3. Se è false, continua.

Livello 2, componenti dell'app

Attività

Per saperne di più sulle attività, consulta la Introduzione alle attività.

a. Controlla se l'app contiene solo attività

Le attività sono orientate all'interfaccia utente. Poiché l'utente di sistema è headless in Automobile, nessun utente umano deve interagire con l'utente di sistema. Di conseguenza, se l'app contiene solo attività, è molto probabile che non sia pertinente per l' utente del sistema.

Verifica la priorità e il privilegio speciale:

  1. Se , potrebbe essere necessario per l'utente di sistema.
  2. Se No, non inserire l'utente di sistema nella lista consentita.

Ad esempio, la Compatibility Test Suite (CTS) (com.android.cts.priv.ctsshim) contiene solo attività, mentre le attività sono definite per testare i filtri per intent. Tuttavia, poiché CTS ha un privilegio elevato, deve essere installato per l'utente del sistema a scopo di test.

Servizio

Per scoprire di più sui servizi, consulta la Panoramica dei servizi.

b. Controlla se il servizio è stato dichiarato come privato e non è possibile accedervi da altre app

Se il servizio viene dichiarato privato, gli altri pacchetti non lo utilizzeranno. Cerca android:exported="false". Se il servizio è dichiarato come privato o non è possibile accedervi da altre app, non può essere vincolato da altre app. Pertanto, i passaggi c e d riportati di seguito non sono pertinenti. Di conseguenza, questo componente non fornisce ulteriori suggerimenti sulla necessità del servizio per l'utente del sistema.

  • Se la risposta è , controlla il componente successivo.
  • Se la risposta è No, continua a controllare questo componente.

c. Controlla se le app installate nell'utente del sistema potrebbero essere associate a questo servizio

Controlla la presenza di pacchetti nella lista consentita nel Livello 1 e identifica i servizi a cui sono associati. Traccia dal filtro intent in questo servizio e startService in altri pacchetti.

Se questo servizio è associato alle app installate nell'utente di sistema (ad esempio, com.android.car.companiondevicesupport è inclusa nella lista consentita per l'esecuzione nell'utente di sistema), inserisci il servizio nella lista consentita:

  • Se , inseriscilo nella lista consentita.
  • Se la risposta è No, continua a controllare questo componente.

d. Controlla se il servizio è associato ad altre app e dichiarato per l'esecuzione in primo piano

Cerca startForeground. Ciò significa che gli utenti interagiscono con l'app in primo piano. Molto probabilmente, questo servizio non sarebbe necessario per l'utente del sistema e non deve essere inserito nella lista consentita:

  • Se è impostata su , non consentire l'accesso alla lista consentita.
  • Se invece è No, continua a controllare il componente successivo.

e. Controlla se il servizio è definito per l'esecuzione nel processo di sistema

Nel file AndroidManifest, cerca android:process="system". Se il servizio è definito intenzionalmente per essere eseguito nel processo di sistema, viene eseguito nello stesso processo del servizio di sistema e deve essere inserito nell'elenco consentiti per essere eseguito nell'utente di sistema. Nell'ambito del design di allocazione della memoria di Android, i servizi di sistema sono alcuni degli ultimi processi da arrestare, il che implica la criticità dei servizi definiti con questo attributo. Per scoprire di più sul design di allocazione della memoria di Android, vedi Kicker con memoria ridotta.

  • Se è impostata su , non consentire l'accesso alla lista consentita.
  • Se invece è No, continua a controllare gli altri componenti.

Ad esempio, il pacchetto com.android.networkstack.inprocess deve essere inserito nella lista consentita perché contiene RegularMaintenanceJobService, che include il tag android:process="system".

Fornitore di contenuti

Per scoprire di più sui fornitori di contenuti, consulta la pagina Fornitori di contenuti.

f. Controlla se l'app installata nell'utente di sistema dipende da questo provider

Controlla se sono presenti pacchetti nella lista consentita nel Livello 1 e verifica da quali fornitori dipendono. Se un'app in esecuzione nell'utente di sistema (ad esempio, com.android.car.companiondevicesupport è nella lista consentita per l'esecuzione nell'utente di sistema) e dipende da questo fornitore di contenuti, assicurati che anche questo fornitore di contenuti sia nella lista consentita.

  1. Se , inseriscilo nella lista consentita.
  2. Se rispondi No, non inserire il dominio nella lista consentita.

Ad esempio, se com.android.car.EXAMPLE contiene fornitori singolari (SystemActionsContentProvider e ManagedProvisioningActionsContentProvider), deve essere inserito nella lista consentita per l'utente di sistema. Quindi, se com.android.car.EXAMPLE dipende da android.webkit per WebViewFactoryProvider, com.android.webview deve essere inserito nella lista consentita per l'utente di sistema dato che carica android.webkit.

Procedura dettagliata per il pacchetto di esempio

L'esempio seguente mostra come valutare il AndroidManifest.xml di un pacchetto:

<?xml version="1.0" encoding="utf-8"?>
<!-- 1. Search in the entire manifest for singleUser attribute.
No. Move to step 2 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.providers.calendar"
        android:sharedUserId="android.uid.calendar">
    We can ignore the entire permission section
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    ...
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<!-- 2. Look for defaultToDeviceProtectedStorage in application's attribute.
No. Continue evaluating app components. -->
    <application android:label="@string/calendar_storage"
                 android:allowBackup="false"
                 android:icon="@drawable/app_icon"
                 android:usesCleartextTraffic="false">
<!-- a. Contain only activities?
No. Continue to evaluate components other than activities. -->
        <provider android:name="CalendarProvider2" android:authorities="com.android.calendar"
                <!-- b. Is this component exported?
                Yes. Continue evaluating this component.
                f. App on u0 might depend on this? Search for CalendarProvider2 in dumpsys, shows ContentProviderRecord{b710923 u0 com.android.providers.calendar/.CalendarProvider2}
                Yes. Whitelist for system user. -->
                android:label="@string/provider_label"
                android:multiprocess="false"
                android:exported="true"
                android:readPermission="android.permission.READ_CALENDAR"
                android:writePermission="android.permission.WRITE_CALENDAR" />

<activity android:name="CalendarContentProviderTests" android:label="Calendar Content Provider" android:exported="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.UNIT_TEST" /> </intent-filter> </activity> <!-- Not service/content provider. Ignore. --> <receiver android:name="CalendarProviderBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.android.providers.calendar.intent.CalendarProvider2"/> <category android:name="com.android.providers.calendar"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.EVENT_REMINDER"/> <data android:scheme="content" /> </intent-filter> </receiver> <service android:name="CalendarProviderIntentService"/> </application> </manifest>