Preinstalled system packages

Android supports having multiple users on a single device. To learn more, see Supporting Multiple Users. Since not all system packages are useful on all types of Android users, you can use an allowlist to specify which system packages should be pre-installed on each type of user. By not pre-installing unnecessary system packages, you can optimize user creation times, start times, and memory usage.

Use system configuration XML files, modeled on frameworks/base/data/etc/preinstalled-packages-platform.xml, to declare which system packages should be initially installed for new users based on their user type. All system packages on the device should ideally have an entry in an XML file (keyed by its manifest name), except for static overlays, which are instead treated automatically according to the entry for their corresponding overlay target package. The way in which the device should handle system packages that are not listed here is controlled by the config mode.

User types

Base user-types (every user is at least one of these types) are:

User type Description
SYSTEM User 0.
FULL Any nonprofile human user.
PROFILE A profile human user.

The precise meaning of each is defined in frameworks/base/core/java/android/content/pm/UserInfo.java.

More granular control can be gained by specifying individual user types since every user is exactly one of these user types, which includes the AOSP user types defined in frameworks/base/core/java/android/os/UserManager.java and any OEM custom user types defined in frameworks/base/services/core/java/com/android/server/pm/UserTypeFactory.java. See the user types page for more information. Currently, AOSP user types include:

  • android.os.usertype.full.SYSTEM
  • android.os.usertype.full.SECONDARY
  • android.os.usertype.full.GUEST
  • android.os.usertype.full.DEMO
  • android.os.usertype.full.RESTRICTED
  • android.os.usertype.profile.MANAGED
  • android.os.usertype.system.HEADLESS

Examples

The following examples address the most common use cases:

  1. For a system package to be pre-installed in user 0 only:
    <install-in-user-type package="com.android.example">
        <install-in user-type="SYSTEM" />
     </install-in-user-type>
    
  2. For a system package to be pre-installed on all human users (such as a web browser), that is, to be installed on any user of type FULL or PROFILE, which addresses all human users:
    <install-in-user-type package="com.android.example">
        <install-in user-type="FULL" />
        <install-in user-type="PROFILE" />
    </install-in-user-type>
    
  3. For a system package to be pre-installed on all human users except for profile users. For example, this could be applied to a wallpaper app:
    <install-in-user-type package="com.android.example">
        <install-in user-type="FULL" />
    </install-in-user-type>
    
  4. Some system packages truly are required to be on all users, regardless of type. In these cases, use:
    <install-in-user-type package="com.android.example">
        <install-in user-type="SYSTEM">
        <install-in user-type="FULL" />
        <install-in user-type="PROFILE" />
    </install-in-user-type>
    
  5. More granular options are also available by specifying individual user types. For example, the following sample code installs this package on any user whose user type is a managed profile or a guest or is of a SYSTEM base type.
    <install-in-user-type package="com.android.example">
        <install-in user-type="android.os.usertype.profile.MANAGED" />
        <install-in user-type="android.os.usertype.full.GUEST" />
        <install-in user-type="SYSTEM">
    </install-in-user-type>
    

do-not-install-in tag

Packages can also be prevented from being pre-installed on particular user types using the do-not-install-in tag. Note that do-not-install-in tags override install-in tags in any file. For example:

<install-in-user-type package="com.android.example">
    <install-in user-type="FULL" />
    <do-not-install-in user-type="android.os.usertype.full.GUEST"/>
</install-in-user-type>
If a user is of type android.os.usertype.full.GUEST (a subtype of FULL), this package is not installed because the do-not-install-in tag takes precedence over install-in.

Control behavior with config.xml

The config resource value config_userTypePackageWhitelistMode controls this feature and determines how a device interprets system packages that have no entry for any user type. For more information, see frameworks/base/core/res/res/values/config.xml#config_userTypePackageWhitelistMode.

In frameworks/base/core/res/res/values/config.xml, set the integer named config_userTypePackageWhitelistMode to a combination of the following values. These flags can be combined. The most important flags are:

Value Description
0 (0b0000) Disable. Install all system packages.
1 (0b0001) Enforce. Only install system packages when allowlisted.
4 (0b0100) Regard any package not mentioned in the allowlist file as implicitly allowlisted.
8 (0b1000) Regard any package not mentioned in the allowlist file as implicitly allowlisted for just the SYSTEM user.

The following config enables the feature (so that install-in and do-not-install-in tags are obeyed) but treats any nonmentioned system packages as though they are install-in for all users:

<integer name="config_userTypePackageWhitelistMode">5</integer>