This article is based on Android Q source code analysis and introduction

Consider a few questions before your introduction:

  1. Which process is the PackageManagerService in
  2. Why PackageManagerService
  3. What are the functions of PackageManagerService

Since the PackageManagerService name is too long, we will use PkMS instead of PackageManagerService as the introduction. As for why not use PMS, PMS usually stands for PermissionManagerService, and the two services are very closely related. Basically, PermissionManagerService can be considered a child of PackageManagerService. To avoid confusion, Therefore, the PackageManagerService is called PkMS and the PermissionManagerService is called PMS.

The start of the PkMS

The process under which the PackageManagerService in the previous question is under is addressed in this section. First of all, let me clarify the Android startup process, which is probably known to many people and not our focus, but here is a general introduction. Zygote is the first Java process to be started by init process parse init.rc, and then Zygote forks out the system_server process. See forkSystemServer() method for details. It is then entered from systemServer.java’s main() method. Then systemServer. Java will start various services, including PkMS start, start PkMS function call process is as follows:

SystemServer.main()
  SystemServer.run()
  	SystemServer.startBootstrapServices()
  		PackageManagerService.main()
Copy the code

PkMS is a common class started by SystemServer. The process is system_server. How does an application communicate with PkMS? The obvious answer is Binder. Binder is a mechanism for inter-process communication in Android. A process can register more than one Binder. Any class that implements the corresponding Binder interface can be registered in The Service_Manager. An application can call a Binder’s interface by obtaining the Binder’s proxy class (new, with an int variable called Handle, serverice_manager 0). The purpose of replacing services with classes is to avoid the illusion that services are unattainable.

The function of PkMS

The reasons for the PackageManagerService and the main functions of the PackageManagerService are answered in this section. First, we need to understand the structure of the APK file, which is divided into three parts:

  1. The Java code, mainly the classes.dex file, can be multiple
  2. Resource files, including Androidmanifest.xml (compiled into binary), all files in the res directory, which is mainly for layouts, images, etc. The assets file in the assets directory, which is primarily the application’s native resource. Resources.arsc, this file contains compiled strings, value types (bool, int, dimens, etc.), which are directly placed in resources.arsc. And file references in the res directory. You can use Android Studio->Build->Analyze APK or go to the SDK directory builder-tools/to select a compiled version and use the aapT2 command to view. Aapt2 in AOSP is under out/host/linux-x86/bin/
  3. Check file, this file is mainly to see if the file has been modified or signed correctly

Now that you know the structure of APK, how do you start the application? We all know the code that starts an Activity at the application layer:

Intent intent = new Intent("action");
startActivity(intent);
Copy the code

It is then passed to AMS to start the Activity. If there is no PkMS, then AMS will have to get the apK path, extract it, and parse androidmanifest.xml. ActivityThread creates an instance of the Activity, which is then managed by AMS. And every time you start an APK Activity, you need to decompress the APK file. File operation is a very time-consuming operation, so is there a way to simplify it? This is where PkMS comes in. One of PkMS’s primary tasks is to cache the APK information. AMS simply takes it from PkMS when it needs it. The time to parse the APK can be compared to the time to install the application, which is why the PackageManagerService is used. Here is a summary of the main functions of the PkMS:

Install/uninstall the application

PkMS accepts three ways to install applications:

  1. PackageInstaller, precisely with android. Intent. Action. INSTALL_PACKAGE application, and the one and only one application of this action, the specific check process is as follows:

    //PackageManagerService.java    
    private @NonNull String getRequiredInstallerLPr(a) {
        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);
    
        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                                                                        MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                                                                        UserHandle.USER_SYSTEM);
        if (matches.size() == 1) {
          ResolveInfo resolveInfo = matches.get(0);
          if(! resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {throw new RuntimeException("The installer must be a privileged app");
          }
          return matches.get(0).getComponentInfo().packageName;
        } else {
          throw new RuntimeException("There must be exactly one installer; found "+ matches); }}Copy the code
  2. Shell is installed, the command for the adb Shell PM install [PATH | -], other parameters can be achieved by PM command to see, but this command can only be equipped with the powers of the Shell folder apk, general Shell will have/data/local/TMP read and write access, Basically application treasure and other application installation applications are installed through this way

  3. Adb install [PATH], Shell install is to install apK on the phone, and ADB is to install APK file on the PC, they are different.

There are also three ways to uninstall an application, so you can learn about it yourself

Storing application Information

PkMS installs the application to obtain the apK information and then cache it. PkMS has two levels of cache:

  1. Level 1 cache is in memory, it’s an ArrayMap,final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<>();The data is updated when the application is installed/uninstalled and when it is started
  2. Level 2 cache is stored as files in/data/system/In, the main information is stored inpackages.xmlIn the

Of course, the data partition will be deleted during the first startup or factory restoration, so delete all application information and rescan all APK