Android 14.0 首次开机默认授予app运行时权限(去掉运行时授权弹窗)

1.概述

  在14.0的系统rom产品定制化开发中,在6.0以后对于权限的申请,都需要动态申请,所以会在系统首次启动后,在app的首次运行时,
会弹出授权窗口,会让用户手动授予app运行时权限,在由于系统产品开发需要要求默认授予app运行时权限,不需要用户默认授予运行时弹窗,所以需要在首次开机默认授予所有app运行时权限
如图所示:

2.首次开机默认授予app运行时权限(去掉运行时授权弹窗)的解决方案的核心类

frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
frameworks/base/services/core/java/com/android/server/pm/permission/Permission.java

3.首次开机默认授予app运行时权限(去掉运行时授权弹窗)的核心功能分析和实现

首次开机默认授予app运行时权限(去掉运行时授权弹窗)的功能实现中,
在Android 6.0以后由于系统出于对运行安全性的考虑,在app运行中需要申请一些权限的时候,
不会像之前那样什么权限都默认授权,既需要在AndroidManifest.xml需要申请权限,同时对于一些特殊权限需要
在app运行时申请权限,并且会在app每次运行的时候弹出没有授权的授权框来然用户授权,
而在系统中关于权限的管理,就是在PermissionManagerService.java中,它就是负责对系统权限管理的服务
下面对PermissionManagerService.java源码进行分析,看系统具体的怎么授权的,然后
在对app安装的时候进行默认授权来实现功能的要求,接下来分析下PermissionManagerService.java
的相关授权流程来实现功能

3.1 PermissionManagerService.java源码关于权限授权的相关源码分析

