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

Commit 5c302db3 authored by Lee Shombert's avatar Lee Shombert
Browse files

WatchedIntentResolver now uses WatchedIntentFilter

Bug: 181964615

Convert WatchedIntentResolver to use WatchedIntentFilter instead of
IntentFilter.  WatchedIntentFilters are converted back to
IntentFilters when they are used in APIs.  The final conversion to
WatchedIntentFilter in PackageManagerService happens in a follow-up
commit.

Test: atest
 * FrameworksServicesTests:WatchedIntentHandlingTest
 * FrameworksServicesTests:AppsFilterTest
 * FrameworksServicesTests:PackageInstallerSessionTest
 * FrameworksServicesTests:PackageManagerServiceTest
 * FrameworksServicesTests:PackageManagerSettingsTests
 * FrameworksServicesTests:ScanTests
 * FrameworksServicesTests:UserSystemPackageInstallerTest
 * PackageManagerServiceBootTest
 * UserLifecycleTests#startUser
 * UserLifecycleTests#stopUser
 * UserLifecycleTests#switchUser
 * android.appsecurity.cts.EphemeralTest
 * android.appsecurity.cts.InstantAppUserTest
 * FrameworksServicesTests:WatcherTest
 * CtsContentTestCases:IntentFilterTest
 * CtsDynamicMimeHostTestCases
 * FrameworksServicesTests:WatcherTest

