Cette page explique comment améliorer les 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 le secteur automobile, l'utilisateur système est sans tête, ce qui signifie qu'il n'est pas destiné à être utilisé ni à être directement accessible par un 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).
Deux types d'utilisateurs sont abordés sur cette page:
- SYSTEM. Toujours l'utilisateur 0
- FULL Utilisateur destiné à être utilisé par un humain (un utilisateur non système), utilisateur 10 et plus
Android 11
Sous Android 11, modifiez la configuration config_userTypePackageWhitelistMode
. 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. Installez tous les packages système. Aucune journalisation. |
1 |
Appliquez-la. N'installez les packages système que lorsqu'ils figurent sur la liste d'autorisation. |
2 |
Consigner les packages non figurant sur une liste d'autorisation |
4 |
Tout paquet 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 |
Ignorez 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, incluez 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:
- Superposez la configuration
config_systemUserPackagesBlacklistSupported
à partir deframeworks/base/core/res/res/values/config.xml
et définissez-la surtrue
. 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. - Créez un fichier
config.xml
listant les packages à désactiver 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>
- Ajoutez une ligne à
device.mk
pour copier le fichier dans le dossier ciblesystem/etc/sysconfig/
de l'appareil, 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.
Figure 1 : Désactivation du workflow de packages.
Niveau 1, 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.
- Recherchez
android:singleUser="true"
dans le fichier manifeste Android. - Si la valeur est
true
, ajoutez-la à la liste d'autorisation. Nécessaire pour l'utilisateur du système. - 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 reposent souvent sur le stockage chiffré de l'appareil (DE) plutôt que sur le stockage chiffré des 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.
- Vérifiez le fichier manifeste Android pour
android:defaultToDeviceProtectedStorage="true"
, qui est nécessaire pour de nombreux services de démarrage du système. - Si la valeur est
true
, ajoutez-la à la liste d'autorisation. - 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 est très probablement sans intérêt pour l'utilisateur du système.
Vérifiez si vous disposez d'un droit de priorité ou d'un droit spécial:
- Si la réponse est Oui, cela peut être nécessaire pour l'utilisateur système.
- 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érifier si le service est déclaré comme privé et ne peut pas être consulté à partir 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 d'indications supplémentaires sur la nécessité du service pour l'utilisateur du système.
- Si la réponse est Oui, vérifiez le composant suivant.
- Si la réponse est Non, continuez à vérifier ce composant.
c. Vérifier si les applications installées dans l'utilisateur système peuvent se lier à ce service
Recherchez les packages de la liste d'autorisation au niveau 1 et identifiez les services auxquels ils sont associé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 à la liste d'autorisation:
- Si la réponse est Oui, ajoutez-le à 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 interagissent avec l'application au premier plan. Il est fort probable que ce service ne soit pas nécessaire pour l'utilisateur système et qu'il n'ait pas besoin d'être ajouté à la liste d'autorisation:
- Si la réponse est Oui, ne l'ajoutez pas à la liste d'autorisation.
- Si la réponse 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 défini intentionnellement 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 conception de l'allocation de mémoire d'Android, 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 de l'allocation de mémoire d'Android, consultez Tueur de faible mémoire.
- Si la réponse est Oui, ne l'ajoutez pas à la liste d'autorisation.
- Si non, continuez à vérifier les autres composants.
Par exemple, le package com.android.networkstack.inprocess
doit être ajouté à la liste d'autorisation, car il contient RegularMaintenanceJobService
, qui possède la balise 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 dans l'utilisateur système dépend de ce fournisseur
Recherchez les packages de la liste d'autorisation au niveau 1 et vérifiez les fournisseurs dont ils 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.
- Si la réponse est Oui, ajoutez-le à la liste d'autorisation.
- Si la réponse est Non, n'ajoutez pas l'application à la liste d'autorisation.
Par exemple, si com.android.car.EXAMPLE
contient des fournisseurs singleton (SystemActionsContentProvider
et ManagedProvisioningActionsContentProvider
), il doit être 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, car il charge android.webkit
.
Exemple de tutoriel sur les packages
L'exemple suivant montre comment évaluer le AndroidManifest.xml
d'un 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>