在系统中关于app权限的管理,可以看到,PMS只是过渡一下,将uid转化成对应的包信息PackageParser.Package,再转交给PermissionManagerService进行相关权限的管理
所以说,对于系统权限的管理核心处理部分就是在当下类,接下来分析下相关功能

            private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {// If the package is being deleted, update the permissions of all the appsfinal int flags =(pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG: UPDATE_PERMISSIONS_REPLACE_PKG);updatePermissions(packageName, pkg, getVolumeUuidForPackage(pkg), flags, mDefaultPermissionCallback);}private void updatePermissions(final @Nullable String changingPkgName,final @Nullable AndroidPackage changingPkg,final @Nullable String replaceVolumeUuid,@UpdatePermissionFlags int flags,final @Nullable PermissionCallback callback) {boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(changingPkgName, changingPkg);boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,changingPkg, callback);if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {Slog.i(TAG, "Permission ownership changed. Updating all permissions.");flags |= UPDATE_PERMISSIONS_ALL;}Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");// Now update the permissions for all packages.if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {if (pkg == changingPkg) {return;}// Only replace for packages on requested volumefinal String volumeUuid = getVolumeUuidForPackage(pkg);final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);restorePermissionState(pkg, replace, changingPkgName, callback,UserHandle.USER_ALL);});}....}

在首次开机默认授予app运行时权限(去掉运行时授权弹窗)的功能实现中,
在上述的PermissionManagerService.java中的相关源码中分析得知,在上述的方法中,在
updatePermissions()方法中,系统开机起来后就会会更新应用的权限,就会调用该方法updatePermissions()
接下来又继续调用updatePermissions(final @Nullable String changingPkgName,
              final @Nullable AndroidPackage changingPkg,
              final @Nullable String replaceVolumeUuid,
              @UpdatePermissionFlags int flags,
              final @Nullable PermissionCallback callback) 来负责申请权限,接下来就在这个方法中
继续调用restorePermissionState(pkg, replace, changingPkgName, callback, UserHandle.USER_ALL);
来负责申请权限的相关方法来开机默认给应用授权,接下来分析下相关的restorePermissionState方法

          private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,@Nullable String packageOfInterest, @Nullable PermissionCallback callback,@UserIdInt int filterUserId) {final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(pkg.getPackageName());if (ps == null) {return;} ....boolean shouldGrantNormalPermission = true;if (bp.isNormal() && !origState.isPermissionGranted(perm)) {if (!ps.isSystem() && userState.areInstallPermissionsFixed(ps.name)) {if (!isNewPlatformPermissionForPackage(perm, pkg)) {shouldGrantNormalPermission = false;}}}if (DEBUG_PERMISSIONS) {Slog.i(TAG, "Considering granting permission " + perm + " to package "+ pkg.getPackageName());}if ((bp.isNormal() && shouldGrantNormalPermission)|| (bp.isSignature()&& (!bp.isPrivileged() || CollectionUtils.contains(isPrivilegedPermissionAllowlisted, permName))&& (CollectionUtils.contains(shouldGrantSignaturePermission,permName)|| (((bp.isPrivileged() && CollectionUtils.contains(shouldGrantPrivilegedPermissionIfWasGranted,permName)) || bp.isDevelopment() || bp.isRole())&& origState.isPermissionGranted(permName))))|| (bp.isInternal()&& (!bp.isPrivileged() || CollectionUtils.contains(isPrivilegedPermissionAllowlisted, permName))&& (CollectionUtils.contains(shouldGrantInternalPermission,permName)|| (((bp.isPrivileged() && CollectionUtils.contains(shouldGrantPrivilegedPermissionIfWasGranted,permName)) || bp.isDevelopment() || bp.isRole())&& origState.isPermissionGranted(permName))))) {// Grant an install permission.if (uidState.grantPermission(bp)) {changedInstallPermission = true;}} else if (bp.isRuntime()) {boolean hardRestricted = bp.isHardRestricted();boolean softRestricted = bp.isSoftRestricted();final boolean permissionPolicyInitialized =isPermissionPolicyInitialized.get(userId);PermissionState origPermState = origState.getPermissionState(perm);int flags = origPermState != null ? origPermState.getFlags() : 0;boolean wasChanged = false;boolean restrictionExempt =(origState.getPermissionFlags(bp.getName())& FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;boolean restrictionApplied = (origState.getPermissionFlags(bp.getName()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;if (appSupportsRuntimePermissions) {// If hard restricted we don't allow holding itif (permissionPolicyInitialized && hardRestricted) {if (!restrictionExempt) {if (origPermState != null && origPermState.isGranted()&& uidState.revokePermission(bp)) {wasChanged = true;}if (!restrictionApplied) {flags |= FLAG_PERMISSION_APPLY_RESTRICTION;wasChanged = true;}}// If soft restricted we allow holding in a restricted form} else if (permissionPolicyInitialized && softRestricted) {if (!restrictionExempt && !restrictionApplied) {flags |= FLAG_PERMISSION_APPLY_RESTRICTION;wasChanged = true;}}if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;wasChanged = true;}if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0&& !isPermissionSplitFromNonRuntime(permName,pkg.getTargetSdkVersion())) {flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;wasChanged = true;// Hard restricted permissions cannot be held.} else if (!permissionPolicyInitialized|| (!hardRestricted || restrictionExempt)) {if ((origPermState != null && origPermState.isGranted())|| legacyActivityRecognitionPermission != null) {if (!uidState.grantPermission(bp)) {wasChanged = true;}}}} else {if (origPermState == null) {// New permissionif (PLATFORM_PACKAGE_NAME.equals(bp.getPackageName())) {if (!bp.isRemoved()) {flags |= FLAG_PERMISSION_REVIEW_REQUIRED| FLAG_PERMISSION_REVOKED_COMPAT;wasChanged = true;}}}if (!uidState.isPermissionGranted(bp.getName())&& uidState.grantPermission(bp)) {wasChanged = true;}if (permissionPolicyInitialized&& (hardRestricted || softRestricted)&& !restrictionExempt && !restrictionApplied) {flags |= FLAG_PERMISSION_APPLY_RESTRICTION;wasChanged = true;}}....updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, pkg,userId, updatedUserIds);updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState,uidState, pkg, newImplicitPermissions, userId, updatedUserIds);}}...}

首次开机默认授予app运行时权限(去掉运行时授权弹窗)的功能实现中,
在上述的PermissionManagerServiceImpl.java文件中的相关源码分析得知,在restorePermissionState方法中会首先根据包名遍历每个需要
申请的权限,然后根据权限的类型判断是否是安装权限,还是运行时权限,在6.0以前都是安装权限,在app安装的过程中授予安全权限,
6.0以后就都变成运行时权限在首次运行的过程中弹窗让用户授权,所以如果授予运行时权限,就需要将应用权限设置为安装权限,就是上文中的bp.isNormal() 就代表是安装权限和bp.isRuntime()
就代表是运行时权限,而他们都是Permission.java中的方法,就需要在Permission.java中来实现功能

3.2 Permission.java中关于权限类型的分析和功能实现

首次开机默认授予app运行时权限(去掉运行时授权弹窗)的功能实现中,
Android系统中对于系统权限授权的一个很明显的分界线是Android 6.0(Api=23),在这之前,只需要在AndroidManifest.xml声明应用需要的权限
在对于运行时权限的属性的管理就是统一由Permission.java中来判断是否是运行时权限还是安装权限的,以及特殊权限等等
接下来具体分析下Permission.java中的相关源码

            public boolean isNormal() {-   return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)-           == PermissionInfo.PROTECTION_NORMAL;+ return true;}public boolean isRuntime() {-  return (mPermissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)-          == PermissionInfo.PROTECTION_DANGEROUS;+ return false;}

首次开机默认授予app运行时权限(去掉运行时授权弹窗)的功能实现中, 在上述Permission.java中的相关源码分析得知,在这里,Permission.java中在安装授予权限的
时候,会首先判断这个权限的属性是运行时权限还是安装权限等等,在上述的PermissionManagerService.java文件
中的restorePermissionState方法中也分析了相关的权限授权,所以在上述的isNormal()中
就默认返回true,代表是安装权限,在isRuntime()中返回false就是代表不是运行时权限来实现功能

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6、JavaWeb-Mybatis

P116 Mybatis-入门 Mybatis是一款优秀的持久层框架,用于简化JDBC的开发。 持久层就是三层控制中的Dao层,数据访问层/持久层, P117 Mybatis-入门-快速入门程序 步骤: 创建springboot工程,数据表和实体类 引入mybat…

【办公类-39-03】批量下载微信公众号图片(三)-微信公众号链接的爬虫下载

背景需求: 测试两种公众号图片下载, 1、UIBOT下载速度慢,也需要有UIBOT软件 【办公类-39-01】批量下载微信公众号图片(一)UIBOT图片下载-CSDN博客文章浏览阅读289次。【办公类-39-01】批量下载微信公众号图片&#…

Python笔记(三)—— Python循环语句

循环普遍存在于日常生活中,同样,在程序中,循环功能也是至关重要的基础功能。 循环在程序中同判断一样,也是广泛存在的,是非常多功能实现的基础: bilibili循环轮播图 循环和判断一样,同样是程序…

XXE-XML实体注入漏洞

目录 1.xml基础 1.1什么是xml 1.2xml文档结构 1.3 什么是DTD 1.4 什么是实体 1.5 什么是外部实体 2.xxe漏洞 2.1xxe漏洞基本介绍 2.2xxe漏洞的危害 经典漏洞案例分析 3.xxe漏洞挖掘和利用 3.1. 识别潜在的XML入口 3.2. 检查XML处理逻辑 3.3. 构造试探Payload 常…

Redis核心数据结构之字典(一)

字典 概述 字典又称为符号表(symbol table)、关联数组(associative array)或映射(map),是一种保存键值对(key-value pair)的抽象数据结构,在字典中,一个键(key)可以和一个值(value)进行关联(或者说将键映射为值),这些关联的键和…

OpenText Availability——适用于 Windows 和 Linux 服务器的高可用性和灾难恢复解决方案

OpenText Availability——适用于 Windows 和 Linux 服务器的高可用性和灾难恢复解决方案 连续复制,最大限度地减少数据丢失快速故障转移,最大限度地减少停机时间可忽略的性能影响支持物理、虚拟和基于云的系统平台 停机从多种途径侵扰 IT 企业。 从相…

最佳牛围栏(二分 + 前缀和)

最佳牛围栏 原题链接&#xff1a;https://www.acwing.com/problem/content/104/ 题目 思路 我们发现若是枚举答案的话&#xff0c;那么我们判断是否存在一个平均值大于等于mid&#xff0c;如果最优解是x&#xff0c;那么mid < x的时候&#xff0c;必然可以找到一段&#x…

算法---双指针练习-1(移动零)

移动零 1. 题目解析2. 讲解算法原理数组划分&#xff0c;数组分块&#xff08;核心思想&#xff09;如何做到 3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 数组划分&#xff0c;数组分块&#xff08;核心思想&#xff09; dest一般初始化为-1&#x…

计算机设计大赛 深度学习的视频多目标跟踪实现

文章目录 1 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的视频多目标跟踪实现 …

16、电源管理入门之驱动Runtime PM管理

目录 1. 框架介绍 1.1 为什么需要Runtime PM Framework? 1.2 系统框架图 2. Drivers 3. Runtime PM core 4. power domain framework 5. runtime pm的sysfs 6参考: Runtime PM管理也就是设备驱动里面的电源管理,即设备驱动结构体里面的struct dev_pm_ops,只控制设…

bun实现HTTP服务器

Bun 提供了原生 Bun.serve API。它实现了 fetch 以及Node.js的 http 和 https 模块。 这些模块已被重新实现&#xff0c;以使用 Bun 的快速内部 HTTP 基础设施。随意直接使用这些模块;像 Express 这样依赖于这些模块的框架应该开箱即用。有关详细的兼容性信息&#xff0c;请参阅…

【HarmonyOS】ArkTS-箭头函数

箭头函数 箭头函数是 比普通函数 更简洁 的一种函数写法 () > {}() > {// 函数体 }let 函数名 () > {// 函数体 }let 函数名 () > {// 函数体 } 函数名(实参1, 实参2)let 函数名 (形参1: 类型, 形参2: 类型) > {// 函数体 } 函数名(实参1, 实参2)let 函数名 …

变频器学习

西门子变频器 SINAMICS V20 入门级变频器 SINAMICS G120C

《Trustzone/TEE/安全-实践版》介绍

第一章&#xff1a;课程说明和准备 课程介绍和说明 资料准备 为什么使用qemu_v8环境&#xff1f; 为什么选择香橙派开发板&#xff1f; optee qemu_v8环境展示 香橙派optee环境展示 第二章&#xff1a;Qemu环境搭建 ubuntu20.04的安装(virtualboxubuntu20.04) 搭建optee qem…

利用“定时执行专家”循环执行BAT、VBS、Python脚本——含参数指定功能

目录 一、软件概述 二、VBS脚本执行设置 三、触发器设置 四、功能亮点 五、总结 在自动化办公和日常计算机任务管理中&#xff0c;定时执行脚本是一项非常重要的功能。今天&#xff0c;我将为大家带来一款名为“定时执行专家”的软件的评测&#xff0c;特别是其定时执行VB…

Unity3D学习之XLua实践——背包系统

文章目录 1 前言2 新建工程导入必要资源2.1 AB包设置2.2 C# 脚本2.3 VSCode 的环境搭建 3 面板拼凑3.1 主面板拼凑3.2 背包面板拼凑3.3 格子复合组件拼凑3.4 常用类别名准备3.5 数据准备3.5.1 图集准备3.5.2 json3.5.3 打AB包 4 Lua读取json表及准备玩家数据5 主面板逻辑6 背包…

寻找旋转排序数组中的最小值[中等]

优质博文IT-BLOG-CN 一、题目 已知一个长度为n的数组&#xff0c;预先按照升序排列&#xff0c;经由1到n次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组nums [0,1,2,4,5,6,7]在变化后可能得到&#xff1a; 【1】若旋转4次&#xff0c;则可以得到[4,5,6,7,0,1,2…

【自然语言处理六-最重要的模型-transformer-下】

自然语言处理六-最重要的模型-transformer-下 transformer decoderMasked multi-head attentionencoder和decoder的连接部分-cross attentiondecoder的输出AT(Autoregresssive)NAT transformer decoder 今天接上一篇文章讲的encoder 自然语言处理六-最重要的模型-transformer-…

吴恩达机器学习笔记十五 什么是导数 计算图 大型神经网络案例

假设函数 J(w)w^2&#xff0c;当 w3 时&#xff0c; J(w)3*39 当我们给w增加一个很小的量时&#xff0c;观察J(w)如何变化。 例如 w30.001&#xff0c; 则J&#xff08;w&#xff09;9.006001&#xff0c;因此当w3且增加一个变化量 ε 时&#xff0c;J(w)将会增加 6ε&#x…

Northwestern University-844计算机科学与技术/软件工程-机试指南【考研复习】

本文提到的西北大学是位于密歇根湖泊畔的西北大学。西北大学&#xff08;英语&#xff1a;Northwestern University&#xff0c;简称&#xff1a;NU&#xff09;是美国的一所著名私立研究型大学。它由九人于1851年创立&#xff0c;目标是建立一所为西北领地地区的人服务的大学。…