Android权限数据结构

本文介绍了Android权限管理系统的基础组件,包括BasePermission、PackageParser.Permission、PermissionInfo、PermissionState和PermissionData。BasePermission作为权限的基本单元,由Settings的mPermissions映射表管理。PackageParser在解析apk的AndroidManifest.xml时,生成PackageParser.Permission对象。PermissionInfo包含了权限等级和序列化功能。PermissionState和PermissionData则分别用于表示单个权限的状态和管理应用的权限状态信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



BasePermission

系统权限的基本表示单元是BasePermission,Settings中维护了一个总的权限映射表mPermissions,所有权限都会添加到mPermissions列表中,其中key是权限的名字,value是具体的BasePermission实例。

[/frameworks/base/services/core/java/com/android/server/pm/Settings.java]

    // Mapping from permission names to info about them.  
    final ArrayMap<String, BasePermission> mPermissions =  new ArrayMap<String, BasePermission>();  

我们都知道绝大部分权限已经在系统中定义好,如READ_EXTERNAL_STORAGE读写外部存储权限、READ_PHONE_STATE读取手机状态信息权限等,这些权限的定义都在framework-res.apk中,在扫描framework-res.apk过程中解析并添加到mPermissions映射表中。系统权限的定义:

[/frameworks/base/core/res/AndroidManifest.xml]

    <!-- Allows an application to send SMS messages. -->  
     <permission android:name="android.permission.SEND_SMS"  
         android:permissionGroup="android.permission-group.MESSAGES"  
         android:protectionLevel="dangerous"  
         android:permissionFlags="costsMoney"  
         android:label="@string/permlab_sendSms"  
         android:description="@string/permdesc_sendSms" />  

绝大部分的权限定义都在上面的AndroidManifest.xml文件中,最终会打包进framework-res.apk中并经过解析保存到Settings的mPermissions映射表中。

final class BasePermission {
    final static int TYPE_NORMAL = 0;

    final static int TYPE_BUILTIN = 1;//构建类型

    final static int TYPE_DYNAMIC = 2;//动态类型

    final String name;

    String sourcePackage;

    PackageSettingBase packageSetting;

    final int type;

    int protectionLevel;

    PackageParser.Permission perm;

    PermissionInfo pendingInfo;

    /** UID that owns the definition of this permission */
    int uid;//拥有此权限定义的UID

    /** Additional GIDs given to apps granted this permission */
    private int[] gids;//授予应用程序这个权限的附加GIDs

    /**
     * Flag indicating that {@link #gids} should be adjusted based on the
     * {@link UserHandle} the granted app is running as.表示gids应该基于UserHandle授予的应用程序进行调整的标志
     */
    private boolean perUser;

    BasePermission(String _name, String _sourcePackage, int _type) {
        name = _name;
        sourcePackage = _sourcePackage;
        type = _type;
        // Default to most conservative protection level.默认为最保守的保护级别
        protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
    }

    @Override
    public String toString() {
        return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name
                + "}";//identityHashCode返回给定对象的哈希码
    }

    public void setGids(int[] gids, boolean perUser) {
        this.gids = gids;
        this.perUser = perUser;
    }

    public int[] computeGids(int userId) {
        if (perUser) {
            final int[] userGids = new int[gids.length];
            for (int i = 0; i < gids.length; i++) {
                userGids[i] = UserHandle.getUid(userId, gids[i]);
            }
            return userGids;
        } else {
            return gids;
        }
    }

    public boolean isRuntime() {
        return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)//保护级别的标志:基本的保护类型
                == PermissionInfo.PROTECTION_DANGEROUS;//危险级别
    }

    public boolean isDevelopment() {
        return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                == PermissionInfo.PROTECTION_SIGNATURE//对应于签名的保护级别,系统级的保护级别。
                && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;//对于development的附加标志
    }

    public boolean isInstant() {
        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0;
    }

    public boolean isRuntimeOnly() {
        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0;
    }
}
PackageParser.Permission

