关联文章:

前言:

在 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 权限控制流程相关推荐

  1. Android稳定性系列8 Native crash处理流程

    一 Native Crash 从系统全局来说,Crash分为Framework/App Crash, Native Crash,以及Kernel Crash. 对于framework层或者app层的C ...

  2. Android 音量控制流程分析

    在Android平台上,音量键,主页键(home),都是全局按键,但是主页键是个例外不能被应用所捕获.下面分析一下音量按键的流程,主要从framework层处理开始,至于 EventHub 从驱动的/ ...

  3. JAVA学习脚印3: java语言控制流程

    JAVA学习脚印3: java语言控制流程 本节首先介绍,java语言中的字符串处理以及输入输出控制,最后介绍控制流程. 在讲述控制流程之前,先介绍以下java中字符串和输入输出的内容,以便后续练习编 ...

  4. qt android 设备权限,QtScrcpy: Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限...

    QtScrcpy QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备,并进行显示和控制.不需要root权限. 单个应用程序最多支持16个安卓设备同时连接. 同时支持GNU/Li ...

  5. 蓝牙权限管理android,基于蓝牙与Android设备的控制系统设计

    3 Android设备软件设计本文引用地址:http://www.eepw.com.cn/article/264461.htm Android2.2版本以上才能很好的支持蓝牙功能,Android上的应 ...

  6. android 录屏流程以及权限管理(底层权限修改及讲解)

    android正常录屏流程需要申请权限,只需要调用正常的api,用户自己点击确定按钮,即可获取到录屏权限,上层app获取录屏权限的流程,废话不多说,下面看代码: public void takeScr ...

  7. Android pms权限管理,Android权限机制

    为什么有权限机制 我们知道 Android 应用程序是沙箱隔离的,每个应用都有一个只有自己具有读写权限的专用数据目录.但是如果应用要访问别人的组件或者一些设备上全局可访问的资源,这时候权限机制就能系统 ...

  8. Android 10.0 PackageManagerService(二)权限扫描-[Android取经之路]

    摘要:PackageManagerService在systemReady()后,进行了/system/etc/permissions中的各种xml进行扫描,进行相应的权限存储,供以后使用 阅读本文大约 ...

  9. 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )

    文章目录 一. 图片质量压缩 二. 图片尺寸压缩 三. Android 10 文件访问 四. 完整源码示例 上一篇博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供 ...

最新文章

  1. STM32为何能在众多单片机中脱颖而出?
  2. 【Android Protobuf 序列化】Protobuf 服务器与客户端通信 ( TCP 通信中使用 Protobuf )
  3. Pet Shop4解密配置文件
  4. 从windows上传到linux服务器的php图片生成不了,windows10上用thinkphp5开发程序上传服务器后出现图片异常的问题...
  5. hana::detail::variadic::split_at用法的测试程序
  6. Codeforces Round #601 (Div. 2)
  7. 蓝桥杯 出现次数最多的整数
  8. JavaScript跨域脚本调用(iframe方式)
  9. python做excel表格代码_python读写Excel表格的实例代码(简单实用)
  10. Newtonsoft.Json序列化和反序列之javascriptConvert.SerializeObject,DeserializeObject,JsonWriter,JsonReader...
  11. 长春技师学院计算机专业,中专院校 / 中专技校 / 长春市技师学院
  12. mobi电子书如何用Windows电脑阅读?
  13. 查看CPU和其他硬件温度的软件
  14. win10 1903 专业版 CreateProcessAsUser
  15. python网课 知乎_如何看待风变编程的 Python 网课
  16. 大学计算机技术导论,北京邮电大学计算机学院网络技术导论第一章资料.ppt
  17. 数据仓库上云那些事儿
  18. “搜索大战”正式打响,微软发布ChatGPT版搜索引擎和浏览器
  19. 嵌入式Linux之我行——C+CGI+Ajax在S3C244
  20. Qt,多语言软件,开发流程,总结

热门文章

  1. 汇编语言程序如何转化成c语言,如何把汇编语言转换成C语言
  2. java的图形界面上传附件_Java图形界面(GUI) 动态获取上传或下载文件的路径问题...
  3. mysql cluster cge (commercial)_Mysql 产品分类和版本说明
  4. 移动app测试的多样性_app移动端接口性能测试
  5. 鱼骨图分析法实际案例_【管理工具详解】鱼骨图分析法
  6. 格式化json_在Spring Boot中格式化JSON日期
  7. python负数取余 整除运算
  8. Python中异常处理不要乱用哦
  9. 用python替换文件中内容的两种方法
  10. python基础教程:3种控制流语句(if,for,while)