返回

Android系统初始化(十):揭秘PMS在初始化时的精妙设计

Android

Android PMS模块:深入剖析其启动过程

前言

在Android系统的启动过程中,包管理器服务(PMS)模块扮演着至关重要的角色。它负责管理系统中所有应用程序包的生命周期、权限控制和组件解析。在启动期间,PMS模块执行一系列初始化操作,为后续的系统运行做好准备。

Watchdog 监听

为了确保 PMS 模块稳定可靠地运行,Android 系统在启动时会为 PMS 注册一个 Watchdog 监听器。该监听器负责监视 PMS 进程的运行状态。如果检测到 PMS 进程异常退出,则会自动重启 PMS 进程。

代码示例:

private void registerWatchdog() {
    final ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mLock) {
                mWatchdog = IActivityManager.Stub.asInterface(service);
                mHasBoundToWatchdog = true;
                mLock.notifyAll();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            synchronized (mLock) {
                mWatchdog = null;
                mHasBoundToWatchdog = false;
            }
        }
    };

    Intent intent = new Intent().setComponent(new ComponentName("system", "com.android.server.am"));
    bindService(intent, conn, Context.BIND_AUTO_CREATE);
}

readPermissions 方法

PMS 模块的另一个重要初始化步骤是读取系统中的权限配置信息。这些信息存储在 XML 文件中。PMS 模块调用 readPermissions 方法来读取这些 XML 文件,并将结果填充到 SystemConfig 对应的数据结构中。

代码示例:

public void readPermissions() {
    File permDir = new File("/system/etc/permissions");
    if (!permDir.exists() || !permDir.isDirectory()) {
        throw new RuntimeException("Directory /system/etc/permissions does not exist");
    }

    for (File file : permDir.listFiles()) {
        if (!file.isFile() || !file.getName().endsWith(".xml")) {
            continue;
        }

        readPermissionsFromXml(file);
    }
}

readPermissionsFromXml 方法

readPermissionsFromXml 方法负责解析权限配置信息 XML 文件。它将 XML 文件的内容解析成 Permission 对象,并将其添加到 SystemConfig 数据结构中。

代码示例:

private void readPermissionsFromXml(File file) {
    try {
        FileInputStream fis = new FileInputStream(file);
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(fis, null);

        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
            if (type == XmlPullParser.START_TAG) {
                String tag = parser.getName();
                if ("permission".equals(tag)) {
                    Permission perm = new Permission();
                    perm.name = parser.getAttributeValue(null, "name");
                    perm.packageName = parser.getAttributeValue(null, "package");
                    perm.descriptionRes = parser.getAttributeResourceValue(null, "description", 0);
                    perm.protectionLevel = parser.getAttributeIntValue(null, "protectionLevel",
                            PermissionInfo.PROTECTION_NORMAL);
                    perm.flags = parser.getAttributeIntValue(null, "flags", 0);

                    mPermissions.put(perm.name, perm);
                }
            }
        }
        fis.close();
    } catch (FileNotFoundException e) {
        Log.e(TAG, "Couldn't find permission file " + file.getPath());
    } catch (IOException e) {
        Log.e(TAG, "Couldn't read permission file " + file.getPath());
    } catch (XmlPullParserException e) {
        Log.e(TAG, "Error parsing permission file " + file.getPath());
    }
}

结论

PMS 模块的启动过程涉及多个关键步骤,包括注册 Watchdog 监听器、读取权限配置信息和解析权限配置信息 XML 文件。这些步骤对于确保 PMS 模块的稳定运行和系统权限配置的正确加载至关重要。

常见问题解答

  1. 为什么需要 Watchdog 监听器?

    • Watchdog 监听器可以监视 PMS 进程的运行状态,并在 PMS 进程异常退出时自动重启它,确保 PMS 模块的稳定运行。
  2. 权限配置信息存储在哪里?

    • 权限配置信息存储在 /system/etc/permissions 目录下的 XML 文件中。
  3. PMS 如何读取权限配置信息?

    • PMS 调用 readPermissions 方法来读取 XML 文件,并将其内容解析成 Permission 对象,存储在 SystemConfig 数据结构中。
  4. PMS 模块在启动过程中还有什么其他重要步骤?

    • 除了注册 Watchdog 监听器和读取权限配置信息外,PMS 模块在启动过程中还负责管理应用程序包的生命周期、控制应用程序权限和解析应用程序组件。
  5. PMS 模块对 Android 系统有哪些好处?

    • PMS 模块为 Android 系统提供了一个集中式框架,用于管理应用程序包、控制权限和解析组件,确保系统安全、稳定和高效。