PackageParser.Permission使用PackageParser解析apkAndroidManifest.xml文件中的<permission>标签后得到的权限表示。PackageParser.Permission中包含一个对应的PermissionInfo

    public final static class Permission extends Component<IntentInfo> implements Parcelable {
        public final PermissionInfo info;
        public boolean tree;
        public PermissionGroup group;

        public Permission(Package _owner) {
            super(_owner);
            info = new PermissionInfo();
        }

        public Permission(Package _owner, PermissionInfo _info) {
            super(_owner);
            info = _info;
        }

        public void setPackageName(String packageName) {
            super.setPackageName(packageName);
            info.packageName = packageName;
        }

        public String toString() {
            return "Permission{"
                + Integer.toHexString(System.identityHashCode(this))
                + " " + info.name + "}";
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeParcelable(info, flags);
            dest.writeInt(tree ? 1 : 0);
            dest.writeParcelable(group, flags);
        }

        private Permission(Parcel in) {
            super(in);
            final ClassLoader boot = Object.class.getClassLoader();
            info = in.readParcelable(boot);
            if (info.group != null) {
                info.group = info.group.intern();
            }

            tree = (in.readInt() == 1);
            group = in.readParcelable(boot);
        }

        public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Permission>() {
            public Permission createFromParcel(Parcel in) {
                return new Permission(in);
            }

            public Permission[] newArray(int size) {
                return new Permission[size];
            }
        };
    }
PermissionInfo

权限信息的表示,其中包含权限等级的定义(NORMAL, DANGER, SIGNERATURE),另外实现了序列化,用户于进程间通信。每个BasePermission实例中包含一个PermissionInfo的实例。

/**
 * 你可以检索有关系统已知的特定安全权限的信息。对应于AndroidManifest中<permission>标签收集的信息。
 */
public class PermissionInfo extends PackageItemInfo implements Parcelable {
    
    public static final int PROTECTION_NORMAL = 0;//protectionLevel为normal

    public static final int PROTECTION_DANGEROUS = 1;//protectionLevel为normal

    public static final int PROTECTION_SIGNATURE = 2;//系统级别的protectionLevel,为signature

    @Deprecated
    public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;//已弃用,用PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED

    public static final int PROTECTION_FLAG_PRIVILEGED = 0x10;//privileged

    //PROTECTION_FLAG_PRIVILEGED的旧名称,只适用于特权应用程序,问不是系统映像上的所有应用程序。
    @Deprecated
    public static final int PROTECTION_FLAG_SYSTEM = 0x10;

    public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;//development

    public static final int PROTECTION_FLAG_APPOP = 0x40;//appop

    public static final int PROTECTION_FLAG_PRE23 = 0x80;

    public static final int PROTECTION_FLAG_INSTALLER = 0x100;

    public static final int PROTECTION_FLAG_VERIFIER = 0x200;

    public static final int PROTECTION_FLAG_PREINSTALLED = 0x400;

    public static final int PROTECTION_FLAG_SETUP = 0x800;

    public static final int PROTECTION_FLAG_INSTANT = 0x1000;

    public static final int PROTECTION_FLAG_RUNTIME_ONLY = 0x2000;

    public static final int PROTECTION_MASK_BASE = 0xf;//protectionLevel标志位,最基本的保护类型
    public static final int PROTECTION_MASK_FLAGS = 0xfff0;//protectionLevel标志位,额外的标志位

    public int protectionLevel;//正在保护的访问权限的级别

    public String group;//此权限是permissionGroup的一部分

    public static final int FLAG_COSTS_MONEY = 1<<0;

    @SystemApi
    public static final int FLAG_REMOVED = 1<<1;

    public static final int FLAG_INSTALLED = 1<<30;//表示这个权限已经安装到了系统的全局定义的permissions中

    public int flags;//由permissionFlags提供的有关此权限的其他标志。

    public int descriptionRes;//此权限描述的字符串资源标识符,从description属性中读取,如果没有设置就是0.

    public CharSequence nonLocalizedDescription;//AndroidManifest中提供的描述字符串,如果描述在资源中,它就为空;使用loadDescription代替

