打印
[资料分享]

安卓底层开发学习资料第二十二期

[复制链接]
860|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这一期我们来看一下packageMangerService的一个启动过程,以及他在系统中起的作用。首先我们来分析一下packageMangerService
1.管理系统的jar包和apk,包括我们jar包的更新,我们应用的安装、卸载,负责系统的权限问题。
2.负责程序的安装、卸载、更新、解析
3.对于其他应用和服务提供安装和卸载服务。
下面我们来看一下packageMangerService所涉及到的模块有哪些:
packageMangerService也是我们系统的一个核心服务,在启动的时候,他会首先把自己添加到ServiceManger中,然后就可以对其他的服务和APP提供服务,这样的话我们其他的应用想调用packageMangerService做一个权限的校验,或者安装程序的话,他就可以直接通过getservice的接口来拿到packageMangerService这个服务,通过这个服务去安装应用。除了ServiceManger这个服务,还有installd服务。我们packageMangerService只是提供一个向上安装的接口,但是其实他真正的安装和卸载,是调用的我们的installd这个服务。packageMangerService在启动的时候,他需要处理的目录包括/system/app/vender/app/system/freamwork下面的jar包,还涉及一个权限问题,是在我们的/system/etc/permission这个目录下会处理我们一些权限相关的文件。
下面我们来看一下packageMangerService的一个启动过程
首先他要和installd进行连接,这个连接是在systemserver启动的时候调用的installd的一个client,已经和我们installd连接好了,他只是把这个变量传给我们的packageMangerService,这样他才能和我们的installd进行连接,进行一个正常的安装卸载操作,第二创建一个PackageHandler的一个线程,这个线程用来处理外部消息的一些安装卸载请求。第三个是处理系统权限相关的文件,这些文件是在/system/etc/permission目录下的所有xml的文件。我们需要把这些系统文件全部解析出来,然后获取到系统的一些权限的设置,以及系统硬件的一些特殊的特性,都在这里有定义。第四就是扫描安装jar包和APK,我们所说的jar包是system/freamwork下的jar包,以及我们系统默认安装的一些应用,当我们第一次启动的时候都需要把这些jar包和apk全部安装到我们的系统中,安装完之后我们会扫描我们的安装包,拿到我们安装包的信息,这样我们就能在系统中查看到我们所有安装文件的信息。
下面我们在代码下来看一下packageMangerService的一个启动过程,它是由systemserver这个服务来启动的,我们来看一下他是如何来初始化packageMangerService的。
初始化的时候首先做了一些mSettings的一些设置,然后传进来一个install,这样我们就可以通过mInstaller和我们的installd这个服务进行通信。然后会做一些环境变量的设置,比如mAppDataDirmAppInstallDir等,都会在这里定义出来,然后读一个readPermissions();我们来看一这个读取的过程
首先要遍历/system/etc/permissions下面所有的文件,也就是我们的xml文件,调用过程中会调用我们的readPermissionsFromXml解析我们这个目录下的所有文件,解析过程中,会将解析结果添加到哈希对象中,包括我们的mGlobalGids等(上边绿框中的内容)。mGlobalGids是根据我们权限的名称来获取一个gids,这个gids可以理解为一个用户组的概念。mSettings.mPermissions是一个权限与几个组的ID对应,当我们的一个应用被授予这个权限时,他同时也就属于这几个用户组了。mSystemPermissions是讲一个权限赋予一个UID,当进程使用这个UID运行时,这个程序就会拥有UID这个权限。mSharedLibraries是系统添加的一些扩展库,比如谷歌的一些服务。mAvailableFeatures是硬件所支持的一些属性。
我们来看一下具体解析过程,找到readPermission函数
在这里访问的其实就是system/etc/readpermissions,在这个目录下会遍历我们所有的xml,在遍历过程中会根据字段一个一个的解析,解析完之后添加到我们预先设置好的全局变量中,比如我们拿到了一个group
当我们拿到group后,就会将解析结果添加到我们的mGlobalGids中。我们这个getGidForName调用的其实就是一个native的方法,根据一个group的名字拿到一个gid,然后把这个gid添加到mGlobalGids中,同样的我们的permission也是这样一个解析过程,我们的libraryfeatureassign-permission都是在这个函数中进行的处理,那么我们处理完之后,我们整个系统的权限问题基本上都能得到一个解决。
下面我们来看一下我们这个权限问题的xml的定义,我们进入到Android目录下的out/target/product/fiber-a31st/system/etc/permissions
在这里有好多的xml的文件,其中我们这些android.hardware相关的就是我们的硬件属性,其他的就是我们软件的一些权限的定义。我们来看一下我们的platform.xml
如果说我想拿到net,那么必须要在这个用户组inet中。如果想要获取BLUETOOTH的协议栈,那么必须要在我们的net_bt_stack中,这样的话就能获取一些权限。
我们再来看一下android.hardware.camera.autofocus.xml,这里定义的就是一些feature,也就是硬件支持哪些东西,比如说支持camera.autofocus,这个就能获取我们硬件支持的一些属性,当我们把这个解析完成之后,我们就能拿到整个系统对应的一些权限关系,比如我们启动一个应用,这个activity启动的时候,他会设置我们的用户组,这样的话我们就能够有权限去访问我们的一些硬件设备。
然后再回到我们的packageMangerService的代码中
在我们读取权限之前,我们首先启动了一个线程,就是PackageHandler这个线程,他就是用来处理和其他应用程序做交互,安装或卸载应用程序的线程。这个线程就是继承了我们Handler这个类,他的具体实现就是在loop中不断地接收消息,然后处理消息,然后doHandleMessage这个函数就会处理其他进程发过来的消息,来做一些安装和remove的操作。当我们把线程启动,权限读取完成之后,后边就是来分析我们的jar包和应用。
下面就来学习一下packageMangerService是如何来安装jar包和应用程序的
首先我们在启动的时候会检查我们system/framework下的jar包,如果我们是第一次启动,或者系统有升级,那么首先会安装这些更新的jar包,更新完成之后,就会扫描我们系统的应用,这些系统应用包括我们system/appwendor/appsystem/private-app,并且他会监听监控我们这些相关目录,比如我们system/app下新放了一个apk,那么packageMangerService就会自动把这个应用安装上,如果说我们的system是可读写的,我们在下面删除一个apk,那么packageMangerService就会把这个应用相关的资源文件全部删除掉,当我们再次调用这个应用程序的时候,我们会发现他已经在我们系统中消失了。这就是我们packageMangerService监控我们主要应用的一个过程。然后会调用我们的scanDirLI来扫描我们系统中所有的apk,扫描的过程首先要检查这些应用有没有更新,然后去解析他们的androidmanifaest.xml,这里会有他的一些activity的一些名字,包括一些服务的名字,还有一些权限的问题,包括签名都会解析出来,解析完成之后他会保存到我们的packageMangerService的一个全局变量中,这样我们系统通过其他的调用就可以访问到我们系统中所有的应用程序。如果这个安装包在我们系统中还没有安装的话,那么会对他进行安装,并且将安装包的信息添加到我们本地的一个配置,这样当我们系统再次启动的时候就不会再次安装了,除非apk有更新。这样就可以加快我们系统的一个启动速度。

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

102

主题

315

帖子

16

粉丝