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

Commit 57137289 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Fix issue #17082301: replacePreferredActivity is ignoring userId" into lmp-dev

parents 49e057d7 f2ac2761
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -564,6 +564,11 @@ public class IntentFilter implements Parcelable {
        return mDataTypes != null && findMimeType(type);
    }

    /** @hide */
    public final boolean hasExactDataType(String type) {
        return mDataTypes != null && mDataTypes.contains(type);
    }

    /**
     * Return the number of data types in the filter.
     */
@@ -681,6 +686,20 @@ public class IntentFilter implements Parcelable {
            return mPort;
        }

        /** @hide */
        public boolean match(AuthorityEntry other) {
            if (mWild != other.mWild) {
                return false;
            }
            if (!mHost.equals(other.mHost)) {
                return false;
            }
            if (mPort != other.mPort) {
                return false;
            }
            return true;
        }

        /**
         * Determine whether this AuthorityEntry matches the given data Uri.
         * <em>Note that this comparison is case-sensitive, unlike formal
@@ -792,6 +811,21 @@ public class IntentFilter implements Parcelable {
        return false;
    }

    /** @hide */
    public final boolean hasDataSchemeSpecificPart(PatternMatcher ssp) {
        if (mDataSchemeSpecificParts == null) {
            return false;
        }
        final int numDataSchemeSpecificParts = mDataSchemeSpecificParts.size();
        for (int i = 0; i < numDataSchemeSpecificParts; i++) {
            final PatternMatcher pe = mDataSchemeSpecificParts.get(i);
            if (pe.getType() == ssp.getType() && pe.getPath().equals(ssp.getPath())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return an iterator over the filter's data scheme specific parts.
     */
@@ -860,6 +894,20 @@ public class IntentFilter implements Parcelable {
        return matchDataAuthority(data) >= 0;
    }

    /** @hide */
    public final boolean hasDataAuthority(AuthorityEntry auth) {
        if (mDataAuthorities == null) {
            return false;
        }
        final int numDataAuthorities = mDataAuthorities.size();
        for (int i = 0; i < numDataAuthorities; i++) {
            if (mDataAuthorities.get(i).match(auth)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return an iterator over the filter's data authorities.
     */
@@ -942,6 +990,21 @@ public class IntentFilter implements Parcelable {
        return false;
    }

    /** @hide */
    public final boolean hasDataPath(PatternMatcher path) {
        if (mDataPaths == null) {
            return false;
        }
        final int numDataPaths = mDataPaths.size();
        for (int i = 0; i < numDataPaths; i++) {
            final PatternMatcher pe = mDataPaths.get(i);
            if (pe.getType() == path.getType() && pe.getPath().equals(path.getPath())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return an iterator over the filter's data paths.
     */
+118 −0
Original line number Diff line number Diff line
@@ -69,6 +69,124 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
        }
    }

    private boolean filterEquals(IntentFilter f1, IntentFilter f2) {
        int s1 = f1.countActions();
        int s2 = f2.countActions();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasAction(f1.getAction(i))) {
                return false;
            }
        }
        s1 = f1.countCategories();
        s2 = f2.countCategories();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasCategory(f1.getCategory(i))) {
                return false;
            }
        }
        s1 = f1.countDataTypes();
        s2 = f2.countDataTypes();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasExactDataType(f1.getDataType(i))) {
                return false;
            }
        }
        s1 = f1.countDataSchemes();
        s2 = f2.countDataSchemes();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasDataScheme(f1.getDataScheme(i))) {
                return false;
            }
        }
        s1 = f1.countDataAuthorities();
        s2 = f2.countDataAuthorities();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasDataAuthority(f1.getDataAuthority(i))) {
                return false;
            }
        }
        s1 = f1.countDataPaths();
        s2 = f2.countDataPaths();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasDataPath(f1.getDataPath(i))) {
                return false;
            }
        }
        s1 = f1.countDataSchemeSpecificParts();
        s2 = f2.countDataSchemeSpecificParts();
        if (s1 != s2) {
            return false;
        }
        for (int i=0; i<s1; i++) {
            if (!f2.hasDataSchemeSpecificPart(f1.getDataSchemeSpecificPart(i))) {
                return false;
            }
        }
        return true;
    }

    private ArrayList<F> collectFilters(F[] array, IntentFilter matching) {
        ArrayList<F> res = null;
        if (array != null) {
            for (int i=0; i<array.length; i++) {
                F cur = array[i];
                if (cur == null) {
                    break;
                }
                if (filterEquals(cur, matching)) {
                    if (res == null) {
                        res = new ArrayList<>();
                    }
                    res.add(cur);
                }
            }
        }
        return res;
    }

    public ArrayList<F> findFilters(IntentFilter matching) {
        if (matching.countDataSchemes() == 1) {
            // Fast case.
            return collectFilters(mSchemeToFilter.get(matching.getDataScheme(0)), matching);
        } else if (matching.countDataTypes() != 0 && matching.countActions() == 1) {
            // Another fast case.
            return collectFilters(mTypedActionToFilter.get(matching.getAction(0)), matching);
        } else if (matching.countDataTypes() == 0 && matching.countDataSchemes() == 0
                && matching.countActions() == 1) {
            // Last fast case.
            return collectFilters(mActionToFilter.get(matching.getAction(0)), matching);
        } else {
            ArrayList<F> res = null;
            for (F cur : mFilters) {
                if (filterEquals(cur, matching)) {
                    if (res == null) {
                        res = new ArrayList<>();
                    }
                    res.add(cur);
                }
            }
            return res;
        }
    }

    public void removeFilter(F f) {
        removeFilterInternal(f);
        mFilters.remove(f);
+56 −22
Original line number Diff line number Diff line
@@ -2931,7 +2931,8 @@ public class PackageManagerService extends IPackageManager.Stub {
        findPreferredActivity(intent, resolvedType,
                flags, query, 0, false, true, false, userId);
        // Add the new activity as the last chosen for this filter
        addPreferredActivityInternal(filter, match, null, activity, false, userId);
        addPreferredActivityInternal(filter, match, null, activity, false, userId,
                "Setting last chosen");
    }
    @Override
@@ -11473,11 +11474,13 @@ public class PackageManagerService extends IPackageManager.Stub {
    @Override
    public void addPreferredActivity(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, int userId) {
        addPreferredActivityInternal(filter, match, set, activity, true, userId);
        addPreferredActivityInternal(filter, match, set, activity, true, userId,
                "Adding preferred");
    }
    private void addPreferredActivityInternal(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, boolean always, int userId) {
            ComponentName[] set, ComponentName activity, boolean always, int userId,
            String opname) {
        // writer
        int callingUid = Binder.getCallingUid();
        enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
@@ -11499,10 +11502,11 @@ public class PackageManagerService extends IPackageManager.Stub {
                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
            }
            Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
                    + userId + ":");
            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
            mSettings.editPreferredActivitiesLPw(userId).addFilter(
                    new PreferredActivity(filter, match, set, activity, always));
            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
            mSettings.writePackageRestrictionsLPr(userId);
        }
    }
