Pakete für den Systemnutzer entfernen

Auf dieser Seite wird beschrieben, wie Sie die Leistung verbessern, indem Sie Pakete identifizieren und entfernen, die für den Systemnutzer nicht erforderlich sind.

Unnötige Pakete deaktivieren

Im Bereich Automotive ist der Systemnutzer headless, d. h., er ist nicht für die Verwendung durch Menschen oder den direkten Zugriff durch Menschen vorgesehen. Daher müssen viele Anwendungen und Dienste nicht im Systemnutzer ausgeführt werden und können zur Verbesserung der Leistung deaktiviert werden. Daher gibt es eine Option, um unnötige Apps für den Systemnutzer (Nutzer 0) zu entfernen.

Auf dieser Seite werden zwei Arten von Nutzern erläutert:

  • SYSTEM Immer „Nutzer 0“
  • FULL gesetzt. Nutzer, der für die Verwendung durch einen Menschen (keinen Systemnutzer) gedacht ist, Nutzer 10+

Android 11

Ändern Sie in Android 11 die config_userTypePackageWhitelistMode-Konfiguration. Flags können kombiniert werden. In diesem Fall entspricht 5 1 + 4 (einer Kombination der Flags 1 und 4).

Melden Beschreibung
0 Deaktivieren Sie die Zulassungsliste. Alle Systempakete werden installiert, es erfolgt keine Protokollierung.
1 Erzwingen. Installieren Sie Systempakete nur, wenn sie auf der Zulassungsliste stehen.
2 Pakete protokollieren, die nicht auf der Zulassungsliste stehen.
4 Alle Pakete, die in der Zulassungsliste nicht aufgeführt sind, werden implizit für alle Nutzer auf die Zulassungsliste gesetzt.
8 Entspricht 4 für den Systemnutzer.
16 OTAs ignorieren. Installieren Sie keine Systempakete während der Over-the-air-Aktualisierungen.

Sehen Sie sich die folgenden häufigen Szenarien an:

  • Zum Aktivieren einer Funktion für eine vollständige Zulassungsliste 1 (vollständig erzwungen)
  • Wenn Sie eine Funktion für eine unvollständige Zulassungsliste aktivieren möchten, 5
  • Um eine Funktion für den Nutzer SYSTEM zu aktivieren, um die lokale Entwicklung zu vereinfachen,9 (implicit allowlist)
  • Wenn Sie eine Funktion so deaktivieren möchten, als wäre sie nie aktiviert gewesen, 16
  • Wenn Sie eine Funktion deaktivieren und alle vorherigen Effekte rückgängig machen möchten, 0

Installieren Sie die XML-Datei im Verzeichnis sysconfig des Geräts. Das ist dasselbe Verzeichnis, das das Makefile (.mk) enthält, mit dem das System-Image für das Gerät erstellt wurde. Geben Sie beim Benennen der XML-Datei den Speicherort an, an dem das Paket im Build definiert ist, z. B. 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 und Android 10

So konfigurieren Sie diese Funktion unter Android 9 und Android 10:

  1. Überlagern Sie die Konfiguration config_systemUserPackagesBlacklistSupported aus frameworks/base/core/res/res/values/config.xml und legen Sie sie auf true fest. Wenn die Funktion aktiviert ist, sollten standardmäßig alle Pakete sowohl für den Systemnutzer als auch für den Nutzer mit Vollzugriff installiert werden.
  2. Erstellen Sie eine config.xml-Datei mit einer Liste der Pakete, die für den Systemnutzer deaktiviert werden sollen. Beispiel:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
  3. Fügen Sie device.mk eine Zeile hinzu, um die Datei in den Zielordner system/etc/sysconfig/ des Geräts zu kopieren, z. B.:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Ergebnis prüfen

Führen Sie folgenden Befehl aus, um das Ergebnis zu prüfen:

$ 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

Gebäude