Change-Id: Iba80142b44268443221c22b5626fc53d60f2aa9f
parent 4d2eee78
Loading
Loading
Loading
Loading
+23 −11
Original line number Diff line number Diff line
@@ -839,33 +839,45 @@ public abstract class IntentResolver<F, R extends Object> {
        }
    };

    // Method to take the snapshot of an F.
    protected F snapshot(F f) {
        return f;
    }

    // Helper method to copy some of the maps.
    private static <E> void copyInto(ArrayMap<String, E[]> l, ArrayMap<String, E[]> r) {
    protected void copyInto(ArrayMap<String, F[]> l, ArrayMap<String, F[]> r) {
        final int end = r.size();
        l.clear();
        l.ensureCapacity(end);
        for (int i = 0; i < end; i++) {
            final E[] val = r.valueAt(i);
            final F[] val = r.valueAt(i);
            final String key = r.keyAt(i);
            l.put(key, Arrays.copyOf(val, val.length));
            final F[] newval = Arrays.copyOf(val, val.length);
            for (int j = 0; j < newval.length; j++) {
                newval[j] = snapshot(newval[j]);
            }
            l.put(key, newval);
        }
    }

    protected void copyInto(ArraySet<F> l, ArraySet<F> r) {
        l.clear();
        final int end = r.size();
        l.ensureCapacity(end);
        for (int i = 0; i < end; i++) {
            l.append(snapshot(r.valueAt(i)));
        }
    }

    // Make <this> a copy of <orig>.  The presumption is that <this> is empty but all
    // arrays are cleared out explicitly, just to be sure.
    protected void copyFrom(IntentResolver orig) {
        mFilters.clear();
        mFilters.addAll(orig.mFilters);
        mTypeToFilter.clear();
        copyInto(mFilters, orig.mFilters);
        copyInto(mTypeToFilter, orig.mTypeToFilter);
        mBaseTypeToFilter.clear();
        copyInto(mBaseTypeToFilter, orig.mBaseTypeToFilter);
        mWildTypeToFilter.clear();
        copyInto(mWildTypeToFilter, orig.mWildTypeToFilter);
        mSchemeToFilter.clear();
        copyInto(mSchemeToFilter, orig.mSchemeToFilter);
        mActionToFilter.clear();
        copyInto(mActionToFilter, orig.mActionToFilter);
        mTypedActionToFilter.clear();
        copyInto(mTypedActionToFilter, orig.mTypedActionToFilter);
    }

+28 −2
Original line number Diff line number Diff line
@@ -19,10 +19,13 @@ package com.android.server;
import android.annotation.NonNull;
import android.annotation.Nullable;

import com.android.server.pm.WatchedIntentFilter;
import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.Watcher;

import java.util.ArrayList;
import java.util.List;

/**
@@ -31,9 +34,9 @@ import java.util.List;
 * @param <R> The resolver type.
 * {@hide}
 */
public abstract class WatchedIntentResolver<F, R extends Object>
public abstract class WatchedIntentResolver<F extends Watchable, R extends Object>
        extends IntentResolver<F, R>
        implements Watchable {
        implements Watchable, Snappable {

    /**
     * Watchable machinery
@@ -78,6 +81,13 @@ public abstract class WatchedIntentResolver<F, R extends Object>
        mWatchable.dispatchChange(what);
    }

    private final Watcher mWatcher = new Watcher() {
            @Override
            public void onChange(@Nullable Watchable what) {
                dispatchChange(what);
            }
        };

    /**
     * Notify listeners that this object has changed.
     */
@@ -88,17 +98,20 @@ public abstract class WatchedIntentResolver<F, R extends Object>
    @Override
    public void addFilter(F f) {
        super.addFilter(f);
        f.registerObserver(mWatcher);
        onChanged();
    }

    @Override
    public void removeFilter(F f) {
        f.unregisterObserver(mWatcher);
        super.removeFilter(f);
        onChanged();
    }

    @Override
    protected void removeFilterInternal(F f) {
        f.unregisterObserver(mWatcher);
        super.removeFilterInternal(f);
        onChanged();
    }
@@ -109,4 +122,17 @@ public abstract class WatchedIntentResolver<F, R extends Object>
        super.sortResults(results);
        onChanged();
    }

    /**
     * @see IntentResolver#findFilters(IntentFilter)
     */
    public ArrayList<F> findFilters(WatchedIntentFilter matching) {
        return super.findFilters(matching.getIntentFilter());
    }

    // Make <this> a copy of <orig>.  The presumption is that <this> is empty but all
    // arrays are cleared out explicitly, just to be sure.
    protected void copyFrom(WatchedIntentResolver orig) {
        super.copyFrom(orig);
    }
}
+40 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;

import com.android.internal.util.XmlUtils;
import com.android.server.utils.SnapshotCache;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -35,7 +36,7 @@ import java.io.IOException;
 * If an {@link Intent} matches the {@link CrossProfileIntentFilter}, then activities in the user
 * {@link #mTargetUserId} can access it.
 */
class CrossProfileIntentFilter extends IntentFilter {
class CrossProfileIntentFilter extends WatchedIntentFilter {
    private static final String ATTR_TARGET_USER_ID = "targetUserId";
    private static final String ATTR_FLAGS = "flags";
    private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
@@ -48,12 +49,41 @@ class CrossProfileIntentFilter extends IntentFilter {
    final String mOwnerPackage; // packageName of the app.
    final int mFlags;

    // The cache for snapshots, so they are not rebuilt if the base object has not
    // changed.
    final SnapshotCache<CrossProfileIntentFilter> mSnapshot;

    private SnapshotCache makeCache() {
        return new SnapshotCache<CrossProfileIntentFilter>(this, this) {
            @Override
            public CrossProfileIntentFilter createSnapshot() {
                CrossProfileIntentFilter s = new CrossProfileIntentFilter(mSource);
                s.seal();
                return s;
            }};
    }

    CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int targetUserId,
            int flags) {
        super(filter);
        mTargetUserId = targetUserId;
        mOwnerPackage = ownerPackage;
        mFlags = flags;
        mSnapshot = makeCache();
    }

    CrossProfileIntentFilter(WatchedIntentFilter filter, String ownerPackage, int targetUserId,
            int flags) {
        this(filter.mFilter, ownerPackage, targetUserId, flags);
    }

    // Copy constructor used only to create a snapshot.
    private CrossProfileIntentFilter(CrossProfileIntentFilter f) {
        super(f);
        mTargetUserId = f.mTargetUserId;
        mOwnerPackage = f.mOwnerPackage;
        mFlags = f.mFlags;
        mSnapshot = new SnapshotCache.Sealed();
    }

    public int getTargetUserId() {
@@ -72,6 +102,7 @@ class CrossProfileIntentFilter extends IntentFilter {
        mTargetUserId = parser.getAttributeInt(null, ATTR_TARGET_USER_ID, UserHandle.USER_NULL);
        mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, "");
        mFlags = parser.getAttributeInt(null, ATTR_FLAGS, 0);
        mSnapshot = makeCache();

        int outerDepth = parser.getDepth();
        String tagName = parser.getName();
@@ -94,7 +125,7 @@ class CrossProfileIntentFilter extends IntentFilter {
            }
        }
        if (tagName.equals(ATTR_FILTER)) {
            readFromXml(parser);
            mFilter.readFromXml(parser);
        } else {
            String msg = "Missing element under " + TAG + ": " + ATTR_FILTER +
                    " at " + parser.getPositionDescription();
@@ -103,7 +134,8 @@ class CrossProfileIntentFilter extends IntentFilter {
        }
    }

    String getStringFromXml(TypedXmlPullParser parser, String attribute, String defaultValue) {
    private String getStringFromXml(TypedXmlPullParser parser, String attribute,
            String defaultValue) {
        String value = parser.getAttributeValue(null, attribute);
        if (value == null) {
            String msg = "Missing element under " + TAG +": " + attribute + " at " +
@@ -120,7 +152,7 @@ class CrossProfileIntentFilter extends IntentFilter {
        serializer.attributeInt(null, ATTR_FLAGS, mFlags);
        serializer.attribute(null, ATTR_OWNER_PACKAGE, mOwnerPackage);
        serializer.startTag(null, ATTR_FILTER);
            super.writeToXml(serializer);
        mFilter.writeToXml(serializer);
        serializer.endTag(null, ATTR_FILTER);
    }

@@ -135,4 +167,8 @@ class CrossProfileIntentFilter extends IntentFilter {
                && mOwnerPackage.equals(other.mOwnerPackage)
                && mFlags == other.mFlags;
    }

    public CrossProfileIntentFilter snapshot() {
        return mSnapshot.snapshot();
    }
}
+30 −4
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.IntentFilter;

import com.android.server.WatchedIntentResolver;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;

import java.util.List;

@@ -47,7 +48,34 @@ class CrossProfileIntentResolver

    @Override
    protected IntentFilter getIntentFilter(@NonNull CrossProfileIntentFilter input) {
        return input;
        return input.getIntentFilter();
    }

    CrossProfileIntentResolver() {
        mSnapshot = makeCache();
    }

    // Take the snapshot of F
    protected CrossProfileIntentFilter snapshot(CrossProfileIntentFilter f) {
        return (f == null) ? null : f.snapshot();
    }

    // Copy constructor used only to create a snapshot.
    private CrossProfileIntentResolver(CrossProfileIntentResolver f) {
        copyFrom(f);
        mSnapshot = new SnapshotCache.Sealed();
    }

    // The cache for snapshots, so they are not rebuilt if the base object has not
    // changed.
    final SnapshotCache<CrossProfileIntentResolver> mSnapshot;

    private SnapshotCache makeCache() {
        return new SnapshotCache<CrossProfileIntentResolver>(this, this) {
            @Override
            public CrossProfileIntentResolver createSnapshot() {
                return new CrossProfileIntentResolver(mSource);
            }};
    }

    /**
@@ -56,8 +84,6 @@ class CrossProfileIntentResolver
     * @return A snapshot of the current object.
     */
    public CrossProfileIntentResolver snapshot() {
        CrossProfileIntentResolver result = new CrossProfileIntentResolver();
        result.copyFrom(this);
        return result;
        return mSnapshot.snapshot();
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -3484,8 +3484,8 @@ public class PackageManagerService extends IPackageManager.Stub
                for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
                    if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
                            & ApplicationInfo.FLAG_SUSPENDED) == 0) {
                        return createForwardingResolveInfoUnchecked(filter, sourceUserId,
                                targetUserId);
                        return createForwardingResolveInfoUnchecked(filter.getIntentFilter(),
                              sourceUserId, targetUserId);
                    }
                }
            }
@@ -22243,7 +22243,7 @@ public class PackageManagerService extends IPackageManager.Stub
                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
                                    && pa.mPref.mAlways)) {
                        if (outFilters != null) {
                            outFilters.add(new IntentFilter(pa));
                            outFilters.add(new IntentFilter(pa.getIntentFilter()));
                        }
                        if (outActivities != null) {
                            outActivities.add(pa.mPref.mComponent);
Loading