В этой статье описывается, как повысить производительность путем определения и удаления пакетов, которые не нужны пользователю SYSTEM.
Отключение ненужных пакетов
В автомобилестроении системный пользователь не имеет головы , что означает, что системный пользователь не предназначен для использования или прямого доступа к нему человеком. В результате многие приложения и службы не нужно запускать в Системном пользователе, и их можно отключить для повышения производительности. Поэтому предоставляется возможность удалить ненужные приложения для пользователя SYSTEM (User 0).
В этой статье обсуждаются два типа пользователей:
- СИСТЕМА . Всегда пользователь 0
 - ПОЛНЫЙ . Пользователь, предназначенный для использования человеком (не СИСТЕМНЫЙ пользователь), Пользователь 10+
 
Андроид 11
 В Android 11 вы меняете конфигурацию config_userTypePackageWhitelistMode . Флаги можно комбинировать. В этом случае 5 равняется 1 плюс 4 (комбинация флагов 1 и 4 ).
0 - disable whitelist (install all system packages; no logging) 1 - enforce (only install system packages if they are whitelisted) 2 - log (log non-whitelisted packages) 4 - any package not mentioned in the whitelist file is implicitly whitelisted on all users 8 - same as 4, but just for the SYSTEM user 16 - ignore OTAs (don't install system packages during OTAs) Common scenarios: - to enable feature (fully enforced) for a complete allowlist: 1 - to enable feature for an incomplete allowlist (so use implicit allowlist mode): 5 - to enable feature but implicitly allowlist for SYSTEM user to ease local development: 9 - to disable feature completely if it had never been enabled: 16 - to henceforth disable feature and try to undo its previous effects: 0
 Обязательно установите XML-файл в каталог sysconfig для устройства (это тот же каталог, в котором находится make-файл (.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:
-  Наложите конфигурацию 
config_systemUserPackagesBlacklistSupportedизframeworks/base/core/res/res/values/config.xmlи установите для нее значениеtrue. Когда эта функция включена, по умолчанию все пакеты должны быть установлены как для СИСТЕМНОГО пользователя, так и для ПОЛНОГО пользователя. -  Создайте файл 
config.xmlсо списком пакетов, которые должны быть отключены для пользователя SYSTEM. Например:<config> <!-- This package will be uninstalled for the system user --> <system-user-blacklisted-app package="com.google.car.calendar" /> </config> -  Добавьте строку в 
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. Проверьте, объявлено ли приложение (или компоненты приложения) как синглтон
Если приложение является singleton , система создаст экземпляр приложения только для пользователя SYSTEM. Скорее всего, приложение задумывалось как многопользовательское. Дополнительные сведения о многопользовательских приложениях см. в разделе Создание многопользовательских приложений .
-  Проверьте манифест Android для 
android:singleUser="true". - Если true , белый список. Требуется для пользователя SYSTEM.
 - Если ложь , продолжайте. Перед удалением проверьте другие критерии.
 
2. Проверьте, требуется ли приложению защищенный доступ к хранилищу.
Многие службы загрузки системы часто используют хранилище с шифрованием устройства (DE), а не хранилище с шифрованием учетных данных (CE). Кроме того, системные приложения, поддерживающие прямую загрузку, также полагаются на зашифрованное хранилище устройства. Дополнительные сведения о приложениях, поддерживающих прямую загрузку, см. в разделе Поддержка прямой загрузки в системных приложениях .
-  Проверьте манифест Android на 
android:defaultToDeviceProtectedStorage="true", который необходим для многочисленных служб загрузки системы. - Если true , белый список.
 - Если ложь , продолжайте.
 
Уровень 2, Компоненты приложения
мероприятия
Дополнительные сведения об операциях см. в разделе Введение в операции.
а. Проверьте, содержит ли приложение только действия
Активности ориентированы на пользовательский интерфейс. Поскольку пользователь SYSTEM не имеет головы в Automotive, ни один человек не должен взаимодействовать с пользователем SYSTEM. В результате, если приложение содержит только Действия, оно, скорее всего, не имеет отношения к Пользователю СИСТЕМЫ.
Проверьте наличие приоритета и особых привилегий.
- Если да , возможно, это необходимо для пользователя SYSTEM.
 - Если No , не вносить в белый список пользователя SYSTEM.
 
 Например, набор тестов совместимости (CTS) ( com.android.cts.priv.ctsshim ) содержит только действия, а действия определены для тестирования фильтров намерений. Однако, поскольку он имеет высокие привилегии, его необходимо установить для пользователя SYSTEM в целях тестирования.
обслуживание
Дополнительные сведения об услугах см. в разделе Обзор услуг .
б. Проверьте, объявлена ли служба частной и к ней нельзя получить доступ из других приложений.
 Если сервис объявлен как частный , другие пакеты не будут его использовать. Найдите android:exported="false" . Если служба объявлена частной или к ней нельзя получить доступ из других приложений, то она не может быть привязана другими приложениями. Следовательно, Шаг C и Шаг D ниже не имеют значения. В результате этот компонент не будет давать больше подсказок о том, нужна ли услуга Пользователю СИСТЕМЫ.
- Если да , проверьте следующий компонент.
 - Если Нет , продолжайте проверять этот компонент.
 
в. Проверьте, могут ли приложения, установленные в SYSTEM User, связываться с этой службой.
 Проверьте наличие пакетов в списке разрешенных на уровне 1 и определите службы, к которым они привязаны. Трассировка из фильтра намерений в этой службе и startService в других пакетах.
 Если эта служба привязана к приложениям, установленным для системного пользователя (например, com.android.car.companiondevicesupport внесена в список разрешенных для запуска системным пользователем), занесите эту службу в список разрешенных.
- Если да , белый список.
 - Если Нет , продолжайте проверять этот компонент.
 
д. Проверьте, не связана ли служба с другими приложениями и объявлена ли она для запуска на переднем плане.
 Найдите startForeground . Это означает, что люди будут взаимодействовать с приложением на переднем плане. Скорее всего, эта служба не понадобится пользователю SYSTEM и не должна быть включена в белый список.
- Если да , не вносить в белый список.
 - Если нет , продолжайте проверку следующего компонента.
 
е. Проверьте, определена ли служба для запуска в системном процессе.
 В AndroidManifest найдите android:process="system" .
 Если служба намеренно определена для запуска в системном процессе, это означает, что она явно будет выполняться в том же процессе, что и системная служба, и должна быть включена в список разрешенных для запуска пользователем SYSTEM. Как часть структуры распределения памяти Android, системные службы являются одними из последних процессов, которые будут уничтожены, что подразумевает критичность служб, определенных с таким атрибутом. Чтобы узнать больше о дизайне распределения памяти в Android, см.статью Убийца нехватки памяти .
- Если да , не вносить в белый список.
 - Если нет , продолжайте проверять другие компоненты.
 
 Например, пакет com.android.networkstack.inprocess должен быть внесен в белый список, так как он содержит RegularMaintenanceJobService с тегом android:process="system" .
Поставщик услуг
Дополнительные сведения о поставщиках содержимого см. в разделе Поставщики содержимого .
ф. Проверьте, зависит ли приложение, установленное в Системном пользователе, от этого провайдера.
 Проверьте наличие пакетов в списке разрешенных на уровне 1 и проверьте, от каких поставщиков они зависят. Если приложение, работающее в Системном пользователе (например, com.android.car.companiondevicesupport , включено в список разрешенных для запуска в Системном пользователе) и зависит от этого поставщика содержимого, убедитесь, что этот поставщик содержимого также находится в белом списке.
- Если да , белый список.
 - Если Нет , не вносить в белый список.
 
 Например, если com.android.car.EXAMPLE содержит одноэлементных поставщиков ( SystemActionsContentProvider и ManagedProvisioningActionsContentProvider ), он должен быть внесен в белый список для пользователя SYSTEM. Затем, если com.android.car.EXAMPLE зависит от android.webkit для WebViewFactoryProvider , тогда com.android.webview должен быть внесен в белый список для пользователя SYSTEM, учитывая, что он загружает 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>