Android PMS(Package Manager Service)源码介绍

文章目录

  • 前言
  • 一、PMS 启动流程
  • 二、APK 安装流程
  • 三、APK 卸载流程
  • 四、权限管理
    • 静态权限
    • 动态权限
  • 五、 数据存储与一致性
  • 六、 PMS 的安全性策略
    • 1、权限检查
    • 2、签名认证
    • 3、动态权限管理
    • 4、应用安装验证
    • 5、保护系统目录
  • 七、PMS 调试方法
  • 总结


前言

PackageManagerService(简称 PMS)是 Android 系统中的核心服务之一,负责应用的安装、卸载、查询和权限管理等。它是 Android 应用生命周期管理和安全机制的基石。

主要职责:
1、应用安装与卸载
2、静态权限解析与动态权限授予
3、应用信息查询
4、系统应用的预加载
5、数据存储与一致性管理


提示:以下是本篇文章正文内容,下面案例可供参考

一、PMS 启动流程

在这里插入图片描述

PMS 在系统启动时由 SystemServer 启动。其核心流程如下:

1、SystemServer 初始化
在 SystemServer 的 startBootstrapServices 方法中,调用 PackageManagerService.main(),完成 PMS 的创建和初始化。

2、关键方法解析
PackageManagerService.main()

public static PackageManagerService main(Context context, Installer installer, boolean factoryTest) {
    PackageManagerService pms = new PackageManagerService(context, installer, factoryTest);
    ServiceManager.addService("package", pms);
    return pms;
}

这里完成了:
1、PMS 对象的实例化。
2、将 PMS 注册到 ServiceManager,供其他服务访问。

3、扫描已安装应用
调用 scanDirLI 方法扫描 /system/app/data/app 等目录,加载所有已安装的应用包信息,并存储到内存和文件中(如 packages.xml)。

二、APK 安装流程

APK 的安装是 PMS 最重要的功能之一。从用户触发安装到系统完成更新的完整流程如下:

1、入口方法 应用安装请求通过 PackageInstaller 模块发起,最终调用 installPackageAsUser 方法。

public void installPackageAsUser(String originPath, InstallParams params, int userId) {
    mHandler.post(new InstallParams(originPath, params, userId));
}

此处将安装请求交给 InstallParams 处理。

2、核心处理逻辑在 InstallParams 的 handleStartCopy 方法中,执行以下步骤:

  • 解析 APK 文件:通过 PackageParser 提取包名、版本等信息。
  • 签名校验:调用 verifySignatures 确保 APK 签名合法。
  • 写入系统记录:调用 mSettings.addPackage() 更新系统数据。
  • 通知系统服务:更新系统组件(如 AMS)和广播安装完成事件

3、安装完成广播 APK 安装完成后,PMS 会通过 Intent.ACTION_PACKAGE_ADDED 广播通知其他组件。

三、APK 卸载流程

APK 卸载的主要流程类似于安装,但涉及的数据清理步骤更多:

1、卸载入口 卸载请求通过 deletePackageAsUser 方法发起,最终调用 deletePackageLI 方法。

2、核心处理逻辑
清理应用数据:删除 /data/app/ 目录中的文件。
移除系统记录:从 packages.xml 中删除相关记录。
广播通知:通过 Intent.ACTION_PACKAGE_REMOVED 通知系统组件和应用。

3、特殊情况 如果应用包含共享库或依赖的资源,PMS 会延迟清理,确保不会影响其他应用。

四、权限管理

权限分为静态权限和动态权限,PMS 通过解析 AndroidManifest.xml 和系统调用提供管理功能。

静态权限

解析过程
在应用安装时,PMS 调用 PackageParser 的 parsePackage 方法,解析应用的 AndroidManifest.xml 文件,提取 标签内容。

PermissionInfo permission = new PermissionInfo();
permission.name = parser.getName();
mPermissions.add(permission);

动态权限

授予与撤销
动态权限的管理主要通过 grantRuntimePermission 和 revokeRuntimePermission 方法实现。

public void grantRuntimePermission(String packageName, String permissionName, int userId) {
    enforcePermissionChecks(permissionName);
    mSettings.grantRuntimePermission(packageName, permissionName, userId);
}

实际场景
例如,在某些即时通讯应用中,用户拒绝麦克风权限会导致无法发送语音消息。

五、 数据存储与一致性

PMS 的数据存储主要通过以下文件完成:

1、packages.xml 存储应用的基本信息,如包名、路径、版本等。

<package name="com.example.app" codePath="/data/app/com.example.app-1/base.apk" />

2、runtime-permissions.xml 存储动态权限授予记录。

<permissions>
    <permission name="android.permission.CAMERA" granted="true" />
</permissions>

3、一致性保障
锁机制:PMS 使用锁机制保护并发读写,确保数据一致性。
文件备份:在文件更新前,系统会先保存备份副本,确保异常恢复能力。

六、 PMS 的安全性策略

PMS 是 Android 安全机制的核心,以下几点尤为重要:
签名校验:通过验证应用签名确保来源可信。
SELinux 策略:限制 PMS 的文件访问权限,增强系统安全性。
权限隔离:动态权限机制确保用户对敏感操作的控制权。

