Android深入理解权限管理系统---权限管理系统全貌

戳蓝字"牛晓伟"关注我哦!

用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章,技术文章也可以有温度。

本文摘要

从本文开始将介绍权限管理系统,权限管理系统同样也是一个系列文章,本文是权限管理系统的第一篇文章。通过本文您将了解到权限管理系统都做了哪些事情权限管理系统分为哪些模块模块之间是如何协同合作的。(文中代码基于Android13)

本文大纲

1. 权限为何物

2. 权限管理系统

3. 权限的"归宿"

4. 权限的授予

5. 权限的鉴定

6. 权限的"消亡"

7. 总结

1.权限为何物

为了对权限管理系统 有一个深入的认识,我觉得非常有必要先把权限 介绍清楚,故第一小节的题目就是权限为何物 (如果您对权限了解,可以跳过此节)

在Android中权限主要指的是App对于别的App提供的私有数据或者系统的私有资源是否具有访问或使用的权利 ,那该如何理解呢,举个例子比如联系人App是拥有所有联系人数据的,而这些数据是非常重要的,别的App想要使用的话就需要用户授予相应的权限给使用者 ;再比如App想要使用录音功能,则也需要用户授予录音权限给该App

权限也有分类,比如可以分为静态权限、运行时权限 (runtime permission)、特权权限等,静态权限是指在Apk安装期间不需要经过用户同意就直接授予的权限,比如网络访问权限;运行时权限是指在App运行期间需要用户授权的权限,比如录音、地理位置权限等;特权权限是指只有特权App可以使用的权限。后面会有章节对权限进行详细的介绍。

1.1 权限的使用

在Android中App使用某个权限,就是在AndroidManifest中通过uses-permission标签来使用权限,如下代码:(使用了录音权限)

ini 复制代码
<uses-permission android:name="android.permission.RECORD_AUDIO" />

1.2 声明权限

声明权限就是指App私有数据或者系统资源提供者会定义一些权限,使用者只有用户授予了这些权限才可以访问或使用这些资源。权限管理系统都已经定义了一套框架,权限声明者只需要声明相应的运行时权限 (当然可以声明别的权限),在资源使用者使用资源之前,对该资源使用者进行授权鉴定,如果授予了相应权限,则可以使用资源;否则禁止使用资源。

声明权限需要在AndroidManifest.xml文件中使用permission标签,如下例子:

ini 复制代码
<permission android:description="string resource"
            android:icon="drawable resource"
            android:label="string resource"
            android:name="string"
            android:permissionGroup="string"
            android:protectionLevel=["normal" | "dangerous" |
                                     "signature" | ...] />

关于权限就介绍到此,那我们还是回归到我们的主题权限管理系统

2. 权限管理系统

权限管理系统所做的事情大体可以分为管理声明的权限管理App使用的权限权限的授予/撤销资源使用记录这四类。

管理声明的权限 就是会对Android设备上所有声明的权限进行管理,其中所有声明的权限包括系统声明的权限App声明的权限 。管理工作包括权限的存储、删除、查询等,其中的存储指的是存储到内存和文件中 。比如某新安装Apk声明了权限,则会把声明的权限保存;比如某Apk被卸载了,则会把声明的权限删除。而查询服务是使用最多的,凡是App使用到的权限都需要为它们提供查询服务,比如某App使用了某个权限,是需要经过权限管理系统确认该权限是否是存在的,要确定是否存在,就需要从所有声明的权限中来进行查询。

管理App使用的权限就是会对Android设备上所有App使用的权限及权限状态进行管理,比如某App使用了哪些权限,这些权限哪些是被用户授予了、哪些是被用户拒绝了等都会进行存储、删除、更新、查询等操作。每个App使用的权限和权限状态都会被保存到文件中,下次Android设备重新启动的时候会从保存的文件中把这些信息读取出来。App使用某个权限时,是需要确认该权限是否被授予,而这个确认过程是需要从权限管理系统来查询的。同样App权限的声明者也需要知道某个App使用的权限是否被用户授予了,同样也需要从权限管理系统来查询。

权限的授予/撤销是指App使用的权限是需要用户授予该权限或者撤销该权限的。

资源使用记录指的是记录下资源使用的时间点以及时长 (如果有时长的话),比如录音操作,权限管理系统会记录下该App在哪个时刻使用了录音功能,以及录音功能使用了多久。