@@ -11525,7 +11529,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        final int callingUid = Binder.getCallingUid();
        enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
        final int callingUserId = UserHandle.getUserId(callingUid);
        synchronized (mPackages) {
            if (mContext.checkCallingOrSelfPermission(
                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -11540,30 +11543,61 @@ public class PackageManagerService extends IPackageManager.Stub {
                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
            }
            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
            if (pir != null) {
                Intent intent = new Intent(filter.getAction(0)).addCategory(filter.getCategory(0));
                if (filter.countDataSchemes() == 1) {
                    Uri.Builder builder = new Uri.Builder();
                    builder.scheme(filter.getDataScheme(0));
                    intent.setData(builder.build());
                }
                List<PreferredActivity> matches = pir.queryIntent(
                        intent, null, true, callingUserId);
                // Get all of the existing entries that exactly match this filter.
                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
                if (existing != null && existing.size() == 1) {
                    PreferredActivity cur = existing.get(0);
                    if (DEBUG_PREFERRED) {
                        Slog.i(TAG, "Checking replace of preferred:");
                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                        if (!cur.mPref.mAlways) {
                            Slog.i(TAG, "  -- CUR; not mAlways!");
                        } else {
                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
                            Slog.i(TAG, "  -- CUR: mSet="
                                    + Arrays.toString(cur.mPref.mSetComponents));
                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
                            Slog.i(TAG, "  -- NEW: mMatch="
                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
                        }
                    }
                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
                            && cur.mPref.sameSet(set)) {
                        if (DEBUG_PREFERRED) {
                    Slog.i(TAG, matches.size() + " preferred matches for " + intent);
                            Slog.i(TAG, "Replacing with same preferred activity "
                                    + cur.mPref.mShortComponent + " for user "
                                    + userId + ":");
                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                        } else {
                            Slog.i(TAG, "Replacing with same preferred activity "
                                    + cur.mPref.mShortComponent + " for user "
                                    + userId);
                        }
                        return;
                    }
                for (int i = 0; i < matches.size(); i++) {
                    PreferredActivity pa = matches.get(i);
                }
                if (DEBUG_PREFERRED) {
                        Slog.i(TAG, "Removing preferred activity "
                                + pa.mPref.mComponent + ":");
                    Slog.i(TAG, existing.size() + " existing preferred matches for:");
                    filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                }
                for (int i = 0; i < existing.size(); i++) {
                    PreferredActivity pa = existing.get(i);
                    if (DEBUG_PREFERRED) {
                        Slog.i(TAG, "Removing existing preferred activity "
                                + pa.mPref.mComponent + ":");
                        pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
                    }
                    pir.removeFilter(pa);
                }
            }
            addPreferredActivityInternal(filter, match, set, activity, true, callingUserId);
            addPreferredActivityInternal(filter, match, set, activity, true, userId,
                    "Replacing preferred");
        }
    }
+31 −5
Original line number Diff line number Diff line
@@ -44,10 +44,10 @@ public class PreferredComponent {
    // Whether this is to be the one that's always chosen. If false, it's the most recently chosen.
    public boolean mAlways;

    private final String[] mSetPackages;
    private final String[] mSetClasses;
    private final String[] mSetComponents;
    private final String mShortComponent;
    final String[] mSetPackages;
    final String[] mSetClasses;
    final String[] mSetComponents;
    final String mShortComponent;
    private String mParseError;

    private final Callbacks mCallbacks;
@@ -193,7 +193,12 @@ public class PreferredComponent {
    }

    public boolean sameSet(List<ResolveInfo> query, int priority) {
        if (mSetPackages == null) return false;
        if (mSetPackages == null) {
            return query == null;
        }
        if (query == null) {
            return false;
        }
        final int NQ = query.size();
        final int NS = mSetPackages.length;
        int numMatch = 0;
@@ -215,6 +220,27 @@ public class PreferredComponent {
        return numMatch == NS;
    }

    public boolean sameSet(ComponentName[] comps) {
        if (mSetPackages == null) return false;
        final int NQ = comps.length;
        final int NS = mSetPackages.length;
        int numMatch = 0;
        for (int i=0; i<NQ; i++) {
            ComponentName cn = comps[i];
            boolean good = false;
            for (int j=0; j<NS; j++) {
                if (mSetPackages[j].equals(cn.getPackageName())
                        && mSetClasses[j].equals(cn.getClassName())) {
                    numMatch++;
                    good = true;
                    break;
                }
            }
            if (!good) return false;
        }
        return numMatch == NS;
    }

    public void dump(PrintWriter out, String prefix, Object ident) {
        out.print(prefix); out.print(
                Integer.toHexString(System.identityHashCode(ident)));