源码介绍

1、权限检查

PMS 负责管理应用的权限,包括动态权限和安装时权限。
权限检查主要在 checkPermission() 和 checkUidPermission() 方法中完成。
源码位置:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

@Override
public int checkPermission(String permName, int uid) {
    final int permission = mSettings.getPermissionLocked(permName, uid);
    return (permission == PERMISSION_GRANTED) ? PERMISSION_GRANTED : PERMISSION_DENIED;
}

2、签名认证

在应用安装或更新时,PMS 会通过 verifySignatures() 方法验证签名是否一致。
防止未授权的 APK 替换已安装的 APK。
源码位置:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java

private void verifySignatures(PackageParser.Package pkg, PackageSetting ps)
        throws PackageManagerException {
    if (!compareSignatures(pkg.mSigningDetails.signatures, ps.signatures.mSignatures)) {
        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                "Signature mismatch for " + pkg.packageName);
    }
}

3、动态权限管理

动态权限是通过运行时授予或拒绝的,主要涉及以下文件:
runtime-permissions.xml 用于存储动态权限的状态
相关代码示例:
源码位置:
frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java

public void grantRuntimePermission(String packageName, String permissionName, int userId) {
    // 检查权限是否属于动态权限
    enforceGrantRuntimePermission(packageName, permissionName, userId);
    // 更新权限的状态
    mPermissionManager.grantRuntimePermission(packageName, permissionName, userId);
}

4、应用安装验证

PMS 在应用安装时会调用 PackageInstaller 验证 APK 文件的完整性

相关代码包括:
安装路径检查
签名校验
安全区域限制

源码位置:
frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java

private void enforceSystemOrRoot(String message) {
    if (Binder.getCallingUid() != Process.SYSTEM_UID &&
            Binder.getCallingUid() != Process.ROOT_UID) {
        throw new SecurityException(message);
    }
}

5、保护系统目录

只有系统权限的应用才可以访问 /system/app/system/priv-app 等系统目录。
安全性检查代码:
源码位置:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

private boolean isPrivilegedApp(String packageName) {
    PackageSetting ps = mSettings.mPackages.get(packageName);
    return ps != null && ps.isPrivileged();
}

七、PMS 调试方法

开发或调试 PMS 时,可以使用以下方法:

1、日志调试
通过 adb logcat | grep PackageManager 查看安装、卸载日志。

2、源码定位
关注 PackageManagerService.java 文件,定位核心方法,如 installPackageAsUser 和 deletePackageLI。

3、文件检查
检查 /data/system/packages.xml 和 runtime-permissions.xml 文件内容,排查问题。

总结

PMS 是 Android 系统中连接应用、用户和系统的桥梁,其源码体现了安装、卸载、权限管理的高效性和安全性。通过深挖源码,理解其核心流程,可以帮助开发者更好地优化和调试应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/924475.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。

2024-11-22 &#xff0c;由格拉斯哥大学创建的OSPTrack数据集&#xff0c;目的是通过捕获在隔离环境中执行包和库时生成的特征&#xff0c;包括静态和动态特征&#xff0c;来识别开源软件&#xff08;OSS&#xff09;中的恶意指标&#xff0c;特别是在源代码访问受限时&#xf…

Web登录页面设计

记录第一个前端界面&#xff0c;暑假期间写的&#xff0c;用了Lottie动画和canvas标签做动画&#xff0c;登录和注册也连接了数据库。 图片是从网上找的&#xff0c;如有侵权私信我删除&#xff0c;谢谢啦~

MySQL45讲 第29讲 如何判断一个数据库是不是出问题了?——阅读总结

文章目录 MySQL45讲 第二十九讲 如何判断一个数据库是不是出问题了&#xff1f;——阅读总结一、检测数据库实例健康状态的重要性二、常见检测方法及问题分析&#xff08;一&#xff09;select 1 判断法&#xff08;二&#xff09;查表判断法&#xff08;三&#xff09;更新判断…

mac下Gpt Chrome升级成GptBrowser书签和保存的密码恢复

cd /Users/自己的用户名/Library/Application\ Support/ 目录下有 GPT\ Chrome/ Google/ GptBrowser/ GPT\ Chrome 为原来的chrome浏览器的文件存储目录. GptBrowser 为升级后chrome浏览器存储目录 书签所在的文件 Bookmarks 登录账号Login 相关的文件 拷贝到GptBrow…

论文阅读笔记 | EEG:运动执行过程中的ERD

参考&#xff1a;https://mp.weixin.qq.com/s/RmcPSLv1ITMZZwqe2uZ_og?token1093147649&langzh_CN

Android U ART young cc流程分析

概述&#xff1a; 众所周知jvm虚拟机为了提高内存回收效率&#xff0c;更高效的进行内存管理与回收&#xff0c;对堆内存进行了分代管理比如hotspot虚拟机的新生代&#xff0c;老年代。根据各代的特征&#xff08; 新生代对象分配频繁而生存周期短&#xff0c;老年代生存周期长…