权限管理系统为了能把它所做的事情做得井井有条,全靠它的模块 之间完美的协同合作,那就允许我把它的各个模块介绍给大家,老规矩为了大家有一个直观的感受,先来看如下的图:

如上图,权限管理系统大体分为权限控制器App管理类服务类三大模块,而有的模块中又会被进一步的划分,那我就从下往上的顺序来介绍。

2.1 服务类

权限管理系统中的服务类都是位于systemserver进程,那我们就来介绍下它们。

2.1.1 权限管理服务 (PermissionManagerService)

PermissionManagerService 它负责了权限管理系统中大部分的功能,凡是声明权限的管理App使用权限的管理权限的授予/撤销 都归该服务负责,当然这里面要排除一点就是不管是App声明权限还是App使用的权限的存储可是不归它负责,而是归PackageManagerService负责。当然在后面章节会再次详细的介绍它。

2.1.2 App操作服务 (AppOpsService)

AppOpsService 负责App操作方面的事情,我第一次接触这个类的时候,对它的存在充满了疑惑,PermissionManagerService 服务已经把权限大部分的功能都负责了,那该类存在的作用是啥呢,当我看到对该类的功能描述是权限控制和跟踪 ,我更是满脑子的疑惑,PermissionManagerService 不是也有权限控制的功能吗,为啥AppOpsService也有权限控制的功能,这不重复了吗?

我持着要解开该类谜团的目的对该类进行分析,最终得出的结论是这个类负责的权限控制主要是对运行时权限的补充 ,那我就来解释下:PermissionManagerService 管理的App使用的权限状态,它其实是一个静态值 (被授予或者被拒绝),该权限状态并没有结合App的状态来做出相应的调整

为啥需要结合App状态进行调整呢,运行时权限的状态分为授予拒绝 两种,其中授予还可以分为前台授予授予 两种,前台授予指该权限被授予后,该权限保护的资源在开始被使用的时机只能是App处于前台的时候 。这句话是不是很绕,那我就举个例子:比如某App的录音权限已经被授予了,如果App这时候在后台,这时候App想要开启录音功能的话,肯定是禁止的,你想啊一个App悄悄的在后台录取你的谈话内容是多么恐怖的一件事情啊,因此对于已经授予录音权限的App想要开启录音功能只能是App处于前台。也就是针对录音、拍照、定位等这类长时使用资源的权限才具有 前台授予的权限状态

就是因为PermissionManagerService 是没有结合App的状态的原因,故AppOpsService 就诞生了,它的权限控制 是指它结合了App的状态 (如App前后台)来对已经授予的运行时权限再次重新计算,给出一个真正的权限状态 ,比如某App的录音权限已经授予了,AppOpsService会结合当前App的前后台状态,如果App位于前台则会告知App录音权限真正的被授予,可以开启录音功能;如果App位于后台,则会告知App录音权限被拒绝了,不能开启录音功能。

AppOpsService除了权限控制,还可以记录被权限包含的资源的使用情况,如何时使用的,使用时长是多久等。在后面的章节还会有详细的文章介绍到它。

2.1.3 包管理服务 (PackageManagerService)

PackageManagerService 它会为权限管理系统中的权限 (App声明的权限和使用的权限) 提供权限存储的功能。当Android设备重新启动的时候,会把存储的这些信息读取出来。

App使用的权限及权限状态存储,如下存储了某度App使用到的权限和权限状态:

ini 复制代码
  <package name="com.baidu.searchbox">
        # DOWNLOAD_WITHOUT_NOTIFICATION权限被允许
        <permission name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" granted="true" flags="0" />
        # 定位权限 被拒绝
        <permission name="android.permission.POST_NOTIFICATIONS" granted="false" flags="301" />
        <permission name="android.permission.ACCESS_FINE_LOCATION" granted="false" flags="10301" />
        <permission name="android.permission.RESTART_PACKAGES" granted="true" flags="0" />
  </package>

App声明的权限存储,Android设备所有App声明的权限都会被存储在 /data/system/package.xml 文件中,如下截取了部分信息:

ini 复制代码
  <permissions>
        # 以下权限是系统声明的权限 (也就是包名为android的Apk)
        <item name="android.permission.LAUNCH_DEVICE_MANAGER_SETUP" package="android" protection="67108866" />
        <item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
        <item name="android.permission.ACCESS_CACHE_FILESYSTEM" package="android" protection="18" />
        <item name="android.permission.REMOTE_AUDIO_PLAYBACK" package="android" protection="2" />
        <item name="android.permission.START_CROSS_PROFILE_ACTIVITIES" package="android" protection="67108866" />
        # 以下是包名为com.android.providers.downloads的Apk声明的权限
        <item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" package="com.android.providers.downloads" />
        <item name="android.permission.NFC_PREFERRED_PAYMENT_INFO" package="android" />
        <item name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" package="android" protection="67108866" />
        省略其他部分······
  </permissions>

