Android system important component PMS

Android PMS (Package Manager Service) is an important component in the Android system, which manages the installation, uninstallation, and update of all applications in the Android system. Let's introduce the principle of Android PMS and its code analysis in detail, as well as its common methods.

1. Principle of Android PMS

Android PMS is a system service of the Android system, which is mainly used to manage the installation, uninstallation and update of applications. It is started when the system starts and is managed by the system process. The main principles of Android PMS can be divided into the following four aspects:

1. Application installation

When the user installs the application, Android PMS will be responsible for parsing the APK package into the corresponding Java object, and storing the relevant information in the data/data/packageManager.xml file in the system directory, and saving the APK package to the system directory In the data/app folder under. In the process of storing relevant information, Android PMS will determine whether the application has certain permissions according to the permission level.

2. Uninstall the application

When the user uninstalls the application, Android PMS will be responsible for deleting the information corresponding to the application in the data/data/packageManager.xml file in the system directory, and deleting the APK package of the application in the data/app folder , which also deletes the app's data and cache.

3. Application update

When the user updates the application, the Android PMS will perform an uninstall and install operation similar to the application, that is, delete the old version first, and then install the new version.

4. Application permission management

Android PMS is also responsible for managing application permissions. It will be responsible for verifying the permissions applied for during the installation process of the application and determining whether the application has the right to use these permissions. When the application is running, Android PMS will also determine whether certain operations can be performed according to the permission level.

Two, Android PMS code analysis

The core code of PMS is in frameworks/base/services/core/java/com/android/server/pm/the directory, mainly including the following files:

  • PackageManagerService.java: The main service class of PMS, which is responsible for starting the application manager, parsing and updating application packages, and maintaining the list and metadata of currently installed applications.
  • PackageParser.java: Application package parser, used to parse APK files and verify permissions and other information.
  • Settings.java: Application package and permission setting class for storing and retrieving data of installed applications.
  • PermissionPolicyInternal.java: Permission policy class, used to handle logic related to application permissions.

In addition, there are some auxiliary classes, such as PackageSetting, UserManagerServiceetc., all for the purpose of enabling PMS to better complete application management and permission control.

In general, the code analysis of PMS requires the knowledge of the overall architecture of the Android system, the file structure of the Android application package, the installation, uninstallation and update of the Android application. A certain Android system development experience and Java programming ability are required for in-depth understanding.

The following are the key code snippets of Android PMS:

public class PackageManagerService extends IPackageManager.Stub implements Context
            .SystemService, Watchdog.Monitor {
    
    
    public void installPackage(String packageURI, PackageInstallObserver observer, int flags, 
            String installerPackageName) {
    
    
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, "Package installer");
        Uri packageUri = Uri.parse(packageURI);
        PackageParser.Package pkg = null;
        try {
    
    
            final File tmpFile = mInstaller.installStage(packageUri, observer, flags, null, 
                    installerPackageName);
            pkg = scanPackageLI(tmpFile, flags | SCAN_NEW_INSTALL | SCAN_FORWARD_LOCK, 0, 
                    System.currentTimeMillis(), null);
            if (pkg != null) {
    
    
                Message msg = mHandler.obtainMessage(POST_INSTALL, 
                        new InstallParams(pkg, tmpFile, 0, installerPackageName, null, 
                        observer));
                mHandler.sendMessage(msg);
            } else {
    
    
                mInstaller.rollbackActiveInstall(observer);
            }
        } catch ...
     }
}

This code snippet is the installPackage method of the PackageManagerService service. In this method, use enforceCallingOrSelfPermission to ensure that only apps that have permission to install apps can perform this action. Then obtain the package object by parsing the package URI, and then scan the package and convert it into a Package object through the scanPackageLI method. Finally, the PackageManagerService service passes the Package object to the Handler to complete the package installation process asynchronously.

The following is the key code snippet of the scanPackageLI method of the PackageManagerService service:

private PackageParser.Package scanPackageLI(File scanFile, int flags, int scanMode,
            long currentTime, UserHandle user) throws PackageManagerException {
    
    
    if ((flags & PackageParser.PARSE_IS_SYSTEM) != 0) {
    
    
        flags |= PackageParser.PARSE_IS_SYSTEM_DIR;
    }
    PackageParser pp = new PackageParser();
    final PackageParser.Package pkg;
    try {
    
    
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setCallback(this);
        pkg = pp.parsePackage(scanFile, flags, true);
    } catch .. {
    
    
        throw new PackageManagerException(INSTALL_PARSE_FAILED_BAD_MANIFEST, 
                "Failed to parse package " + scanFile);
    }
    return pkg;
}

This code snippet is the scanPackageLI method of the PackageManagerService service. In this method, this code creates a PackageParser object, sets the parsing process independent flag of this object, and passes this instance to the scanner and parser parts of PackageParser to scan and parse the package. Ultimately, this method returns a PackageParser.Package object.

3. Common methods of Android PMS

1. Obtain application information

PackageManager pm = getPackageManager();
List<PackageInfo> packages = pm.getInstalledPackages(0);
for (PackageInfo packageInfo : packages) {
    
    
    String packageName = packageInfo.packageName;
    String versionName = packageInfo.versionName;
    int versionCode = packageInfo.versionCode;
    ApplicationInfo applicationInfo = packageInfo.applicationInfo;
    String appName = pm.getApplicationLabel(applicationInfo).toString();
    Drawable icon = pm.getApplicationIcon(applicationInfo);
}

2. Install the application

private void install(String path) {
    
    
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
    startActivity(intent); 
}

3. Uninstall the application

Intent intent = new Intent(Intent.ACTION_DELETE, Uri.parse("package:" + packageName));
startActivity(intent);

4. Obtain the permission information of the application

PackageManager pm = getPackageManager();
String[] permissions = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions;

5. Obtain the application component information of the application

PackageManager pm = getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES |PackageManager.GET_SERVICES|PackageManager.GET_PROVIDERS|PackageManager.GET_RECEIVERS);
ActivityInfo[] activities = packageInfo.activities;
ServiceInfo[] services = packageInfo.services;
ContentProviderInfo[] providers = packageInfo.providers;
BroadcastReceiver[] receivers = packageInfo.receivers;

The above is the introduction of the principle of Android PMS, its code analysis and its common methods. It is very important to understand the principle of PMS. It can help us better understand the operating mechanism of the Android system and help us better develop our own applications.

Guess you like

Origin blog.csdn.net/weixin_44008788/article/details/130017634