Loading core/java/android/content/pm/IPackageManager.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -748,5 +748,4 @@ interface IPackageManager { void clearMimeGroup(String packageName, String group); List<String> getMimeGroup(String packageName, String group); } services/core/java/android/content/pm/PackageManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -986,4 +986,11 @@ public abstract class PackageManagerInternal { * Returns MIME types contained in {@code mimeGroup} from {@code packageName} package */ public abstract List<String> getMimeGroup(String packageName, String mimeGroup); /** * Toggles visibility logging to help in debugging the app enumeration feature. * @param packageName the package name that should begin logging * @param enabled true if visibility blocks should be logged */ public abstract void setVisibilityLogging(String packageName, boolean enabled); } services/core/java/com/android/server/pm/AppsFilter.java +75 −36 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseSetArray; import com.android.internal.R; Loading Loading @@ -123,6 +124,7 @@ public class AppsFilter { } public interface FeatureConfig { /** Called when the system is ready and components can be queried. */ void onSystemReady(); Loading @@ -132,11 +134,21 @@ public class AppsFilter { /** @return true if the feature is enabled for the given package. */ boolean packageIsEnabled(AndroidPackage pkg); /** @return true if debug logging is enabled for the given package. */ boolean isLoggingEnabled(int appId); /** * Turns on logging for the given appId * @param enable true if logging should be enabled, false if disabled. */ void enableLogging(int appId, boolean enable); /** * Initializes the package enablement state for the given package. This gives opportunity * to do any expensive operations ahead of the actual checks. * @param removed true if adding, false if removing */ void initializePackageState(String packageName); void updatePackageState(PackageSetting setting, boolean removed); } private static class FeatureConfigImpl implements FeatureConfig, CompatChange.ChangeListener { Loading @@ -147,6 +159,9 @@ public class AppsFilter { PackageManager.APP_ENUMERATION_ENABLED_BY_DEFAULT; private final ArraySet<String> mDisabledPackages = new ArraySet<>(); @Nullable private SparseBooleanArray mLoggingEnabled = null; private FeatureConfigImpl( PackageManagerInternal pmInternal, PackageManagerService.Injector injector) { mPmInternal = pmInternal; Loading Loading @@ -192,39 +207,65 @@ public class AppsFilter { } } private boolean fetchPackageIsEnabled(AndroidPackage pkg) { @Override public boolean isLoggingEnabled(int uid) { return mLoggingEnabled != null && mLoggingEnabled.indexOfKey(uid) >= 0; } @Override public void enableLogging(int appId, boolean enable) { if (enable) { if (mLoggingEnabled == null) { mLoggingEnabled = new SparseBooleanArray(); } mLoggingEnabled.put(appId, true); } else { if (mLoggingEnabled != null) { final int index = mLoggingEnabled.indexOfKey(appId); if (index >= 0) { mLoggingEnabled.removeAt(index); if (mLoggingEnabled.size() == 0) { mLoggingEnabled = null; } } } } } @Override public void onCompatChange(String packageName) { updateEnabledState(mPmInternal.getPackage(packageName)); } private void updateEnabledState(AndroidPackage pkg) { final long token = Binder.clearCallingIdentity(); try { // TODO(b/135203078): Do not use toAppInfo final boolean changeEnabled = final boolean enabled = mInjector.getCompatibility().isChangeEnabled( PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState()); return changeEnabled; if (enabled) { mDisabledPackages.remove(pkg.getPackageName()); } else { mDisabledPackages.add(pkg.getPackageName()); } } finally { Binder.restoreCallingIdentity(token); } } @Override public void onCompatChange(String packageName) { final AndroidPackage pkg = mPmInternal.getPackage(packageName); if (pkg == null) { mDisabledPackages.remove(packageName); return; } boolean enabled = fetchPackageIsEnabled(pkg); if (enabled) { mDisabledPackages.remove(packageName); public void updatePackageState(PackageSetting setting, boolean removed) { final boolean enableLogging = !removed && (setting.pkg.isTestOnly() || setting.pkg.isDebuggable()); enableLogging(setting.appId, enableLogging); if (removed) { mDisabledPackages.remove(setting.pkg.getPackageName()); } else { mDisabledPackages.add(packageName); updateEnabledState(setting.pkg); } } @Override public void initializePackageState(String packageName) { onCompatChange(packageName); } } /** Builder method for an AppsFilter */ Loading @@ -250,6 +291,10 @@ public class AppsFilter { forceSystemAppsQueryable, null); } public FeatureConfig getFeatureConfig() { return mFeatureConfig; } /** Returns true if the querying package may query for the potential target package */ private static boolean canQueryViaComponents(AndroidPackage querying, AndroidPackage potentialTarget) { Loading Loading @@ -447,7 +492,7 @@ public class AppsFilter { } } mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs); mFeatureConfig.initializePackageState(newPkgSetting.pkg.getPackageName()); mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading Loading @@ -499,7 +544,7 @@ public class AppsFilter { } mOverlayReferenceMapper.removePkg(setting.name); mFeatureConfig.initializePackageState(setting.pkg.getPackageName()); mFeatureConfig.updatePackageState(setting, true /*removed*/); } /** Loading @@ -516,13 +561,13 @@ public class AppsFilter { PackageSetting targetPkgSetting, int userId) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication"); try { if (!shouldFilterApplicationInternal(callingUid, callingSetting, targetPkgSetting, userId)) { if (!shouldFilterApplicationInternal( callingUid, callingSetting, targetPkgSetting, userId)) { return false; } if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED", new RuntimeException()); if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(UserHandle.getAppId(callingUid))) { log(callingSetting, targetPkgSetting, "BLOCKED"); } return !DEBUG_ALLOW_ALL; } finally { Loading Loading @@ -737,17 +782,11 @@ public class AppsFilter { } } private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, private static void log(SettingBase callingSetting, PackageSetting targetPkgSetting, String description) { log(callingPkgSetting, targetPkgSetting, description, null); } private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, String description, Throwable throwable) { Slog.wtf(TAG, "interaction: " + callingPkgSetting + " -> " + targetPkgSetting + " " + description, throwable); Slog.i(TAG, "interaction: " + (callingSetting == null ? "system" : callingSetting) + " -> " + targetPkgSetting + " " + description); } public void dumpQueries( Loading services/core/java/com/android/server/pm/PackageManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -24152,6 +24152,18 @@ public class PackageManagerService extends IPackageManager.Stub public List<String> getMimeGroup(String packageName, String mimeGroup) { return PackageManagerService.this.getMimeGroup(packageName, mimeGroup); } @Override public void setVisibilityLogging(String packageName, boolean enable) { final PackageSetting pkg; synchronized (mLock) { pkg = mSettings.getPackageLPr(packageName); } if (pkg == null) { throw new IllegalStateException("No package found for " + packageName); } mAppsFilter.getFeatureConfig().enableLogging(pkg.appId, enable); } } @GuardedBy("mLock") services/core/java/com/android/server/pm/PackageManagerShellCommand.java +37 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,8 @@ class PackageManagerShellCommand extends ShellCommand { return runRollbackApp(); case "get-moduleinfo": return runGetModuleInfo(); case "log-visibility": return runLogVisibility(); default: { String nextArg = getNextArg(); if (nextArg == null) { Loading Loading @@ -360,6 +362,36 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } private int runLogVisibility() { final PrintWriter pw = getOutPrintWriter(); boolean enable = true; String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--disable": enable = false; break; case "--enable": enable = true; break; default: pw.println("Error: Unknown option: " + opt); return -1; } } String packageName = getNextArg(); if (packageName != null) { LocalServices.getService(PackageManagerInternal.class) .setVisibilityLogging(packageName, enable); } else { getErrPrintWriter().println("Error: no package specified"); return -1; } return 1; } private int uninstallSystemUpdates() { final PrintWriter pw = getOutPrintWriter(); List<String> failedUninstalls = new LinkedList<>(); Loading Loading @@ -3715,6 +3747,11 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" --all: show all module info"); pw.println(" --installed: show only installed modules"); pw.println(""); pw.println(" log-visibility [--enable|--disable] <PACKAGE>"); pw.println(" Turns on debug logging when visibility is blocked for the given package."); pw.println(" --enable: turn on debug logging (default)"); pw.println(" --disable: turn off debug logging"); pw.println(""); Intent.printIntentArgsHelp(pw , ""); } Loading Loading
core/java/android/content/pm/IPackageManager.aidl +0 −1 Original line number Diff line number Diff line Loading @@ -748,5 +748,4 @@ interface IPackageManager { void clearMimeGroup(String packageName, String group); List<String> getMimeGroup(String packageName, String group); }
services/core/java/android/content/pm/PackageManagerInternal.java +7 −0 Original line number Diff line number Diff line Loading @@ -986,4 +986,11 @@ public abstract class PackageManagerInternal { * Returns MIME types contained in {@code mimeGroup} from {@code packageName} package */ public abstract List<String> getMimeGroup(String packageName, String mimeGroup); /** * Toggles visibility logging to help in debugging the app enumeration feature. * @param packageName the package name that should begin logging * @param enabled true if visibility blocks should be logged */ public abstract void setVisibilityLogging(String packageName, boolean enabled); }
services/core/java/com/android/server/pm/AppsFilter.java +75 −36 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseSetArray; import com.android.internal.R; Loading Loading @@ -123,6 +124,7 @@ public class AppsFilter { } public interface FeatureConfig { /** Called when the system is ready and components can be queried. */ void onSystemReady(); Loading @@ -132,11 +134,21 @@ public class AppsFilter { /** @return true if the feature is enabled for the given package. */ boolean packageIsEnabled(AndroidPackage pkg); /** @return true if debug logging is enabled for the given package. */ boolean isLoggingEnabled(int appId); /** * Turns on logging for the given appId * @param enable true if logging should be enabled, false if disabled. */ void enableLogging(int appId, boolean enable); /** * Initializes the package enablement state for the given package. This gives opportunity * to do any expensive operations ahead of the actual checks. * @param removed true if adding, false if removing */ void initializePackageState(String packageName); void updatePackageState(PackageSetting setting, boolean removed); } private static class FeatureConfigImpl implements FeatureConfig, CompatChange.ChangeListener { Loading @@ -147,6 +159,9 @@ public class AppsFilter { PackageManager.APP_ENUMERATION_ENABLED_BY_DEFAULT; private final ArraySet<String> mDisabledPackages = new ArraySet<>(); @Nullable private SparseBooleanArray mLoggingEnabled = null; private FeatureConfigImpl( PackageManagerInternal pmInternal, PackageManagerService.Injector injector) { mPmInternal = pmInternal; Loading Loading @@ -192,39 +207,65 @@ public class AppsFilter { } } private boolean fetchPackageIsEnabled(AndroidPackage pkg) { @Override public boolean isLoggingEnabled(int uid) { return mLoggingEnabled != null && mLoggingEnabled.indexOfKey(uid) >= 0; } @Override public void enableLogging(int appId, boolean enable) { if (enable) { if (mLoggingEnabled == null) { mLoggingEnabled = new SparseBooleanArray(); } mLoggingEnabled.put(appId, true); } else { if (mLoggingEnabled != null) { final int index = mLoggingEnabled.indexOfKey(appId); if (index >= 0) { mLoggingEnabled.removeAt(index); if (mLoggingEnabled.size() == 0) { mLoggingEnabled = null; } } } } } @Override public void onCompatChange(String packageName) { updateEnabledState(mPmInternal.getPackage(packageName)); } private void updateEnabledState(AndroidPackage pkg) { final long token = Binder.clearCallingIdentity(); try { // TODO(b/135203078): Do not use toAppInfo final boolean changeEnabled = final boolean enabled = mInjector.getCompatibility().isChangeEnabled( PackageManager.FILTER_APPLICATION_QUERY, pkg.toAppInfoWithoutState()); return changeEnabled; if (enabled) { mDisabledPackages.remove(pkg.getPackageName()); } else { mDisabledPackages.add(pkg.getPackageName()); } } finally { Binder.restoreCallingIdentity(token); } } @Override public void onCompatChange(String packageName) { final AndroidPackage pkg = mPmInternal.getPackage(packageName); if (pkg == null) { mDisabledPackages.remove(packageName); return; } boolean enabled = fetchPackageIsEnabled(pkg); if (enabled) { mDisabledPackages.remove(packageName); public void updatePackageState(PackageSetting setting, boolean removed) { final boolean enableLogging = !removed && (setting.pkg.isTestOnly() || setting.pkg.isDebuggable()); enableLogging(setting.appId, enableLogging); if (removed) { mDisabledPackages.remove(setting.pkg.getPackageName()); } else { mDisabledPackages.add(packageName); updateEnabledState(setting.pkg); } } @Override public void initializePackageState(String packageName) { onCompatChange(packageName); } } /** Builder method for an AppsFilter */ Loading @@ -250,6 +291,10 @@ public class AppsFilter { forceSystemAppsQueryable, null); } public FeatureConfig getFeatureConfig() { return mFeatureConfig; } /** Returns true if the querying package may query for the potential target package */ private static boolean canQueryViaComponents(AndroidPackage querying, AndroidPackage potentialTarget) { Loading Loading @@ -447,7 +492,7 @@ public class AppsFilter { } } mOverlayReferenceMapper.addPkg(newPkgSetting.pkg, existingPkgs); mFeatureConfig.initializePackageState(newPkgSetting.pkg.getPackageName()); mFeatureConfig.updatePackageState(newPkgSetting, false /*removed*/); } finally { Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } Loading Loading @@ -499,7 +544,7 @@ public class AppsFilter { } mOverlayReferenceMapper.removePkg(setting.name); mFeatureConfig.initializePackageState(setting.pkg.getPackageName()); mFeatureConfig.updatePackageState(setting, true /*removed*/); } /** Loading @@ -516,13 +561,13 @@ public class AppsFilter { PackageSetting targetPkgSetting, int userId) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication"); try { if (!shouldFilterApplicationInternal(callingUid, callingSetting, targetPkgSetting, userId)) { if (!shouldFilterApplicationInternal( callingUid, callingSetting, targetPkgSetting, userId)) { return false; } if (DEBUG_LOGGING) { log(callingSetting, targetPkgSetting, DEBUG_ALLOW_ALL ? "ALLOWED" : "BLOCKED", new RuntimeException()); if (DEBUG_LOGGING || mFeatureConfig.isLoggingEnabled(UserHandle.getAppId(callingUid))) { log(callingSetting, targetPkgSetting, "BLOCKED"); } return !DEBUG_ALLOW_ALL; } finally { Loading Loading @@ -737,17 +782,11 @@ public class AppsFilter { } } private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, private static void log(SettingBase callingSetting, PackageSetting targetPkgSetting, String description) { log(callingPkgSetting, targetPkgSetting, description, null); } private static void log(SettingBase callingPkgSetting, PackageSetting targetPkgSetting, String description, Throwable throwable) { Slog.wtf(TAG, "interaction: " + callingPkgSetting + " -> " + targetPkgSetting + " " + description, throwable); Slog.i(TAG, "interaction: " + (callingSetting == null ? "system" : callingSetting) + " -> " + targetPkgSetting + " " + description); } public void dumpQueries( Loading
services/core/java/com/android/server/pm/PackageManagerService.java +12 −0 Original line number Diff line number Diff line Loading @@ -24152,6 +24152,18 @@ public class PackageManagerService extends IPackageManager.Stub public List<String> getMimeGroup(String packageName, String mimeGroup) { return PackageManagerService.this.getMimeGroup(packageName, mimeGroup); } @Override public void setVisibilityLogging(String packageName, boolean enable) { final PackageSetting pkg; synchronized (mLock) { pkg = mSettings.getPackageLPr(packageName); } if (pkg == null) { throw new IllegalStateException("No package found for " + packageName); } mAppsFilter.getFeatureConfig().enableLogging(pkg.appId, enable); } } @GuardedBy("mLock")
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +37 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,8 @@ class PackageManagerShellCommand extends ShellCommand { return runRollbackApp(); case "get-moduleinfo": return runGetModuleInfo(); case "log-visibility": return runLogVisibility(); default: { String nextArg = getNextArg(); if (nextArg == null) { Loading Loading @@ -360,6 +362,36 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } private int runLogVisibility() { final PrintWriter pw = getOutPrintWriter(); boolean enable = true; String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--disable": enable = false; break; case "--enable": enable = true; break; default: pw.println("Error: Unknown option: " + opt); return -1; } } String packageName = getNextArg(); if (packageName != null) { LocalServices.getService(PackageManagerInternal.class) .setVisibilityLogging(packageName, enable); } else { getErrPrintWriter().println("Error: no package specified"); return -1; } return 1; } private int uninstallSystemUpdates() { final PrintWriter pw = getOutPrintWriter(); List<String> failedUninstalls = new LinkedList<>(); Loading Loading @@ -3715,6 +3747,11 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" --all: show all module info"); pw.println(" --installed: show only installed modules"); pw.println(""); pw.println(" log-visibility [--enable|--disable] <PACKAGE>"); pw.println(" Turns on debug logging when visibility is blocked for the given package."); pw.println(" --enable: turn on debug logging (default)"); pw.println(" --disable: turn off debug logging"); pw.println(""); Intent.printIntentArgsHelp(pw , ""); } Loading