    /** @hide */
    public static int fixProtectionLevel(int level) {
        if (level == PROTECTION_SIGNATURE_OR_SYSTEM) {
            level = PROTECTION_SIGNATURE | PROTECTION_FLAG_PRIVILEGED;
        }
        return level;
    }

    /** @hide */
    public static String protectionToString(int level) {//将保护级别转化为字符串
        String protLevel = "????";
        switch (level&PROTECTION_MASK_BASE) {
            case PermissionInfo.PROTECTION_DANGEROUS:
                protLevel = "dangerous";
                break;
            case PermissionInfo.PROTECTION_NORMAL:
                protLevel = "normal";
                break;
            case PermissionInfo.PROTECTION_SIGNATURE:
                protLevel = "signature";
                break;
            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
                protLevel = "signatureOrSystem";
                break;
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
            protLevel += "|privileged";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
            protLevel += "|development";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
            protLevel += "|appop";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
            protLevel += "|pre23";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) {
            protLevel += "|installer";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) {
            protLevel += "|verifier";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) {
            protLevel += "|preinstalled";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_SETUP) != 0) {
            protLevel += "|setup";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_INSTANT) != 0) {
            protLevel += "|instant";
        }
        if ((level&PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0) {
            protLevel += "|runtime";
        }
        return protLevel;
    }

    public PermissionInfo() {
    }

    public PermissionInfo(PermissionInfo orig) {
        super(orig);
        protectionLevel = orig.protectionLevel;
        flags = orig.flags;
        group = orig.group;
        descriptionRes = orig.descriptionRes;
        nonLocalizedDescription = orig.nonLocalizedDescription;
    }

    /**
     * 检索此权限的文本说明。调用PackageManager从应用程序中加载description。
     */
    public CharSequence loadDescription(PackageManager pm) {
        if (nonLocalizedDescription != null) {
            return nonLocalizedDescription;
        }
        if (descriptionRes != 0) {
            CharSequence label = pm.getText(packageName, descriptionRes, null);
            if (label != null) {
                return label;
            }
        }
        return null;
    }

    public String toString() {
        return "PermissionInfo{"
            + Integer.toHexString(System.identityHashCode(this))
            + " " + name + "}";
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int parcelableFlags) {
        super.writeToParcel(dest, parcelableFlags);
        dest.writeInt(protectionLevel);
        dest.writeInt(flags);
        dest.writeString(group);
        dest.writeInt(descriptionRes);
        TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
    }

    public static final Creator<PermissionInfo> CREATOR =
        new Creator<PermissionInfo>() {
        public PermissionInfo createFromParcel(Parcel source) {
            return new PermissionInfo(source);
        }
        public PermissionInfo[] newArray(int size) {
            return new PermissionInfo[size];
        }
    };

    private PermissionInfo(Parcel source) {
        super(source);
        protectionLevel = source.readInt();
        flags = source.readInt();
        group = source.readString();
        descriptionRes = source.readInt();
        nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
    }
}
PermissionState

PermissionState是PermissionsState的内部类,表示单一的某个权限,对这个权限的封装,此处封装的是名字、是否授权和状态。

    public static final class PermissionState {
        private final String mName;//权限名
        private boolean mGranted;//是否授权
        private int mFlags;//权限标记位

        public PermissionState(String name) {
            mName = name;
        }

        public PermissionState(PermissionState other) {
            mName = other.mName;
            mGranted = other.mGranted;
            mFlags = other.mFlags;
        }

        public boolean isDefault() {//默认情况是没有授权,标记为0
            return !mGranted && mFlags == 0;
        }

        public String getName() {
            return mName;
        }

        public boolean isGranted() {
            return mGranted;
        }

        public int getFlags() {
            return mFlags;
        }
    }
PermissionData

