Android检查权限
举个例子,来看下面段代码
1 if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
2 "updateOrientationFromAppTokens()")) {
3 throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
4 }
找到函数checkCallingPermission(),我们查看函数内容
1 boolean checkCallingPermission(String permission, String func) {
2 // Quick check: if the calling permission is me, it's all okay.
3 if (Binder.getCallingPid() == Process.myPid()) {
4 return true;
5 }
6
7 if (mContext.checkCallingPermission(permission)
8 == PackageManager.PERMISSION_GRANTED) {
9 return true;
10 }
11 String msg = "Permission Denial: " + func + " from pid="
12 + Binder.getCallingPid()
13 + ", uid=" + Binder.getCallingUid()
14 + " requires " + permission;
15 Slog.w(TAG, msg);
16 return false;
17 }
上面函数返回false的时候抛出异常,那么返回true的时候就是权限检查通过了,继续跟进Context.java
1 public abstract int checkCallingPermission(String permission);
原来是抽象的,继续查看继承它的类找到ContextImpl.java
1 @Override
2 public int checkPermission(String permission, int pid, int uid) {
3 if (permission == null) {
4 throw new IllegalArgumentException("permission is null");
5 }
6
7 if (!Process.supportsProcesses()) {
8 return PackageManager.PERMISSION_GRANTED;
9 }
10 try {
11 return ActivityManagerNative.getDefault().checkPermission(
12 permission, pid, uid);
13 } catch (RemoteException e) {
14 return PackageManager.PERMISSION_DENIED;
15 }
16 }
17
18 @Override
19 public int checkCallingPermission(String permission) {
20 if (permission == null) {
21 throw new IllegalArgumentException("permission is null");
22 }
23
24 if (!Process.supportsProcesses()) {
25 return PackageManager.PERMISSION_GRANTED;
26 }
27 int pid = Binder.getCallingPid();
28 if (pid != Process.myPid()) {
29 return checkPermission(permission, pid,
30 Binder.getCallingUid());
31 }
32 return PackageManager.PERMISSION_DENIED;
33 }
ActivityManagerNative.getDefault() 返回 IActivityManager,拿到ActivityManagerProxy对象的引用
static public IActivityManager getDefault() { if (gDefault != null) { return gDefault; } IBinder b = ServiceManager.getService("activity"); gDefault = asInterface(b);
return gDefault; }
找到ActivityManagerNative.java
public int checkPermission(String permission, int pid, int uid) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeString(permission); data.writeInt(pid); data.writeInt(uid); mRemote.transact(CHECK_PERMISSION_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); data.recycle(); reply.recycle(); return res; }
通过Binder机制调用到onTransact
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { case CHECK_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String perm = data.readString(); int pid = data.readInt(); int uid = data.readInt(); int res = checkPermission(perm, pid, uid); reply.writeNoException(); reply.writeInt(res); return true; } ................. }
找到ActivityManagerService.java
public int checkPermission(String permission, int pid, int uid) { if (permission == null) { return PackageManager.PERMISSION_DENIED; } return checkComponentPermission(permission, pid, uid, -1); }
int checkComponentPermission(String permission, int pid, int uid, int reqUid) { try { return AppGlobals.getPackageManager().checkUidPermission(permission, uid); } catch (RemoteException e) { } }
转到 AppGlobals.java
public static IPackageManager getPackageManager() { return ActivityThread.getPackageManager(); }
转到 ActivityThread.java
public static IPackageManager getPackageManager() { if (sPackageManager != null) { return sPackageManager; } IBinder b = ServiceManager.getService("package"); sPackageManager = IPackageManager.Stub.asInterface(b); return sPackageManager; }
转到PackageManagerService.java
public int checkUidPermission(String permName, int uid) { synchronized (mPackages) { Object obj = mSettings.getUserIdLP(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; }