Supprimer des packages pour l'utilisateur système

Cette page explique comment améliorer vos performances en identifiant et en supprimant les packages qui ne sont pas nécessaires à l’utilisateur du système.

Désactiver les packages inutiles

Dans Automotive, l'utilisateur système est sans interface graphique, ce qui signifie que l'utilisateur du système n'est pas destiné à être utilisé ou accessible directement humain. Par conséquent, de nombreuses applications et services n'ont pas besoin d'être exécutés dans l'utilisateur système et peuvent être désactivés pour améliorer les performances. Par conséquent, une option est fournie pour supprimer les applications inutiles pour l'utilisateur système (utilisateur 0).

Cette page présente deux types d'utilisateurs:

  • SYSTEM (SYSTÈME) Toujours utilisateur 0
  • FULL Utilisateur destiné à être utilisé par un humain (un utilisateur non système), utilisateur 10 et plus

Android 11

Dans Android 11, modifiez config_userTypePackageWhitelistMode configuration. Les indicateurs peuvent être combinés. Dans ce cas, 5 équivaut à 1 plus 4 (une combinaison des options 1 et 4).

Signaler Description
0 Désactivez la liste d'autorisation. Installer tous les packages système aucune journalisation.
1 Appliquer. N'installez les packages système que s'ils figurent sur la liste d'autorisation.
2 Consignez les packages qui ne figurent pas sur la liste d'autorisation.
4 Tout package non mentionné dans le fichier de liste d'autorisation est implicitement ajouté à la liste d'autorisation pour tous les utilisateurs.
8 Identique à 4 pour l'utilisateur système.
16 Ignorer les OTA. N'installez pas de packages système lors des mises à jour OTA.

Voici quelques scénarios courants :

  • Pour activer une fonctionnalité pour une liste d'autorisation complète, 1 (application complète)
  • Pour activer une fonctionnalité pour une liste d'autorisation incomplète, 5
  • Pour activer une fonctionnalité permettant à l'utilisateur SYSTEM de faciliter le développement local, 9 (liste d'autorisation implicite)
  • Pour désactiver une fonctionnalité comme si elle n'avait jamais été activée, 16
  • Pour désactiver une fonctionnalité et annuler tous les effets précédents, 0

Installez le fichier XML dans le répertoire sysconfig de l'appareil (il s'agit du même répertoire que celui contenant le fichier makefile (.mk) utilisé pour créer l'image système de l'appareil). Lorsque vous nommez le fichier XML, indiquez l'emplacement où le package est défini dans la compilation, par exemple 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 et Android 10

Pour configurer cette fonctionnalité sous Android 9 et Android 10 :

  1. Superposez la configuration config_systemUserPackagesBlacklistSupported à partir de frameworks/base/core/res/res/values/config.xml et définissez-la sur true. Lorsque la fonctionnalité est activée, tous les paquets doivent être installés par défaut pour l'utilisateur système et l'utilisateur FULL.
  2. Créez un fichier config.xml listant les packages à utiliser. désactivé pour l'utilisateur système, par exemple:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
  3. Ajoutez une ligne à device.mk pour copier le fichier dans le Dossier cible system/etc/sysconfig/, par exemple:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Vérifier le résultat

Pour vérifier le résultat, exécutez la commande suivante:

$ 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

Bâtiment

Pour déterminer si un package doit être installé dans l'utilisateur système, examinez le fichier AndroidManifest.xml du package situé à la racine de la source du projet, y compris les attributs de l'application et les composants de l'application, qui incluent toutes les activités, services, broadcast receivers et fournisseurs de contenu. Pour en savoir plus, consultez la présentation du fichier manifeste d'application.

Désactiver le workflow des packages

Figure 1 : Désactiver le workflow des packages

Niveau 1, au niveau de l'application

1. Vérifier si l'application (ou ses composants) est déclarée comme un singleton

Si l'application est un singleton, le système instancie l'application dans l'utilisateur système uniquement. Il est probable que l'application ait été conçue pour être multi-utilisateur. Pour en savoir plus sur les applications multi-utilisateurs, consultez Créer des applications multi-utilisateurs.

  1. Recherchez android:singleUser="true" dans le fichier manifeste Android.
  2. Si la valeur est true, ajoutez à la liste d'autorisation. Requis pour l'utilisateur système.
  3. Si la réponse est false, continuez. Vérifiez d'autres critères avant de supprimer.

2. Vérifier si l'application nécessite un accès au stockage protégé

De nombreux services de démarrage du système s'appuient souvent sur un stockage chiffré par l'appareil de stockage chiffré par identifiants (CE). De plus, les applications système compatibles avec le démarrage direct reposent également sur le stockage chiffré de l'appareil. Pour en savoir plus sur les applications compatibles avec le démarrage direct, consultez la section Prendre en charge le démarrage direct dans les applications système.

  1. Recherchez dans le fichier manifeste Android android:defaultToDeviceProtectedStorage="true", qui est nécessaire pour de nombreux services de démarrage du système.
  2. Si la valeur est true, ajoutez-le à la liste d'autorisation.
  3. Si la réponse est false, continuez.

Niveau 2 : composants de l'application

Activités