PermissionData是PermissionsState的内部类,在PermissionsState中管理了一组PermissionData,记录app的每个permission的状态信息。

    private static final class PermissionData {
        private final BasePermission mPerm;//一个权限对应一个BasePermission对象
        private SparseArray<PermissionState> mUserStates = new SparseArray<>();//一个权限对应一个PermissionState,这里数组只有一个元素

        public PermissionData(BasePermission perm) {
            mPerm = perm;
        }

        public PermissionData(PermissionData other) {
            this(other.mPerm);
            final int otherStateCount = other.mUserStates.size();
            for (int i = 0; i < otherStateCount; i++) {
                final int otherUserId = other.mUserStates.keyAt(i);
                PermissionState otherState = other.mUserStates.valueAt(i);
                mUserStates.put(otherUserId, new PermissionState(otherState));
            }
        }

        public int[] computeGids(int userId) {
            return mPerm.computeGids(userId);
        }

        public boolean isGranted(int userId) {//是否被授权了
            if (isInstallPermission()) {
                userId = UserHandle.USER_ALL;//userId=-1
            }

            PermissionState userState = mUserStates.get(userId);
            if (userState == null) {
                return false;
            }

            return userState.mGranted;
        }

        public boolean grant(int userId) {//将PermissionState的mGranted置位true
            if (!isCompatibleUserId(userId)) {
                return false;//不匹配用户
            }

            if (isGranted(userId)) {
                return false;//已授权
            }

            PermissionState userState = mUserStates.get(userId);//第一次获取的时候为null
            if (userState == null) {
                userState = new PermissionState(mPerm.name);//创建单一权限对应的PermissionState对象
                mUserStates.put(userId, userState);
            }

            userState.mGranted = true;//将PermissionState的mGranted置为true,表示允许授权

            return true;
        }

        public boolean revoke(int userId) {
            if (!isCompatibleUserId(userId)) {
                return false;
            }

            if (!isGranted(userId)) {
                return false;//未授权
            }

            PermissionState userState = mUserStates.get(userId);
            userState.mGranted = false;//将PermissionState置为false

            if (userState.isDefault()) {//!mGranted && mFlags == 0
                mUserStates.remove(userId);//从PermissionState数组中移除
            }

            return true;
        }

        public PermissionState getPermissionState(int userId) {//返回数组中对应userId的PermissionState对象
            return mUserStates.get(userId);
        }

        public int getFlags(int userId) {
            PermissionState userState = mUserStates.get(userId);
            if (userState != null) {
                return userState.mFlags;
            }
            return 0;
        }

        public boolean isDefault() {//默认情况下,PermissionState数组中没有元素
            return mUserStates.size() <= 0;
        }

        public static boolean isInstallPermissionKey(int userId) {
            return userId == UserHandle.USER_ALL;
        }

        public boolean updateFlags(int userId, int flagMask, int flagValues) {//更新标记位
            if (isInstallPermission()) {//已经生成permission
                userId = UserHandle.USER_ALL;
            }

            if (!isCompatibleUserId(userId)) {不兼容该userId
                return false;
            }

            final int newFlags = flagValues & flagMask;//按位与

            PermissionState userState = mUserStates.get(userId);
            if (userState != null) {
                final int oldFlags = userState.mFlags;//获取标记位
                userState.mFlags = (userState.mFlags & ~flagMask) | newFlags;
                if (userState.isDefault()) {//如果PermissionState的mFlags=0,mGranted=false
                    mUserStates.remove(userId);
                }
                return userState.mFlags != oldFlags;
            } else if (newFlags != 0) {
                userState = new PermissionState(mPerm.name);
                userState.mFlags = newFlags;
                mUserStates.put(userId, userState);
                return true;
            }

            return false;
        }

        private boolean isCompatibleUserId(int userId) {//是否兼容指定的userId
            return isDefault() || !(isInstallPermission() ^ isInstallPermissionKey(userId));
        }

        private boolean isInstallPermission() {//这里是对单一permission的处理,一个permission对应一个PermissionState
            return mUserStates.size() == 1//PermissionState数组只有一个元素,并且不为空。
                    && mUserStates.get(UserHandle.USER_ALL) != null;
        }
    }
PermissionsState
/**
 * PermissionsState基本囊括了一个应用或一个共享用户的所有权限的状态。
 * 有两种类型的权限:安装(在安装时授予)和运行时(在运行时授予)。安装权限授予所有设备用户,而运行时权限则明确授予特定用户。
 */
