Android PackageManagerService: In-depth Understanding

In this post, I will try to explain what is Android PackageManagerService, what is its importance, what is a PackageManager al-together, what is installer, and what is installd?

Android PackageManagerService feature image

We used to install, uninstall multiple numbers of APKs in our Android device, but have you thought how the installation process happens? How the apps get updated when any new update comes? To which directory, your application gets installed. Well, to answer these questions, Android is using a SystemService called PackageManagerService, and its associates. The associates includs PackageInstaller, installd, Installer.java, etc.

What is Android PackageManagerService?

Android PackageManagerService is a System service that comes into picture when you perform any of the activities such as install a package, uninstall a packge, update a packge, etc. It is started by SystemServer as a part of bootStrapServices. BootStrapServices are nothing but the number of critical services that are required to fully function the Android.

It is the Android PackageManagerService responsibility to install the package on your device. It also allocates an ID and as well as space to the package. The space, where the application data to be stored.

If you see the bootStrapServices(), there is a sequence in which the services are getting started

  • Installer
  • DeviceIdentifierPolicyService
  • ActivityManagerService
  • PowerManagerService
  • RecoverySystemService
  • LightService
  • DisplayManagerService
  • PackageManagerService

So, do we need a sequence like this? Can we start the services independent of the sequence?

The answer is Yes, there is a need to have a sequence like this. I will talk about this later.

How Android PackageManagerService install apk at boot-time?

Do you know how will the PackageManagerService comes to know, which all applications need to be installed and where it needs to be installed at boot-time?

It’s simple, it scans all the directories. When PMS is started, it calls a method scanDirTracedLI() which starts the scan of directory provided in its argument. scanDirTracedLI() uses ParallelPackageParser class to parse the package when it is found. For example, if you have defined LOCAL_PRIVILEGED_MODULE := true in your application’s Android.mk file, then ParallelPackageParser will parse this information and place the apk in /system/priv-app/ dir. Once all the files are scanned, scanDirLI() method calls scanChildPackageLI() Now, scanChildPackageLI() method will call addForinitLI() method for lock, then it adds the package and updates the package information in packages.xml.

PackageManagerService scanDirTracedLI()
scanDirTracedLI() method

If you look at the SystemServer on how PackageManagerService is started.

mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);

You will notice that PackageManagerService requires, the installer service as one of its argument. Now at this point, you will get the answer to the question of why the sequence is required? PMS uses installer, DisplayMetrics, and other components on its execution. So, these services need to be started first.

Android PackageManagerService during package installation

Now, whenever you try to install any package, you will get a popup asking whether you want to install the package or not. This is the case where the PackageInstaller comes into picture.

fresh installation of package
Fresh package installation
updating the existing package
Updating the existing package

installation progress
Installation Progress

PackageInstaller

It is the default application for Android to interactively install a normal package. PackageInstaller provide user interface to manage applications/packages. PackageInstaller calls InstallAppProgress activity to receive instructions from the user. InstallAppProgress will ask Package Manager Service to install package via installd.

Now when you click on install, the package manager will calls installPackageLI(). Here LI means Locked install. In PackageManagerService, if a method ends with ‘LI’, it means that during the install time it has a lock and no other process can manipulate it.

In Android Q, installPackageLI() is replaced with preparepackageLI().

When PackageManagerService calls the installPackageLI(), it is like confirming that you have to install the APK and it will be installed.

PackageInstallerService

This is the guy who is responsible for mantaining the session, if you are trying to install/uninstall multiple applications at a time. It tries to create a session for every installation/uninstallation which is going on.

Installer and Installd

When SystemServer starts, it start all the system critical services. It also starts the Installer which will bind to the installd.

Installer is a SystemService that is responsible for linking the installd to the PackageManagerService. It is like binding the installd to PackageManagerService. Previously it was more like a socket-based communication where PMS uses linux domain socket /dev/socket/installd to send any message to installd.

Installd is a daemon service responsible for handling the installation of packages.

APK file storage in Android

Now APK is installed, but where are these applications are stored in your device.

  1. Pre-installed apk such as camera, phone, calender etc are stored in /system/[app/priv-app]

  2. User install apk such WhatsApp, Facebook, etc are stored in /data/app

  3. PackagerManager creates a data directory /data/data/<package name>/  to store the database, shared preference, native library, and cache data.

How PackageManagerService Store its data?

PackageManagerService store its data across three different files stored at location /data/system

  • packages.xml
  • packages.list
  • packages-stopped.xml

Packages.xml

Packages.xml file contains two things: 1. all the packages information and 2. all the permissions that are present in the device.

