Usuń pakiety dla użytkownika systemu

W tym artykule opisano, jak poprawić wydajność poprzez identyfikację i usunięcie pakietów, które nie są potrzebne Użytkownikowi Systemu.

Wyłącz niepotrzebne pakiety

W branży motoryzacyjnej użytkownik systemu jest bezgłowy , co oznacza, że ​​użytkownik systemu nie jest przeznaczony do używania ani bezpośredniego dostępu przez człowieka. W rezultacie wiele aplikacji i usług nie musi być uruchamianych w systemie użytkownika i można je wyłączyć w celu poprawy wydajności. Dlatego dostępna jest opcja usunięcia niepotrzebnych aplikacji dla Użytkownika Systemu (Użytkownika 0).

Na tej stronie omówiono dwa typy Użytkowników:

  • SYSTEMU . Zawsze użytkownik 0
  • PEŁNY . Użytkownik przeznaczony do użytku przez człowieka (użytkownik niebędący użytkownikiem Systemu), Użytkownik 10+

Androida 11

W systemie Android 11 zmieniasz konfigurację config_userTypePackageWhitelistMode . Flagi można łączyć. W tym przypadku 5 równa się 1 plus 4 (kombinacja flag 1 i 4 ).

Flaga Opis
0 Wyłącz listę dozwolonych. Zainstaluj wszystkie pakiety systemowe; brak logowania.
1 Egzekwować. Instaluj pakiety systemowe tylko wtedy, gdy znajdują się na liście dozwolonych.
2 Rejestruj pakiety nie znajdujące się na liście dozwolonych.
4 Każdy pakiet, który nie jest wymieniony w pliku listy dozwolonych, jest domyślnie umieszczany na liście dozwolonych dla wszystkich użytkowników.
8 To samo co 4 dla użytkownika System.
16 Ignoruj ​​OTA. Nie instaluj pakietów systemowych podczas OTA.
Rozważ te typowe scenariusze.
  • Aby włączyć funkcję dla pełnej listy dozwolonych, 1 ( w pełni wymuszona )
  • Aby włączyć funkcję dla niekompletnej listy dozwolonych, 5
  • Aby włączyć funkcję dla użytkownika SYSTEM ułatwiającą rozwój lokalny, 9 ( ukryta 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

Pamiętaj, aby zainstalować plik XML w katalogu sysconfig urządzenia (jest to ten sam katalog, który zawiera plik makefile (`.mk`) użyty do zbudowania obrazu systemu dla urządzenia). Nadając nazwę plikowi XML, podaj lokalizację, w której pakiet jest zdefiniowany w pliku build. 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->

Androida 9 i Androida 10

Aby skonfigurować tę funkcję w systemie Android 9 i Android 10:

  1. Nałóż konfigurację config_systemUserPackagesBlacklistSupported z frameworks/base/core/res/res/values/config.xml i ustaw ją na true . Gdy ta funkcja jest włączona, domyślnie wszystkie pakiety powinny zostać zainstalowane zarówno dla Użytkownika Systemowego, jak i Użytkownika PEŁNEGO.
  2. Utwórz plik config.xml zawierający listę pakietów, które powinny 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 linię 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 zweryfikować 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

Przesłanka

Aby określić, czy pakiet powinien zostać zainstalowany na Użytkowniku Systemu, sprawdź plik AndroidManifest.xml pakietu znajdujący się w katalogu głównym źródła projektu, w tym atrybuty aplikacji i komponenty aplikacji, które obejmują wszystkie działania, usługi, odbiorniki transmisji, i dostawców treści. Aby dowiedzieć się więcej, zobacz Omówienie manifestu aplikacji .

Wyłącz przepływ pracy pakietów

Rysunek 1. Wyłącz przepływ pracy z pakietami

Poziom 1, poziom aplikacji

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

Jeśli aplikacja jest singletonem , system utworzy instancję aplikacji tylko w użytkowniku systemu. Prawdopodobnie aplikacja miała być przeznaczona dla wielu użytkowników. Aby dowiedzieć się więcej na temat aplikacji obsługujących wielu użytkowników, zobacz Tworzenie aplikacji obsługujących wielu użytkowników .

  1. Sprawdź manifest Androida pod kątem android:singleUser="true" .
  2. Jeśli to prawda , lista dozwolonych. Potrzebne dla użytkownika systemu.
  3. Jeśli fałszywe , kontynuuj. Przed usunięciem sprawdź inne kryteria.

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

Wiele usług rozruchu systemu często opiera się na pamięci zaszyfrowanej urządzeniem (DE), a nie na pamięci zaszyfrowanej poświadczeniami (CE). Ponadto aplikacje systemowe obsługujące bezpośredni rozruch również korzystają z pamięci zaszyfrowanej na urządzeniu. Aby dowiedzieć się więcej na temat aplikacji obsługujących rozruch bezpośredni, zobacz temat Obsługa rozruchu bezpośredniego w aplikacjach systemowych .

  1. Sprawdź manifest Androida pod kątem android:defaultToDeviceProtectedStorage="true" , ​​który jest wymagany w przypadku wielu usług rozruchu systemu.
  2. Jeśli to prawda , lista dozwolonych.
  3. Jeśli fałszywe , kontynuuj.

Poziom 2, komponenty aplikacji

Zajęcia

Więcej informacji na temat działań można znaleźć w części Wprowadzenie do działań .

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

Działania są zorientowane na interfejs użytkownika. Ponieważ Użytkownik Systemu jest bezgłowy w branży Automotive, żaden człowiek nie powinien wchodzić w interakcję z Użytkownikiem Systemu. W rezultacie, jeśli aplikacja zawiera tylko działania, najprawdopodobniej nie jest istotna dla użytkownika systemu.

Sprawdź priorytet i specjalne uprawnienia.

  1. Jeśli tak , być może potrzebne użytkownikowi systemu.
  2. Jeśli nie , nie umieszczaj użytkownika systemowego na liście dozwolonych.

Na przykład pakiet testów zgodności (CTS) ( com.android.cts.priv.ctsshim ) zawiera tylko działania, a działania są zdefiniowane w celu filtrowania zamiarów testowych. Ponieważ jednak ma wysokie uprawnienia, musi zostać zainstalowany dla użytkownika systemu w celach testowych.

Praca

Aby dowiedzieć się więcej o usługach, zobacz Przegląd usług .

B. Sprawdź, czy usługa jest zadeklarowana jako prywatna i 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 innych aplikacji, nie można jej powiązać z innymi aplikacjami. Dlatego też kroki C i D poniżej są nieistotne. W rezultacie komponent ten nie dostarczałby więcej wskazówek, czy usługa jest potrzebna Użytkownikowi Systemu.

  1. Jeśli tak , sprawdź następny komponent.
  2. Jeśli nie , kontynuuj sprawdzanie tego komponentu.

C. Sprawdź, czy aplikacje zainstalowane w Użytkowniku Systemowym mogą powiązać się z tą usługą

Sprawdź listę dozwolonych pakietów na poziomie 1 i zidentyfikuj usługi, z którymi są powiązane. Śledź filtr intencji w tej usłudze i startService w innych pakietach.

Jeśli ta usługa jest powiązana z aplikacjami zainstalowanymi na Użytkowniku Systemowym (na przykład com.android.car.companiondevicesupport znajduje się na liście dozwolonych do uruchomienia na Użytkowniku Systemowym), umieść tę usługę na liście dozwolonych.

  1. Jeśli tak , dodaj listę dozwolonych.
  2. Jeśli 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 będą wchodzić w interakcję z aplikacją na pierwszym planie. Najprawdopodobniej ta usługa nie będzie potrzebna Użytkownikowi Systemu i nie musi znajdować się na liście dozwolonych.

  1. Jeśli tak , nie umieszczaj na liście dozwolonych.
  2. Jeżeli nie , kontynuuj sprawdzanie następnego komponentu.

mi. Sprawdź, czy usługa jest zdefiniowana do uruchamiania w procesie systemowym

W pliku AndroidManifest poszukaj android:process="system" .
Jeśli usługa jest celowo zdefiniowana do uruchamiania w procesie systemowym, oznacza to, że jawnie będzie działać w tym samym procesie co usługa systemowa i powinna znajdować się na liście dozwolonych do uruchamiania w systemie użytkownika. W ramach projektu alokacji pamięci w systemie Android usługi systemowe są jednymi z procesów, które należy zabić jako ostatnie, co oznacza krytyczność usług zdefiniowanych za pomocą takiego atrybutu. Aby dowiedzieć się więcej na temat projektu alokacji pamięci w systemie Android, zobacz Zabójca małej ilości pamięci .

  1. Jeśli tak , nie umieszczaj na liście dozwolonych.
  2. Jeśli nie , kontynuuj sprawdzanie innych komponentów.

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

Dostawca treści

Aby dowiedzieć się więcej o dostawcach treści, zobacz Dostawcy treści .

F. Sprawdź, czy aplikacja zainstalowana w Użytkowniku Systemowym zależy od tego dostawcy

Sprawdź listę dozwolonych pakietów na poziomie 1 i sprawdź, od jakich dostawców są one zależne. Jeśli aplikacja działająca na koncie użytkownika systemowego (na przykład com.android.car.companiondevicesupport znajduje się na liście dozwolonych do uruchomienia na koncie użytkownika systemowego) i zależy od tego dostawcy treści, upewnij się, że ten dostawca treści również znajduje się na liście dozwolonych.

  1. Jeśli tak , dodaj listę dozwolonych.
  2. Jeśli nie , nie umieszczaj na liście dozwolonych.

Na przykład, jeśli com.android.car.EXAMPLE zawiera pojedynczych dostawców ( SystemActionsContentProvider i ManagedProvisioningActionsContentProvider ), powinien znaleźć się na liście dozwolonych dla użytkownika systemu. Następnie, jeśli com.android.car.EXAMPLE zależy od android.webkit dla WebViewFactoryProvider , wówczas com.android.webview musi znajdować się na liście dozwolonych dla użytkownika systemowego, biorąc pod uwagę, że ładuje android.webkit .

Przykładowy przewodnik po pakiecie

Poniższy 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>