Rimuovere i pacchetti per l'utente del sistema

In questo articolo viene descritto come migliorare le prestazioni identificando e rimuovendo i pacchetti non necessari per l'utente del sistema.

Disabilita i pacchetti non necessari

In Automotive, l'utente del sistema è senza testa , il che significa che l'utente del sistema non è destinato a essere utilizzato o accessibile direttamente da un essere umano. Di conseguenza, non è necessario che molte app e servizi vengano eseguiti nell'utente del sistema e possono essere disabilitati per migliorare le prestazioni. Pertanto, viene fornita un'opzione per rimuovere le app non necessarie per l'utente del sistema (utente 0).

In questa pagina vengono discusse due tipologie di Utenti:

  • SISTEMA . Sempre Utente 0
  • PIENO . Utente destinato a essere utilizzato da un essere umano (un utente non di sistema), Utente 10+

Androide 11

In Android 11, modifichi la configurazione, config_userTypePackageWhitelistMode . Le bandiere possono essere combinate. In questo caso, 5 equivale a 1 più 4 (una combinazione dei flag 1 e 4 ).

Bandiera Descrizione
0 Disattiva la lista consentita. Installa tutti i pacchetti di sistema; nessuna registrazione.
1 Imporre. Installa i pacchetti di sistema solo quando sono inclusi nella lista consentita.
2 Registra i pacchetti non consentiti.
4 Qualsiasi pacchetto non menzionato nel file della lista consentita è implicitamente consentito per tutti gli utenti.
8 Uguale a 4 , per l'utente di sistema.
16 Ignora le OTA. Non installare pacchetti di sistema durante le OTA.
Considera questi scenari comuni.
  • Per abilitare una funzionalità per una lista consentita completa, 1 ( applicazione completa )
  • Per abilitare una funzionalità per una lista consentita incompleta, 5
  • Per abilitare una funzionalità per l'utente SYSTEM per facilitare lo sviluppo locale, 9 ( lista consentita implicita )
  • Per disabilitare una funzionalità come se non fosse mai stata abilitata, 16
  • Per disabilitare una funzione e annullare tutti gli effetti precedenti, 0