The Package will contains every detailed information about the package such as name, it’s location in the device, the location of the libraries that it is using, its userId, version, the certificate with which it is signed, the list of permissions the application is requesting, etc. You can see the example below, here is the application named DhcpInfo.

    <package name="com.swetabh.dhcpinfoapp" codePath="/data/app/com.swetabh.dhcpinfoapp-Tw1b0ywEt9clURpJKtI5sQ==" nativeLibraryPath="/data/app/com.swetabh.dhcpinfoapp-Tw1b0ywEt9clURpJKtI5sQ==/lib" publicFlags="541638470" privateFlags="0" ft="174a4d493c8" it="174a4d4a70e" ut="174a4d4a70e" version="1" userId="10236">
        <sigs count="1" schemeVersion="2">
            <cert index="27" key="308202e4308201cc020101300d06092a864886f70d010105050030373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b30090603550406130255533020170d3230303331373036313035365a180f32303530303331303036313035365a30373116301406035504030c0d416e64726f69642044656275673110300e060355040a0c07416e64726f6964310b300906035504061302555330820122300d06092a864886f70d01010105000382010f003082010a0282010100927514005701794f048171f21008313fbb12a233fa130c9acb5fccaf6ad83718cbb454ea155ddb8585ff603ec2ce35d982517b3dd7fc7aa5df371f6b8a6673423edc56ffae6ed193d0978f5cdd53d0187422f8adcfe18ff10c72bea3a7a3f2d318a0894e3be9ee54d20afa902e89dfb7ac12e06c5dc98a519d9786b09c8e1feef7852178a932bf233c257d683ced077c17d9a9f760561462e88afed62d253853b7bf8ec9a5026a84293fa38539b7282b2a2cb7135940699846768cad2062eb02a3cc7c3e2ef91054eaf024e882a57dad2f51eb8c7fef46047133facf837b05d0c5f557a0359ab7b8cd23dd6533e1d5ffc80b894bf8ddf04880c599de42e565930203010001300d06092a864886f70d010105050003820101002384b6d797d9a1aadf95416fa31bc566cccdb365b8f0958b3fcc622711f2b6bbd81b098171beb00f5ab716e5cb2ed0a32511ee97575d06c1e315eb7209ccf8189eb4a94f3627be1ac2d57553a0872f7c03625e0618be392e69d223a821decda6b46c31e74a48b3ab7499f756661a563cf2dfdf643d8fc3fbb5e0c62a2b93c0a072a1672eeea823c040c72a16a9de875b11bb2946ee48fb3c5a904538a62b17a2a39229995e8345e159bcbe788a558758b991bc06ce10fba9512797a7766c043244609699df5ce619d0e73e4948315497154de6c9c67e1ab41272edae3500f69d60a59778320b936ae36fc1df112111658b87fd6a802f0b75b6ca6913a871b3eb" />
        </sigs>
        <perms>
            <item name="android.permission.ACCESS_NETWORK_STATE" granted="true" flags="0" />
            <item name="android.permission.ACCESS_WIFI_STATE" granted="true" flags="0" />
        </perms>
        <proper-signing-keyset identifier="45" />
    </package>

The permissions will have three different attributes.

  1. Name
  2. Package
  3. Protection

By default the value for package is android in the permissions tag.

    <permissions>
        <item name="com.google.android.gms.auth.api.phone.permission.SEND" package="com.google.android.gms" protection="2" />
        <item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
        <item name="android.permission.ACCESS_CACHE_FILESYSTEM" package="android" protection="18" />
        <item name="android.permission.REMOTE_AUDIO_PLAYBACK" package="android" protection="2" />
        <item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" package="com.android.providers.downloads" />
        <item name="com.google.android.apps.photos.permission.C2D_MESSAGE" package="com.google.android.apps.photos" protection="2" />
        <item name="android.permission.MANAGE_APPOPS" package="android" protection="2" />
        <item name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" package="android" protection="2" />
        <item name="android.permission.INTENT_FILTER_VERIFICATION_AGENT" package="android" protection="18" />
        <item name="android.permission.BIND_INCALL_SERVICE" package="android" protection="18" />
        <item name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" package="android" protection="18" />
.
.
.
	</permission>

packages.list

It is a simple text file that contains the package name, user id, flag, data directory, and target SDK version. The assumption is packages.list file may provide faster lookup of installed packages, because it keeps important information only.

E.g.:

com.swetabh.dhcpinfoapp 10236 1 /data/user/0/com.swetabh.dhcpinfoapp default:targetSdkVersion=29 none 1 1
com.android.storagemanager 10200 0 /data/user/0/com.android.storagemanager default:privapp:targetSdkVersion=29 1065 0 29
com.android.bookmarkprovider 10150 0 /data/user/0/com.android.bookmarkprovider default:targetSdkVersion=29 none 0 29
com.android.settings 1000 0 /data/user_de/0/com.android.settings platform:privapp:targetSdkVersion=19 
.
.
.

packages-stopped.xml

This file contains the list of packages that has been stopped. Suppose you have stopped any package, then the packages-stopped.xml will be updated with that value.

How does PackageManagerService install APK in android?

These are the following steps which are performed in PMS

  1. It keeps on waiting to get request for installing an APK.
  2. After getting the request, add the package to the queue for installation process.
  3. It determines appropriate location for the package installation. It will decide, where the APK must be installed. For system apps or priv-app this is done with the help of ParallelPackageParser at boot time.
  4. Determine the installation, whether it is fresh install or to update the existing one.
  5. Copies the APK to the directory where it is getting installed.
  6. Determine the UID of the application.
  7. Request the installd daemon process (via installer -> installd native calls) to do an installation.
  8. Then creates the application directory and set required permissions.
  9. Reflect the latest changes in packages.list and packages.xml.
  10. Lastly, it sends a Broadcast to the system along with the name of the effect of installation.
  11. Intent: ACTION_PACKAGE_ADDED -> If it is a new installation
    Intent: ACTION_PACKAGE_REPLACED -> If it is an update.

I hope in this post, at least you got the undertsanding of what is PackagerManagerService, what are its use, and how it works in in order to install/uninstall APK in android device.

You can also watch this video to understand how it work.

Swetabh

Swetabh is an Android Developer and a Tech enthusiast. His enthusiasm drives him to know about various technologies. Now he wanted to share his knowledge to other enthusiast who are passionate to know-how and become a GIZMOMIND.

Leave a Reply