Loading core/java/com/android/internal/util/CollectionUtils.java +7 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,13 @@ import java.util.stream.Stream; public class CollectionUtils { private CollectionUtils() { /* cannot be instantiated */ } /** * @see Collection#contains(Object) */ public static <T> boolean contains(@Nullable Collection<T> collection, T element) { return collection != null && collection.contains(element); } /** * Returns a list of items from the provided list that match the given condition. * Loading services/core/java/com/android/server/pm/permission/PermissionManagerService.java +108 −97 Original line number Diff line number Diff line Loading @@ -2590,6 +2590,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; ArraySet<String> isPrivilegedPermissionAllowlisted = null; ArraySet<String> shouldGrantSignaturePermission = null; ArraySet<String> shouldGrantInternalPermission = null; final List<String> requestedPermissions = pkg.getRequestedPermissions(); Loading @@ -2604,7 +2605,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (permission == null) { continue; } if (permission.isSignature() && (shouldGrantSignaturePermission(pkg, permission) if (permission.isPrivileged() && checkPrivilegedPermissionAllowlist(pkg, ps, permission)) { if (isPrivilegedPermissionAllowlisted == null) { isPrivilegedPermissionAllowlisted = new ArraySet<>(); } isPrivilegedPermissionAllowlisted.add(permissionName); } if (permission.isSignature() && (shouldGrantPermissionBySignature(pkg, permission) || shouldGrantPermissionByProtectionFlags(pkg, ps, permission))) { if (shouldGrantSignaturePermission == null) { shouldGrantSignaturePermission = new ArraySet<>(); Loading Loading @@ -2830,13 +2838,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { if ((bp.isNormal() && shouldGrantNormalPermission) || (bp.isSignature() && ((shouldGrantSignaturePermission != null && shouldGrantSignaturePermission.contains(permName)) && (!bp.isPrivileged() || CollectionUtils.contains( isPrivilegedPermissionAllowlisted, permName)) && (CollectionUtils.contains(shouldGrantSignaturePermission, permName) || ((bp.isDevelopment() || bp.isRole()) && origState.isPermissionGranted(permName)))) || (bp.isInternal() && ((shouldGrantInternalPermission != null && shouldGrantInternalPermission.contains(permName)) && (!bp.isPrivileged() || CollectionUtils.contains( isPrivilegedPermissionAllowlisted, permName)) && (CollectionUtils.contains(shouldGrantInternalPermission, permName) || ((bp.isDevelopment() || bp.isRole()) && origState.isPermissionGranted(permName))))) { // Grant an install permission. Loading Loading @@ -3343,7 +3355,92 @@ public class PermissionManagerService extends IPermissionManager.Stub { return allowed; } private boolean shouldGrantSignaturePermission(@NonNull AndroidPackage pkg, private boolean checkPrivilegedPermissionAllowlist(@NonNull AndroidPackage pkg, @NonNull PackageSetting packageSetting, @NonNull Permission permission) { if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { return true; } final String packageName = pkg.getPackageName(); if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) { return true; } if (!pkg.isPrivileged()) { return true; } if (!Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME)) { return true; } final String permissionName = permission.getName(); if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { return true; } // Only enforce the allowlist on boot if (!mSystemReady // Updated system apps do not need to be allowlisted && !packageSetting.getPkgState().isUpdatedSystemApp()) { final ApexManager apexManager = ApexManager.getInstance(); final String containingApexPackageName = apexManager.getActiveApexPackageNameContainingPackage(packageName); final boolean isInUpdatedApex = containingApexPackageName != null && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName, MATCH_ACTIVE_PACKAGE)); // Apps that are in updated apexs' do not need to be allowlisted if (!isInUpdatedApex) { // it's only a reportable violation if the permission isn't explicitly // denied if (isInSystemConfigPrivAppDenyPermissions(pkg, permissionName)) { return false; } Slog.w(TAG, "Privileged permission " + permissionName + " for package " + packageName + " (" + pkg.getPath() + ") not in privapp-permissions allowlist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { synchronized (mLock) { if (mPrivappPermissionsViolations == null) { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): " + permissionName); } } } } return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE; } private boolean isInSystemConfigPrivAppPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppPermissions(pkg.getPackageName()); } return CollectionUtils.contains(permissions, permission); } private boolean isInSystemConfigPrivAppDenyPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppDenyPermissions(pkg.getPackageName()); } return CollectionUtils.contains(permissions, permission); } private boolean shouldGrantPermissionBySignature(@NonNull AndroidPackage pkg, @NonNull Permission bp) { // expect single system package String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames( Loading Loading @@ -3373,8 +3470,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { private boolean shouldGrantPermissionByProtectionFlags(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @NonNull Permission bp) { boolean allowed = false; final boolean isVendorPrivilegedPermission = bp.isVendorPrivileged(); final boolean isPrivilegedPermission = bp.isPrivileged() || isVendorPrivilegedPermission; final boolean isPrivilegedPermission = bp.isPrivileged(); final boolean isOemPermission = bp.isOem(); if (!allowed && (isPrivilegedPermission || isOemPermission) && pkg.isSystem()) { final String permissionName = bp.getName(); Loading @@ -3386,19 +3482,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg; if (disabledPkg != null && disabledPkg.getRequestedPermissions().contains( permissionName)) { allowed = (isPrivilegedPermission && canGrantPrivilegedPermission(disabledPkg, true, bp)) || (isOemPermission && canGrantOemPermission(disabledPkg, allowed = (isPrivilegedPermission && disabledPkg.isPrivileged()) || (isOemPermission && canGrantOemPermission(disabledPkg, permissionName)); } } else { allowed = (isPrivilegedPermission && canGrantPrivilegedPermission(pkg, false, bp)) allowed = (isPrivilegedPermission && pkg.isPrivileged()) || (isOemPermission && canGrantOemPermission(pkg, permissionName)); } // In any case, don't grant a privileged permission to privileged vendor apps, if // the permission's protectionLevel does not have the extra 'vendorPrivileged' // flag. if (allowed && isPrivilegedPermission && !isVendorPrivilegedPermission && pkg.isVendor()) { if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged() && pkg.isVendor()) { Slog.w(TAG, "Permission " + permissionName + " cannot be granted to privileged vendor apk " + pkg.getPackageName() + " because it isn't a 'vendorPrivileged' permission."); Loading Loading @@ -3541,90 +3636,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return mPackageManagerInt.getPackageSetting(sourcePackageName); } private boolean canGrantPrivilegedPermission(@NonNull AndroidPackage pkg, boolean isUpdatedSystemApp, @NonNull Permission permission) { if (!pkg.isPrivileged()) { return false; } final boolean isPlatformPermission = PLATFORM_PACKAGE_NAME.equals( permission.getPackageName()); if (!isPlatformPermission) { return true; } if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { return true; } final String permissionName = permission.getName(); if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { return true; } // Only enforce the allowlist on boot if (!mSystemReady // Updated system apps do not need to be allowlisted && !isUpdatedSystemApp) { final ApexManager apexManager = ApexManager.getInstance(); final String packageName = pkg.getPackageName(); final String containingApexPackageName = apexManager.getActiveApexPackageNameContainingPackage(packageName); final boolean isInUpdatedApex = containingApexPackageName != null && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName, MATCH_ACTIVE_PACKAGE)); // Apps that are in updated apexs' do not need to be allowlisted if (!isInUpdatedApex) { // it's only a reportable violation if the permission isn't explicitly // denied if (isInSystemConfigPrivAppDenyPermissions(pkg, permissionName)) { return false; } Slog.w(TAG, "Privileged permission " + permissionName + " for package " + packageName + " (" + pkg.getPath() + ") not in privapp-permissions allowlist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { synchronized (mLock) { if (mPrivappPermissionsViolations == null) { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): " + permissionName); } } } } return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE; } private boolean isInSystemConfigPrivAppPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppPermissions(pkg.getPackageName()); } return permissions != null && permissions.contains(permission); } private boolean isInSystemConfigPrivAppDenyPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppDenyPermissions(pkg.getPackageName()); } return permissions != null && permissions.contains(permission); } private static boolean canGrantOemPermission(AndroidPackage pkg, String permission) { if (!pkg.isOem()) { return false; Loading Loading
core/java/com/android/internal/util/CollectionUtils.java +7 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,13 @@ import java.util.stream.Stream; public class CollectionUtils { private CollectionUtils() { /* cannot be instantiated */ } /** * @see Collection#contains(Object) */ public static <T> boolean contains(@Nullable Collection<T> collection, T element) { return collection != null && collection.contains(element); } /** * Returns a list of items from the provided list that match the given condition. * Loading
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +108 −97 Original line number Diff line number Diff line Loading @@ -2590,6 +2590,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { boolean runtimePermissionsRevoked = false; int[] updatedUserIds = EMPTY_INT_ARRAY; ArraySet<String> isPrivilegedPermissionAllowlisted = null; ArraySet<String> shouldGrantSignaturePermission = null; ArraySet<String> shouldGrantInternalPermission = null; final List<String> requestedPermissions = pkg.getRequestedPermissions(); Loading @@ -2604,7 +2605,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (permission == null) { continue; } if (permission.isSignature() && (shouldGrantSignaturePermission(pkg, permission) if (permission.isPrivileged() && checkPrivilegedPermissionAllowlist(pkg, ps, permission)) { if (isPrivilegedPermissionAllowlisted == null) { isPrivilegedPermissionAllowlisted = new ArraySet<>(); } isPrivilegedPermissionAllowlisted.add(permissionName); } if (permission.isSignature() && (shouldGrantPermissionBySignature(pkg, permission) || shouldGrantPermissionByProtectionFlags(pkg, ps, permission))) { if (shouldGrantSignaturePermission == null) { shouldGrantSignaturePermission = new ArraySet<>(); Loading Loading @@ -2830,13 +2838,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { if ((bp.isNormal() && shouldGrantNormalPermission) || (bp.isSignature() && ((shouldGrantSignaturePermission != null && shouldGrantSignaturePermission.contains(permName)) && (!bp.isPrivileged() || CollectionUtils.contains( isPrivilegedPermissionAllowlisted, permName)) && (CollectionUtils.contains(shouldGrantSignaturePermission, permName) || ((bp.isDevelopment() || bp.isRole()) && origState.isPermissionGranted(permName)))) || (bp.isInternal() && ((shouldGrantInternalPermission != null && shouldGrantInternalPermission.contains(permName)) && (!bp.isPrivileged() || CollectionUtils.contains( isPrivilegedPermissionAllowlisted, permName)) && (CollectionUtils.contains(shouldGrantInternalPermission, permName) || ((bp.isDevelopment() || bp.isRole()) && origState.isPermissionGranted(permName))))) { // Grant an install permission. Loading Loading @@ -3343,7 +3355,92 @@ public class PermissionManagerService extends IPermissionManager.Stub { return allowed; } private boolean shouldGrantSignaturePermission(@NonNull AndroidPackage pkg, private boolean checkPrivilegedPermissionAllowlist(@NonNull AndroidPackage pkg, @NonNull PackageSetting packageSetting, @NonNull Permission permission) { if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { return true; } final String packageName = pkg.getPackageName(); if (Objects.equals(packageName, PLATFORM_PACKAGE_NAME)) { return true; } if (!pkg.isPrivileged()) { return true; } if (!Objects.equals(permission.getPackageName(), PLATFORM_PACKAGE_NAME)) { return true; } final String permissionName = permission.getName(); if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { return true; } // Only enforce the allowlist on boot if (!mSystemReady // Updated system apps do not need to be allowlisted && !packageSetting.getPkgState().isUpdatedSystemApp()) { final ApexManager apexManager = ApexManager.getInstance(); final String containingApexPackageName = apexManager.getActiveApexPackageNameContainingPackage(packageName); final boolean isInUpdatedApex = containingApexPackageName != null && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName, MATCH_ACTIVE_PACKAGE)); // Apps that are in updated apexs' do not need to be allowlisted if (!isInUpdatedApex) { // it's only a reportable violation if the permission isn't explicitly // denied if (isInSystemConfigPrivAppDenyPermissions(pkg, permissionName)) { return false; } Slog.w(TAG, "Privileged permission " + permissionName + " for package " + packageName + " (" + pkg.getPath() + ") not in privapp-permissions allowlist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { synchronized (mLock) { if (mPrivappPermissionsViolations == null) { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): " + permissionName); } } } } return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE; } private boolean isInSystemConfigPrivAppPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppPermissions(pkg.getPackageName()); } return CollectionUtils.contains(permissions, permission); } private boolean isInSystemConfigPrivAppDenyPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppDenyPermissions(pkg.getPackageName()); } return CollectionUtils.contains(permissions, permission); } private boolean shouldGrantPermissionBySignature(@NonNull AndroidPackage pkg, @NonNull Permission bp) { // expect single system package String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames( Loading Loading @@ -3373,8 +3470,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { private boolean shouldGrantPermissionByProtectionFlags(@NonNull AndroidPackage pkg, @NonNull PackageSetting pkgSetting, @NonNull Permission bp) { boolean allowed = false; final boolean isVendorPrivilegedPermission = bp.isVendorPrivileged(); final boolean isPrivilegedPermission = bp.isPrivileged() || isVendorPrivilegedPermission; final boolean isPrivilegedPermission = bp.isPrivileged(); final boolean isOemPermission = bp.isOem(); if (!allowed && (isPrivilegedPermission || isOemPermission) && pkg.isSystem()) { final String permissionName = bp.getName(); Loading @@ -3386,19 +3482,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg; if (disabledPkg != null && disabledPkg.getRequestedPermissions().contains( permissionName)) { allowed = (isPrivilegedPermission && canGrantPrivilegedPermission(disabledPkg, true, bp)) || (isOemPermission && canGrantOemPermission(disabledPkg, allowed = (isPrivilegedPermission && disabledPkg.isPrivileged()) || (isOemPermission && canGrantOemPermission(disabledPkg, permissionName)); } } else { allowed = (isPrivilegedPermission && canGrantPrivilegedPermission(pkg, false, bp)) allowed = (isPrivilegedPermission && pkg.isPrivileged()) || (isOemPermission && canGrantOemPermission(pkg, permissionName)); } // In any case, don't grant a privileged permission to privileged vendor apps, if // the permission's protectionLevel does not have the extra 'vendorPrivileged' // flag. if (allowed && isPrivilegedPermission && !isVendorPrivilegedPermission && pkg.isVendor()) { if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged() && pkg.isVendor()) { Slog.w(TAG, "Permission " + permissionName + " cannot be granted to privileged vendor apk " + pkg.getPackageName() + " because it isn't a 'vendorPrivileged' permission."); Loading Loading @@ -3541,90 +3636,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return mPackageManagerInt.getPackageSetting(sourcePackageName); } private boolean canGrantPrivilegedPermission(@NonNull AndroidPackage pkg, boolean isUpdatedSystemApp, @NonNull Permission permission) { if (!pkg.isPrivileged()) { return false; } final boolean isPlatformPermission = PLATFORM_PACKAGE_NAME.equals( permission.getPackageName()); if (!isPlatformPermission) { return true; } if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE) { return true; } final String permissionName = permission.getName(); if (isInSystemConfigPrivAppPermissions(pkg, permissionName)) { return true; } // Only enforce the allowlist on boot if (!mSystemReady // Updated system apps do not need to be allowlisted && !isUpdatedSystemApp) { final ApexManager apexManager = ApexManager.getInstance(); final String packageName = pkg.getPackageName(); final String containingApexPackageName = apexManager.getActiveApexPackageNameContainingPackage(packageName); final boolean isInUpdatedApex = containingApexPackageName != null && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName, MATCH_ACTIVE_PACKAGE)); // Apps that are in updated apexs' do not need to be allowlisted if (!isInUpdatedApex) { // it's only a reportable violation if the permission isn't explicitly // denied if (isInSystemConfigPrivAppDenyPermissions(pkg, permissionName)) { return false; } Slog.w(TAG, "Privileged permission " + permissionName + " for package " + packageName + " (" + pkg.getPath() + ") not in privapp-permissions allowlist"); if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) { synchronized (mLock) { if (mPrivappPermissionsViolations == null) { mPrivappPermissionsViolations = new ArraySet<>(); } mPrivappPermissionsViolations.add(packageName + " (" + pkg.getPath() + "): " + permissionName); } } } } return !RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE; } private boolean isInSystemConfigPrivAppPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppPermissions(pkg.getPackageName()); } return permissions != null && permissions.contains(permission); } private boolean isInSystemConfigPrivAppDenyPermissions(@NonNull AndroidPackage pkg, @NonNull String permission) { final SystemConfig systemConfig = SystemConfig.getInstance(); final Set<String> permissions; if (pkg.isVendor()) { permissions = systemConfig.getVendorPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isProduct()) { permissions = systemConfig.getProductPrivAppDenyPermissions(pkg.getPackageName()); } else if (pkg.isSystemExt()) { permissions = systemConfig.getSystemExtPrivAppDenyPermissions(pkg.getPackageName()); } else { permissions = systemConfig.getPrivAppDenyPermissions(pkg.getPackageName()); } return permissions != null && permissions.contains(permission); } private static boolean canGrantOemPermission(AndroidPackage pkg, String permission) { if (!pkg.isOem()) { return false; Loading