Loading services/core/java/com/android/server/pm/AppsFilterBase.java +37 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading services/core/java/com/android/server/pm/AppsFilterImpl.java +105 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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 * <permission>} 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 * <uses-permission>} 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. Loading Loading @@ -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 Loading Loading @@ -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() Loading Loading @@ -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()); } Loading services/core/java/com/android/server/pm/AppsFilterLocked.java +9 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading Loading @@ -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) { Loading services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +255 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/pm/AppsFilterBase.java +37 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading
services/core/java/com/android/server/pm/AppsFilterImpl.java +105 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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 * <permission>} 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 * <uses-permission>} 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. Loading Loading @@ -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 Loading Loading @@ -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() Loading Loading @@ -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()); } Loading
services/core/java/com/android/server/pm/AppsFilterLocked.java +9 −1 Original line number Diff line number Diff line Loading @@ -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}; Loading Loading @@ -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) { Loading
services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading
services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +255 −85 File changed.Preview size limit exceeded, changes collapsed. Show changes