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

Commit ad047f83 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Grant package visibility to dependent library" into sc-dev am: 0446108e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13698352

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I41d8144e100681173d4070cd06bbfa862bde8a38
parents 7adde2ff 0446108e
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -104,6 +104,12 @@ public class AppsFilter implements Watchable, Snappable {
     */
    private final SparseSetArray<Integer> mQueriesViaComponent = new SparseSetArray<>();

    /**
     * A mapping from the set of App IDs that query other App IDs via library name to the
     * list of packages that they can see.
     */
    private final SparseSetArray<Integer> mQueryableViaUsesLibrary = new SparseSetArray<>();

    /**
     * Executor for running reasonably short background tasks such as building the initial
     * visibility cache.
@@ -239,6 +245,7 @@ public class AppsFilter implements Watchable, Snappable {
        Snapshots.copy(mImplicitlyQueryable, orig.mImplicitlyQueryable);
        Snapshots.copy(mQueriesViaPackage, orig.mQueriesViaPackage);
        Snapshots.copy(mQueriesViaComponent, orig.mQueriesViaComponent);
        Snapshots.copy(mQueryableViaUsesLibrary, orig.mQueryableViaUsesLibrary);
        mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute;
        mForceQueryable.addAll(orig.mForceQueryable);
        mForceQueryableByDevicePackageNames = orig.mForceQueryableByDevicePackageNames;
@@ -508,6 +515,22 @@ public class AppsFilter implements Watchable, Snappable {
        return false;
    }

    private static boolean canQueryViaUsesLibrary(AndroidPackage querying,
            AndroidPackage potentialTarget) {
        if (potentialTarget.getLibraryNames().isEmpty()) {
            return false;
        }
        final List<String> libNames = potentialTarget.getLibraryNames();
        for (int i = 0, size = libNames.size(); i < size; i++) {
            final String libName = libNames.get(i);
            if (querying.getUsesLibraries().contains(libName)
                    || querying.getUsesOptionalLibraries().contains(libName)) {
                return true;
            }
        }
        return false;
    }

    private static boolean matchesProviders(
            Set<String> queriesAuthorities, AndroidPackage potentialTarget) {
        for (int p = ArrayUtils.size(potentialTarget.getProviders()) - 1; p >= 0; p--) {
@@ -707,6 +730,9 @@ public class AppsFilter implements Watchable, Snappable {
                        || canQueryAsInstaller(existingSetting, newPkg)) {
                    mQueriesViaPackage.add(existingSetting.appId, newPkgSetting.appId);
                }
                if (canQueryViaUsesLibrary(existingPkg, newPkg)) {
                    mQueryableViaUsesLibrary.add(existingSetting.appId, newPkgSetting.appId);
                }
            }
            // now we'll evaluate our new package's ability to see existing packages
            if (!mForceQueryable.contains(existingSetting.appId)) {
@@ -718,6 +744,9 @@ public class AppsFilter implements Watchable, Snappable {
                        || canQueryAsInstaller(newPkgSetting, existingPkg)) {
                    mQueriesViaPackage.add(newPkgSetting.appId, existingSetting.appId);
                }
                if (canQueryViaUsesLibrary(newPkg, existingPkg)) {
                    mQueryableViaUsesLibrary.add(newPkgSetting.appId, existingSetting.appId);
                }
            }
            // if either package instruments the other, mark both as visible to one another
            if (newPkgSetting.pkg != null && existingSetting.pkg != null
@@ -1035,6 +1064,10 @@ public class AppsFilter implements Watchable, Snappable {
            for (int i = mQueriesViaPackage.size() - 1; i >= 0; i--) {
                mQueriesViaPackage.remove(mQueriesViaPackage.keyAt(i), setting.appId);
            }
            mQueryableViaUsesLibrary.remove(setting.appId);
            for (int i = mQueryableViaUsesLibrary.size() - 1; i >= 0; i--) {
                mQueryableViaUsesLibrary.remove(mQueryableViaUsesLibrary.keyAt(i), setting.appId);
            }

            mForceQueryable.remove(setting.appId);

@@ -1315,6 +1348,18 @@ public class AppsFilter implements Watchable, Snappable {
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }

            try {
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesLibrary");
                if (mQueryableViaUsesLibrary.contains(callingAppId, targetAppId)) {
                    if (DEBUG_LOGGING) {
                        log(callingSetting, targetPkgSetting, "queryable for library users");
                    }
                    return false;
                }
            } finally {
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }

            return true;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -1394,6 +1439,8 @@ public class AppsFilter implements Watchable, Snappable {
                    filteringAppId == null ? null : UserHandle.getUid(user, filteringAppId),
                    mImplicitlyQueryable, "      ", expandPackages);
        }
        pw.println("  queryable via uses-library:");
        dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesLibrary, "    ", expandPackages);
    }

    private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
+117 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.Signature;
import android.content.pm.UserInfo;
import android.content.pm.parsing.ParsingPackage;
@@ -141,6 +142,10 @@ public class AppsFilterTest {
        return pkg(packageName).addReceiver(receiver);
    }

    private static ParsingPackage pkgWithSharedLibrary(String packageName, String libName) {
        return pkg(packageName).addLibraryName(libName);
    }

    private static ParsedActivity createActivity(String packageName, IntentFilter[] filters) {
        ParsedActivity activity = new ParsedActivity();
        activity.setPackageName(packageName);
@@ -412,6 +417,118 @@ public class AppsFilterTest {
                SYSTEM_USER));
    }

    @Test
    public void testNoUsesLibrary_Filters() throws Exception {
        final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                mMockExecutor);

        simulateAddBasicAndroid(appsFilter);
        appsFilter.onSystemReady();

        final Signature mockSignature = Mockito.mock(Signature.class);
        final SigningDetails mockSigningDetails = new SigningDetails(
                new Signature[]{mockSignature},
                SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2);

        final PackageSetting target = simulateAddPackage(appsFilter,
                pkgWithSharedLibrary("com.some.package", "com.some.shared_library"),
                DUMMY_TARGET_APPID,
                setting -> setting.setSigningDetails(mockSigningDetails)
                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
        final PackageSetting calling = simulateAddPackage(appsFilter,
                pkg("com.some.other.package"), DUMMY_CALLING_APPID);

        assertTrue(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
                SYSTEM_USER));
    }

    @Test
    public void testUsesLibrary_DoesntFilter() throws Exception {
        final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                mMockExecutor);

        simulateAddBasicAndroid(appsFilter);
        appsFilter.onSystemReady();

        final Signature mockSignature = Mockito.mock(Signature.class);
        final SigningDetails mockSigningDetails = new SigningDetails(
                new Signature[]{mockSignature},
                SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2);

        final PackageSetting target = simulateAddPackage(appsFilter,
                pkgWithSharedLibrary("com.some.package", "com.some.shared_library"),
                DUMMY_TARGET_APPID,
                setting -> setting.setSigningDetails(mockSigningDetails)
                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
        final PackageSetting calling = simulateAddPackage(appsFilter,
                pkg("com.some.other.package").addUsesLibrary("com.some.shared_library"),
                DUMMY_CALLING_APPID);

        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
                SYSTEM_USER));
    }

    @Test
    public void testUsesOptionalLibrary_DoesntFilter() throws Exception {
        final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                mMockExecutor);

        simulateAddBasicAndroid(appsFilter);
        appsFilter.onSystemReady();

        final Signature mockSignature = Mockito.mock(Signature.class);
        final SigningDetails mockSigningDetails = new SigningDetails(
                new Signature[]{mockSignature},
                SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2);

        final PackageSetting target = simulateAddPackage(appsFilter,
                pkgWithSharedLibrary("com.some.package", "com.some.shared_library"),
                DUMMY_TARGET_APPID,
                setting -> setting.setSigningDetails(mockSigningDetails)
                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
        final PackageSetting calling = simulateAddPackage(appsFilter,
                pkg("com.some.other.package").addUsesOptionalLibrary("com.some.shared_library"),
                DUMMY_CALLING_APPID);

        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
                SYSTEM_USER));
    }

    @Test
    public void testUsesLibrary_ShareUid_DoesntFilter() throws Exception {
        final AppsFilter appsFilter = new AppsFilter(mStateProvider, mFeatureConfigMock,
                new String[]{}, /* systemAppsQueryable */ false, /* overlayProvider */ null,
                mMockExecutor);

        simulateAddBasicAndroid(appsFilter);
        appsFilter.onSystemReady();

        final Signature mockSignature = Mockito.mock(Signature.class);
        final SigningDetails mockSigningDetails = new SigningDetails(
                new Signature[]{mockSignature},
                SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2);

        final PackageSetting target = simulateAddPackage(appsFilter,
                pkgWithSharedLibrary("com.some.package", "com.some.shared_library"),
                DUMMY_TARGET_APPID,
                setting -> setting.setSigningDetails(mockSigningDetails)
                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM));
        final PackageSetting calling = simulateAddPackage(appsFilter,
                pkg("com.some.other.package_a").setSharedUserId("com.some.uid"),
                DUMMY_CALLING_APPID);
        simulateAddPackage(appsFilter, pkg("com.some.other.package_b")
                .setSharedUserId("com.some.uid").addUsesLibrary("com.some.shared_library"),
                DUMMY_CALLING_APPID);

        // Although package_a doesn't use library, it should be granted visibility. It's because
        // package_a shares userId with package_b, and package_b uses that shared library.
        assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_APPID, calling, target,
                SYSTEM_USER));
    }

    @Test
    public void testForceQueryable_SystemDoesntFilter() throws Exception {
        final AppsFilter appsFilter =