下面列出了android.content.pm.PermissionInfo#PROTECTION_DANGEROUS 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Returns page-entry for each defined permission in the app (the passed activity belongs to).
* <p>
* See {@link DefaultProperties#createSectionRuntimePermissions(Activity, List)} for more details
*
* @param context must not be null and must be instance of activity (needed for getting the state)
* @param packageInfo from {@link PackageManager#getPackageInfo(String, int)} requiring {@link PackageManager#GET_PERMISSIONS} flag
* @param onlyDangerousPermissions only include permissions with flag PROTECTION_DANGEROUS (ie. have to be granted by the user)
* @return list of page-entries
*/
@SuppressLint("NewApi")
public static List<PageEntry<?>> createPmPermissionInfo(final @NonNull Context context, @NonNull PackageInfo packageInfo, boolean onlyDangerousPermissions) {
if (!(context instanceof Activity)) {
throw new IllegalArgumentException("context must be of type activity - needed for getting current permission state");
}
List<PageEntry<?>> entries = new ArrayList<>();
if (packageInfo.requestedPermissions != null && packageInfo.requestedPermissions.length > 0) {
List<String> permissionNames = new ArrayList<>();
for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1
|| !onlyDangerousPermissions
|| packageInfo.requestedPermissionsFlags[i] == PermissionInfo.PROTECTION_DANGEROUS) {
permissionNames.add(packageInfo.requestedPermissions[i]);
}
}
Collections.sort(permissionNames);
return DefaultProperties.createSectionRuntimePermissions(((Activity) context), permissionNames).removeHeader().asEntryList();
}
return entries;
}
@TargetApi(23)
private boolean isDisplayablePermission(PermissionInfo pInfo, int existingReqFlags) {
final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
final boolean isNormal = base == PermissionInfo.PROTECTION_NORMAL;
final boolean isDangerous = base == PermissionInfo.PROTECTION_DANGEROUS
|| ((pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0);
// Dangerous and normal permissions are always shown to the user
// this is matches the permission list in AppDetailsActivity
if (isNormal || isDangerous) {
return true;
}
final boolean isDevelopment = (pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
final boolean wasGranted = (existingReqFlags & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
// Development permissions are only shown to the user if they are already
// granted to the app -- if we are installing an app and they are not
// already granted, they will not be granted as part of the install.
return isDevelopment && wasGranted;
}
private int adjustPermissionProtectionFlagsLocked(
int protectionLevel, String packageName, int uid) {
// Signature permission flags area always reported
final int protectionLevelMasked = protectionLevel
& (PermissionInfo.PROTECTION_NORMAL
| PermissionInfo.PROTECTION_DANGEROUS
| PermissionInfo.PROTECTION_SIGNATURE);
if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
return protectionLevel;
}
// System sees all flags.
final int appId = UserHandle.getAppId(uid);
if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
|| appId == Process.SHELL_UID) {
return protectionLevel;
}
// Normalize package name to handle renamed packages and static libs
final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null) {
return protectionLevel;
}
if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
return protectionLevelMasked;
}
// Apps that target O see flags for all protection levels.
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return protectionLevel;
}
if (ps.getAppId() != appId) {
return protectionLevel;
}
return protectionLevel;
}
private boolean isDisplayablePermission(PermissionInfo pInfo, int newReqFlags,
int existingReqFlags) {
final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
final boolean isNormal = (base == PermissionInfo.PROTECTION_NORMAL);
// We do not show normal permissions in the UI.
if (isNormal) {
return false;
}
final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS)
|| ((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_PRE23) != 0);
final boolean isRequired =
((newReqFlags&PackageInfo.REQUESTED_PERMISSION_REQUIRED) != 0);
final boolean isDevelopment =
((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0);
final boolean wasGranted =
((existingReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0);
final boolean isGranted =
((newReqFlags&PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0);
// Dangerous and normal permissions are always shown to the user if the permission
// is required, or it was previously granted
if (isDangerous && (isRequired || wasGranted || isGranted)) {
return true;
}
// Development permissions are only shown to the user if they are already
// granted to the app -- if we are installing an app and they are not
// already granted, they will not be granted as part of the install.
if (isDevelopment && wasGranted) {
if (localLOGV) Log.i(TAG, "Special perm " + pInfo.name
+ ": protlevel=0x" + Integer.toHexString(pInfo.protectionLevel));
return true;
}
return false;
}
public static String getProtectionLevelString(int level) {
String protLevel = "????";
switch (level & PermissionInfo.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_SYSTEM) != 0) {
protLevel += "|system";
}
if ((level & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
protLevel += "|development";
}
if ((level & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
protLevel += "|appop";
}
return protLevel;
}
private boolean isRuntimePermission(PackageManager packageManager, String permission) {
try {
PermissionInfo pInfo = packageManager.getPermissionInfo(permission, 0);
if (pInfo != null) {
if ((pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS) {
return true;
}
}
} catch (PackageManager.NameNotFoundException e) {
Log.i(TAG, "Could not retrieve info about the permission: " + permission);
}
return false;
}
private static boolean isPermissionDangerous(String permission, Context context) {
PermissionInfo permissionInfo;
try {
permissionInfo = context.getPackageManager().getPermissionInfo(permission, 0);
} catch (NameNotFoundException e) {
Log.e(TAG, "Failed to look up permission.", e);
return false;
}
return permissionInfo != null
&& (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS;
}
public boolean isRuntime() {
return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS;
}
/**
* We might auto-grant permissions if any permission of the group is already granted. Hence if
* the group of a granted permission changes we need to revoke it to avoid having permissions of
* the new group auto-granted.
*
* @param newPackage The new package that was installed
* @param oldPackage The old package that was updated
* @param allPackageNames All package names
* @param permissionCallback Callback for permission changed
*/
private void revokeRuntimePermissionsIfGroupChanged(
@NonNull PackageParser.Package newPackage,
@NonNull PackageParser.Package oldPackage,
@NonNull ArrayList<String> allPackageNames,
@NonNull PermissionCallback permissionCallback) {
final int numOldPackagePermissions = oldPackage.permissions.size();
final ArrayMap<String, String> oldPermissionNameToGroupName
= new ArrayMap<>(numOldPackagePermissions);
for (int i = 0; i < numOldPackagePermissions; i++) {
final PackageParser.Permission permission = oldPackage.permissions.get(i);
if (permission.group != null) {
oldPermissionNameToGroupName.put(permission.info.name,
permission.group.info.name);
}
}
final int numNewPackagePermissions = newPackage.permissions.size();
for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
newPermissionNum++) {
final PackageParser.Permission newPermission =
newPackage.permissions.get(newPermissionNum);
final int newProtection = newPermission.info.getProtection();
if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
final String permissionName = newPermission.info.name;
final String newPermissionGroupName =
newPermission.group == null ? null : newPermission.group.info.name;
final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
permissionName);
if (newPermissionGroupName != null
&& !newPermissionGroupName.equals(oldPermissionGroupName)) {
final int[] userIds = mUserManagerInt.getUserIds();
final int numUserIds = userIds.length;
for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
final int userId = userIds[userIdNum];
final int numPackages = allPackageNames.size();
for (int packageNum = 0; packageNum < numPackages; packageNum++) {
final String packageName = allPackageNames.get(packageNum);
if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
userId) == PackageManager.PERMISSION_GRANTED) {
EventLog.writeEvent(0x534e4554, "72710897",
newPackage.applicationInfo.uid,
"Revoking permission " + permissionName +
" from package " + packageName +
" as the group changed from " + oldPermissionGroupName +
" to " + newPermissionGroupName);
try {
revokeRuntimePermission(permissionName, packageName, false,
Process.SYSTEM_UID, userId, permissionCallback);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Could not revoke " + permissionName + " from "
+ packageName, e);
}
}
}
}
}
}
}
}
public static ReportDisplay buildReportDisplay(Context context, ApplicationViewModel model, PackageManager manager, PackageInfo info) {
ReportDisplay reportDisplay = new ReportDisplay();
reportDisplay.packageName = model.packageName;
reportDisplay.versionName = model.versionName;
reportDisplay.versionCode = model.versionCode;
reportDisplay.displayName = model.label.toString();
reportDisplay.report = model.report;
reportDisplay.trackers = model.trackers;
if (reportDisplay.report != null)
reportDisplay.creator = DatabaseManager.getInstance(context).getCreator(reportDisplay.report.appId);
List<Permission> requestedPermissions= new ArrayList<>();
if (info.requestedPermissions != null) {
for(int i = 0; i < info.requestedPermissions.length; i++) {
Permission permission = new Permission();
permission.fullName = info.requestedPermissions[i];
try {
PermissionInfo permissionInfo = manager.getPermissionInfo(permission.fullName,PackageManager.GET_META_DATA);
if(permissionInfo.loadDescription(manager) != null)
permission.description = permissionInfo.loadDescription(manager).toString();
if(permissionInfo.loadLabel(manager) != null)
permission.name = permissionInfo.loadLabel(manager).toString();
permission.dangerous = permissionInfo.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
if(permission.fullName.equals(Manifest.permission.WRITE_SETTINGS) || permission.fullName.equals(Manifest.permission.SYSTEM_ALERT_WINDOW)) //Special permissions
permission.dangerous = true;
if (permissionInfo.group != null) {
PermissionGroupInfo permissionGroupInfo = manager.getPermissionGroupInfo(permissionInfo.group, PackageManager.GET_META_DATA);
if(permissionGroupInfo.loadIcon(manager) != null)
permission.icon = permissionGroupInfo.loadIcon(manager);
}
} catch (PackageManager.NameNotFoundException e) {
e.getLocalizedMessage();
}
requestedPermissions.add(permission);
}
}
reportDisplay.permissions = requestedPermissions;
reportDisplay.logo = model.icon;
return reportDisplay;
}