AndroidL的checkPermission方法详解
来源:互联网 发布:自适应网页源码 编辑:程序博客网 时间:2024/06/03 19:42
在Android源码的很多地方都会出现权限检查的方法checkPermission,此篇文字主要介绍Android5.1.1源码中的checkPermission方法是如何实现的,在此以WallpaperManagerService.java中的checkPermission方法为例来分析。
./base/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
........final Context mContext;
........
public WallpaperManagerService(Context context) {
mContext = context;
........
}
........
private void checkPermission(String permission) {
// 调用Context的checkCallingOrSelfPermission来检查权限
if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
throw new SecurityException("Access denied to process: " + Binder.getCallingPid()+ ", must have permission " + permission);
}
}
checkCallingOrSelfPermission中checkCallingOrSelfPermission的定义
./base/core/java/android/context/Context.java
public abstract int checkCallingOrSelfPermission(@NonNull String permission);
ContextImpl实现了Context接口,权限检查是在ContextImpl类的checkPermission方法来完成的
./base/core/java/android/app/ContextImpl.java
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
try {
return ActivityManagerNative.getDefault().checkPermission(
permission, pid, uid); // 调用ActivityManagerNative的getDefault()方法来获取ActivityManagerService的对象
} catch (RemoteException e) {
return PackageManager.PERMISSION_DENIED;
}
}
........
@Override
public int checkCallingOrSelfPermission(String permission) {
if (permission == null) {
throw new IllegalArgumentException("permission is null");
}
return checkPermission(permission, Binder.getCallingPid(),
Binder.getCallingUid()); // 调用checkPermission函数来检查权限
}
ActivityManagerNative中getDefault方法实现过程
./base/core/java/android/app/ActivityManagerNative.java
static public IActivityManager getDefault() {
return gDefault.get(); // 最终返回的是个ActivityManagerService的对象
}
ActivityManagerService中checkPermission的实现过程
./base/services/core/java/com/android/server/am/ActivityManagerService.java
int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
// We might be performing an operation on behalf of an indirect binder
// invocation, e.g. via {@link #openContentUri}. Check and adjust the
// client identity accordingly before proceeding.
Identity tlsIdentity = sCallerIdentity.get();
if (tlsIdentity != null) {
Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
+ tlsIdentity.pid + "," + tlsIdentity.uid + "}");
uid = tlsIdentity.uid;
pid = tlsIdentity.pid;
}
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
}
return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported); // 调用ActivityManager的checkComponentPermission来检查权限
}
........
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
return PackageManager.PERMISSION_DENIED;
}
// 调用checkComponentPermission函数来检查权限
}
ActivityManager中checkComponentPermission的实现过程
./base/core/java/android/app/ActivityManager.java
public static int checkComponentPermission(String permission, int uid,
int owningUid, boolean exported) {
........
try {
return AppGlobals.getPackageManager() // 调用AppGlobals的getPackageManager()函数返回IPackageManager对象
.checkUidPermission(permission, uid);
} catch (RemoteException e) {
// Should never happen, but if it does... deny!
Slog.e(TAG, "PackageManager is dead?!?", e);
}
return PackageManager.PERMISSION_DENIED;
}
AppGlobals的getPackageManager方法实现过程
./base/core/java/android/app/AppGlobals.java
public static IPackageManager getPackageManager() {
return ActivityThread.getPackageManager(); // 调用ActivityThread的getPackageManager()函数
}
ActivityThread的getPackageManager实现过程
./base/core/java/android/app/ActivityThread.java
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
//Slog.v("PackageManager", "returning cur default = " + sPackageManager);
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
//Slog.v("PackageManager", "default service binder = " + b);
sPackageManager = IPackageManager.Stub.asInterface(b); // 最终获取的是PackageManagerService的对象
//Slog.v("PackageManager", "default service = " + sPackageManager);
return sPackageManager;
}
PackageManagerService的checkUidPermission实现过程
./base/services/core/java/com/android/server/pm/PackageManagerService.java
@Override
public int checkUidPermission(String permName, int uid) {
synchronized (mPackages) {
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
if (obj != null) {
GrantedPermissions gp = (GrantedPermissions)obj;
if (gp.grantedPermissions.contains(permName)) { // 判断应用是否已声明了此权限
return PackageManager.PERMISSION_GRANTED;
}
} else {
HashSet<String> perms = mSystemPermissions.get(uid);
if (perms != null && perms.contains(permName)) {
return PackageManager.PERMISSION_GRANTED;
}
}
}
return PackageManager.PERMISSION_DENIED;
}
至此权限检查就已完成
原文地址:
0 0
- AndroidL的checkPermission方法详解
- AndroidL的checkPermission方法详解
- AndroidL 操作延时的方法
- AndroidL 系统属性的修改
- Android权限判断checkPermission
- checkPermission知识点小记
- 关于AndroidL到androidM的STLC++库的改变
- 共享动画的实现(AndroidL及以上)
- AndroidL之后ROOM的zip包中关于system.new.dat无法挂载
- AndroidL系列-CardView
- androidL,自定义状态栏
- AndroidL 音频文件编译过程
- AndroidL ANR分析整理
- AndroidL JNI技术
- AndroidL 传感器系统
- AndroidL 预置APK
- androidl开机动画流程
- AndroidL分析之Keyguard
- Leetcode140:Word Break II
- 小水怪微信爬虫(1):俄语;雅思;人工智能;旅游;搞笑
- 一个虐你千百遍的问题:“RPC好,还是RESTful好?”
- Error converting bytecode to dex
- Ajax 实例演示 涉及其它 jQuery php
- AndroidL的checkPermission方法详解
- 编程语言 - 标识符命名规范
- PackageManagerService启动过程
- 「译」JUnit 5 系列:扩展模型(Extension Model)
- 【每天进步一点点】 限定查询
- 第九章简化条件表达式
- 用C语言实现两变量内容交换的N种方法
- 配置 DHCP 服务 - 每天5分钟玩转 OpenStack(89)
- [LeetCode73]Set Matrix Zeroes