Um festzustellen, ob ein Paket für den Systemnutzer installiert werden soll, prüfen Sie die AndroidManifest.xml-Datei des Pakets im Stammverzeichnis der Projektquelle. Dazu gehören die Attribute und Komponenten der App, einschließlich aller Aktivitäten, Dienste, Broadcastempfänger und Inhaltsanbieter. Weitere Informationen finden Sie unter App-Manifest – Übersicht.

Paketworkflow deaktivieren

Abbildung 1: Paketworkflow deaktivieren.

Ebene 1, App-Ebene

1. Prüfen, ob die App (oder App-Komponenten) als Singleton deklariert ist

Wenn die Anwendung ein Singleton ist, instanziiert das System die Anwendung nur im Systemnutzer. Die App war wahrscheinlich als mehrbenutzerfähige App gedacht. Weitere Informationen zu mehrbenutzerfähigen Apps finden Sie unter Mehrbenutzerfähige Apps erstellen.

  1. Prüfe das Android-Manifest auf android:singleUser="true".
  2. Bei true auf die Zulassungsliste setzen. Wird für den Systemnutzer benötigt.
  3. Wenn false angezeigt wird, fahren Sie fort. Prüfen Sie andere Kriterien, bevor Sie die Seite entfernen.

2. Prüfen, ob die App Zugriff auf den geschützten Speicher benötigt

Viele Systemstartdienste nutzen häufig den geräteverschlüsselten Speicher (Device Encrypted, DE) anstelle des mit Anmeldedaten verschlüsselten Speichers (Credential Encrypted, CE). Außerdem benötigen System-Apps, die Direct Boot-fähig sind, ebenfalls den verschlüsselten Speicher des Geräts. Weitere Informationen zu Direct Boot-kompatiblen Apps finden Sie unter Direct Boot in System-Apps unterstützen.

  1. Prüfen Sie das Android-Manifest für android:defaultToDeviceProtectedStorage="true". Es wird für zahlreiche System-Bootdienste benötigt.
  2. Bei true auf die Zulassungsliste setzen.
  3. Wenn false, fahren Sie fort.

Ebene 2, App-Komponenten

Aktivitäten

Weitere Informationen zu Aktivitäten finden Sie unter Einführung in Aktivitäten.

a. Prüfen, ob die App nur Aktivitäten enthält

Aktivitäten sind auf die Benutzeroberfläche ausgerichtet. Da der Systemnutzer in Automotive monitorlos ist, sollte kein Mensch mit dem Systemnutzer interagieren. Wenn die App also nur Aktivitäten enthält, ist sie für den Systemnutzer höchstwahrscheinlich irrelevant.

Suchen Sie nach Priorität und besonderen Berechtigungen:

  1. Wenn Ja, ist dies möglicherweise für den Systemnutzer erforderlich.
  2. Wenn Nein, setzen Sie den Systemnutzer nicht auf die Zulassungsliste.

Die Compatibility Test Suite (CTS) (com.android.cts.priv.ctsshim) enthält beispielsweise nur Aktivitäten und Aktivitäten werden definiert, um Intent-Filter zu testen. Da CTS jedoch eine hohe Berechtigung hat, muss es für den Systemnutzer zu Testzwecken installiert werden.

Dienst

Weitere Informationen zu Diensten finden Sie unter Dienste – Übersicht.

b. Prüfen, ob der Dienst als privat deklariert ist und über andere Apps nicht aufgerufen werden kann

Wenn der Dienst als privat deklariert ist, wird er von anderen Paketen nicht verwendet. Suchen Sie nach android:exported="false". Wenn der Dienst als privat deklariert ist oder nicht über andere Anwendungen aufgerufen werden kann, kann er nicht an andere Anwendungen gebunden werden. Daher sind Schritt c und Schritt d unten irrelevant. Daher liefert diese Komponente keine weiteren Hinweise darauf, ob der Dienst für den Systemnutzer benötigt wird.

  • Wenn Ja, prüfen Sie die nächste Komponente.
  • Falls Nein, fahren Sie mit der Überprüfung dieser Komponente fort.

