Удалить пакеты для системного пользователя

На этой странице описывается, как повысить производительность путем выявления и удаления пакетов, которые не нужны пользователю системы.

Отключить ненужные пакеты

В Automotive системный пользователь является headless , что означает, что системный пользователь не предназначен для использования или прямого доступа человеком. В результате многие приложения и службы не должны запускаться в системном пользователе и могут быть отключены для повышения производительности. Поэтому предоставляется возможность удалить ненужные приложения для системного пользователя (Пользователь 0).

На этой странице обсуждаются два типа пользователей:

  • СИСТЕМА . Всегда Пользователь 0
  • ПОЛНЫЙ . Пользователь, который предназначен для использования человеком (несистемным пользователем), Пользователь 10+

Андроид 11

В Android 11 измените конфигурацию config_userTypePackageWhitelistMode . Флаги можно комбинировать. В этом случае 5 равно 1 плюс 4 (комбинация флагов 1 и 4 ).

Флаг Описание
0 Отключить белый список. Установить все системные пакеты; без регистрации.
1 Принудительно. Устанавливайте системные пакеты только в том случае, если они внесены в список разрешенных.
2 Регистрировать пакеты, не входящие в разрешенный список.
4 Любой пакет, не упомянутый в файле разрешенного списка, неявно заносится в разрешенный список для всех пользователей.
8 То же, что и 4 , для системного пользователя.
16 Игнорируйте OTA. Не устанавливайте системные пакеты во время OTA.

Рассмотрим следующие распространенные сценарии:

  • Чтобы включить функцию для полного списка разрешений, 1 ( полностью принудительно )
  • Чтобы включить функцию для неполного списка разрешенных, 5
  • Чтобы включить функцию для пользователя SYSTEM для облегчения локальной разработки, 9 ( неявный список разрешенных )
  • Чтобы отключить функцию, как будто она никогда не была включена, 16
  • Чтобы отключить функцию и отменить все предыдущие эффекты, 0

Установите XML-файл в каталог sysconfig для устройства (это тот же каталог, который содержит makefile ( .mk ), используемый для сборки образа системы для устройства). При присвоении имени XML-файлу включите местоположение, где пакет определен в сборке, например, 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->

Андроид 9 и Андроид 10

Чтобы настроить эту функцию в Android 9 и Android 10:

  1. Наложите конфигурацию config_systemUserPackagesBlacklistSupported из frameworks/base/core/res/res/values/config.xml и установите ее в true . Когда эта функция включена, по умолчанию все пакеты должны быть установлены как для системного пользователя, так и для ПОЛНОГО пользователя.
  2. Создайте файл config.xml , в котором перечислены пакеты, которые следует отключить для пользователя системы, например:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
  3. Добавьте строку в device.mk , чтобы скопировать файл в целевую папку устройства system/etc/sysconfig/ , например:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Проверьте результат

Для проверки результата выполните:

$ 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

Помещение

Чтобы определить, следует ли устанавливать пакет в системном пользователе, проверьте файл AndroidManifest.xml пакета, расположенный в корне исходного кода проекта, включая атрибуты приложения и компоненты приложения, включающие все действия, службы, приемники вещания и поставщики контента. Чтобы узнать больше, см. Обзор манифеста приложения .

Отключить пакеты рабочего процесса

Рисунок 1. Рабочий процесс отключения пакетов.

Уровень 1, уровень приложения

1. Проверьте, объявлено ли приложение (или компоненты приложения) как синглтон

Если приложение является синглтоном , система создает экземпляр приложения только в системном пользователе. Вероятно, приложение было предназначено для многопользовательского использования. Чтобы узнать больше о многопользовательских приложениях, см. раздел Создание многопользовательских приложений .

  1. Проверьте манифест Android на наличие android:singleUser="true" .
  2. Если true , белый список. Требуется для пользователя системы.
  3. Если false , продолжить. Проверьте другие критерии перед удалением.

2. Проверьте, требует ли приложение защищенный доступ к хранилищу.

Многие службы загрузки системы часто полагаются на хранилище, зашифрованное устройством (DE), вместо хранилища, зашифрованного учетными данными (CE). Кроме того, системные приложения, поддерживающие прямую загрузку, также полагаются на хранилище, зашифрованное устройством. Чтобы узнать больше о приложениях, поддерживающих прямую загрузку, см. раздел Поддержка прямой загрузки в системных приложениях .

  1. Проверьте манифест Android на наличие android:defaultToDeviceProtectedStorage="true" , ​​который необходим для многочисленных служб загрузки системы.
  2. Если true , белый список.
  3. Если false , продолжайте.

