android service 之pm

pm 是Android的包管理器, 对应着包安装, 删除, 信息查看等操作. 其主Service为 PackageManagerService, 对权限的限制部分也在PackageManagerService中。 由于PM服务中有大量的InstantApp的处理代码, 忽略这部分代码.

源码粗略

在pm服务中, 有属性mActivities, mReceivers, mServices, mProviders四个IntentResolver, 分别对应Android的四大组件。 在系统启动, 安装, 删除, 移动时这些会进行相应的更新. 而且这些信息是时时刻刻都在内存中的, 可以明确说过多的安装应用, 即使不运行也会拖慢运行速度。

PackageManagerService类中有很多get方法用于query.

mPackages的写入(commitPackageSettings)

mPackages作为一个记录包与对应包信息的Map, 其写入是PM服务的第一步. 其写入位置只有一个即

  • commitPackageSettings(Package pkg, PackageSetting pkgSetting, UserHandle user, int scanFlags, boolean chatty)

其由scanPackageLI调用, 最终的调用来源:

  • installNewPackageLIF: 安装一个不存在的安装包
  • replaceNonSystemPackageLIF:
  • replaceSystemPackageLIF:
  • scanDirLI:
  • PackageManagerService的构造函数
  • decompressSystemApplications
  • setEnableSetting
  • loadMediaPackages
  • loadPrivatePackagesInner
  • installPackageFromSystemLIF

PackageHandler

PackageManagerService中有一个消息循环, PackageHandler是其Handler。 这个线程用于bind service, 并与该Service通信. 该Service是”com.android.defcontainer.DefaultContainerService”, 使用这个单独Service的目的是为了防止在COPY和检查apk文件时, 对应的文件所在磁盘被移除, 而进程被内核kill的情况, 防止系统进程收到影响.

  • 第一步: 下发INIT_COPY指令, 用于检测Service绑定状态, 并记录安装信息
  • 第二步: Service绑定后, 下发MSC_BOUND绑定成功消息, 从记录的需要安装的信息中取出第一个开始处理copy
  • 第三步: service.getMinimalPackageInfo, 然后校验各种信息
  • 第四步: 调用InstallArg.copyApk开始copy(最终调用service.copyPackage这个方法)

其中第三步与第四步之间可能会存在异步的校验, 待校验完成后会通过PackageHandler抛出PACKAGE_VERIFIED, CHECK_PENDING_VERIFICATION这两个消息(各大厂商提示安装包非官方包应该是通过这里做的), 支持复制步骤完成.

  • 第五步: processPendingInstall,
  • 第六步: 调用installPackageTracedLI, 这里就与commitPackageSettings连接上了

Installer与Installd

Installer是一个系统服务, 集成自SystemService, 是一个Java层的包装, 通过Binder与native服务”installd”进行通信服务, 可以理解为Installd的一层壳.

提供能力如下:
createAppData, migrateAppData, clearAppData, destroyAppData等操作AppData的能力, 获取AppSize, dexopt, 操控profile等能力.

其真实实现为InstalldNativeService.cpp(framewors/native/cmds/installd/InstalldNativeService.cpp)