Usuwanie pakietów dla użytkownika systemowego

Na tej stronie opisujemy, jak zwiększyć wydajność przez zidentyfikowanie i usunięcie pakietów, które nie są potrzebne użytkownikowi systemu.

Wyłącz niepotrzebne pakiety

W przypadku Automotive użytkownik systemu jest bezgłowy, co oznacza, że nie jest przeznaczony do użytku przez człowieka ani do bezpośredniego dostępu przez człowieka. Dzięki temu wiele aplikacji i usług nie musi uruchamiać się przez użytkownika systemowego, można je wyłączyć, by poprawić wydajność. Dlatego udostępniamy opcję usuwania niepotrzebnych aplikacji dla użytkownika systemu (użytkownik 0).

Na tej stronie omawiamy 2 rodzaje użytkowników:

  • SYSTEM. Zawsze użytkownik 0
  • PEŁNY. Użytkownik, który ma być używany przez człowieka (użytkownik niesystemowy), Użytkownik 10+

Android 11

W Androidzie 11 zmień konfigurację config_userTypePackageWhitelistMode. Flagi można łączyć. W tym przypadku 5 jest równoważne z 1 plus 4 (kombinacja flag 14).

Zgłoś Opis
0 Wyłącz listę dozwolonych. zainstalować wszystkie pakiety systemowe; brak logowania.
1 Wymuś. Instaluj pakiety systemowe tylko wtedy, gdy są one na liście dozwolonych.
2 Rejestruj pakiety spoza listy dozwolonych.
4 Każdy pakiet, który nie jest wymieniony w pliku z dozwolonymi pakietami, jest domyślnie dodawany do listy dozwolonych pakietów dla wszystkich użytkowników.
8 Takie same jak 4 w przypadku użytkownika systemowego.
16 Ignoruj OTA. Nie instaluj pakietów systemowych podczas aktualizacji OTA.

Rozważ te typowe scenariusze:

  • Aby włączyć funkcję na liście dozwolonych, 1 (w pełni wymuszone)
  • Aby włączyć funkcję na niepełnej liście dozwolonych, 5
  • Aby włączyć funkcję dla użytkownika SYSTEM, aby ułatwić lokalny rozwój, 9 (implikatywna lista dozwolonych)
  • Aby wyłączyć funkcję, tak jakby nigdy nie była włączona, 16
  • Aby wyłączyć funkcję i cofnąć wszystkie poprzednie efekty, 0

Zainstaluj plik XML w katalogu sysconfig urządzenia (to ten sam katalog, który zawiera plik makefile (.mk) używany do kompilowania obrazu systemu urządzenia). W nazwie pliku XML umieść lokalizację gdzie pakiet jest zdefiniowany w kompilacji, na przykład 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 i Android 10

Aby skonfigurować tę funkcję na Androidzie 9 i 10:

  1. Nałóż: config_systemUserPackagesBlacklistSupported Konfiguracja z frameworks/base/core/res/res/values/config.xml i ustawiona go do true. Gdy ta funkcja jest włączona, domyślnie wszystkie pakiety powinna być zainstalowana zarówno dla użytkownika systemowego, jak i użytkownika FULL.
  2. Utwórz plik config.xml, w którym podasz, które pakiety mają być wyłączone dla użytkownika systemu, na przykład:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
  3. Dodaj wiersz do device.mk, aby skopiować plik do folderu docelowego urządzenia system/etc/sysconfig/, na przykład:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Sprawdź wynik

Aby sprawdzić wynik, uruchom:

$ 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

Budynek

Aby określić, czy pakiet powinien być zainstalowany u użytkownika systemu, przejrzyj AndroidManifest.xml pakietu znajduje się w katalogu głównym źródła projektu, w tym atrybuty aplikacji i komponenty w tym dane dotyczące wszystkich aktywności, usług, odbiorników i treści dostawców usług. Więcej informacji: Kampanie promujące aplikacje plik manifestu.

Wyłączanie przepływu pracy pakietów

Rysunek 1. Wyłączenie przepływu pracy pakietów.

Poziom 1, poziom aplikacji

1. Sprawdź, czy aplikacja (lub jej komponenty) jest zadeklarowana jako singleton

Jeśli aplikacja jest singletonem, system tworzy instancję aplikacji tylko dla użytkownika systemowego. Prawdopodobnie aplikacja była przeznaczona dla wielu użytkowników. Więcej informacji o aplikacji dla wielu użytkowników znajdziesz w artykule Tworzenie aplikacji dla wielu użytkowników.

  1. Sprawdź plik manifestu Androida dla aplikacji android:singleUser="true".
  2. Jeśli true, dodaj do listy dozwolonych. Wymagane dla użytkownika systemu.
  3. Jeśli false, przejdź dalej. Zanim usuniesz, sprawdź inne kryteria.

2. Sprawdź, czy aplikacja wymaga dostępu do chronionej pamięci

Wiele usług uruchamiania systemu często korzysta z urządzenia z szyfrowaniem (DE) zamiast z urządzenia z szyfrowaniem poświadczeń (CE). Poza tym bezpośrednie aplikacje systemowe również zależy od pamięci zaszyfrowanej na urządzeniu. Więcej informacji o aplikacjach obsługujących bezpośrednie uruchamianie znajdziesz w artykule Obsługa bezpośredniego uruchamiania w aplikacjach systemowych.

  1. Sprawdź plik manifestu Androida android:defaultToDeviceProtectedStorage="true", które jest wymagane w przypadku przy uruchamianiu systemu.
  2. Jeśli true, dodaj do listy dozwolonych.
  3. Jeśli false, kontynuuj.

Poziom 2. Komponenty aplikacji

Działania