Уровень 2, компоненты приложения

Деятельность

Чтобы узнать больше о мероприятиях, см. Введение в мероприятия .

а. Проверьте, содержит ли приложение только действия

Действия ориентированы на пользовательский интерфейс. Поскольку пользователь системы в Automotive не имеет головы, ни один человек не должен взаимодействовать с пользователем системы. В результате, если приложение содержит только действия, приложение, скорее всего, не имеет отношения к пользователю системы.

Проверка приоритета и особых привилегий:

  1. Если да , то это может потребоваться пользователю системы.
  2. Если «Нет» , не добавлять пользователя системы в список разрешенных.

Например, Compatibility Test Suite (CTS) ( com.android.cts.priv.ctsshim ) содержит только действия, а действия определены для проверки фильтров намерений. Однако, поскольку CTS имеет высокую привилегию, его необходимо установить для пользователя системы для целей тестирования.

Услуга

Более подробную информацию об услугах можно найти в разделе Обзор услуг .

б) Проверьте, объявлена ​​ли служба как частная и не может ли она быть доступна из других приложений.

Если служба объявлена ​​как частная , другие пакеты не будут ее использовать. Найдите android:exported="false" . Если служба объявлена ​​как частная или к ней нельзя получить доступ из других приложений, то ее нельзя связать с другими приложениями. Поэтому шаги c и d ниже не имеют значения. В результате этот компонент не будет предоставлять дополнительных подсказок относительно того, нужна ли служба пользователю системы.

  • Если да , проверьте следующий компонент.
  • Если Нет , продолжайте проверку этого компонента.

в) Проверьте, могут ли приложения, установленные в системе пользователя, привязываться к этой службе.

Проверьте наличие разрешенных пакетов на уровне 1 и определите службы, к которым они привязаны. Проследите от фильтра намерений в этой службе и startService в других пакетах.

Если эта служба привязана к приложениям, установленным в системном пользователе (например, com.android.car.companiondevicesupport разрешен для запуска в системном пользователе), то добавьте службу в список разрешенных:

  • Если да , то внесите в белый список.
  • Если Нет , продолжайте проверку этого компонента.

г. Проверьте, связана ли служба с другими приложениями и объявлена ​​ли она для работы на переднем плане.

Найдите startForeground . Это означает, что люди будут взаимодействовать с приложением на переднем плане. Скорее всего, эта служба не понадобится пользователю системы и не должна быть разрешена:

  • Если да , не добавляйте в белый список.
  • Если нет , продолжайте проверку следующего компонента.

е. Проверьте, определена ли служба для запуска в системном процессе

В файле AndroidManifest найдите android:process="system" . Если служба намеренно определена для запуска в системном процессе, то она запускается в том же процессе, что и системная служба, и должна быть разрешена для запуска в системном пользователе. В рамках структуры распределения памяти Android системные службы являются одними из последних процессов, которые будут завершены, что подразумевает критичность служб, определенных с таким атрибутом. Чтобы узнать больше о структуре распределения памяти Android, см. Low-memory killer .

  • Если да , не добавляйте в белый список.
  • Если нет , продолжайте проверять другие компоненты.

Например, пакет com.android.networkstack.inprocess должен быть внесён в разрешённый список, поскольку он содержит RegularMaintenanceJobService , имеющий тег android:process="system" .

Поставщик контента

Дополнительную информацию о поставщиках контента см. в разделе Поставщики контента .

е. Проверьте, зависит ли установленное в системе пользователя приложение от этого провайдера

Проверьте наличие разрешенных пакетов на уровне 1 и проверьте, от каких поставщиков они зависят. Если приложение, работающее в системном пользователе (например, com.android.car.companiondevicesupport , разрешено для запуска в системном пользователе) и зависит от этого поставщика контента, убедитесь, что этот поставщик контента также разрешен.

  1. Если да , то внесите в белый список.
  2. Если нет , не добавляйте в белый список.

Например, если com.android.car.EXAMPLE содержит поставщиков singleton ( SystemActionsContentProvider и ManagedProvisioningActionsContentProvider ), он должен быть разрешен для пользователя системы. Затем, если com.android.car.EXAMPLE зависит от android.webkit для WebViewFactoryProvider , то com.android.webview должен быть разрешен для пользователя системы, учитывая, что он загружает android.webkit .

Пример пошагового руководства по пакету

В следующем примере показано, как оценить AndroidManifest.xml пакета:

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