Remove packages for the System User

This article describes how to improve performance by identifying and removing packages that are not needed for the System User.

Disable unnecessary packages

In Automotive, the System User is headless, which means the System User isn't intended to be used or directly accessed by a human. As a result, many apps and services need not run in the System User and can be disabled to improve performance. Therefore, an option is provided to remove unnecessary apps for the System User (User 0).

On this page, two types of Users are discussed:

  • SYSTEM. Always User 0
  • FULL. User that is intended to be used by a human (a non-System User), User 10+

Android 11

In Android 11, you change the configuration, config_userTypePackageWhitelistMode. Flags can be combined. In this case, 5 equates to 1 plus 4 (a combination of flags 1 and 4).

Flag Description
0 Disable allowlist. Install all system packages; no logging.
1 Enforce. Install system packages only when they are allowlisted.
2 Log non-allowlisted packages.
4 Any package not mentioned in the allowlist file is implicitly allowlisted for all users.
8 Same as 4, for the System user.
16 Ignore OTAs . Don't install system packages during OTAs.
Consider these common scenarios.
  • To enable a feature for a complete allowlist, 1 (fully enforced)
  • To enable a feature for an incomplete allowlist, 5
  • To enable a feature for the SYSTEM user to ease local development, 9 (implicit allowlist)
  • To disable a feature as though it had never been enabled, 16
  • To disable a feature and undo all previous effects, 0

Be sure to install the XML file in the sysconfig directory for the device (this is the same directory that contains the makefile (`.mk`) used to build the system image for the device). When you name the XML file, include the location at which the package is defined in the build. For example, preinstalled-packages-product-car-CAR_PRODUCT_NAME.xml.

<!- this package will be installed for both FULL and SYSTEM user -->
    <install-in-user-type package=""->
        <install-in user-type="FULL" /->
        <install-in user-type="SYSTEM" /->

<!- this package will only be installed for both FULL user -->
    <install-in-user-type package=""->
        <install-in user-type="FULL" >

Android 9 and Android 10

To configure this feature in Android 9 and Android 10:

  1. Overlay the config_systemUserPackagesBlacklistSupported config from frameworks/base/core/res/res/values/config.xml and set it to true. When the feature is turned on, by default, all packages should be installed for both the System User and the FULL User.
  2. Create a config.xml file listing which packages should be disabled for the System User. For example:
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="" />
  3. Add a line to to copy the file to the device's target folder system/etc/sysconfig/. For example:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml

Verify the result

To verify the result, run:

$ 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


To determine if a package should be installed in the System User, examine the package's AndroidManifest.xml file located at the root of the project source, including the app's attributes and the components of the app, which include all activities, services, broadcast receivers, and content providers. To learn more, see App Manifest Overview.

Disable packages workflow

Figure 1. Disable packages workflow

Level 1, app level

1. Check if app (or app components) is declared as a singleton

If the app is a singleton, the system will instantiate the app in the System User only. It's likely the app was intended to be a multiuser-aware app. To learn more about multi-user aware apps, see Building Multiuser-Aware Apps.

  1. Check the Android manifest for android:singleUser="true".
  2. If true, allowlist. Needed for the System User.
  3. If false, continue. Check other criteria before removing.

2. Check if the app requires protected storage access

Many system boot services often rely on device encrypted (DE) storage instead of credential encrypted (CE) storage. Also, system apps that are direct boot aware also rely on device encrypted storage. To learn more about direct boot aware apps, see Supporting Direct Boot in system apps.

  1. Check the Android manifest for android:defaultToDeviceProtectedStorage="true", which is needed for numerous system boot services.
  2. If true, allowlist.
  3. If false, continue.

Level 2, app components


To learn more about activities, see Introduction to Activities.

a. Check if the app contains only activities

Activities are user interface-oriented. Since the System User is headless in Automotive, no human should be interacting with the System User. As a result, if the app contains Activities only, the app is most likely not relevant to the System User.

Check for priority and special privilege.

  1. If Yes, perhaps needed for the System User.
  2. If No, do not allowlist for the System User.

For example, the Compatibility Test Suite (CTS) ( contains only Activities, and Activities are defined to test intent filters. However, since it has a high privilege, it needs to be installed for the System User for testing purposes.


To learn more about services, see Services overview.

b. Check if service is declared as private and can't be accessed from other apps

If the service is declared as private, other packages will not use the service. Look for android:exported="false". If the service is declared as private or cannot be accessed from other apps, then it cannot be bound by other apps. Therefore, Step C and Step D below are irrelevant. As a result, this component would not provide more hints as to whether or not the service is needed for the System User.

  1. If Yes, check the next component.
  2. If No, continue to check this component.

c. Check if apps installed in System User might bind to this service

Check for allowlisted packages in Level 1 and identify the services to which they are bound. Trace from the intent filter in this service and startService in other packages.

If this service is bound to apps installed in the System User (for example, is allowlisted to run in the System User), then allowlist the service.

  1. If Yes, allowlist.
  2. If No, continue to check this component.

d. Check if service is bound from other apps and declared to run in foreground

Look for startForeground. This means people would be interacting with the app in the foreground. Most likely, this service would not be needed for the System User and need not be allowlisted.

  1. If Yes, do not allowlist.
  2. If No, continue to check the next component.

e. Check if service is defined to run in system process

In the AndroidManifest, look for android:process="system".
If the service is intentionally defined to run in the system process, then it means it explicitly will run in the same process as the system service and should be allowlisted to run in the System User. As part of Android's memory allocation design, system services are some of the last processes to be killed, which implies the criticality of services defined with such an attribute. To learn more about Android's memory allocation design, see Low-memory killer.

  1. If Yes, do not allowlist.
  2. If No, continue to check other components.

For example, package must be allowlisted since it contains RegularMaintenanceJobService, which has the android:process="system" tag.

Content provider

To learn more about content providers, see Content providers.

f. Check if app installed in System User depends on this provider

Check for allowlisted packages in Level 1 and check which providers they depend on. If an app running in the System User (for example, is allowlisted to run in the System User) and depends on this content provider, then ensure that this content provider is also allowlisted.

  1. If Yes, allowlist.
  2. If No, do not allowlist.

For example, if contains singleton providers (SystemActionsContentProvider and ManagedProvisioningActionsContentProvider), it should be allowlisted for the System User. Then, if depends on android.webkit for WebViewFactoryProvider then, must be allowlisted for the System User given that it loads the android.webkit.

Sample package walkthrough

The following example shows how to evaluate the AndroidManifest.xml of a package:

<?xml version="1.0" encoding="utf-8"?>
<!-- 1. Search in the entire manifest for singleUser attribute.
No. Move to step 2 -->
<manifest xmlns:android=""
    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"
<!-- a. Contain only activities?
No. Continue to evaluate components other than activities. -->
        <provider android:name="CalendarProvider2" android:authorities=""
                <!-- 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}
                Yes. Whitelist for system user. -->
                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=""/> <category android:name=""/> </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>