Pour en savoir plus sur les activités, consultez la section Présentation des activités.

a. Vérifier si l'application ne contient que des activités

Les activités sont orientées interface utilisateur. Étant donné que l'utilisateur système est headless dans Automotive, aucun humain ne doit interagir avec l'utilisateur système. Par conséquent, si l'application ne contient que des activités, elle n'est probablement pas pertinente pour utilisateur système.

Vérifiez si vous disposez des droits prioritaires et des privilèges spéciaux:

  1. Si la réponse est Oui, cela peut être nécessaire pour l'utilisateur système.
  2. Si la réponse est Non, n'ajoutez pas l'utilisateur système à la liste d'autorisation.

Par exemple, la suite de tests de compatibilité (CTS) (com.android.cts.priv.ctsshim) ne contient que des activités, et les activités sont définies pour tester les filtres d'intent. Toutefois, comme CTS dispose de droits élevés, il doit être installé pour l'utilisateur système à des fins de test.

Services

Pour en savoir plus sur les services, consultez la page Présentation des services.

b. Vérifiez si le service est déclaré comme privé et s'il n'est pas accessible depuis d'autres applications

Si le service est déclaré comme privé, les autres packages ne l'utiliseront pas. Recherchez android:exported="false". Si le service est déclaré comme privé ou qu'il n'est pas accessible à partir d'autres applications, il ne peut pas être lié par d'autres applications. Par conséquent, les étapes c et d ci-dessous sont sans objet. Par conséquent, ce composant ne fournirait pas plus d'indications sur l'utilité du service pour l'utilisateur système.

  • Si la réponse est Oui, vérifiez le composant suivant.
  • Si la valeur est Non, continuez à vérifier ce composant.

c. Vérifiez si les applis installées dans l'utilisateur système peuvent être liées à ce service

Vérifiez les packages ajoutés à la liste d'autorisation au niveau 1 et identifiez les services auquel ils sont liés. Traçage à partir du filtre d'intent dans ce service et startService dans d'autres packages.

Si ce service est lié aux applications installées dans l'utilisateur système (par exemple, com.android.car.companiondevicesupport est ajouté à la liste d'autorisation pour s'exécuter dans l'utilisateur système), ajoutez le service à la liste d'autorisation :

  • Si Oui, ajoutez la liste d'autorisation.
  • Si la réponse est Non, continuez à vérifier ce composant.

d. Vérifier si le service est lié à d'autres applications et déclaré pour s'exécuter au premier plan

Recherchez startForeground. Cela signifie que les utilisateurs interagiront avec l'application au premier plan. Très probablement, ce service ne serait pas nécessaire pour utilisateur système et ne doivent pas être ajoutés à la liste d'autorisation:

  • Si oui, ne pas ajouter à la liste d'autorisation.
  • Si la valeur est Non, passez au composant suivant.

e. Vérifier si le service est défini pour s'exécuter dans le processus système

Dans le fichier AndroidManifest, recherchez android:process="system". Si le service est intentionnellement défini pour s'exécuter dans le processus système, il s'exécute dans le même processus que le service système et doit être ajouté à la liste d'autorisation pour s'exécuter dans l'utilisateur système. Dans la mémoire d'Android conception de l’allocation, les services système sont parmi les derniers processus à être arrêtés, ce qui implique la criticité des services définis avec un tel attribut. À Pour en savoir plus sur la conception d'allocation de mémoire d'Android, consultez la section Faible mémoire meurtrier.

  • Si oui, ne pas ajouter à la liste d'autorisation.
  • Si la valeur est Non, poursuivez la vérification des autres composants.

Par exemple, le package com.android.networkstack.inprocess doit être ajoutée à la liste d'autorisation, car elle contient RegularMaintenanceJobService, qui comporte le tag android:process="system".

Fournisseur de contenu

Pour en savoir plus sur les fournisseurs de contenu, consultez la section Fournisseurs de contenu.

f. Vérifier si l'application installée pour l'utilisateur système dépend de ce fournisseur

Recherchez les packages sur la liste d'autorisation au niveau 1 et les fournisseurs concernés dépendent. Si une application exécutée dans l'utilisateur système (par exemple, com.android.car.companiondevicesupport est ajouté à la liste d'autorisation pour s'exécuter dans l'utilisateur système) et dépend de ce fournisseur de contenu, assurez-vous que ce fournisseur de contenu est également ajouté à la liste d'autorisation.

  1. Si la réponse est Oui, ajoutez-le à la liste d'autorisation.
  2. Si Non, n'ajoutez pas à la liste d'autorisation.

Par exemple, si com.android.car.EXAMPLE contient singleton fournisseurs (SystemActionsContentProvider et ManagedProvisioningActionsContentProvider), il doit s'agir de ajouté à la liste d'autorisation pour l'utilisateur système. Ensuite, si com.android.car.EXAMPLE dépend de android.webkit pour WebViewFactoryProvider, com.android.webview doit être ajouté à la liste d'autorisation pour l'utilisateur système étant donné qu'elle charge android.webkit.

Tutoriel d'exemple de package

L'exemple suivant montre comment évaluer le AndroidManifest.xml d'une package:

<?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>