public final class PermissionsState {

    /** The permission operation failed. */
    public static final int PERMISSION_OPERATION_FAILURE = -1;

    /** The permission operation succeeded and no gids changed. */
    public static final int PERMISSION_OPERATION_SUCCESS = 0;

    /** The permission operation succeeded and gids changed. */
    public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 1;

    private static final int[] NO_GIDS = {};

    private ArrayMap<String, PermissionData> mPermissions;//key是权限名,value是权限名对应的PermissionData

    private int[] mGlobalGids = NO_GIDS;

    private SparseBooleanArray mPermissionReviewRequired;

    public PermissionsState() {
        /* do nothing */
    }

    public PermissionsState(PermissionsState prototype) {
        copyFrom(prototype);//从另一个PermissionsState获取数据,此时一般mPermissions都不是null。
    }

    /**
     * 设置适用于所有用户的全局gid
     */
    public void setGlobalGids(int[] globalGids) {
        if (!ArrayUtils.isEmpty(globalGids)) {
            mGlobalGids = Arrays.copyOf(globalGids, globalGids.length);
        }
    }

    public void copyFrom(PermissionsState other) {
        //......将参数PermissionsState的mPermissions复制给this.mPermissions

        //......复制mGlobalGids

        //......复制mPermissionReviewRequired
    }

    @Override
    public boolean equals(Object obj) {
        ......
    }

    public boolean isPermissionReviewRequired(int userId) {
        return mPermissionReviewRequired != null && mPermissionReviewRequired.get(userId);
    }

    public int grantInstallPermission(BasePermission permission) {//授予安装权限
        return grantPermission(permission, UserHandle.USER_ALL);
    }

    public int revokeInstallPermission(BasePermission permission) {//撤销一个安装权限
        return revokePermission(permission, UserHandle.USER_ALL);
    }

    public int grantRuntimePermission(BasePermission permission, int userId) {//对指定用户授予一个运行时权限
        enforceValidUserId(userId);
        if (userId == UserHandle.USER_ALL) {//运行时权限是在应用程序运行时请求的,此时对应一个特定用户
            return PERMISSION_OPERATION_FAILURE;
        }
        return grantPermission(permission, userId);
    }

    public int revokeRuntimePermission(BasePermission permission, int userId) {//对指定用户撤销一个运行时权限
        enforceValidUserId(userId);
        if (userId == UserHandle.USER_ALL) {
            return PERMISSION_OPERATION_FAILURE;
        }
        return revokePermission(permission, userId);
    }

    public boolean hasRuntimePermission(String name, int userId) {//对指定用户是否有指定的运行时权限
        enforceValidUserId(userId);
        return !hasInstallPermission(name) && hasPermission(name, userId);
    }

    public boolean hasInstallPermission(String name) {//是否有指定的安装权限
        return hasPermission(name, UserHandle.USER_ALL);
    }

    /**
     * 对指定用户是否有指定权限,不管是安装权限还是运行时权限
     */
    public boolean hasPermission(String name, int userId) {
        enforceValidUserId(userId);

        if (mPermissions == null) {
            return false;
        }

        PermissionData permissionData = mPermissions.get(name);
        return permissionData != null && permissionData.isGranted(userId);
    }

    public boolean hasRequestedPermission(ArraySet<String> names) {
        if (mPermissions == null) {
            return false;
        }
        for (int i=names.size()-1; i>=0; i--) {
            if (mPermissions.get(names.valueAt(i)) != null) {
                return true;//只要有一个就返回true
            }
        }
        return false;
    }

    /**
     *获取指定用户的所有permission,包括install permission和runtime permission
     */
    public Set<String> getPermissions(int userId) {
        ......
    }

    public PermissionState getInstallPermissionState(String name) {
        return getPermissionState(name, UserHandle.USER_ALL);//获取一个install permission的状态
    }

    public PermissionState getRuntimePermissionState(String name, int userId) {
        enforceValidUserId(userId);
        return getPermissionState(name, userId);//获取一个runtime permission状态
    }