更多信息请查看Android深入理解包管理--记录存储模块这篇文章。

2.2 管理类

管理类就非常容易理解了就是各种manager,管理类的作用就是为App提供访问各种服务的能力 ,访问各种服务是通过binder通信 访问的。管理类是属于framework.jar ,而framework.jarzygote进程 中就已经被预加载了,因此在App被zygote孵化成功后,就已经拥有了各种管理类了,因此每个App都是可以直接使用自己进程内的管理类的。

权限管理系统的管理类主要有PackageManagerPermissionManagerPermissionCheckerManagerAppOpsManager

PackageManager 是属于PackageManagerService服务 ,为啥出现在权限管理系统呢?其主要原因是PackageManagerService 与权限管理之间是没有明显的界限划分的,它们是"你中有我,我中有你的"一个互相服务的关系。权限管理系统会使用到PackageManagerService中的一小部分功能。权限控制器App会使用到该类。

PermissionManagerPermissionCheckerManager 主要与PermissionManagerService 进行交互,而AppOpsManagerAppOpsService进行交互。

管理类的作用就是把访问各种服务的能力封装了起来,这样App就可以直接使用了,比如App想要检查某个权限是否被授予了,就可以使用PermissionCheckerManager 进行检查,进而PermissionManagerService会把检查结果返回。

2.3 权限控制器App

权限控制器App它的"英文名"是PermissionController ,它是一个App是一个独立运行的进程,它的主要作用就是权限的授予/撤销。比如某App在运行过程中发现自己没有录音权限 ,则会弹出如下界面:

上面的界面就是由该App弹出来的。再比如在某App的应用详情--权限列表界面,也是又该App提供的,如下图:

用户在此界面是可以撤销/授权某些权限的。

2.4 小结

以上就是权限管理系统的模块划分,但是上面只是对模块做了一个相关介绍,但是模块之间是如何协同合作来保证权限管理系统的正常运作是没有一个完整体现的 ,因此我从权限的"归宿"权限的授予权限的鉴定 、*权限的"消亡"*这四个方面来展示权限管理系统 的模块之间是如何协同合作的,当然这四个方面也基本就是权限管理系统的"日常所有工作内容"了。

3. 权限的"归宿"

权限的"归宿"指的是当Apk被安装成功后,Apk使用的权限 (若存在) 和 Apk声明的权限 (若存在)将被存放于何处?答案显而易见,那就是PermissionManagerService服务会把Apk的权限信息保存起来。但是这里的保存只是保存在内存中,当Android设备重新启动的时候,内存中保存的各种Apk的权限信息就会丢掉,那该如何是好呢?

为了解决以上问题那就需要PackageManagerService记录存储模块 (Settings)来帮忙 (关于记录存储模块可以看这篇文章),它会把安装的Apk的包名版本号Apk文件路径 等信息,当然还有最重要的权限信息 (声明的权限和使用的权限)存储到文件中,这样当Android设备重新启动的时候,就可以把已安装的Apk信息及它的权限都读取出来。(关于如何存储权限信息可以看这篇文章)

还有一个非常重要的点AppOpsService 也需要知道Apk使用的权限及权限状态 ,为啥AppOpsService 需要知道呢?还记得上面提到过AppOpsService 其中的一个作用是权限控制 ,也就是使用者是可以从它这了解到某个App使用的某个权限是否真正的授予 ,而计算权限真正授予 是需要结合权限原先的状态和App的前后台状态计算得出的,因此AppOpsService 是需要知道的。并且AppOpsService 会把权限及权限状态信息也保存到/data/system/appops.xml 文件中,当设备重新启动的时候,AppOpsService也会从文件中把保存的信息读取出来。

实际例子

为了加深对权限"归宿"的理解,现安装一个Apk,该Apk的AndroidManifest.xml文件中声明和使用的权限如下:

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    
    <!--使用录音权限-->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
    <!--读取图片、录音、视频的权限-->
    <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
    <uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>

    <!-- 声明权限-->
    <permission android:name="com.niu" android:protectionLevel="dangerous"/>
</manifest>

