mContext.enforceCallingOrSelfPermission

来源:互联网 发布:python 判断sys.argv 编辑:程序博客网 时间:2024/06/05 11:32
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET, null);
大家经常会看到上面这句话在runtime是check 权限,具体是怎么实现的呢?
xref: /frameworks/base/core/java/android/app/ContextImpl.java
1568    public void enforceCallingOrSelfPermission(
1569            String permission, String message) {
1570        enforce(permission,
1571                checkCallingOrSelfPermission(permission),
1572                true,
1573                Binder.getCallingUid(),
1574                message);
1575    }


1537    private void enforce(
1538            String permission, int resultOfCheck,
1539            boolean selfToo, int uid, String message) {
1540        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1541            throw new SecurityException(
1542                    (message != null ? (message + ": ") : "") +
1543                    (selfToo
1544                     ? "Neither user " + uid + " nor current process has "
1545                     : "uid " + uid + " does not have ") +
1546                    permission +
1547                    ".");
1548        }
1549    }
resultOfCheck=checkCallingOrSelfPermission(permission) 
只要resultOfCheck 等于PackageManager.PERMISSION_GRANTED 就表示有权限,我们在来看看checkCallingOrSelfPermission的实现。




1528    public int checkCallingOrSelfPermission(String permission) {
1529        if (permission == null) {
1530            throw new IllegalArgumentException("permission is null");
1531        }
1532
1533        return checkPermission(permission, Binder.getCallingPid(),
1534                Binder.getCallingUid());
1535    }
checkCallingOrSelfPermission 在判断permission 不能为空后,继续调用checkPermission


1501    public int checkPermission(String permission, int pid, int uid) {
1502        if (permission == null) {
1503            throw new IllegalArgumentException("permission is null");
1504        }
1505
1506        try {
1507            return ActivityManagerNative.getDefault().checkPermission(
1508                    permission, pid, uid);
1509        } catch (RemoteException e) {
1510            return PackageManager.PERMISSION_DENIED;
1511        }
1512    }

第1507行可知最后是调用到ActivityManagerService 那边

/server/am/ActivityManagerService.java
@Override
    public int checkPermission(String permission, int pid, int uid) {
        if (permission == null) {
            return PackageManager.PERMISSION_DENIED;
        }
        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
    }


继续调用checkComponentPermission
  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);
    }
android/app/ActivityManager.java
调用activitymanager 的checkComponentPermission
 public static int checkComponentPermission(String permission, int uid,
            int owningUid, boolean exported) {
        // Root, system server get to do everything.
        final int appId = UserHandle.getAppId(uid);
        if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // Isolated processes don't get any permissions.
        if (UserHandle.isIsolated(uid)) {
            return PackageManager.PERMISSION_DENIED;
        }
        // If there is a uid that owns whatever is being accessed, it has
        // blanket access to it regardless of the permissions it requires.
        if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) {
            return PackageManager.PERMISSION_GRANTED;
        }
        // If the target is not exported, then nobody else can get to it.
        if (!exported) {
            /*
            RuntimeException here = new RuntimeException("here");
            here.fillInStackTrace();
            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
                    here);
            */
            return PackageManager.PERMISSION_DENIED;
        }
        if (permission == null) {
            return PackageManager.PERMISSION_GRANTED;
        }
        try {
            return AppGlobals.getPackageManager()
                    .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().checkUidPermission(permission, uid);
最后还是调用packagemanagerservice的checkUiPermission函数。
 public int checkUidPermission(String permName, int uid) {
        final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
        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;
                }
            }
            if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
                return PackageManager.PERMISSION_GRANTED;
            }
        }
        return PackageManager.PERMISSION_DENIED;
    }
分两种情况,分别查mSettings 里面和 mSystemPermissions 这个hashset里面是否有权限.


0 0
原创粉丝点击