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. Zainstaluj wszystkie pakiety systemowe; brak 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, ale 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 w celu ułatwienia lokalnego rozwoju,9 (domyślna 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ładaj konfigurację config_systemUserPackagesBlacklistSupportedframeworks/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.

Przepływ pracy dotyczący 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 elementu android:singleUser="true".
  2. Jeśli true, dodaj do listy dozwolonych. Wymagane dla użytkownika systemu.
  3. Jeśli false, przejdź dalej. Przed usunięciem sprawdź inne kryteria.

2. Sprawdzanie, 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 danych uwierzytelniających (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ź manifest Androida pod kątem elementu 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 związku z tym jeśli aplikacja zawiera tylko aktywności, prawdopodobnie nie jest 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 musi być zainstalowany 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 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ć powią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ę wiązać 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 startService w innych pakietach.

Jeśli ta usługa jest powiązana z aplikacjami zainstalowanymi w użytkowniku systemowym (na przykład com.android.car.companiondevicesupport jest na liście dozwolonych do uruchamiania w użytkowniku systemowym), 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 czy jest deklarowana jako usługa 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 uruchamiania w procesie systemowym, jest uruchamiana w tym samym procesie co usługa systemowa i powinna być dodana do listy dozwolonych do uruchamiania 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, 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 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 zależy od tego dostawcy

Sprawdź, czy na poziomie 1 są uwzględnione pakiety z dozwoloną 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, upewnij się, że 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 pojedynczych dostawców (SystemActionsContentProvider i ManagedProvisioningActionsContentProvider), należy dodać ich 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>