当该Apk被安装后,声明的权限com.baidu.niu 放入/data/system/packages.xml文件中,如下

ini 复制代码
<item name="com.baidu.niu" package="com.example.myapplication2" protection="1" />

该Apk使用的权限及状态放入/data/misc_de/0/apexdata/com.android.permission/runtime-permissions.xml文件中,如下

xml 复制代码
<package name="com.example.myapplication2">
  <!--granted为false代表没有被授权-->
		<permission name="android.permission.READ_MEDIA_IMAGES" granted="false" flags="300" />
		<permission name="android.permission.READ_MEDIA_AUDIO" granted="false" flags="300" />
		<permission name="android.permission.READ_MEDIA_VIDEO" granted="false" flags="300" />
		<permission name="com.example.myapplication2.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" granted="true" flags="0" />
		<permission name="android.permission.RECORD_AUDIO" granted="false" flags="300" />
</package>

AppOpsService 会把使用的权限及状态放入/data/system/appops.xml文件,如下

xml 复制代码
<!--10115是该app的uid-->
<uid n="10115">
  <!--下面的n代表的是使用的权限对应的code值,m为1代表该权限被拒绝-->
		<op n="27" m="1" />
		<op n="81" m="1" />
		<op n="83" m="1" />
		<op n="85" m="1" />
	</uid>

3.1 小结

Apk安装成功后,Apk使用的权限 (若存在) 和 Apk声明的权限 (若存在)会被放入PermissionManagerService 中;同时PackageManagerServiceSettings 会把Apk声明的权限 (若存在)存储在/data/system/packages.xml 文件中,会把Apk使用的权限 (若存在) 存储在/data/misc_de/0/apexdata/com.android.permission/runtime-permissions.xml (0代表userid为0的用户)文件中;AppOpsService 也会保存Apk使用的权限及状态,并且存放在/data/system/appops.xml文件。

4. 权限的授予

Apk已经安装上来,是不是该打开App使用了,当第一次使用时候是不是会弹出一些权限请求的界面,那咱们就来聊聊权限的授予

权限的授予指的是打开App后,App会检查某个权限是否被授予,若没有被授予就会弹出请求权限的页面,用户点击允许则代表该权限被授予了。大家在进行权限授予的时候代码模板是不是下面这样的:(下面是伪代码)

kotlin 复制代码
//先检查某个权限是否授予
if (ContextCompat.checkSelfPermission(this, 权限) != PackageManager.PERMISSION_GRANTED) {
    //没有授予则调用requestPermissions方法
    ActivityCompat.requestPermissions(this, 请求权限, REQUEST_PERMISSION_CODE);
}

那就从检查权限请求授予权限 两步来介绍权限的授予过程,并且在这个过程中看下模块之间是如何配合的。

4.1 检查权限

如上图,检查权限是否被授予的过程:在App进程中调用PermissionManager 的相关检查方法,该方法调用是一个binder 通信过程,最终请求到达PermissionManagerService服务 ,而PermissionManagerService服务 在内存中存储了Apk使用权限及权限的状态的,PermissionManagerService服务 根据Apk包名权限把最终的结果返回给使用者。

4.2 请求授予权限

同样也是先来看下面的图:

结合上图,请求授予权限过程如下:

4.2.1 通过Intent启动一个Activity

在App进程的某个Activity 界面,是需要调用ActivityCompat.requestPermissions 方法来请求权限的,而该方法最终会把请求的权限包名 等关键信息放入Intent中,在通过该Intent启动PermissionController App中的相应Activity

4.2.2 启动Activity

通过ActivityTaskManagerService 处理后,PermissionController 中的授权Activity被启动。

4.2.3 通知PermissionManagerService服务

授权Activity的界面大致如下 (每个厂家都有自己的页面样式)

当用户选择了仅在使用该应用时允许 ,会通知PermissionManagerService服务 修改相应权限的状态,PermissionManagerService服务 根据包名uid请求的权限权限状态 ,找到对应的权限信息并修改它的权限状态,并且把状态值更新到对应文件中 (上面提到过更新哪个文件),修改成功后把结果返回给PermissionController 中的授权Activity

4.2.4 通知AppOpsService服务

为啥要通知AppOpsService服务 呢?上面已经交代过AppOpsService服务 也起到权限访问控制 的功能,因此它有必要知道App使用的权限的状态,AppOpsService服务 根据包名uid请求的权限权限状态 ,做一些检查操作,修改相应状态值。并且把修改的值更新到/data/system/appops.xml文件中。