Więcej informacji o aktywnościach znajdziesz w artykule Wprowadzenie do aktywności.

a. Sprawdzanie, czy aplikacja zawiera tylko aktywności

Działania są zorientowane na interfejs. W systemie Automotive użytkownik jest bez głowy, więc żadna osoba nie powinna wchodzić z nim w interakcję. Z tego względu, jeśli Aplikacja zawiera same aktywności, prawdopodobnie nie ma związku z użytkownika systemu.

Sprawdź priorytet i specjalne uprawnienia:

  1. Jeśli odpowiedź to Tak, może być potrzebna dla użytkownika systemu.
  2. Jeśli odpowiedź to Nie, nie dodawaj użytkownika systemu do listy dozwolonych.

Na przykład Compatibility Test Suite (CTS) (com.android.cts.priv.ctsshim) zawiera tylko aktywności, na potrzeby testowania filtrów intencji. Jednak ze względu na to, że CTS ma wysokie uprawnienia, do celów testowania należy go zainstalować dla użytkownika systemu.

Usługa

Więcej informacji o usługach znajdziesz w artykule Omówienie usług.

b. Sprawdź, czy usługa jest zadeklarowana jako prywatna i czy nie można uzyskać do niej dostępu z innych aplikacji

Jeśli usługa jest zadeklarowana jako prywatna, inne pakiety nie będą z niej korzystać. Poszukaj android:exported="false". Jeśli usługa jest zadeklarowana jako prywatne lub niedostępne w innych aplikacjach, nie można go powiązać przez z innymi aplikacjami. Dlatego kroki cd są nieistotne. W rezultacie ten komponent nie poda dodatkowych wskazówek na temat tego, czy usługa jest potrzebna użytkownikowi systemu.

  • Jeśli Tak, sprawdź następny komponent.
  • Jeśli Nie, kontynuuj sprawdzanie tego komponentu.
.

c. Sprawdź, czy aplikacje zainstalowane w systemie użytkownika mogą się z nim połączyć

Sprawdź, czy na poziomie 1 są dostępne pakiety z dozwoloną listą, i ustal, do których usług są one powiązane. Ślad z filtra intencji w tej usłudze i w startService w innych pakietach.

Jeśli ta usługa jest powiązana z aplikacjami zainstalowanymi w ramach konta użytkownika systemu (na przykład com.android.car.companiondevicesupport jest na liście dozwolonych do uruchamiania w ramach konta użytkownika systemu), dodaj tę usługę do listy dozwolonych:

  • Jeśli odpowiedź to Tak, dodaj aplikację do listy dozwolonych.
  • Jeśli odpowiedź brzmi Nie, kontynuuj sprawdzanie tego komponentu.

d. Sprawdź, czy usługa jest powiązana z innymi aplikacjami i zadeklarowana do działania na pierwszym planie

Poszukaj startForeground. Oznacza to, że ludzie wchodzą w interakcję z: i aplikacjami na pierwszym planie. Najprawdopodobniej ta usługa nie będzie potrzebna w przypadku użytkownika systemu i nie muszą znajdować się na liście dozwolonych:

  • Jeśli Tak, nie dodawaj do listy dozwolonych.
  • Jeśli nie, sprawdź następny komponent.

e. Sprawdź, czy usługa jest zdefiniowana do działania w procesie systemowym

W pliku AndroidManifest odszukaj android:process="system". Jeśli usługa jest celowo zdefiniowana do uruchamiania w procesie systemowym, działa w tym samym procesie co usługa systemowa, powinny znajdować się na liście dozwolonych i uruchamiać je u użytkownika systemowego. W ramach projektu alokacji pamięci Androida usługi systemowe są jednymi z ostatnich procesów, które są zabijane, co sugeruje, że są to usługi krytyczne zdefiniowane za pomocą tego atrybutu. Aby dowiedzieć się więcej o projektowaniu alokacji pamięci w Androidzie, zapoznaj się z artykułem Low-memory killer (ang.).

  • Jeśli odpowiedź brzmi Tak, nie dodawaj do listy dozwolonych.
  • Jeśli odpowiedź brzmi Nie, sprawdź inne komponenty.

Na przykład pakiet com.android.networkstack.inprocess musi być znajduje się na liście dozwolonych, ponieważ zawiera RegularMaintenanceJobService, który zawiera tag android:process="system".

Dostawca treści

Więcej informacji o dostawcach treści znajdziesz w artykule Dostawcy treści.

f. Sprawdź, czy aplikacja zainstalowana w systemie użytkownika zależy od tego dostawcy

Sprawdź, czy znajdują się na liście dozwolonych na poziomie 1, i sprawdź, których dostawców od których zależy. Jeśli aplikacja uruchomiona przez użytkownika systemowego (na przykład com.android.car.companiondevicesupport może działać w użytkownika systemu) i zależnie od tego dostawcy treści, upewnij się, że treści dostawca usług znajduje się na liście dozwolonych.

  1. Jeśli Tak, dodaj do listy dozwolonych.
  2. Jeśli odpowiedź to Nie, nie dodawaj do listy dozwolonych.

Jeśli na przykład com.android.car.EXAMPLE zawiera pojedyncze dostawców (SystemActionsContentProvider i ManagedProvisioningActionsContentProvider), należy dodać je do listy dozwolonych dla użytkownika systemu. Następnie, jeśli com.android.car.EXAMPLE zależy od wartości android.webkit dla WebViewFactoryProvider, wtedy com.android.webview musi znajdować się na liście dozwolonych dla użytkownika systemowego ponieważ wczytuje się android.webkit.

Przykładowa prezentacja pakietu

Poniższy przykład pokazuje, jak ocenić AndroidManifest.xml pakiet:

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