Fix domain verification CATEGORY_DEFAULT check

The category is actually not added to startActivity Intents
automatically, instead relying on the MATCH_DEFAULT_ONLY flag being set.
This updates the Intent validity check to match.

Bug: 179683649

Test: manual, launch without DEFAULT, with MATCH_DEFAULT_ONLY

Change-Id: I00b78d596ee05c5a4a228771bbf8082af2b0ab8a
This commit is contained in:
Winson
2021-02-25 17:29:21 -08:00
parent 0f47704827
commit 1ad90d5a2d
4 changed files with 34 additions and 28 deletions

View File

@@ -1960,9 +1960,10 @@ public class PackageManagerService extends IPackageManager.Stub
boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid); boolean isInstantAppInternal(String packageName, @UserIdInt int userId, int callingUid);
boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid); boolean isInstantAppInternalBody(String packageName, @UserIdInt int userId, int callingUid);
boolean isInstantAppResolutionAllowed(Intent intent, List<ResolveInfo> resolvedActivities, boolean isInstantAppResolutionAllowed(Intent intent, List<ResolveInfo> resolvedActivities,
int userId, boolean skipPackageCheck); int userId, boolean skipPackageCheck, int flags);
boolean isInstantAppResolutionAllowedBody(Intent intent, boolean isInstantAppResolutionAllowedBody(Intent intent,
List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck); List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
int flags);
boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId, boolean isPersistentPreferredActivitySetByDpm(Intent intent, int userId,
String resolvedType, int flags); String resolvedType, int flags);
boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId); boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId);
@@ -2321,7 +2322,7 @@ public class PackageManagerService extends IPackageManager.Stub
result = filterIfNotSystemUser(mComponentResolver.queryActivities( result = filterIfNotSystemUser(mComponentResolver.queryActivities(
intent, resolvedType, flags, userId), userId); intent, resolvedType, flags, userId), userId);
addInstant = isInstantAppResolutionAllowed(intent, result, userId, addInstant = isInstantAppResolutionAllowed(intent, result, userId,
false /*skipPackageCheck*/); false /*skipPackageCheck*/, flags);
// Check for cross profile results. // Check for cross profile results.
boolean hasNonNegativePriorityResult = hasNonNegativePriority(result); boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents( xpResolveInfo = queryCrossProfileIntents(
@@ -2386,8 +2387,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (result == null || result.size() == 0) { if (result == null || result.size() == 0) {
// the caller wants to resolve for a particular package; however, there // the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result // were no installed results, so, try to find an ephemeral result
addInstant = isInstantAppResolutionAllowed( addInstant = isInstantAppResolutionAllowed(intent, null /*result*/, userId,
intent, null /*result*/, userId, true /*skipPackageCheck*/); true /*skipPackageCheck*/, flags);
if (result == null) { if (result == null) {
result = new ArrayList<>(); result = new ArrayList<>();
} }
@@ -2617,7 +2618,7 @@ public class PackageManagerService extends IPackageManager.Stub
// We'll want to include browser possibilities in a few cases // We'll want to include browser possibilities in a few cases
boolean includeBrowser = false; boolean includeBrowser = false;
if (!DomainVerificationUtils.isDomainVerificationIntent(intent)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, matchFlags)) {
result.addAll(undefinedList); result.addAll(undefinedList);
// Maybe add one for the other profile. // Maybe add one for the other profile.
if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel if (xpDomainInfo != null && xpDomainInfo.highestApprovalLevel
@@ -2801,7 +2802,7 @@ public class PackageManagerService extends IPackageManager.Stub
} }
result.highestApprovalLevel = Math.max(mDomainVerificationManager result.highestApprovalLevel = Math.max(mDomainVerificationManager
.approvalLevelForDomain(ps, intent, riTargetUser.targetUserId), .approvalLevelForDomain(ps, intent, flags, riTargetUser.targetUserId),
result.highestApprovalLevel); result.highestApprovalLevel);
} }
if (result != null && result.highestApprovalLevel if (result != null && result.highestApprovalLevel
@@ -3048,7 +3049,7 @@ public class PackageManagerService extends IPackageManager.Stub
final String packageName = info.activityInfo.packageName; final String packageName = info.activityInfo.packageName;
final PackageSetting ps = mSettings.getPackageLPr(packageName); final PackageSetting ps = mSettings.getPackageLPr(packageName);
if (ps.getInstantApp(userId)) { if (ps.getInstantApp(userId)) {
if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
userId)) { userId)) {
if (DEBUG_INSTANT) { if (DEBUG_INSTANT) {
Slog.v(TAG, "Instant app approved for intent; pkg: " Slog.v(TAG, "Instant app approved for intent; pkg: "
@@ -3927,7 +3928,7 @@ public class PackageManagerService extends IPackageManager.Stub
public boolean isInstantAppResolutionAllowed( public boolean isInstantAppResolutionAllowed(
Intent intent, List<ResolveInfo> resolvedActivities, int userId, Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) { boolean skipPackageCheck, int flags) {
if (mInstantAppResolverConnection == null) { if (mInstantAppResolverConnection == null) {
return false; return false;
} }
@@ -3960,14 +3961,14 @@ public class PackageManagerService extends IPackageManager.Stub
// Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
// Or if there's already an ephemeral app installed that handles the action // Or if there's already an ephemeral app installed that handles the action
return isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId, return isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
skipPackageCheck); skipPackageCheck, flags);
} }
// Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
// Or if there's already an ephemeral app installed that handles the action // Or if there's already an ephemeral app installed that handles the action
public boolean isInstantAppResolutionAllowedBody( public boolean isInstantAppResolutionAllowedBody(
Intent intent, List<ResolveInfo> resolvedActivities, int userId, Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) { boolean skipPackageCheck, int flags) {
final int count = (resolvedActivities == null ? 0 : resolvedActivities.size()); final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
for (int n = 0; n < count; n++) { for (int n = 0; n < count; n++) {
final ResolveInfo info = resolvedActivities.get(n); final ResolveInfo info = resolvedActivities.get(n);
@@ -3976,7 +3977,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (ps != null) { if (ps != null) {
// only check domain verification status if the app is not a browser // only check domain verification status if the app is not a browser
if (!info.handleAllWebDataURI) { if (!info.handleAllWebDataURI) {
if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, if (hasAnyDomainApproval(mDomainVerificationManager, ps, intent, flags,
userId)) { userId)) {
if (DEBUG_INSTANT) { if (DEBUG_INSTANT) {
Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName Slog.v(TAG, "DENY instant app;" + " pkg: " + packageName
@@ -4675,10 +4676,11 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
public boolean isInstantAppResolutionAllowedBody(Intent intent, public boolean isInstantAppResolutionAllowedBody(Intent intent,
List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck) { List<ResolveInfo> resolvedActivities, int userId, boolean skipPackageCheck,
int flags) {
synchronized (mLock) { synchronized (mLock) {
return super.isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId, return super.isInstantAppResolutionAllowedBody(intent, resolvedActivities, userId,
skipPackageCheck); skipPackageCheck, flags);
} }
} }
public int getPackageUidInternal(String packageName, int flags, int userId, public int getPackageUidInternal(String packageName, int flags, int userId,
@@ -9469,20 +9471,20 @@ public class PackageManagerService extends IPackageManager.Stub
private boolean isInstantAppResolutionAllowed( private boolean isInstantAppResolutionAllowed(
Intent intent, List<ResolveInfo> resolvedActivities, int userId, Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) { boolean skipPackageCheck, int flags) {
return liveComputer().isInstantAppResolutionAllowed( return liveComputer().isInstantAppResolutionAllowed(
intent, resolvedActivities, userId, intent, resolvedActivities, userId,
skipPackageCheck); skipPackageCheck, flags);
} }
// Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution. // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
// Or if there's already an ephemeral app installed that handles the action // Or if there's already an ephemeral app installed that handles the action
private boolean isInstantAppResolutionAllowedBody( private boolean isInstantAppResolutionAllowedBody(
Intent intent, List<ResolveInfo> resolvedActivities, int userId, Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) { boolean skipPackageCheck, int flags) {
return liveComputer().isInstantAppResolutionAllowedBody( return liveComputer().isInstantAppResolutionAllowedBody(
intent, resolvedActivities, userId, intent, resolvedActivities, userId,
skipPackageCheck); skipPackageCheck, flags);
} }
private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj, private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
@@ -9539,7 +9541,7 @@ public class PackageManagerService extends IPackageManager.Stub
final String packageName = ri.activityInfo.packageName; final String packageName = ri.activityInfo.packageName;
final PackageSetting ps = mSettings.getPackageLPr(packageName); final PackageSetting ps = mSettings.getPackageLPr(packageName);
if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps, if (ps != null && hasAnyDomainApproval(mDomainVerificationManager, ps,
intent, userId)) { intent, flags, userId)) {
return ri; return ri;
} }
} }
@@ -9596,8 +9598,9 @@ public class PackageManagerService extends IPackageManager.Stub
*/ */
private static boolean hasAnyDomainApproval( private static boolean hasAnyDomainApproval(
@NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting, @NonNull DomainVerificationManagerInternal manager, @NonNull PackageSetting pkgSetting,
@NonNull Intent intent, @UserIdInt int userId) { @NonNull Intent intent, @PackageManager.ResolveInfoFlags int resolveInfoFlags,
return manager.approvalLevelForDomain(pkgSetting, intent, userId) @UserIdInt int userId) {
return manager.approvalLevelForDomain(pkgSetting, intent, resolveInfoFlags, userId)
> DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE; > DomainVerificationManagerInternal.APPROVAL_LEVEL_NONE;
} }

View File

@@ -310,7 +310,7 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan
*/ */
@ApprovalLevel @ApprovalLevel
int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent,
@UserIdInt int userId); @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId);
/** /**
* @return the domain verification set ID for the given package, or null if the ID is * @return the domain verification set ID for the given package, or null if the ID is

View File

@@ -1346,9 +1346,9 @@ public class DomainVerificationService extends SystemService
@Override @Override
public int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent, public int approvalLevelForDomain(@NonNull PackageSetting pkgSetting, @NonNull Intent intent,
@UserIdInt int userId) { @PackageManager.ResolveInfoFlags int resolveInfoFlags, @UserIdInt int userId) {
String packageName = pkgSetting.name; String packageName = pkgSetting.name;
if (!DomainVerificationUtils.isDomainVerificationIntent(intent)) { if (!DomainVerificationUtils.isDomainVerificationIntent(intent, resolveInfoFlags)) {
if (DEBUG_APPROVAL) { if (DEBUG_APPROVAL) {
debugApproval(packageName, intent, userId, false, "not valid intent"); debugApproval(packageName, intent, userId, false, "not valid intent");
} }

View File

@@ -40,10 +40,13 @@ public final class DomainVerificationUtils {
throw new NameNotFoundException("Package " + packageName + " unavailable"); throw new NameNotFoundException("Package " + packageName + " unavailable");
} }
public static boolean isDomainVerificationIntent(Intent intent) { public static boolean isDomainVerificationIntent(Intent intent, int resolveInfoFlags) {
return intent.isWebIntent() if (!intent.isWebIntent() || !intent.hasCategory(Intent.CATEGORY_BROWSABLE)) {
&& intent.hasCategory(Intent.CATEGORY_BROWSABLE) return false;
&& intent.hasCategory(Intent.CATEGORY_DEFAULT); }
return ((resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0)
|| intent.hasCategory(Intent.CATEGORY_DEFAULT);
} }
static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg, static boolean isChangeEnabled(PlatformCompat platformCompat, AndroidPackage pkg,