4.2.5 返回授权结果

返回授权结果画为虚线的原因:是因为返回过程要经过ActivityTaskManagerService服务来处理,为了清晰故把这个过程省略掉了。

返回授权结果,在App进程的ActivityonRequestPermissionsResult方法中就可以拿到。

实际例子

同样还拿【权限"归宿"】中的例子,那个Apk中使用了录音权限,那就以请求录音权限来举例子,看下相应模块的数据都发生了哪些变化。

因为该Apk的录音权限已经被授予,因此PermissionManagerService服务 会把新的权限状态保存到/data/misc_de/0/apexdata/com.android.permission/runtime-permissions.xml文件中,如下

xml 复制代码
<package name="com.example.myapplication2">
  <!--granted为false代表没有被授权-->
		<permission name="android.permission.READ_MEDIA_IMAGES" granted="false" flags="300" />
		<permission name="android.permission.READ_MEDIA_AUDIO" granted="false" flags="300" />
		<permission name="android.permission.READ_MEDIA_VIDEO" granted="false" flags="300" />
		<permission name="com.example.myapplication2.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" granted="true" flags="0" />
  <!--RECORD_AUDIO权限的granted变为true,代表已经被授予了-->
		<permission name="android.permission.RECORD_AUDIO" granted="true" flags="300" />
</package>

AppOpsService服务 会把权限状态放入/data/system/appops.xml文件,如下

xml 复制代码
<!--10115是该app的uid-->
<uid n="10115">
  <!--下面的n代表的是使用的权限对应的code值,m为1代表该权限被拒绝-->
  
  <!--27就是录音权限,m为4代表该权限是前台权限-->
		<op n="27" m="4" />
		<op n="81" m="1" />
		<op n="83" m="1" />
		<op n="85" m="1" />
	</uid>

AppOpsService服务 对权限状态做了更进一步的细分,因为录音只能在App处于前台的情况下开启,因此录音权限会对应一个前台状态值。

4.2 小结

权限的授予,涉及到了PermissionControllerPermissionManagerService服务AppOpsService服务 ,其中PermissionController 会负责展示一个权限授予的Activity ,当用户选择了允许 后,就会通知PermissionManagerService服务AppOpsService服务更新相应权限的状态。权限的拒绝流程和授予也是一样的。

5. 权限的鉴定

既然【权限授予】例子中的Apk已经被授予了录音 权限,那就来使用它来开启录音吧,在App层是看不到开启录音做了哪些工作的,开启录音之前是需要对该Apk做权限鉴定的,需要坚定该Apk是不是真正的获取了录音 权限的,那我们就来介绍权限的鉴定吧。

权限的鉴定 是指受权限保护的资源需要对使用者进行权限鉴定,确定它是否真正的拥有权限。不能完全凭使用者的"一面之词"说自己已经授权了,就相信它,因此必须得进行鉴定。就拿开启录音来说吧,mediaserver进程是需要对使用者进行权限鉴定的。如下图:

那就结合上图来分析下开启录音权限鉴定的过程吧。

5.1 App进程请求开启录音

App请求开启录音,这个请求会通过binder通信 进入mediaserver 进程,mediaserver 进程是可以拿到开启者的包名uid (App的唯一id)等信息的。

5.2 鉴定权限

mediaserver 进程会通过binder通信PermissionManagerService服务开启录音的使用者 进行权限鉴定,这个鉴定过程是非常简单的,PermissionManagerService服务 根据包名uid权限 去查询下该权限是否被授予 ,如果授予 了该权限,则会进入下一步;否则终止后面流程,直接告诉mediaserver 进程对应使用者是没有获取录音权限的。

5.3 再次鉴定权限

PermissionManagerService服务 会到AppOpsService服务 再次进程权限鉴定,而此次鉴定会结合开启录音的使用者的前后台状态等信息,重新计算一个新的权限状态值。

如果开启录音的使用者 位于前台,并且顺利经过其他检查,则会做一件很重要的事情开始把使用者使用录音的开始时间点、包名等信息记录并且存储到文件中 ,并且会把结果返回给mediaserver 进程,告诉它授予 了该权限;否则告诉mediaserver 进程对应使用者是没有获取录音权限。

5.4 收到鉴定结果

mediaserver进程收到鉴定结果后,如果鉴定结果是成功的,则为使用者开启录音;否则不开启录音。

