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

Commit 03ae7ccd authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add a permissions filter in AppsFilter"

parents fa6099a6 3fd950c5
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -127,6 +127,16 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
    @NonNull
    protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesLibrarySnapshot;

    /**
     * A mapping from the set of App IDs that query other App IDs via custom permissions to the
     * list of packages that they can see.
     */
    @NonNull
    @Watched
    protected WatchedSparseSetArray<Integer> mQueryableViaUsesPermission;
    @NonNull
    protected SnapshotCache<WatchedSparseSetArray<Integer>> mQueryableViaUsesPermissionSnapshot;

    /**
     * Handler for running reasonably short background tasks such as building the initial
     * visibility cache.
@@ -217,6 +227,10 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
        return mQueryableViaUsesLibrary.contains(callingAppId, targetAppId);
    }

    protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
        return mQueryableViaUsesPermission.contains(callingAppId, targetAppId);
    }

    protected boolean isQueryableViaComponentWhenRequireRecompute(
            ArrayMap<String, ? extends PackageStateInternal> existingSettings,
            PackageStateInternal callingPkgSetting,
@@ -628,6 +642,22 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
                }
            }

            try {
                if (DEBUG_TRACING) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "mQueryableViaUsesPermission");
                }
                if (isQueryableViaUsesPermission(callingAppId, targetAppId)) {
                    if (DEBUG_LOGGING) {
                        log(callingSetting, targetPkgSetting, "queryable for permission users");
                    }
                    return false;
                }
            } finally {
                if (DEBUG_TRACING) {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
            }

            return true;
        } finally {
            if (DEBUG_TRACING) {
@@ -763,6 +793,13 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot {
                expandPackages);
    }

    protected void dumpQueriesViaUsesPermission(PrintWriter pw, @Nullable Integer filteringAppId,
            ToString<Integer> expandPackages) {
        pw.println("  queryable via uses-permission:");
        dumpQueriesMap(pw, filteringAppId, mQueryableViaUsesPermission, "    ",
                expandPackages);
    }

    private static void dumpQueriesMap(PrintWriter pw, @Nullable Integer filteringId,
            WatchedSparseSetArray<Integer> queriesMap, String spacing,
            @Nullable ToString<Integer> toString) {
+105 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedPermission;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.Watchable;
@@ -68,8 +70,11 @@ import com.android.server.utils.Watcher;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Implementation of the methods that update the internal structures of AppsFilter. Because of the
@@ -89,6 +94,26 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
     */
    private final WatchableImpl mWatchable = new WatchableImpl();

    /**
     * A cache that maps parsed {@link android.R.styleable#AndroidManifestPermission
     * &lt;permission&gt;} to the packages that define them. While computing visibility based on
     * permissions, this cache is used to save the cost of reading through every existing package
     * to determine the App Ids that define a particular permission.
     */
    @GuardedBy("mQueryableViaUsesPermissionLock")
    @NonNull
    private HashMap<String, Set<Integer>> mPermissionToUids;

    /**
     * A cache that maps parsed {@link android.R.styleable#AndroidManifestUsesPermission
     * &lt;uses-permission&gt;} to the packages that request them. While computing visibility based
     * on permissions, this cache is used to save the cost of reading through every existing
     * package to determine the App Ids that request a particular permission.
     */
    @GuardedBy("mQueryableViaUsesPermissionLock")
    @NonNull
    private HashMap<String, Set<Integer>> mUsesPermissionToUids;

    /**
     * Ensures an observer is in the list, exactly once. The observer cannot be null.  The
     * function quietly returns if the observer is already in the list.
@@ -179,12 +204,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
        mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Auto<>(
                mQueryableViaUsesLibrary, mQueryableViaUsesLibrary,
                "AppsFilter.mQueryableViaUsesLibrary");
        mQueryableViaUsesPermission = new WatchedSparseSetArray<>();
        mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Auto<>(
                mQueryableViaUsesPermission, mQueryableViaUsesPermission,
                "AppsFilter.mQueryableViaUsesPermission");
        mForceQueryable = new WatchedArraySet<>();
        mForceQueryableSnapshot = new SnapshotCache.Auto<>(
                mForceQueryable, mForceQueryable, "AppsFilter.mForceQueryable");
        mProtectedBroadcasts = new WatchedArrayList<>();
        mProtectedBroadcastsSnapshot = new SnapshotCache.Auto<>(
                mProtectedBroadcasts, mProtectedBroadcasts, "AppsFilter.mProtectedBroadcasts");
        mPermissionToUids = new HashMap<>();
        mUsesPermissionToUids = new HashMap<>();

        mSnapshot = new SnapshotCache<AppsFilterSnapshot>(this, this) {
            @Override
@@ -532,6 +563,54 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
            }
        }

        if (!newPkg.getUsesPermissions().isEmpty()) {
            // newPkg requests some permissions
            synchronized (mQueryableViaUsesPermissionLock) {
                for (ParsedUsesPermission usesPermission : newPkg.getUsesPermissions()) {
                    String usesPermissionName = usesPermission.getName();
                    // Lookup in the mPermissionToUids cache if installed packages have
                    // defined this permission.
                    if (mPermissionToUids.containsKey(usesPermissionName)) {
                        for (int targetAppId : mPermissionToUids.get(usesPermissionName)) {
                            if (targetAppId != newPkgSetting.getAppId()) {
                                mQueryableViaUsesPermission.add(newPkgSetting.getAppId(),
                                        targetAppId);
                            }
                        }
                    }
                    // Record in mUsesPermissionToUids that a permission was requested
                    // by a new package
                    if (!mUsesPermissionToUids.containsKey(usesPermissionName)) {
                        mUsesPermissionToUids.put(usesPermissionName, new HashSet<>());
                    }
                    mUsesPermissionToUids.get(usesPermissionName).add(newPkgSetting.getAppId());
                }
            }
        }
        if (!newPkg.getPermissions().isEmpty()) {
            synchronized (mQueryableViaUsesPermissionLock) {
                // newPkg defines some permissions
                for (ParsedPermission permission : newPkg.getPermissions()) {
                    String permissionName = permission.getName();
                    // Lookup in the mUsesPermissionToUids cache if installed packages have
                    // requested this permission.
                    if (mUsesPermissionToUids.containsKey(permissionName)) {
                        for (int queryingAppId : mUsesPermissionToUids.get(permissionName)) {
                            if (queryingAppId != newPkgSetting.getAppId()) {
                                mQueryableViaUsesPermission.add(queryingAppId,
                                        newPkgSetting.getAppId());
                            }
                        }
                    }
                    // Record in mPermissionToUids that a permission was defined by a new package
                    if (!mPermissionToUids.containsKey(permissionName)) {
                        mPermissionToUids.put(permissionName, new HashSet<>());
                    }
                    mPermissionToUids.get(permissionName).add(newPkgSetting.getAppId());
                }
            }
        }

        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            final PackageStateInternal existingSetting = existingSettings.valueAt(i);
            if (existingSetting.getAppId() == newPkgSetting.getAppId()
@@ -960,6 +1039,32 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable,
            }
        }

        synchronized (mQueryableViaUsesPermissionLock) {
            if (setting.getPkg() != null && !setting.getPkg().getPermissions().isEmpty()) {
                for (ParsedPermission permission : setting.getPkg().getPermissions()) {
                    String permissionName = permission.getName();
                    if (mPermissionToUids.containsKey(permissionName)) {
                        mPermissionToUids.get(permissionName).remove(setting.getAppId());
                        if (mPermissionToUids.get(permissionName).isEmpty()) {
                            mPermissionToUids.remove(permissionName);
                        }
                    }
                }
            }
            if (setting.getPkg() != null && !setting.getPkg().getUsesPermissions().isEmpty()) {
                for (ParsedUsesPermission usesPermission : setting.getPkg().getUsesPermissions()) {
                    String usesPermissionName = usesPermission.getName();
                    if (mUsesPermissionToUids.containsKey(usesPermissionName)) {
                        mUsesPermissionToUids.get(usesPermissionName).remove(setting.getAppId());
                        if (mUsesPermissionToUids.get(usesPermissionName).isEmpty()) {
                            mUsesPermissionToUids.remove(usesPermissionName);
                        }
                    }
                }
            }
            mQueryableViaUsesPermission.remove(setting.getAppId());
        }

        synchronized (mForceQueryableLock) {
            mForceQueryable.remove(setting.getAppId());
        }
+9 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ abstract class AppsFilterLocked extends AppsFilterBase {
    protected final Object mImplicitlyQueryableLock = new Object();
    protected final Object mQueryableViaUsesLibraryLock = new Object();
    protected final Object mProtectedBroadcastsLock = new Object();
    protected final Object mQueryableViaUsesPermissionLock = new Object();

    /**
     * Guards the access for {@link AppsFilterBase#mShouldFilterCache};
@@ -85,6 +86,13 @@ abstract class AppsFilterLocked extends AppsFilterBase {
        }
    }

    @Override
    protected boolean isQueryableViaUsesPermission(int callingAppId, int targetAppId) {
        synchronized (mQueryableViaUsesPermissionLock) {
            return super.isQueryableViaUsesPermission(callingAppId, targetAppId);
        }
    }

    @Override
    protected boolean shouldFilterApplicationUsingCache(int callingUid, int appId, int userId) {
        synchronized (mCacheLock) {
+4 −0
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase {
            mQueryableViaUsesLibrary = orig.mQueryableViaUsesLibrarySnapshot.snapshot();
        }
        mQueryableViaUsesLibrarySnapshot = new SnapshotCache.Sealed<>();
        synchronized (orig.mQueryableViaUsesPermissionLock) {
            mQueryableViaUsesPermission = orig.mQueryableViaUsesPermissionSnapshot.snapshot();
        }
        mQueryableViaUsesPermissionSnapshot = new SnapshotCache.Sealed<>();
        synchronized (orig.mForceQueryableLock) {
            mForceQueryable = orig.mForceQueryableSnapshot.snapshot();
        }
+255 −85

File changed.

Preview size limit exceeded, changes collapsed.