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解析apk的AndroidManifest.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;
}
}
}