    public List<PermissionState> getInstallPermissionStates() {//Gets all install permission states.
        return getPermissionStatesInternal(UserHandle.USER_ALL);
    }

    public List<PermissionState> getRuntimePermissionStates(int userId) {
        enforceValidUserId(userId);
        return getPermissionStatesInternal(userId);//获取所有runtime permission的状态
    }

    public int getPermissionFlags(String name, int userId) {
        PermissionState installPermState = getInstallPermissionState(name);
        if (installPermState != null) {
            return installPermState.getFlags();//先获取指定权限的安装权限状态
        }
        PermissionState runtimePermState = getRuntimePermissionState(name, userId);
        if (runtimePermState != null) {
            return runtimePermState.getFlags();//否则获取运行时权限状态
        }
        return 0;
    }

    /**
     * Update the flags associated with a given permission.
     * @param permission The permission whose flags to update.
     * @param userId The user for which to update.
     * @param flagMask Mask for which flags to change.
     * @param flagValues New values for the mask flags.
     * @return Whether the permission flags changed.
     */
    public boolean updatePermissionFlags(BasePermission permission, int userId,
            int flagMask, int flagValues) {
        enforceValidUserId(userId);

        final boolean mayChangeFlags = flagValues != 0 || flagMask != 0;

        if (mPermissions == null) {
            if (!mayChangeFlags) {
                return false;
            }
            ensurePermissionData(permission);
        }

        PermissionData permissionData = mPermissions.get(permission.name);
        if (permissionData == null) {
            if (!mayChangeFlags) {
                return false;
            }
            permissionData = ensurePermissionData(permission);
        }

        final int oldFlags = permissionData.getFlags(userId);

        final boolean updated = permissionData.updateFlags(userId, flagMask, flagValues);
        if (updated) {
            final int newFlags = permissionData.getFlags(userId);
            if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0
                    && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
                if (mPermissionReviewRequired == null) {
                    mPermissionReviewRequired = new SparseBooleanArray();
                }
                mPermissionReviewRequired.put(userId, true);
            } else if ((oldFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0
                    && (newFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
                if (mPermissionReviewRequired != null && !hasPermissionRequiringReview(userId)) {
                    mPermissionReviewRequired.delete(userId);
                    if (mPermissionReviewRequired.size() <= 0) {
                        mPermissionReviewRequired = null;
                    }
                }
            }
        }
        return updated;
    }

    private boolean hasPermissionRequiringReview(int userId) {//是否有组件运行之前审查的flag
        final int permissionCount = mPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            final PermissionData permission = mPermissions.valueAt(i);
            if ((permission.getFlags(userId)//在任何应用程序组件都可以运行之前,必须审查权限。
                    & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
                return true;
            }
        }
        return false;
    }

    public boolean updatePermissionFlagsForAllPermissions(
            int userId, int flagMask, int flagValues) {//更新所有权限的权限标记位
        enforceValidUserId(userId);

        if (mPermissions == null) {
            return false;
        }
        boolean changed = false;
        final int permissionCount = mPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            PermissionData permissionData = mPermissions.valueAt(i);
            changed |= permissionData.updateFlags(userId, flagMask, flagValues);
        }
        return changed;
    }

    /**
     * Compute the Linux gids for a given device user from the permissions
     * granted to this user. Note that these are computed to avoid additional
     * state as they are rarely accessed.
     *
     * @param userId The device user id.
     * @return The gids for the device user.
     */
    public int[] computeGids(int userId) {
        enforceValidUserId(userId);

        int[] gids = mGlobalGids;

        if (mPermissions != null) {
            final int permissionCount = mPermissions.size();
            for (int i = 0; i < permissionCount; i++) {
                String permission = mPermissions.keyAt(i);
                if (!hasPermission(permission, userId)) {
                    continue;
                }
                PermissionData permissionData = mPermissions.valueAt(i);
                final int[] permGids = permissionData.computeGids(userId);
                if (permGids != NO_GIDS) {
                    gids = appendInts(gids, permGids);
                }
            }
        }

        return gids;
    }