C++ 11重点总结1

智能指针 智能指针: C11引入了四种智能指针: auto_ptr(已弃用)、unique_ptr、shared_ptr和weak_ptr。智能指针可以更有效地管理堆内存,并避免常见的内存泄漏问题。 shared_ptr: 自定义删除器。 shared_ptr使用引用计数来管理它指向的对象的生命周期。多个shared_ptr实例可以指向…

Sickos1.1 详细靶机思路 实操笔记

Sickos1.1 详细靶机思路 实操笔记 免责声明 本博客提供的所有信息仅供学习和研究目的&#xff0c;旨在提高读者的网络安全意识和技术能力。请在合法合规的前提下使用本文中提供的任何技术、方法或工具。如果您选择使用本博客中的任何信息进行非法活动&#xff0c;您将独自承担…

GB28181系列二:SIP信令

我的音视频/流媒体开源项目(github) GB28181系列目录 目录 一、SIP报文介绍 二、SIP交互流程&#xff1a; 1、Session Model 2、Pager Model 3、SIP信令交互过程中的3个定义 三、媒体传输&#xff08;SDP和RTP&#xff09; 一、SIP报文介绍 这里将会介绍SIP…

【接口自动化测试】一文从0到1详解接口测试协议!

接口自动化测试是软件开发过程中重要的环节之一。通过对接口进行测试&#xff0c;可以验证接口的功能和性能&#xff0c;确保系统正常运行。本文将从零开始详细介绍接口测试的协议和规范。 定义接口测试协议 接口测试协议是指用于描述接口测试的规范和约定。它包含了接口的请求…

CentOS7执行yum命令报错,已加载插件:fastestmirrorLoading mirror speeds from cached hostfile

一、出现一下异常问题&#xff0c;表示域名没有配置或配置错误 问题一&#xff1a; 0curl: (6) Could not resolve host: mirrors.aliyun.com; 未知的错误 问题二&#xff1a;虚拟机使用ping主机&#xff0c;提示network unreachable 2.原因分析 出现这个问题是因为yum在安装…

【Threejs进阶教程-着色器篇】9.顶点着色器入门

【Threejs进阶教程-着色器篇】9.顶点着色器入门 本系列教程第一篇地址&#xff0c;建议按顺序学习认识顶点着色器varying介绍顶点着色器与片元着色器分别的作用Threejs在Shader中的内置变量各种矩阵gl_Position 尝试使用顶点着色器增加分段数增强效果 制作平面鼓包效果鼓包效果…

Ubuntu 硬盘分区并挂载

一、什么是挂载 1.挂载的定义 在 Ubuntu&#xff08;或其他 Linux 系统&#xff09;中&#xff0c;挂载&#xff08;Mount&#xff09; 是将一个存储设备或分区连接到系统的文件系统层次结构中的过程。挂载后&#xff0c;你可以通过某个目录&#xff08;挂载点&#xff09;访问…

【前端开发】一文带你快速入门 JavaScript(上)Web 前端必备程序语言 | 环境搭建与基础知识

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析

在数字科技日新月异的今天&#xff0c;视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台&#xff0c;提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务&#xff0c;广泛应用于…

Qt读写Usb设备的数据

Qt读写Usb设备的数据 问题:要读取usb设备进行通讯&#xff0c;qt好像没有对应的库支持。解决&#xff1a;libusbwindow下载 :Linux下载: QtUsb 开源的第三方库库里面的函数说明&#xff1a;window版本&#xff1a;Linux中也提供的直接下载测试代码&#xff1a;库下载&#xff1…

2024最新python使用yt-dlp

2024最新python使用yt-dlp下载YT视频 1.获取yt的cookie1&#xff09;google浏览器下载Get cookies.txt LOCALLY插件2&#xff09;导出cookie 2.yt-dlp下载[yt-dlp的GitHub地址](https://github.com/yt-dlp/yt-dlp?tabreadme-ov-file)1&#xff09;使用Pycharm(2024.3)进行代码…

一加ACE 3 Pro手机无法连接电脑传输文件问题

先说结论&#xff1a;OnePlus手机无法连接电脑传输数据的原因&#xff0c;大概率是一加数据线的问题。尝试其他手机品牌的数据线&#xff08;比如华为&#xff09;&#xff0c;再次尝试。 连接电脑方法&#xff1a; 1 打开开发者模式&#xff08;非必要操作&#xff09; 进入…

java:aqs实现自定义锁

aqs采用模板方式设计模式&#xff0c;需要重写方法 package com.company.aqs;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock;…

linux系统下如何将xz及ISO\img等格式压缩包(系统)烧写到优盘(TF卡)

最近用树莓派做了个NAS&#xff0c;效果一般&#xff0c;缺少监控及UI等&#xff0c;详细见这篇文章&#xff1a; https://blog.csdn.net/bugsycrack/article/details/135344782?spm1001.2014.3001.5501 所以下载了专门的基于树莓派的NAS系统直接使用。这篇文章是顺便复习一…