Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 807e01cb authored by Tony Mak's avatar Tony Mak
Browse files

Introduce ONLY_IF_NO_MATCH_FOUND in CrossProfileIntentFilter

With this flag, activities in other profiles can respond to the intent
only if no intent-filter with non-negative priority in current profile can
respond to it.
It is designed like this because activities with negative priority
intentfilter are always used as a fallback in case no one can respond
to the intent. In this case, we expect there is a "real" activity in
other profiles can handle the intentfilter

Here is the example activity that handle the call related intents when
there is no dialer.

NonPhoneActivity.java in Contacts app is an example.
https://github.com/android/platform_packages_apps_contacts/blob/master/AndroidManifest.xml#L461

Bug: 25760508

Change-Id: Ife2a7c19e91ddf5d2e81ad09bd4cf712cdcdb986
parent 08998124
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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)
@@ -4629,7 +4637,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,
+26 −8
Original line number Diff line number Diff line
@@ -4833,15 +4833,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)) {
                    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);
@@ -4974,6 +4980,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;
@@ -5177,10 +5191,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
@@ -5190,8 +5204,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,