Merge "Update app links resolution to handle no category Intents" into sc-dev

This commit is contained in:
Winson Chiu
2021-03-02 03:23:34 +00:00
committed by Android (Google) Code Review
4 changed files with 74 additions and 17 deletions

View File

@@ -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
@@ -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) {
@@ -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);
@@ -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");
@@ -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;
}
}
@@ -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;
}
/**

View File

@@ -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);
/**

View File

@@ -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");
}

View File

@@ -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 {
/**
@@ -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;
}
return ((resolveInfoFlags & PackageManager.MATCH_DEFAULT_ONLY) != 0)
|| intent.hasCategory(Intent.CATEGORY_DEFAULT);
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);
}
// 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,