From 5ebb0db1043f71ca785396ca98047639e7627e99 Mon Sep 17 00:00:00 2001 From: Cody Northrop Date: Tue, 15 Jan 2019 14:06:36 -0700 Subject: [PATCH] Guard ANGLE rules checking with a whitelist In order to reduce the startup impact to near zero, we are creating a whitelist to be checked before parsing rules. The whitelist will be generated by the APK based on apps mentioned in the rules files. At app launch, only those in the whitelist will do full rules checking. The whitelist will be checked via Global Settings, which will be populated by the ANGLE APK when intents are received. The APK will listen for intents at boot (LOCKED_BOOT_COMPLETED) and when ANGLE itself is updated (MY_PACKAGE_REPLACED). The whitelist can also be populated by hand: adb shell settings put global angle_whitelist app1,app2,appN We plan to further mitigate the ANGLE-enabled app impact by parsing the full rules when creating the whitelist, off of the critical path. Note: Developer Options will continue to work, regardless of whitelist. But temp rules will not be loaded if the app is not whitelisted. Test: atest CtsAngleIntegrationHostTestCases Test: atest google/perf/app-startup/hermetic-apps/cold-dropcache-test -v Bug: 80239516 Bug: 122528316 Change-Id: I96e5b4d5b4774f59aadbd1e52295437a395cab6b --- core/java/android/os/GraphicsEnvironment.java | 43 ++++++++++++++++++- core/java/android/provider/Settings.java | 7 +++ .../android/providers/settings/global.proto | 2 + .../android/provider/SettingsBackupTest.java | 1 + .../settings/SettingsProtoDumpUtil.java | 3 ++ .../server/am/CoreSettingsObserver.java | 2 + 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 099b4f33fa4db..efcad3ece97d2 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -404,17 +404,58 @@ public class GraphicsEnvironment { return false; } + /** + * Pull ANGLE whitelist from GlobalSettings and compare against current package + */ + private boolean checkAngleWhitelist(Bundle bundle, String packageName) { + List angleWhitelist = + getGlobalSettingsString(bundle, + Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST); + + return angleWhitelist.contains(packageName); + } + /** * Pass ANGLE details down to trigger enable logic */ public void setupAngle(Context context, Bundle bundle, String packageName) { - String devOptIn = getDriverForPkg(bundle, packageName); + if (packageName.isEmpty()) { + Log.v(TAG, "No package name available yet, skipping ANGLE setup"); + return; + } + String devOptIn = getDriverForPkg(bundle, packageName); if (DEBUG) { Log.v(TAG, "ANGLE Developer option for '" + packageName + "' " + "set to: '" + devOptIn + "'"); } + // We only need to check rules if the app is whitelisted or the developer has + // explicitly chosen something other than default driver. + // + // The whitelist will be generated by the ANGLE APK at both boot time and + // ANGLE update time. It will only include apps mentioned in the rules file. + // + // If the user has set the developer option to something other than default, + // we need to call setupAngleRulesApk() with the package name and the developer + // option value (native/angle/other). Then later when we are actually trying to + // load a driver, GraphicsEnv::shouldUseAngle() has seen the package name before + // and can confidently answer yes/no based on the previously set developer + // option value. + boolean whitelisted = checkAngleWhitelist(bundle, packageName); + boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT)); + boolean rulesCheck = (whitelisted || !defaulted); + if (!rulesCheck) { + return; + } + + if (whitelisted) { + Log.v(TAG, "ANGLE whitelist includes " + packageName); + } + if (!defaulted) { + Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn); + } + String anglePkgName = getAnglePackageName(context); if (anglePkgName.isEmpty()) { Log.e(TAG, "Failed to find ANGLE package."); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index bdeacdf91fe3c..b0bbc3286b407 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12137,6 +12137,13 @@ public final class Settings { public static final String GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES = "angle_gl_driver_selection_values"; + /** + * List of package names that should check ANGLE rules + * @hide + */ + public static final String GLOBAL_SETTINGS_ANGLE_WHITELIST = + "angle_whitelist"; + /** * Game Update Package global preference for all Apps. * 0 = Default diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index d79eb9402132e..f06165cc7e006 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -451,6 +451,8 @@ message GlobalSettingsProto { optional SettingProto gup_blacklist = 11; // List of Apps that are allowed to use Game Driver package. optional SettingProto game_driver_whitelist = 12; + // ANGLE - List of Apps that can check ANGLE rules + optional SettingProto angle_whitelist = 13; } optional Gpu gpu = 59; diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index a010cb6576f2e..00f691d6c0a66 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -482,6 +482,7 @@ public class SettingsBackupTest { Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, + Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST, Settings.Global.GUP_DEV_ALL_APPS, Settings.Global.GUP_DEV_OPT_IN_APPS, Settings.Global.GUP_DEV_OPT_OUT_APPS, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index 850a3c2dea9bd..aff6f0452533c 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -697,6 +697,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, GlobalSettingsProto.Gpu.ANGLE_GL_DRIVER_SELECTION_VALUES); + dumpSetting(s, p, + Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST, + GlobalSettingsProto.Gpu.ANGLE_WHITELIST); dumpSetting(s, p, Settings.Global.GPU_DEBUG_LAYER_APP, GlobalSettingsProto.Gpu.DEBUG_LAYER_APP); diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index d3953b58296c8..3d69aa8088f58 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -61,6 +61,8 @@ final class CoreSettingsObserver extends ContentObserver { Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, String.class); sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST, String.class); sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class); sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_APP, String.class); sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS, String.class);