当App结束录音的时候,App会把结束录音的事件通知给mediaserver进程,并且会执行如下操作,如下图:

同样结合上图来分析下结束录音过程,权限管理都做了哪些事情。

5.5 结束录音

App进程会通过binder 通信把结束录音的信息发送给mediaserver进程。

5.6 发送finishDataDelivery事件

mediaserver 进程会调用PermissionmanagerfinishDataDelivery 方法,通知PermissionManagerService服务 结束某个数据传递过程,PermissionManagerService服务 处理了对应事情后,会调用AppOpsService服务finishOperation

5.7 发送finishOperation

AppOpsService服务 收到该事件后,做的最重要的一件事情就是停止记录使用者使用录音的信息,也就是说该使用者使用录音的信息已经记录完毕,如下展示了都记录了哪些信息:

yaml 复制代码
Uid u0a115:
    state=top
    省略······
    Package com.example.myapplication2:
      //录音权限 allow代表对该app已经授予了录音权限
      RECORD_AUDIO (allow): 
        null=[
          //Access 代表该app被允许访问录音资源, 2024-10-18 14:45:05.191 代表访问的起始时间,duration代表使用录音的时长
          Access: [cch-s] 2024-10-18 14:45:05.191 (-1d6h19m47s305ms) duration=+717ms
          //Reject 代表该app被禁止访问录音资源
          Reject: [cch-s]2024-10-18 20:13:36.768 (-1d0h51m15s728ms)
        ]

5.8 小结

通过开启录音 的例子,展示了权限的鉴定 过程,录音权限 在进行权限鉴定的时候除了要经过PermissionManagerService服务 进行鉴定外,还需要经过AppOpsService服务 进行再次鉴定的,AppOpsService服务 会结合录音使用者 的前后台状态重新计算权限状态,只有使用者位于前台,才代表使用者被授予了录音权限,并且这时候会把使用者使用录音的开始时间等信息记录下来

当App使用完录音后,AppOpsService服务也需要知道该信息,进而停止记录使用者使用录音的时间。

系统声明大部分的权限 (如录音权限、定位权限、camera相关的权限,存储权限) 除了要经过PermissionManagerService服务进行鉴定外,还需要经过AppOpsService服务进行再次鉴定的AppOpsService服务 除了鉴定外,还会把使用者使用资源的时间等信息记录下来

6. 权限的"消亡"

权限的"消亡"指的是某Apk的所有权限从Android设备上被移除了 ,只有Apk被卸载了才会出现这种情况。当Apk被卸载时,PermissionManagerService服务AppOpsService服务 都会把保存在内存和文件中的该Apk的权限信息都删除掉,同时PackageManagerService服务Settings也会把该Apk使用到的保存在内存和文件中的所有权限信息都删除掉。这样一个Apk的所有权限也就从这台设备上"消亡"了。

7. 总结

本文主要介绍了权限管理系统 都做了哪些事情,以及相应的模块划分,同时从权限的"归宿"权限的授予权限的鉴定 、*权限的"消亡"*这四个方面来展示权限管理系统的模块之间是如何协同合作的。

本文主要带您先了解权限管理系统 的全貌,后面的章节会对权限管理系统的各个模块再次进行详细的介绍。

欢迎关注我的公众号 --牛晓伟(搜索或者点击牛晓伟链接)

相关推荐
小羊子说1 分钟前
智能座舱相关术语全解及多模态交互在智能座舱中的应用
android·车载系统·汽车·交互
wrx繁星点点1 小时前
桥接模式:解耦抽象与实现的利器
android·java·开发语言·jvm·spring cloud·intellij-idea·桥接模式
镰刀出海2 小时前
RN开发环境配置与Android版本app运行
android·react native
Python大数据分析3 小时前
JetPack Compose安卓开发之底部导航Tabbar
android·vue.js·elementui
前期后期3 小时前
Android 在github网站下载项目:各种很慢怎么办?比如gradle下载慢;访问github慢;依赖下载慢
android·github
如果'\'真能转义说3 小时前
从网络到缓存:在Android中高效管理图片加载
android·网络·缓存
无休居士4 小时前
Java8中CompletableFuture.allOf的使用
android·java·开发语言·future·completable·allof
Asin²+cos²=112 小时前
关于Android Studio Koala Feature Drop | 2024.1.2下载不了插件的解决办法
android·ide·android studio
大耳猫13 小时前
Android gradle和maven国内镜像地址
android·gradle·maven
-seventy-15 小时前
Android 玩机知识储备
android