Assicurati di installare il file XML nella directory sysconfig per il dispositivo (questa è la stessa directory che contiene il makefile (`.mk`) utilizzato per creare l'immagine di sistema per il dispositivo). Quando assegni un nome al file XML, includi il percorso in cui è definito il pacchetto nel file build. 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 la configurazione config_systemUserPackagesBlacklistSupported da frameworks/base/core/res/res/values/config.xml e impostala su true . Quando la funzionalità è attivata, per impostazione predefinita, tutti i pacchetti dovrebbero essere installati sia per l'utente di sistema che per l'utente COMPLETO.
  2. Creare un file config.xml che elenca quali pacchetti devono essere disabilitati per l'utente del 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 del dispositivo system/etc/sysconfig/ . Ad esempio:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml
    

Verificare il risultato

Per verificare il risultato, eseguire:

$ 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

Premessa

Per determinare se un pacchetto deve essere installato nell'utente di sistema, esaminare il file AndroidManifest.xml del pacchetto situato nella radice dell'origine del progetto, inclusi gli attributi dell'app e i componenti dell'app, che includono tutte le attività, i servizi, i ricevitori di trasmissione, e fornitori di contenuti. Per ulteriori informazioni, consulta Panoramica del manifest dell'app .

Disabilita il flusso di lavoro dei pacchetti

Figura 1. Disabilita il flusso di lavoro dei pacchetti

Livello 1, livello dell'app

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

Se l'app è un singleton , il sistema creerà un'istanza dell'app solo nell'utente del sistema. È probabile che l'app fosse concepita per essere un'app multiutente. Per ulteriori informazioni sulle app multiutente, consulta Creazione di app multiutente .

  1. Controlla il file manifest di Android per android:singleUser="true" .
  2. Se vero , lista consentita. Necessario per l'utente del sistema.
  3. Se falso , continua. Controlla altri criteri prima di rimuovere.

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

Molti servizi di avvio del sistema si basano spesso sull'archiviazione con crittografia del dispositivo (DE) invece che sull'archiviazione con crittografia delle credenziali (CE). Inoltre, anche le app di sistema che rilevano l'avvio diretto si affidano all'archiviazione crittografata del dispositivo. Per ulteriori informazioni sulle app che supportano l'avvio diretto, consulta Supporto dell'avvio diretto nelle app di sistema .

  1. Controllare il manifest Android per android:defaultToDeviceProtectedStorage="true" , ​​necessario per numerosi servizi di avvio del sistema.
  2. Se vero , lista consentita.
  3. Se falso , continua.

Livello 2, componenti dell'app

Attività

Per ulteriori informazioni sulle attività, vedere Introduzione alle attività .

UN. Controlla se l'app contiene solo attività

Le attività sono orientate all'interfaccia utente. Poiché nel settore automobilistico l'utente del sistema è senza testa, nessun essere umano dovrebbe interagire con l'utente del sistema. Di conseguenza, se l'app contiene solo attività, molto probabilmente non è rilevante per l'utente del sistema.

Verifica la priorità e i privilegi speciali.

  1. Se , forse è necessario per l'utente del sistema.
  2. Se No , non consentire l'inserimento nella lista consentita per l'utente del sistema.

Ad esempio, Compatibility Test Suite (CTS) ( com.android.cts.priv.ctsshim ) contiene solo attività e le attività sono definite per testare i filtri di intenti. Tuttavia, poiché dispone di privilegi elevati, deve essere installato per l'utente del sistema a scopo di test.

Servizio

Per ulteriori informazioni sui servizi, consulta Panoramica dei servizi .

B. Controlla se il servizio è dichiarato privato e non è possibile accedervi da altre app

Se il servizio viene dichiarato privato , gli altri pacchetti non utilizzeranno il servizio. Cerca android:exported="false" . Se il servizio è dichiarato privato o non è accessibile da altre app, non può essere vincolato da altre app. Pertanto, i passaggi C e D riportati di seguito sono irrilevanti. Di conseguenza, questo componente non fornirebbe ulteriori suggerimenti sulla necessità o meno del servizio per l'utente del sistema.

  1. Se , controlla il componente successivo.
  2. In caso negativo , continuare a controllare questo componente.

C. Controlla se le app installate nell'utente di sistema potrebbero collegarsi a questo servizio

Controlla i pacchetti consentiti nel Livello 1 e identifica i servizi a cui sono vincolati. Traccia dal filtro intent in questo servizio e startService in altri pacchetti.

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

  1. Se , lista consentita.
  2. In caso negativo , continuare 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 le persone interagirebbero con l'app in primo piano. Molto probabilmente, questo servizio non sarà necessario per l'utente del sistema e non dovrà essere inserito nella lista consentita.

  1. Se , non consentire la lista.
  2. In caso negativo , continuare a controllare il componente successivo.

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

Nel Manifest Android, cerca android:process="system" .
Se il servizio è intenzionalmente definito per l'esecuzione nel processo di sistema, significa che verrà eseguito esplicitamente nello stesso processo del servizio di sistema e dovrebbe essere consentito l'esecuzione nell'utente di sistema. Nell'ambito del progetto di allocazione della memoria di Android, i servizi di sistema sono alcuni degli ultimi processi a essere terminati, il che implica la criticità dei servizi definiti con tale attributo. Per ulteriori informazioni sulla progettazione dell'allocazione della memoria di Android, vedere Killer per memoria insufficiente .

  1. Se , non consentire la lista.
  2. In caso negativo , continuare a controllare gli altri componenti.

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

Fornitore di contenuti

Per ulteriori informazioni sui fornitori di contenuti, consulta Fornitori di contenuti .

F. Controlla se l'app installata nell'utente del sistema dipende da questo provider

Controlla i pacchetti consentiti nel Livello 1 e controlla 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 , lista consentita.
  2. Se No , non consentire la lista.

Ad esempio, se com.android.car.EXAMPLE contiene provider singleton ( SystemActionsContentProvider e ManagedProvisioningActionsContentProvider ), dovrebbe essere inserito nella lista consentita per l'utente del 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 del sistema dato che carica android.webkit .

Procedura dettagliata del pacchetto di esempio

L'esempio seguente mostra come valutare 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>