Loading core/java/android/provider/Settings.java +5 −0 Original line number Diff line number Diff line Loading @@ -6421,6 +6421,10 @@ public final class Settings { */ public static final String PREFERRED_REGION = "preferred_region"; /** @hide */ public static final String HIDE_MICROG_PACKAGES_FOR_PACKAGE = "hide_microg_packages_for_package"; /** * Setting to enable camera flash notification feature. * <ul> Loading Loading @@ -6607,6 +6611,7 @@ public final class Settings { PRIVATE_SETTINGS.add(MOUSE_REVERSE_VERTICAL_SCROLLING); PRIVATE_SETTINGS.add(MOUSE_SWAP_PRIMARY_BUTTON); PRIVATE_SETTINGS.add(PREFERRED_REGION); PRIVATE_SETTINGS.add(HIDE_MICROG_PACKAGES_FOR_PACKAGE); } /** Loading packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java +15 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.provider.settings.validators.SettingsValidators.FONT_SCALE import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_FLOAT_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.VIBRATION_INTENSITY_VALIDATOR; import static android.view.PointerIcon.DEFAULT_POINTER_SCALE; Loading Loading @@ -268,5 +269,19 @@ public class SystemSettingsValidators { VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ALL, BOOLEAN_VALIDATOR); VALIDATORS.put(System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED, BOOLEAN_VALIDATOR); VALIDATORS.put(System.PREFERRED_REGION, ANY_STRING_VALIDATOR); VALIDATORS.put(System.HIDE_MICROG_PACKAGES_FOR_PACKAGE, value -> { if (value == null) { return true; } for (String packageName : value.split(",")) { final String trimmedPackageName = packageName.trim(); if (trimmedPackageName.isEmpty() || !PACKAGE_NAME_VALIDATOR.validate(trimmedPackageName)) { return false; } } return true; }); } } services/core/java/com/android/server/pm/AppsFilterBase.java +89 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected static final String TAG = "AppsFilter"; private static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms"; private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending"; private static final String GOOGLE_SERVICES_FRAMEWORK_PACKAGE = "com.google.android.gsf"; // Logs all filtering instead of enforcing protected static final boolean DEBUG_ALLOW_ALL = false; Loading Loading @@ -199,11 +202,81 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected volatile boolean mCacheReady = false; protected volatile boolean mCacheEnabled = true; protected volatile boolean mNeedToUpdateCacheForImplicitAccess = false; @NonNull protected volatile SparseArray<ArraySet<String>> mHideMicrogPackagesForCallerByUser = new SparseArray<>(); protected static final boolean CACHE_VALID = true; protected static final boolean CACHE_INVALID = false; protected final AtomicBoolean mCacheValid = new AtomicBoolean(CACHE_INVALID); protected static SparseArray<ArraySet<String>> copyPackageNamesByUser( @NonNull SparseArray<ArraySet<String>> packageNamesByUser) { final SparseArray<ArraySet<String>> copy = new SparseArray<>(packageNamesByUser.size()); for (int i = 0; i < packageNamesByUser.size(); i++) { final ArraySet<String> packageNames = packageNamesByUser.valueAt(i); copy.put(packageNamesByUser.keyAt(i), packageNames == null ? null : new ArraySet<>(packageNames)); } return copy; } private static boolean isMicrogPackageHiddenByConfig(@NonNull String packageName) { return GOOGLE_PLAY_SERVICES_PACKAGE.equals(packageName) || GOOGLE_PLAY_STORE_PACKAGE.equals(packageName) || GOOGLE_SERVICES_FRAMEWORK_PACKAGE.equals(packageName); } private boolean shouldHideMicrogPackagesForCaller(int callingUserId, @Nullable String[] callingPackageNames, @NonNull String targetPackageName) { if (!isMicrogPackageHiddenByConfig(targetPackageName)) { return false; } final ArraySet<String> configuredPackageNames = mHideMicrogPackagesForCallerByUser.get(callingUserId); if (configuredPackageNames == null || configuredPackageNames.isEmpty() || callingPackageNames == null) { return false; } for (String callingPackageName : callingPackageNames) { if (configuredPackageNames.contains(callingPackageName)) { return true; } } return false; } private boolean shouldHideMicrogPackagesForCaller(int callingUid, @Nullable PackageStateInternal callingPkgSetting, @NonNull ArraySet<PackageStateInternal> callingSharedPkgSettings, @NonNull PackageStateInternal targetPkgSetting) { if (!isMicrogPackageHiddenByConfig(targetPkgSetting.getPackageName())) { return false; } final ArraySet<String> configuredPackageNames = mHideMicrogPackagesForCallerByUser.get(UserHandle.getUserId(callingUid)); if (configuredPackageNames == null || configuredPackageNames.isEmpty()) { return false; } if (callingPkgSetting != null) { return configuredPackageNames.contains(callingPkgSetting.getPackageName()); } for (int i = 0; i < callingSharedPkgSettings.size(); i++) { if (configuredPackageNames.contains( callingSharedPkgSettings.valueAt(i).getPackageName())) { return true; } } return false; } protected boolean isForceQueryable(int callingAppId) { return mForceQueryable.contains(callingAppId); } Loading Loading @@ -342,6 +415,13 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { || callingAppId == targetPkgSetting.getAppId()) { return false; } else if (Process.isSdkSandboxUid(callingAppId)) { final Computer computer = (Computer) snapshot; if (shouldHideMicrogPackagesForCaller(UserHandle.getUserId(callingUid), computer.getPackagesForUid(Process.getAppUidForSdkSandboxUid(callingUid)), targetPkgSetting.getPackageName())) { return true; } final int targetAppId = targetPkgSetting.getAppId(); final int targetUid = UserHandle.getUid(userId, targetAppId); // we only allow sdk sandbox processes access to forcequeryable packages or Loading Loading @@ -453,6 +533,15 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } if (shouldHideMicrogPackagesForCaller(callingUid, callingPkgSetting, callingSharedPkgSettings, targetPkgSetting)) { if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, "hidden package by microg config"); } return true; } if (callingPkgSetting != null) { if (callingPkgSetting.getPkg() != null && !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) { Loading services/core/java/com/android/server/pm/AppsFilterImpl.java +83 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseSetArray; Loading Loading @@ -496,6 +497,62 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT); } public void updateHiddenMicrogPackagesConfig(Computer snapshot, @NonNull SparseArray<ArraySet<String>> packageNamesByUser) { final SparseArray<ArraySet<String>> oldPackageNamesByUser = mHideMicrogPackagesForCallerByUser; final SparseArray<ArraySet<String>> newPackageNamesByUser = copyPackageNamesByUser(packageNamesByUser); if (samePackageNamesByUser(oldPackageNamesByUser, newPackageNamesByUser)) { return; } mHideMicrogPackagesForCallerByUser = newPackageNamesByUser; if (mCacheReady) { for (UserInfo userInfo : snapshot.getUserInfos()) { final int userId = userInfo.id; if (!Objects.equals(oldPackageNamesByUser.get(userId), newPackageNamesByUser.get(userId))) { updateEntireShouldFilterCache(snapshot, userId); } } } onChanged(); } public void updateHiddenMicrogPackagesConfig(Computer snapshot, @UserIdInt int userId, @Nullable ArraySet<String> packageNames) { final SparseArray<ArraySet<String>> oldPackageNamesByUser = mHideMicrogPackagesForCallerByUser; final ArraySet<String> oldPackageNames = oldPackageNamesByUser.get(userId); final ArraySet<String> newPackageNames = packageNames == null ? null : new ArraySet<>(packageNames); if (Objects.equals(oldPackageNames, newPackageNames)) { return; } final SparseArray<ArraySet<String>> newPackageNamesByUser = copyPackageNamesByUser(oldPackageNamesByUser); if (newPackageNames == null || newPackageNames.isEmpty()) { newPackageNamesByUser.remove(userId); } else { newPackageNamesByUser.put(userId, newPackageNames); } mHideMicrogPackagesForCallerByUser = newPackageNamesByUser; if (mCacheReady && hasUser(snapshot.getUserInfos(), userId)) { updateEntireShouldFilterCache(snapshot, userId); } onChanged(); } /** * Adds a package that should be considered when filtering visibility between apps. * Loading Loading @@ -1295,4 +1352,30 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED, eventId, appId, latency, userCount, packageCount, mShouldFilterCache.size()); } private static boolean samePackageNamesByUser( @NonNull SparseArray<ArraySet<String>> oldPackageNamesByUser, @NonNull SparseArray<ArraySet<String>> newPackageNamesByUser) { if (oldPackageNamesByUser.size() != newPackageNamesByUser.size()) { return false; } for (int i = 0; i < oldPackageNamesByUser.size(); i++) { final int userId = oldPackageNamesByUser.keyAt(i); if (!Objects.equals(oldPackageNamesByUser.valueAt(i), newPackageNamesByUser.get(userId))) { return false; } } return true; } private static boolean hasUser(@NonNull UserInfo[] users, @UserIdInt int userId) { for (UserInfo user : users) { if (user.id == userId) { return true; } } return false; } } services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -57,9 +57,13 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase { } mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; mHideMicrogPackagesForCallerByUser = copyPackageNamesByUser(orig.mHideMicrogPackagesForCallerByUser); mForceQueryableByDevicePackageNames = Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, orig.mForceQueryableByDevicePackageNames.length); mSystemAppsQueryable = orig.mSystemAppsQueryable; mFeatureConfig = orig.mFeatureConfig.snapshot(); mOverlayReferenceMapper = orig.mOverlayReferenceMapper; Loading Loading
core/java/android/provider/Settings.java +5 −0 Original line number Diff line number Diff line Loading @@ -6421,6 +6421,10 @@ public final class Settings { */ public static final String PREFERRED_REGION = "preferred_region"; /** @hide */ public static final String HIDE_MICROG_PACKAGES_FOR_PACKAGE = "hide_microg_packages_for_package"; /** * Setting to enable camera flash notification feature. * <ul> Loading Loading @@ -6607,6 +6611,7 @@ public final class Settings { PRIVATE_SETTINGS.add(MOUSE_REVERSE_VERTICAL_SCROLLING); PRIVATE_SETTINGS.add(MOUSE_SWAP_PRIMARY_BUTTON); PRIVATE_SETTINGS.add(PREFERRED_REGION); PRIVATE_SETTINGS.add(HIDE_MICROG_PACKAGES_FOR_PACKAGE); } /** Loading
packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java +15 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import static android.provider.settings.validators.SettingsValidators.FONT_SCALE import static android.provider.settings.validators.SettingsValidators.LENIENT_IP_ADDRESS_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_FLOAT_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.NON_NEGATIVE_INTEGER_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.PACKAGE_NAME_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.URI_VALIDATOR; import static android.provider.settings.validators.SettingsValidators.VIBRATION_INTENSITY_VALIDATOR; import static android.view.PointerIcon.DEFAULT_POINTER_SCALE; Loading Loading @@ -268,5 +269,19 @@ public class SystemSettingsValidators { VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ALL, BOOLEAN_VALIDATOR); VALIDATORS.put(System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED, BOOLEAN_VALIDATOR); VALIDATORS.put(System.PREFERRED_REGION, ANY_STRING_VALIDATOR); VALIDATORS.put(System.HIDE_MICROG_PACKAGES_FOR_PACKAGE, value -> { if (value == null) { return true; } for (String packageName : value.split(",")) { final String trimmedPackageName = packageName.trim(); if (trimmedPackageName.isEmpty() || !PACKAGE_NAME_VALIDATOR.validate(trimmedPackageName)) { return false; } } return true; }); } }
services/core/java/com/android/server/pm/AppsFilterBase.java +89 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ import java.util.concurrent.atomic.AtomicBoolean; */ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected static final String TAG = "AppsFilter"; private static final String GOOGLE_PLAY_SERVICES_PACKAGE = "com.google.android.gms"; private static final String GOOGLE_PLAY_STORE_PACKAGE = "com.android.vending"; private static final String GOOGLE_SERVICES_FRAMEWORK_PACKAGE = "com.google.android.gsf"; // Logs all filtering instead of enforcing protected static final boolean DEBUG_ALLOW_ALL = false; Loading Loading @@ -199,11 +202,81 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { protected volatile boolean mCacheReady = false; protected volatile boolean mCacheEnabled = true; protected volatile boolean mNeedToUpdateCacheForImplicitAccess = false; @NonNull protected volatile SparseArray<ArraySet<String>> mHideMicrogPackagesForCallerByUser = new SparseArray<>(); protected static final boolean CACHE_VALID = true; protected static final boolean CACHE_INVALID = false; protected final AtomicBoolean mCacheValid = new AtomicBoolean(CACHE_INVALID); protected static SparseArray<ArraySet<String>> copyPackageNamesByUser( @NonNull SparseArray<ArraySet<String>> packageNamesByUser) { final SparseArray<ArraySet<String>> copy = new SparseArray<>(packageNamesByUser.size()); for (int i = 0; i < packageNamesByUser.size(); i++) { final ArraySet<String> packageNames = packageNamesByUser.valueAt(i); copy.put(packageNamesByUser.keyAt(i), packageNames == null ? null : new ArraySet<>(packageNames)); } return copy; } private static boolean isMicrogPackageHiddenByConfig(@NonNull String packageName) { return GOOGLE_PLAY_SERVICES_PACKAGE.equals(packageName) || GOOGLE_PLAY_STORE_PACKAGE.equals(packageName) || GOOGLE_SERVICES_FRAMEWORK_PACKAGE.equals(packageName); } private boolean shouldHideMicrogPackagesForCaller(int callingUserId, @Nullable String[] callingPackageNames, @NonNull String targetPackageName) { if (!isMicrogPackageHiddenByConfig(targetPackageName)) { return false; } final ArraySet<String> configuredPackageNames = mHideMicrogPackagesForCallerByUser.get(callingUserId); if (configuredPackageNames == null || configuredPackageNames.isEmpty() || callingPackageNames == null) { return false; } for (String callingPackageName : callingPackageNames) { if (configuredPackageNames.contains(callingPackageName)) { return true; } } return false; } private boolean shouldHideMicrogPackagesForCaller(int callingUid, @Nullable PackageStateInternal callingPkgSetting, @NonNull ArraySet<PackageStateInternal> callingSharedPkgSettings, @NonNull PackageStateInternal targetPkgSetting) { if (!isMicrogPackageHiddenByConfig(targetPkgSetting.getPackageName())) { return false; } final ArraySet<String> configuredPackageNames = mHideMicrogPackagesForCallerByUser.get(UserHandle.getUserId(callingUid)); if (configuredPackageNames == null || configuredPackageNames.isEmpty()) { return false; } if (callingPkgSetting != null) { return configuredPackageNames.contains(callingPkgSetting.getPackageName()); } for (int i = 0; i < callingSharedPkgSettings.size(); i++) { if (configuredPackageNames.contains( callingSharedPkgSettings.valueAt(i).getPackageName())) { return true; } } return false; } protected boolean isForceQueryable(int callingAppId) { return mForceQueryable.contains(callingAppId); } Loading Loading @@ -342,6 +415,13 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { || callingAppId == targetPkgSetting.getAppId()) { return false; } else if (Process.isSdkSandboxUid(callingAppId)) { final Computer computer = (Computer) snapshot; if (shouldHideMicrogPackagesForCaller(UserHandle.getUserId(callingUid), computer.getPackagesForUid(Process.getAppUidForSdkSandboxUid(callingUid)), targetPkgSetting.getPackageName())) { return true; } final int targetAppId = targetPkgSetting.getAppId(); final int targetUid = UserHandle.getUid(userId, targetAppId); // we only allow sdk sandbox processes access to forcequeryable packages or Loading Loading @@ -453,6 +533,15 @@ public abstract class AppsFilterBase implements AppsFilterSnapshot { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } if (shouldHideMicrogPackagesForCaller(callingUid, callingPkgSetting, callingSharedPkgSettings, targetPkgSetting)) { if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, "hidden package by microg config"); } return true; } if (callingPkgSetting != null) { if (callingPkgSetting.getPkg() != null && !mFeatureConfig.packageIsEnabled(callingPkgSetting.getPkg())) { Loading
services/core/java/com/android/server/pm/AppsFilterImpl.java +83 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import android.provider.DeviceConfig; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseSetArray; Loading Loading @@ -496,6 +497,62 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT); } public void updateHiddenMicrogPackagesConfig(Computer snapshot, @NonNull SparseArray<ArraySet<String>> packageNamesByUser) { final SparseArray<ArraySet<String>> oldPackageNamesByUser = mHideMicrogPackagesForCallerByUser; final SparseArray<ArraySet<String>> newPackageNamesByUser = copyPackageNamesByUser(packageNamesByUser); if (samePackageNamesByUser(oldPackageNamesByUser, newPackageNamesByUser)) { return; } mHideMicrogPackagesForCallerByUser = newPackageNamesByUser; if (mCacheReady) { for (UserInfo userInfo : snapshot.getUserInfos()) { final int userId = userInfo.id; if (!Objects.equals(oldPackageNamesByUser.get(userId), newPackageNamesByUser.get(userId))) { updateEntireShouldFilterCache(snapshot, userId); } } } onChanged(); } public void updateHiddenMicrogPackagesConfig(Computer snapshot, @UserIdInt int userId, @Nullable ArraySet<String> packageNames) { final SparseArray<ArraySet<String>> oldPackageNamesByUser = mHideMicrogPackagesForCallerByUser; final ArraySet<String> oldPackageNames = oldPackageNamesByUser.get(userId); final ArraySet<String> newPackageNames = packageNames == null ? null : new ArraySet<>(packageNames); if (Objects.equals(oldPackageNames, newPackageNames)) { return; } final SparseArray<ArraySet<String>> newPackageNamesByUser = copyPackageNamesByUser(oldPackageNamesByUser); if (newPackageNames == null || newPackageNames.isEmpty()) { newPackageNamesByUser.remove(userId); } else { newPackageNamesByUser.put(userId, newPackageNames); } mHideMicrogPackagesForCallerByUser = newPackageNamesByUser; if (mCacheReady && hasUser(snapshot.getUserInfos(), userId)) { updateEntireShouldFilterCache(snapshot, userId); } onChanged(); } /** * Adds a package that should be considered when filtering visibility between apps. * Loading Loading @@ -1295,4 +1352,30 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED, eventId, appId, latency, userCount, packageCount, mShouldFilterCache.size()); } private static boolean samePackageNamesByUser( @NonNull SparseArray<ArraySet<String>> oldPackageNamesByUser, @NonNull SparseArray<ArraySet<String>> newPackageNamesByUser) { if (oldPackageNamesByUser.size() != newPackageNamesByUser.size()) { return false; } for (int i = 0; i < oldPackageNamesByUser.size(); i++) { final int userId = oldPackageNamesByUser.keyAt(i); if (!Objects.equals(oldPackageNamesByUser.valueAt(i), newPackageNamesByUser.get(userId))) { return false; } } return true; } private static boolean hasUser(@NonNull UserInfo[] users, @UserIdInt int userId) { for (UserInfo user : users) { if (user.id == userId) { return true; } } return false; } }
services/core/java/com/android/server/pm/AppsFilterSnapshotImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -57,9 +57,13 @@ public final class AppsFilterSnapshotImpl extends AppsFilterBase { } mProtectedBroadcastsSnapshot = new SnapshotCache.Sealed<>(); mQueriesViaComponentRequireRecompute = orig.mQueriesViaComponentRequireRecompute; mHideMicrogPackagesForCallerByUser = copyPackageNamesByUser(orig.mHideMicrogPackagesForCallerByUser); mForceQueryableByDevicePackageNames = Arrays.copyOf(orig.mForceQueryableByDevicePackageNames, orig.mForceQueryableByDevicePackageNames.length); mSystemAppsQueryable = orig.mSystemAppsQueryable; mFeatureConfig = orig.mFeatureConfig.snapshot(); mOverlayReferenceMapper = orig.mOverlayReferenceMapper; Loading