热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mContext.enforceCallingOrSelfPermission

mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BIND_APPWIDGET,null);大
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 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里面是否有权限.



推荐阅读
author-avatar
不乱于心丨不困于丶情
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有