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łączanie niepotrzebnych pakietów

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. W rezultacie wiele aplikacji i usług nie musi działać w ramach konta systemowego i może zostać wyłączone, aby zwiększyć 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 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. Instalowanie wszystkich pakietów systemowych bez rejestrowania.
1 Wymuś. Instaluj pakiety systemowe tylko wtedy, gdy są one umieszczone na liście dozwolonych.
2 rejestrowanie pakietów, które nie są na liście 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 To samo co 4 dla użytkownika systemu.
16 Ignoruj OTA. Nie instaluj pakietów systemowych podczas aktualizacji OTA.

Rozważ te typowe scenariusze:

  • Aby włączyć funkcję na całej liście dozwolonych, 1 (w pełni zaimplementowana)
  • 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). Nadając nazwę plikowi XML, uwzględnij lokalizację, w której pakiet jest zdefiniowany w kompilacji, np. 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ę w Androidzie 9 i 10:

  1. Nakładanie konfiguracji config_systemUserPackagesBlacklistSupported z frameworks/base/core/res/res/values/config.xml na true. Gdy funkcja jest włączona, domyślnie wszystkie pakiety powinny być zainstalowane zarówno dla użytkownika systemu, jak i użytkownika z pełnymi uprawnieniami.
  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 na urządzeniu system/etc/sysconfig/, na przykład:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Sprawdzanie wyniku

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 ustalić, czy pakiet powinien być zainstalowany w użytkowniku systemu, sprawdź plik AndroidManifest.xml pakietu znajdujący się w katalogu głównym źródła projektu, w tym atrybuty aplikacji i jej komponenty, które obejmują wszystkie działania, usługi, odbiorniki transmisji i dostawców treści. Więcej informacji znajdziesz w artykule Omówienie pliku manifestu aplikacji.

Proces wyłączania pakietów

Rysunek 1. Wyłączanie przepływu pracy dotyczącego 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 pod kątem wartości 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). Aplikacje systemowe, które są uruchamiane bezpośrednio, również korzystają z zaszyfrowanego miejsca na dane 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 pod kątem android:defaultToDeviceProtectedStorage="true", który jest potrzebny do obsługi wielu usług uruchamiania systemu.
  2. Jeśli true, dodaj do listy dozwolonych.
  3. Jeśli false, przejdź dalej.

Poziom 2. Komponenty aplikacji

Działania

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

a. Sprawdź, czy aplikacja zawiera tylko aktywności

Działania są ukierunkowane na interfejs użytkownika. W systemie Automotive użytkownik jest bez głowy, więc żadna osoba nie powinna wchodzić z nim w interakcję. W efekcie, jeśli aplikacja zawiera tylko aktywności, prawdopodobnie nie jest ona istotna dla użytkownika systemu.

Sprawdź, czy masz priorytet i specjalne uprawnienia:

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

Na przykład zestaw testów zgodności (com.android.cts.priv.ctsshim) zawiera tylko aktywności, a aktywności są zdefiniowane w celu 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 oznaczona jako prywatna i czy nie można uzyskać do niej dostępu z poziomu 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 prywatna lub nie można uzyskać do niej dostępu z poziomu innych aplikacji, nie może być związana 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 odpowiedź brzmi Tak, sprawdź następny komponent.
  • Jeśli odpowiedź brzmi Nie, kontynuuj sprawdzanie tego komponentu.

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

Sprawdź, czy na poziomie 1 są dostępne pakiety z dozwoloną listą, i ustal, z jakimi usługami są powiązane. Ślad z filtru intencji w tej usłudze i startServicew 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 usług w ramach konta użytkownika systemu), dodaj 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 czy jest deklarowana jako działająca na pierwszym planie

Poszukaj startForeground. Oznacza to, że użytkownicy będą wchodzić w interakcję z aplikacją na pierwszym planie. Ta usługa prawdopodobnie nie będzie potrzebna użytkownikowi systemu i nie będzie musiała być dodana do listy dozwolonych:

  • Jeśli odpowiedź brzmi Tak, nie dodawaj do listy dozwolonych.
  • Jeśli odpowiedź brzmi Nie, przejdź do sprawdzania kolejnego komponentu.

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 działania w procesie systemowym, działa w tym samym procesie co usługa systemowa i powinna być dodana do listy dozwolonych do działania w ramach użytkownika systemowego. W ramach projektu alokacji pamięci w Androidzie usługi systemowe są jednymi z ostatnich procesów, które są zabijane, co sugeruje, że są to usługi o najwyższej krytyczności. Aby dowiedzieć się więcej o przydzielaniu pamięci w Androidzie, przeczytaj artykuł Low-memory killer (w języku angielskim).

  • 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 zostać dodany do listy dozwolonych, ponieważ zawiera pakiet RegularMaintenanceJobService, który ma 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 na poziomie 1 są uwzględnione pakiety z dozwolonej listy, i sprawdź, od których dostawców są one zależne. Jeśli aplikacja działająca w ramach konta użytkownika systemu (np. com.android.car.companiondevicesupport) jest dozwolona do działania w ramach konta użytkownika systemu i korzysta z usług dostawcy treści, sprawdź, czy ten dostawca jest też dodany do listy dozwolonych.

  1. Jeśli odpowiedź to Tak, dodaj aplikację 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. Jeśli com.android.car.EXAMPLE zależy od android.webkit w przypadku WebViewFactoryProvider, com.android.webview musi być dodany do listy dozwolonych dla użytkownika systemu, pod warunkiem, że wczytuje android.webkit.

Prezentacja przykładowego pakietu

Ten przykład pokazuje, jak ocenić AndroidManifest.xml pakietu:

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