summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageManager.java11
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java34
2 files changed, 36 insertions, 9 deletions
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index aa960a400ebb..abd4c28d9f1c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -259,6 +259,14 @@ public abstract class PackageManager {
*/
public static final int SKIP_CURRENT_PROFILE = 0x00000002;
+ /**
+ * Flag for {@link addCrossProfileIntentFilter}: if this flag is set:
+ * activities in the other profiles can respond to the intent only if no activity with
+ * non-negative priority in current profile can respond to the intent.
+ * @hide
+ */
+ public static final int ONLY_IF_NO_MATCH_FOUND = 0x00000004;
+
/** @hide */
@IntDef({PERMISSION_GRANTED, PERMISSION_DENIED})
@Retention(RetentionPolicy.SOURCE)
@@ -4636,7 +4644,8 @@ public abstract class PackageManager {
* @param filter The {@link IntentFilter} the intent has to match
* @param sourceUserId The source user id.
* @param targetUserId The target user id.
- * @param flags The only possible value is {@link SKIP_CURRENT_PROFILE}
+ * @param flags The possible values are {@link SKIP_CURRENT_PROFILE} and
+ * {@link ONLY_IF_NO_MATCH_FOUND}.
* @hide
*/
public abstract void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId,
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8ef8276967dc..6f1991175f32 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4868,15 +4868,21 @@ public class PackageManagerService extends IPackageManager.Stub {
// Check for results in the current profile.
List<ResolveInfo> result = mActivities.queryIntent(
intent, resolvedType, flags, userId);
+ result = filterIfNotSystemUser(result, userId);
// Check for cross profile results.
+ boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents(
- matchingFilters, intent, resolvedType, flags, userId);
+ matchingFilters, intent, resolvedType, flags, userId,
+ hasNonNegativePriorityResult);
if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
- result.add(xpResolveInfo);
- Collections.sort(result, mResolvePrioritySorter);
+ boolean isVisibleToUser = filterIfNotSystemUser(
+ Collections.singletonList(xpResolveInfo), userId).size() > 0;
+ if (isVisibleToUser) {
+ result.add(xpResolveInfo);
+ Collections.sort(result, mResolvePrioritySorter);
+ }
}
- result = filterIfNotSystemUser(result, userId);
if (hasWebURI(intent)) {
CrossProfileDomainInfo xpDomainInfo = null;
final UserInfo parent = getProfileParent(userId);
@@ -5009,6 +5015,14 @@ public class PackageManagerService extends IPackageManager.Stub {
return resolveInfos;
}
+ /**
+ * @param resolveInfos list of resolve infos in descending priority order
+ * @return if the list contains a resolve info with non-negative priority
+ */
+ private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
+ return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
+ }
+
private static boolean hasWebURI(Intent intent) {
if (intent.getData() == null) {
return false;
@@ -5212,10 +5226,10 @@ public class PackageManagerService extends IPackageManager.Stub {
return null;
}
- // Return matching ResolveInfo if any for skip current profile intent filters.
+ // Return matching ResolveInfo in target user if any.
private ResolveInfo queryCrossProfileIntents(
List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
- int flags, int sourceUserId) {
+ int flags, int sourceUserId, boolean matchInCurrentProfile) {
if (matchingFilters != null) {
// Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
// match the same intent. For performance reasons, it is better not to
@@ -5225,8 +5239,12 @@ public class PackageManagerService extends IPackageManager.Stub {
for (int i = 0; i < size; i++) {
CrossProfileIntentFilter filter = matchingFilters.get(i);
int targetUserId = filter.getTargetUserId();
- if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) == 0
- && !alreadyTriedUserIds.get(targetUserId)) {
+ boolean skipCurrentProfile =
+ (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
+ boolean skipCurrentProfileIfNoMatchFound =
+ (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
+ if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
+ && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
// Checking if there are activities in the target user that can handle the
// intent.
ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,