Loading services/core/java/com/android/server/pm/PackageManagerService.java +13 −12 Original line number Diff line number Diff line Loading @@ -2636,7 +2636,8 @@ public class PackageManagerService extends IPackageManager.Stub // We'll want to include browser possibilities in a few cases boolean includeBrowser = false; if (!DomainVerificationUtils.isDomainVerificationIntent(intent, matchFlags)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, candidates, matchFlags)) { result.addAll(undefinedList); // Maybe add one for the other profile. if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel Loading Loading @@ -2820,8 +2821,8 @@ public class PackageManagerService extends IPackageManager.Stub } result.highestApprovalLevel = Math.max(mDomainVerificationManager .approvalLevelForDomain(ps, intent, flags, riTargetUser.targetUserId), result.highestApprovalLevel); .approvalLevelForDomain(ps, intent, resultTargetUser, flags, riTargetUser.targetUserId), result.highestApprovalLevel); } if (result != null && result.highestApprovalLevel <= DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) { Loading Loading @@ -3067,8 +3068,8 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = info.activityInfo.packageName; final PackageSetting ps = mSettings.getPackageLPr(packageName); if (ps.getInstantApp(userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, instantApps, flags, userId)) { if (DEBUG_INSTANT) { Slog.v(TAG, "Instant app approved for intent; pkg: " + packageName); Loading Loading @@ -3995,8 +3996,8 @@ public class PackageManagerService extends IPackageManager.Stub if (ps != null) { // only check domain verification status if the app is not a browser if (!info.handleAllWebDataURI) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, resolvedActivities, flags, userId)) { if (DEBUG_INSTANT) { Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName + ", approved"); Loading Loading @@ -9575,7 +9576,7 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = ri.activityInfo.packageName; final PackageSetting ps = mSettings.getPackageLPr(packageName); if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { intent, query, flags, userId)) { return ri; } } Loading Loading @@ -9632,10 +9633,10 @@ public class PackageManagerService extends IPackageManager.Stub */ private static boolean hasAnyDomainApproval( @NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting, @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId) > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE; @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { return manager.approvalLevelForDomain(pkgSetting, intent, candidates, resolveInfoFlags, userId) > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE; } /** services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan */ @ApprovalLevel int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId); /** Loading services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +3 −1 Original line number Diff line number Diff line Loading @@ -1494,9 +1494,11 @@ public class DomainVerificationService extends SystemService @Override public int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { String packageName = pkgSetting.getName(); if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, candidates, resolveInfoFlags)) { if (DEBUG_APPROVAL) { debugApproval(packageName, intent, userId, false, "not valid intent"); } Loading services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java +57 −4 Original line number Diff line number Diff line Loading @@ -22,12 +22,17 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.os.Binder; import com.android.internal.util.CollectionUtils; import com.android.server.compat.PlatformCompat; import com.android.server.pm.PackageManagerService; import com.android.server.pm.parsing.pkg.AndroidPackage; import java.util.List; import java.util.Set; public final class DomainVerificationUtils { /** Loading @@ -40,13 +45,61 @@ public final class DomainVerificationUtils { throw new NameNotFoundException("Package " + packageName + " unavailable"); } public static boolean isDomainVerificationIntent(Intent intent, int resolveInfoFlags) { if (!intent.isWebIntent() || !intent.hasCategory(Intent.CATEGORY_BROWSABLE)) { public static boolean isDomainVerificationIntent(Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags) { if (!intent.isWebIntent()) { return false; } Set<String> categories = intent.getCategories(); int categoriesSize = CollectionUtils.size(categories); if (categoriesSize > 2) { // Specifying at least one non-app-link category return false; } else if (categoriesSize == 2) { // Check for explicit app link intent with exactly BROWSABLE && DEFAULT return intent.hasCategory(Intent.CATEGORY_DEFAULT) && intent.hasCategory(Intent.CATEGORY_BROWSABLE); } return ((resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0) || intent.hasCategory(Intent.CATEGORY_DEFAULT); // In cases where at least one browser is resolved and only one non-browser is resolved, // the Intent is coerced into an app links intent, under the assumption the browser can // be skipped if the app is approved at any level for the domain. boolean foundBrowser = false; boolean foundOneApp = false; final int candidatesSize = candidates.size(); for (int index = 0; index < candidatesSize; index++) { final ResolveInfo info = candidates.get(index); if (info.handleAllWebDataURI) { foundBrowser = true; } else if (foundOneApp) { // Already true, so duplicate app foundOneApp = false; break; } else { foundOneApp = true; } } boolean matchDefaultByFlags = (resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0; boolean onlyOneNonBrowser = foundBrowser && foundOneApp; // Check if matches (BROWSABLE || none) && DEFAULT if (categoriesSize == 0) { // No categories, run coerce case, matching DEFAULT by flags return onlyOneNonBrowser && matchDefaultByFlags; } else if (intent.hasCategory(Intent.CATEGORY_DEFAULT)) { // Run coerce case, matching by explicit DEFAULT return onlyOneNonBrowser; } else if (intent.hasCategory(Intent.CATEGORY_BROWSABLE)) { // Intent matches BROWSABLE, must match DEFAULT by flags return matchDefaultByFlags; } else { // Otherwise not matching any app link categories return false; } } static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg, Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +13 −12 Original line number Diff line number Diff line Loading @@ -2636,7 +2636,8 @@ public class PackageManagerService extends IPackageManager.Stub // We'll want to include browser possibilities in a few cases boolean includeBrowser = false; if (!DomainVerificationUtils.isDomainVerificationIntent(intent, matchFlags)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, candidates, matchFlags)) { result.addAll(undefinedList); // Maybe add one for the other profile. if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel Loading Loading @@ -2820,8 +2821,8 @@ public class PackageManagerService extends IPackageManager.Stub } result.highestApprovalLevel = Math.max(mDomainVerificationManager .approvalLevelForDomain(ps, intent, flags, riTargetUser.targetUserId), result.highestApprovalLevel); .approvalLevelForDomain(ps, intent, resultTargetUser, flags, riTargetUser.targetUserId), result.highestApprovalLevel); } if (result != null && result.highestApprovalLevel <= DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE) { Loading Loading @@ -3067,8 +3068,8 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = info.activityInfo.packageName; final PackageSetting ps = mSettings.getPackageLPr(packageName); if (ps.getInstantApp(userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, instantApps, flags, userId)) { if (DEBUG_INSTANT) { Slog.v(TAG, "Instant app approved for intent; pkg: " + packageName); Loading Loading @@ -3995,8 +3996,8 @@ public class PackageManagerService extends IPackageManager.Stub if (ps != null) { // only check domain verification status if the app is not a browser if (!info.handleAllWebDataURI) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, resolvedActivities, flags, userId)) { if (DEBUG_INSTANT) { Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName + ", approved"); Loading Loading @@ -9575,7 +9576,7 @@ public class PackageManagerService extends IPackageManager.Stub final String packageName = ri.activityInfo.packageName; final PackageSetting ps = mSettings.getPackageLPr(packageName); if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags, userId)) { intent, query, flags, userId)) { return ri; } } Loading Loading @@ -9632,10 +9633,10 @@ public class PackageManagerService extends IPackageManager.Stub */ private static boolean hasAnyDomainApproval( @NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting, @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId) > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE; @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { return manager.approvalLevelForDomain(pkgSetting, intent, candidates, resolveInfoFlags, userId) > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE; } /**
services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +1 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,7 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan */ @ApprovalLevel int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId); /** Loading
services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +3 −1 Original line number Diff line number Diff line Loading @@ -1494,9 +1494,11 @@ public class DomainVerificationService extends SystemService @Override public int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) { String packageName = pkgSetting.getName(); if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, candidates, resolveInfoFlags)) { if (DEBUG_APPROVAL) { debugApproval(packageName, intent, userId, false, "not valid intent"); } Loading
services/core/java/com/android/server/pm/verify/domain/DomainVerificationUtils.java +57 −4 Original line number Diff line number Diff line Loading @@ -22,12 +22,17 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.os.Binder; import com.android.internal.util.CollectionUtils; import com.android.server.compat.PlatformCompat; import com.android.server.pm.PackageManagerService; import com.android.server.pm.parsing.pkg.AndroidPackage; import java.util.List; import java.util.Set; public final class DomainVerificationUtils { /** Loading @@ -40,13 +45,61 @@ public final class DomainVerificationUtils { throw new NameNotFoundException("Package " + packageName + " unavailable"); } public static boolean isDomainVerificationIntent(Intent intent, int resolveInfoFlags) { if (!intent.isWebIntent() || !intent.hasCategory(Intent.CATEGORY_BROWSABLE)) { public static boolean isDomainVerificationIntent(Intent intent, @NonNull List<ResolveInfo> candidates, @PackageManager.ResolveInfoFlags int resolveInfoFlags) { if (!intent.isWebIntent()) { return false; } Set<String> categories = intent.getCategories(); int categoriesSize = CollectionUtils.size(categories); if (categoriesSize > 2) { // Specifying at least one non-app-link category return false; } else if (categoriesSize == 2) { // Check for explicit app link intent with exactly BROWSABLE && DEFAULT return intent.hasCategory(Intent.CATEGORY_DEFAULT) && intent.hasCategory(Intent.CATEGORY_BROWSABLE); } return ((resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0) || intent.hasCategory(Intent.CATEGORY_DEFAULT); // In cases where at least one browser is resolved and only one non-browser is resolved, // the Intent is coerced into an app links intent, under the assumption the browser can // be skipped if the app is approved at any level for the domain. boolean foundBrowser = false; boolean foundOneApp = false; final int candidatesSize = candidates.size(); for (int index = 0; index < candidatesSize; index++) { final ResolveInfo info = candidates.get(index); if (info.handleAllWebDataURI) { foundBrowser = true; } else if (foundOneApp) { // Already true, so duplicate app foundOneApp = false; break; } else { foundOneApp = true; } } boolean matchDefaultByFlags = (resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0; boolean onlyOneNonBrowser = foundBrowser && foundOneApp; // Check if matches (BROWSABLE || none) && DEFAULT if (categoriesSize == 0) { // No categories, run coerce case, matching DEFAULT by flags return onlyOneNonBrowser && matchDefaultByFlags; } else if (intent.hasCategory(Intent.CATEGORY_DEFAULT)) { // Run coerce case, matching by explicit DEFAULT return onlyOneNonBrowser; } else if (intent.hasCategory(Intent.CATEGORY_BROWSABLE)) { // Intent matches BROWSABLE, must match DEFAULT by flags return matchDefaultByFlags; } else { // Otherwise not matching any app link categories return false; } } static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg, Loading