APK installation process in Android

Foreword:

What can you get from this article?
This article describes how Android handles the application installation process. Specifically include:

What are the methods to install the application?
How does android handle the installation process?
How does the default application PackageInstaller perform its magic?
How does the process flow from one activity to another?
What are the different components involved in this process?
Different methods of installing APKs.
There are several ways to install Android apps.

Different Ways to Install APKs

There are several ways to install Android apps:

App Market, which is how most users install apps.

Download the APK file to the device, then open it. This option can only be installed if the "Unknown sources" option is enabled in the settings.

Use the command of adb installandroidsdk, which at the end calls the command cmd package install pointed to by pm install.

Copy the APK file directly to one of the system application directories. When an APK file is copied directly to an application directory, it is automatically detected and installed.

android operating system

Recently, Android has become the most popular mobile platform in the world. Originally designed for smartphones, it now powers tablets, TVs, wearables, and soon even cars.

Android is built on the Linux kernel. In the Android system architecture, the application is at the highest level. In Android, each application has its own directory to save data. Android assigns each application a UID (userID) when it is installed. It is a constant value and will not change until the application is reinstalled. It is different from PID (processID), which changes all the time.

Android uses UIDs to set up kernel-level application sandboxing. The kernel enforces security between applications and the system at the process level through standard Linux tools such as user and group ids assigned to applications. By default, applications cannot interact with each other and access to the operating system is limited.

There are two main categories of Android applications.

1. System application
It is included in the operating system image and is a read-only application, which cannot be uninstalled or changed by ordinary users. System apps can live in the /system/app/ directory, while certain privileged apps live in the /system/private-apps/ directory. The /system/vendor/app/ directory hosts vendor-specific applications.

2. User applications
User-installed applications are installed on a dedicated read-write partition (usually called /data), which carries user data and can be uninstalled or changed. User-installed apps can be found in /data/app/ .

Installation process

PackageInstaller and PackageManager
PackageInstaller is the default application for installing any application on android devices. It provides an interactive interface to install a common package.

PackageManager is a class used to retrieve various information related to the application package currently installed on the device. It is an abstract class whose implementation is created by the application package manager in ContextImpl#getPackageManager() .

initial activity

Any app installed using its APK file is considered an "unknown source". The actual definition of an unknown source is a bit broader; on startup, the PackageInstaller retrieves the UID and request to install the APK's application package. It checks if the requested app is privileged (exists in /system/priv-app/, i.e. the Google Pack installer), and if not, treats it as an unknown source.

The package to install can be in the form of a content URI or a file URI. The first activity that happens is that InstallStart determines which activity is the first visible activity for the install and forwards the intent to it.

If a package is installed from a content URI, then the InstallStaging activity is started, which loads the package and converts it from file to install, which creates the staging task and fetches a package file.

If an error occurs during this process, the error result is set and showError() is called. If the file is staged then it initiates the delete StagedFileOnResult which at the end calls the PackageInstallerActivity and deletes the staged install file.

package installation

Installing an APK file is also known as an installer package to sideload an application. PackageInstallerActivity is launched when an application is installed via sideloading.

In PackageInstallerActivity, the package is parsed first, and then the user is notified of parsing errors through a dialog box. If the package is successfully parsed, the user is notified to turn on the option in the "Unknown sources" settings. If the package already exists on the device, a confirmation dialog will be shown to the user (to replace the existing package). All state transitions are handled in this activity.

The activity analyzes the package and checks for any errors. If the package is parsed correctly, then it will set the installer for this package.

PackageInstaller calls startInstall() which raises the subactivity Installing...Installing to actually install the application

installation activity

The InstallInstalling activity sends packages to the package manager and processes the results from the package manager. This has two phases: first, sending the data to the package manager, and then waiting for the package manager to process the results.

This activity checks for packages, and if an application with the given package name is already installed on the system for another user, then it will call PackageManager#installExistingPackage() and install it for the calling user.

actual installation

The InstallInstalling activity creates PackageInstaller.SessionParams and sets some important properties:

Full Install Mode
Package Source
Package Name
Package Size
Install Location
All other important properties can be found in the documentation.
This information session is created by createSession(params) .

The InstallInstallInstalling activity creates an InstallingAsyncTask, an AsyncTask that sends packages to the installer. It opens the package installer session, which is retrieved by openSession() and opened with OutputStreamopenWrite(String name, long offsetBytes, long lengthBytes) which opens a stream to write the APK file to the session. Set the progress of the installation using setStagingProgress(float) and addProgress(float) at the end of the session and hand everything over.

result activity

In the InstallInstalling activity broadcast receiver the install event receiver registers the launchFinishBasedOnResult method with the observer. The InstallEventReceiver notifies the observer when the installation process is complete

launchFinishBasedOnResult launches the corresponding completion activity based on the result.

  • InstallSuccess by calling launchSuccess() if the process completed successfully
  • InstallFailed by calling launchFailure() with the appropriate status and status message for the failed result

Update information in the system database

The Android operating system has two configuration files for saving application information in the Android system. packages.list and packages.xml. Both files can be located in the /data/system/ directory

package.list

com.google.android.carriersetup 10073 0 /data/user/0/com.google.android.carriersetup default:privapp:targetSdkVersion=28 3003
com.android.wallpaperbackup 1000 0 /data/user/0/com.android.wallpaperbackup platform:privapp:targetSdkVersion=28 1065,3002,1023,3003,3001
com.innersloth.spacemafia 10090 0 /data/user/0/com.innersloth.spacemafia default:targetSdkVersion=30 3003
...
com.kruna1pate1.pictionaryapp 10089 1 /data/user/0/com.kruna1pate1.pictionaryapp default:targetSdkVersion=32 3003

Here, the space is divided into 6 columns with 6 application related information:

The name of the application package
The UID of the application. (We can easily plot this by looking at them u0_a89 => ten thousand and eighty-nine )
Whether the application is in debug mode or not.
The data storage path of the application.
Information from the SEinfo company app.
The user group to which the application belongs.

package.xml

Here's an abstract view of its contents:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<packages>
    <version ... />

    <permission-trees>
        <item name="xyz" package="xyz" />
        ...
    </permission-trees>

    <permissions>
        ...
    </permissions>

    <package ...>
        <sigs count="1" schemeVersion="3">
            <cert ... />
        </sigs>

        <perms>
            <item name="xyz" granted="true" flags="0" />
            ...
        </perms>

        <proper-signing-keyset identifier="6" />
    </package>

    <updated-package ... >
        <perms>
            ...
        </perms>
    </updated-package>

    <shared-user ... >
        <sigs count="1" schemeVersion="3">
            <cert index="4" />
        </sigs>

        <perms>
            ...
        </perms>
    </shared-user>

    <keyset-settings version="1">
        <keys>
            <public-key ... />
            ...
        </keys>

        <keysets>
            <keyset identifier="1">
                <key-id identifier="1" />
            </keyset>
        </keysets>

        <lastIssuedKeyId value="17" />
        <lastIssuedKeySetId value="17" />

    </keyset-settings>
</packages>

Key elements of this file:

Permission Block: A list of permissions defined in the system.
Package block: Details of installed applications.
Update package block: Information related to the update package
Shared user block: System-defined shared user information.
Keyset settings block: Contains the public key information for signing the installed application.

Notify other components

Finally, changes to the package database (new package entries and any new permissions) are persisted to disk. PackageManagerService sends ACTION_PACKAGE_ADDED or ACTION_PACKAGE_REPLACED in case of updates to notify other components about newly added applications.

Guess you like

Origin blog.csdn.net/m0_56255097/article/details/127559656