android p 权限流程,Android native 权限控制流程
关联文章:
前言:
在 Android Runtime Permission 详解 中详细的说明了permission 在Android 6.0 前后的区别,对于M 以后应用可以通过checkPermission 、requestPermission 等一系列的接口控制,但是在M之前的应用是看不到这样的接口,功能的开启会直接调用接口,例如Camera,会直接调用open 的接口。
那我们如何来控制这些权限的呢?在M 之后的系统中,native 的接口里会通过checkPermission 的接口,来确认是否拥有改功能对应的权限,例如Camera,会check android.permission.CAMERA 这个权限。
这一篇博文就是分析M 之后系统对于权限native接口的控制流程。
源码分析:
首先来看IServiceManager.h:
namespace android {
// ----------------------------------------------------------------------
class IServiceManager : public IInterface
{
...
...
};
sp defaultServiceManager();
template
status_t getService(const String16& name, sp* outService)
{
const sp sm = defaultServiceManager();
if (sm != NULL) {
*outService = interface_cast(sm->getService(name));
if ((*outService) != NULL) return NO_ERROR;
}
return NAME_NOT_FOUND;
}
bool checkCallingPermission(const String16& permission);
bool checkCallingPermission(const String16& permission,
int32_t* outPid, int32_t* outUid);
bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
}; // namespace android
1、首先命名空间是android,所以有的地方通过接口android::checkPermission 来调用此处的接口
例如,PermissionCache.cpp 中:
bool PermissionCache::checkPermission(
const String16& permission, pid_t pid, uid_t uid) {
if ((uid == 0) || (pid == getpid())) {
// root and ourselves is always okay
return true;
}
PermissionCache& pc(PermissionCache::getInstance());
bool granted = false;
if (pc.check(&granted, permission, uid) != NO_ERROR) {
nsecs_t t = -systemTime();
granted = android::checkPermission(permission, pid, uid);
t += systemTime();
ALOGD("checking %s for uid=%d => %s (%d us)",
String8(permission).string(), uid,
granted?"granted":"denied", (int)ns2us(t));
pc.cache(permission, uid, granted);
}
return granted;
2、之所以首先来看IServiceManager.h,是因为其中提供了很多android 空间中的公共接口,例如defaultServiceManager()、getService()、checkPermission()
最终checkPermission() 实现的地方是在IServiceManger.cpp 中:
bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
{
sp pc;
gDefaultServiceManagerLock.lock();
pc = gPermissionController;
gDefaultServiceManagerLock.unlock();
int64_t startTime = 0;
while (true) {
if (pc != NULL) {
bool res = pc->checkPermission(permission, pid, uid);
...
}
...
}
...
}
通过IPermissionController 来调用checkPermission()
来看下IPermissionController.h:
class IPermissionController : public IInterface
{
public:
DECLARE_META_INTERFACE(PermissionController)
virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid) = 0;
virtual void getPackagesForUid(const uid_t uid, Vector &packages) = 0;
virtual bool isRuntimePermission(const String16& permission) = 0;
enum {
CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
GET_PACKAGES_FOR_UID_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1,
IS_RUNTIME_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 2
};
};
class BnPermissionController : public BnInterface
{
public:
virtual status_t onTransact( uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags = 0);
};
实现的地方就看BnPermissionController 的地方了,从整个项目来看,native 会启动一个permission 的native service,详细看framework/native/services/nativeperms/nativeperms.cpp:
class PermissionService : public android::os::BnPermissionController {
public:
::android::binder::Status checkPermission(
const ::android::String16& permission, int32_t pid, int32_t uid,
bool* _aidl_return) {
(void)permission;
(void)pid;
(void)uid;
*_aidl_return = true;
return binder::Status::ok();
}
再来看下Java 中android.os.IPermissionController,首先来看aidl,
package android.os;
/** @hide */
interface IPermissionController {
boolean checkPermission(String permission, int pid, int uid);
String[] getPackagesForUid(int uid);
boolean isRuntimePermission(String permission);
}
跟着这个aidl 来知道它的service 端,在ActivityManagerService.java中,
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));//这里添加permission 的service
ServiceManager.addService("processinfo", new ProcessInfoService(this));
接着就是service 端:
static class PermissionController extends IPermissionController.Stub {
ActivityManagerService mActivityManagerService;
PermissionController(ActivityManagerService activityManagerService) {
mActivityManagerService = activityManagerService;
}
@Override
public boolean checkPermission(String permission, int pid, int uid) {
return mActivityManagerService.checkPermission(permission, pid,
uid) == PackageManager.PERMISSION_GRANTED;
}
接着:
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
return checkComponentPermission(permission, pid, uid, -1, true);
}
接着:
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported);
}
接着:
public static int checkComponentPermission(String permission, int uid,
int owningUid, boolean exported) {
...
...
try {
return AppGlobals.getPackageManager()
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
最终会调到PMS 中的checkUidPermission,完成最后的确认工作。
这里source code 基本都是逻辑问题,不需要详细讲解,有什么问题可以随时交流。
checkUidPermission 的source code 这里暂不贴出来,详细可以看下 android grantRuntimePermission 详解
其实,最主要的是PermissionsState 中的mPermissions,如果grant 了,那么里面会有这样的permission,如果是revoke 的,那么就不会有这样的permission。当然,对于M 之前的app,这里默认肯定都是granted的。
这一篇博文主要是分析native 的check 流程,至于CTA 要求M 之前app 同样需要弹出对话框提示用户,看另一篇博文。
android p 权限流程,Android native 权限控制流程相关推荐
- Android稳定性系列8 Native crash处理流程
一 Native Crash 从系统全局来说,Crash分为Framework/App Crash, Native Crash,以及Kernel Crash. 对于framework层或者app层的C ...
- Android 音量控制流程分析
在Android平台上,音量键,主页键(home),都是全局按键,但是主页键是个例外不能被应用所捕获.下面分析一下音量按键的流程,主要从framework层处理开始,至于 EventHub 从驱动的/ ...
- JAVA学习脚印3: java语言控制流程
JAVA学习脚印3: java语言控制流程 本节首先介绍,java语言中的字符串处理以及输入输出控制,最后介绍控制流程. 在讲述控制流程之前,先介绍以下java中字符串和输入输出的内容,以便后续练习编 ...
- qt android 设备权限,QtScrcpy: Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限...
QtScrcpy QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和控制.不需要root权限. 单个应用程序最多支持16个安卓设备同时连接. 同时支持GNU/Li ...
- 蓝牙权限管理android,基于蓝牙与Android设备的控制系统设计
3 Android设备软件设计本文引用地址:http://www.eepw.com.cn/article/264461.htm Android2.2版本以上才能很好的支持蓝牙功能,Android上的应 ...
- android 录屏流程以及权限管理(底层权限修改及讲解)
android正常录屏流程需要申请权限,只需要调用正常的api,用户自己点击确定按钮,即可获取到录屏权限,上层app获取录屏权限的流程,废话不多说,下面看代码: public void takeScr ...
- Android pms权限管理,Android权限机制
为什么有权限机制 我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录.但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统 ...
- Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]
摘要:PackageManagerService在systemReady()后,进行了/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,供以后使用 阅读本文大约 ...
- 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )
文章目录 一. 图片质量压缩 二. 图片尺寸压缩 三. Android 10 文件访问 四. 完整源码示例 上一篇博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供 ...
最新文章
- STM32为何能在众多单片机中脱颖而出?
- 【Android Protobuf 序列化】Protobuf 服务器与客户端通信 ( TCP 通信中使用 Protobuf )
- Pet Shop4解密配置文件
- 从windows上传到linux服务器的php图片生成不了,windows10上用thinkphp5开发程序上传服务器后出现图片异常的问题...
- hana::detail::variadic::split_at用法的测试程序
- Codeforces Round #601 (Div. 2)
- 蓝桥杯 出现次数最多的整数
- JavaScript跨域脚本调用(iframe方式)
- python做excel表格代码_python读写Excel表格的实例代码(简单实用)
- Newtonsoft.Json序列化和反序列之javascriptConvert.SerializeObject,DeserializeObject,JsonWriter,JsonReader...
- 长春技师学院计算机专业,中专院校 / 中专技校 / 长春市技师学院
- mobi电子书如何用Windows电脑阅读?
- 查看CPU和其他硬件温度的软件
- win10 1903 专业版 CreateProcessAsUser
- python网课 知乎_如何看待风变编程的 Python 网课
- 大学计算机技术导论,北京邮电大学计算机学院网络技术导论第一章资料.ppt
- 数据仓库上云那些事儿
- “搜索大战”正式打响,微软发布ChatGPT版搜索引擎和浏览器
- 嵌入式Linux之我行——C+CGI+Ajax在S3C244
- Qt,多语言软件,开发流程,总结
热门文章
- 汇编语言程序如何转化成c语言,如何把汇编语言转换成C语言
- java的图形界面上传附件_Java图形界面(GUI) 动态获取上传或下载文件的路径问题...
- mysql cluster cge (commercial)_Mysql 产品分类和版本说明
- 移动app测试的多样性_app移动端接口性能测试
- 鱼骨图分析法实际案例_【管理工具详解】鱼骨图分析法
- 格式化json_在Spring Boot中格式化JSON日期
- python负数取余 整除运算
- Python中异常处理不要乱用哦
- 用python替换文件中内容的两种方法
- python基础教程:3种控制流语句(if,for,while)