c. Prüfen, ob die im Systemnutzer installierten Apps an diesen Dienst gebunden werden

Prüfe, ob Pakete auf der Zulassungsliste in Ebene 1 stehen, und identifiziere die Dienste, mit denen sie verknüpft sind. Trace vom Intent-Filter in diesem Dienst und startService in anderen Paketen.

Wenn dieser Dienst an Anwendungen gebunden ist, die im Systemnutzer installiert sind (z. B. wenn com.android.car.companiondevicesupport auf der Zulassungsliste für die Ausführung im Systemnutzer steht), dann setzen Sie den Dienst auf die Zulassungsliste:

  • Wenn Ja, setzen Sie sie auf die Zulassungsliste.
  • Falls Nein, fahren Sie mit der Überprüfung dieser Komponente fort.

d. Prüfen, ob der Dienst von anderen Apps gebunden und für die Ausführung im Vordergrund deklariert ist

Suchen Sie nach startForeground. Das bedeutet, dass Nutzer mit der App im Vordergrund interagieren. Dieser Dienst ist für den Systemnutzer höchstwahrscheinlich nicht erforderlich und muss nicht auf die Zulassungsliste gesetzt werden:

  • Wenn Ja, setzen Sie die Domain nicht auf die Zulassungsliste.
  • Wenn Nein, fahren Sie mit der Prüfung der nächsten Komponente fort.

e. Prüfen, ob der Dienst so definiert ist, dass er im Systemprozess ausgeführt wird

Suche in der AndroidManifest-Datei nach android:process="system". Wenn der Dienst so definiert ist, dass er im Systemprozess ausgeführt wird, wird er im selben Prozess wie der Systemdienst ausgeführt und sollte in die Zulassungsliste für die Ausführung als Systemnutzer aufgenommen werden. Im Rahmen der Speicherzuweisung von Android sind Systemdienste einige der letzten Prozesse, die beendet werden. Das bedeutet, dass Dienste, die mit einem solchen Attribut definiert sind, kritisch sind. Weitere Informationen zum Arbeitsspeicherzuweisungsdesign von Android finden Sie unter Killer mit wenig Arbeitsspeicher.

  • Wenn Ja, setzen Sie die Domain nicht auf die Zulassungsliste.
  • Falls Nein, prüfen Sie die anderen Komponenten.

Beispiel: Paket com.android.networkstack.inprocess muss auf die Zulassungsliste gesetzt werden, da es RegularMaintenanceJobService enthält, das das Tag android:process="system" hat.

Contentanbieter

Weitere Informationen zu Contentanbietern finden Sie unter Contentanbieter.

f. Prüfen, ob die im System installierte App vom Nutzer abhängig ist

Prüfe, ob Pakete auf der Zulassungsliste in Stufe 1 stehen und von welchen Anbietern sie abhängig sind. Wenn eine App im Systemnutzer ausgeführt wird (z. B. com.android.car.companiondevicesupport auf der Zulassungsliste für die Ausführung im Systemnutzer steht) und von diesem Inhaltsanbieter abhängig ist, muss dieser Inhaltsanbieter ebenfalls auf der Zulassungsliste stehen.

  1. Wenn Ja, setzen Sie sie auf die Zulassungsliste.
  2. Wenn Nein, setzen Sie sie nicht auf die Zulassungsliste.

Wenn com.android.car.EXAMPLE beispielsweise Singleton-Anbieter (SystemActionsContentProvider und ManagedProvisioningActionsContentProvider) enthält, sollte es auf die Zulassungsliste für den Systemnutzer gesetzt werden. Wenn com.android.car.EXAMPLE dann für WebViewFactoryProvider von android.webkit abhängt, muss com.android.webview für den Systemnutzer auf die Zulassungsliste gesetzt werden, da android.webkit geladen wird.

Beispielhafte Schritt-für-Schritt-Anleitung für ein Paket

Das folgende Beispiel zeigt, wie die AndroidManifest.xml eines Pakets ausgewertet wird:

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