    /**
     * Compute the Linux gids for all device users from the permissions
     * granted to these users.
     *
     * @return The gids for all device users.
     */
    public int[] computeGids(int[] userIds) {
        int[] gids = mGlobalGids;

        for (int userId : userIds) {
            final int[] userGids = computeGids(userId);
            gids = appendInts(gids, userGids);
        }

        return gids;
    }

    /**
     * Resets the internal state of this object.
     */
    public void reset() {
        mGlobalGids = NO_GIDS;
        mPermissions = null;
        mPermissionReviewRequired = null;
    }

    private PermissionState getPermissionState(String name, int userId) {
        if (mPermissions == null) {
            return null;
        }
        PermissionData permissionData = mPermissions.get(name);
        if (permissionData == null) {
            return null;
        }
        return permissionData.getPermissionState(userId);
    }

    private List<PermissionState> getPermissionStatesInternal(int userId) {
        enforceValidUserId(userId);

        if (mPermissions == null) {
            return Collections.emptyList();
        }

        List<PermissionState> permissionStates = new ArrayList<>();

        final int permissionCount = mPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
            PermissionData permissionData = mPermissions.valueAt(i);

            PermissionState permissionState = permissionData.getPermissionState(userId);
            if (permissionState != null) {
                permissionStates.add(permissionState);
            }
        }

        return permissionStates;
    }

    private int grantPermission(BasePermission permission, int userId) {
        if (hasPermission(permission.name, userId)) {
            return PERMISSION_OPERATION_FAILURE;//已经授予了该权限,直接返回
        }

        final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId));
        final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;

        PermissionData permissionData = ensurePermissionData(permission);//实例化PermissionData

        if (!permissionData.grant(userId)) {//调用permissionData 的grant方法来完成权限的允许过程。
            return PERMISSION_OPERATION_FAILURE;
        }

        if (hasGids) {
            final int[] newGids = computeGids(userId);
            if (oldGids.length != newGids.length) {
                return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
            }
        }

        return PERMISSION_OPERATION_SUCCESS;
    }

    private int revokePermission(BasePermission permission, int userId) {
        if (!hasPermission(permission.name, userId)) {
            return PERMISSION_OPERATION_FAILURE;//如果已经拒绝了,直接返回
        }

        final boolean hasGids = !ArrayUtils.isEmpty(permission.computeGids(userId));
        final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;

        PermissionData permissionData = mPermissions.get(permission.name);

        if (!permissionData.revoke(userId)) {//revoke方法来完成拒绝的操作
            return PERMISSION_OPERATION_FAILURE;
        }

        if (permissionData.isDefault()) {
            ensureNoPermissionData(permission.name);
        }

        if (hasGids) {
            final int[] newGids = computeGids(userId);
            if (oldGids.length != newGids.length) {
                return PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
            }
        }

        return PERMISSION_OPERATION_SUCCESS;
    }

    // TODO: fix this to use arraycopy and append all ints in one go
    private static int[] appendInts(int[] current, int[] added) {
        if (current != null && added != null) {
            for (int guid : added) {
                current = ArrayUtils.appendInt(current, guid);
            }
        }
        return current;
    }

    private static void enforceValidUserId(int userId) {//确保是有效的userId
        if (userId != UserHandle.USER_ALL && userId < 0) {
            throw new IllegalArgumentException("Invalid userId:" + userId);
        }
    }

    private PermissionData ensurePermissionData(BasePermission permission) {
        if (mPermissions == null) {当第一次到这mPermissions 为null时,初始化一个
            mPermissions = new ArrayMap<>();
        }
        PermissionData permissionData = mPermissions.get(permission.name);
        if (permissionData == null) {第一次获取某个权限时必定为null
            permissionData = new PermissionData(permission);
            mPermissions.put(permission.name, permissionData);
        }
        return permissionData;
    }

    private void ensureNoPermissionData(String name) {
        if (mPermissions == null) {
            return;
        }
        mPermissions.remove(name);//从mPermissions中移除指定权限
        if (mPermissions.isEmpty()) {
            mPermissions = null;
        }
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值