From 318ad33061fdcf1d50419f605206f767f21634e3 Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Sat, 26 Sep 2020 13:47:49 -0700 Subject: [PATCH] Add global settings variables for ANGLE debug. Introduce angle.egl.features to assist ANGLE debugging. The input contains lists for each opt-in apps. The format is each list of features is separated by a comma, each feature in each list is separated by a colon, e.g. feature1:feature2:feature3,feature1:feature3:feature5 Bug: b/169156341 Test: use adb shell command to verify Test: atest android.gputools.cts.CtsRootlessGpuDebugHostTest Test: atest CtsAngleIntegrationHostTestCases Change-Id: I752047df1c2567b4ebf900c3acb4a965e35dd6c2 --- core/java/android/os/GraphicsEnvironment.java | 93 ++++++++++++------- core/java/android/provider/Settings.java | 9 ++ core/jni/android_os_GraphicsEnvironment.cpp | 57 +++++++++--- .../android/providers/settings/global.proto | 2 + .../settings/SettingsProtoDumpUtil.java | 3 + .../android/provider/SettingsBackupTest.java | 1 + .../server/am/CoreSettingsObserver.java | 2 + 7 files changed, 119 insertions(+), 48 deletions(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 52ee04c169c10..040225a4f93c3 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -49,6 +49,9 @@ import java.util.List; /** * GraphicsEnvironment sets up necessary properties for the graphics environment of the * application process. + * GraphicsEnvironment uses a bunch of settings global variables to determine the setup, + * the change of settings global variables will only take effect before setup() is called, + * and any subsequent change will not impact the current running processes. * * @hide */ @@ -119,6 +122,8 @@ public class GraphicsEnvironment { private String mLibrarySearchPaths; private String mLibraryPermittedPaths; + private int mAngleOptInIndex = -1; + /** * Set up GraphicsEnvironment */ @@ -145,16 +150,10 @@ public class GraphicsEnvironment { Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); } - /** - * Hint for GraphicsEnvironment that an activity is launching on the process. - * Then the app process is allowed to send stats to GpuStats module. - */ - public static native void hintActivityLaunch(); - /** * Query to determine if ANGLE should be used */ - public static boolean shouldUseAngle(Context context, Bundle coreSettings, + private boolean shouldUseAngle(Context context, Bundle coreSettings, String packageName) { if (TextUtils.isEmpty(packageName)) { Log.v(TAG, "No package name specified, ANGLE should not be used"); @@ -182,7 +181,7 @@ public class GraphicsEnvironment { return allowed || requested; } - private static int getVulkanVersion(PackageManager pm) { + private int getVulkanVersion(PackageManager pm) { // PackageManager doesn't have an API to retrieve the version of a specific feature, and we // need to avoid retrieving all system features here and looping through them. if (pm.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, VULKAN_1_1)) { @@ -199,7 +198,7 @@ public class GraphicsEnvironment { /** * Check whether application is has set the manifest metadata for layer injection. */ - private static boolean canInjectLayers(ApplicationInfo ai) { + private boolean canInjectLayers(ApplicationInfo ai) { return (ai.metaData != null && ai.metaData.getBoolean(METADATA_INJECT_LAYERS_ENABLE) && setInjectLayersPrSetDumpable()); } @@ -257,7 +256,7 @@ public class GraphicsEnvironment { /** * Return the debug layer app's on-disk and in-APK lib directories */ - private static String getDebugLayerAppPaths(IPackageManager pm, String packageName) { + private String getDebugLayerAppPaths(IPackageManager pm, String packageName) { final ApplicationInfo appInfo; try { appInfo = pm.getApplicationInfo(packageName, PackageManager.MATCH_ALL, @@ -354,11 +353,10 @@ public class GraphicsEnvironment { return valueList; } - private static int getGlobalSettingsPkgIndex(String pkgName, - List globalSettingsDriverPkgs) { - for (int pkgIndex = 0; pkgIndex < globalSettingsDriverPkgs.size(); pkgIndex++) { - if (globalSettingsDriverPkgs.get(pkgIndex).equals(pkgName)) { - return pkgIndex; + private static int getPackageIndex(String packageName, List packages) { + for (int idx = 0; idx < packages.size(); idx++) { + if (packages.get(idx).equals(packageName)) { + return idx; } } @@ -379,7 +377,7 @@ public class GraphicsEnvironment { return ai; } - private static String getDriverForPackage(Context context, Bundle bundle, String packageName) { + private String getDriverForPackage(Context context, Bundle bundle, String packageName) { final int allUseAngle; if (bundle != null) { allUseAngle = @@ -401,31 +399,32 @@ public class GraphicsEnvironment { } final ContentResolver contentResolver = context.getContentResolver(); - final List globalSettingsDriverPkgs = + final List optInPackages = getGlobalSettingsString(contentResolver, bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS); - final List globalSettingsDriverValues = + final List optInValues = getGlobalSettingsString(contentResolver, bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES); // Make sure we have good settings to use - if (globalSettingsDriverPkgs.size() != globalSettingsDriverValues.size()) { + if (optInPackages.size() != optInValues.size()) { Log.w(TAG, "Global.Settings values are invalid: " + "number of packages: " - + globalSettingsDriverPkgs.size() + ", " + + optInPackages.size() + ", " + "number of values: " - + globalSettingsDriverValues.size()); + + optInValues.size()); return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } - final int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs); + final int pkgIndex = getPackageIndex(packageName, optInPackages); if (pkgIndex < 0) { return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } + mAngleOptInIndex = pkgIndex; - return globalSettingsDriverValues.get(pkgIndex); + return optInValues.get(pkgIndex); } /** @@ -479,7 +478,7 @@ public class GraphicsEnvironment { * True: Temporary rules file was loaded. * False: Temporary rules file was *not* loaded. */ - private static boolean setupAngleWithTempRulesFile(Context context, + private boolean setupAngleWithTempRulesFile(Context context, String packageName, String paths, String devOptIn) { @@ -515,7 +514,8 @@ public class GraphicsEnvironment { final long rulesLength = stream.getChannel().size(); Log.i(TAG, "Loaded temporary ANGLE rules from " + angleTempRules); - setAngleInfo(paths, packageName, devOptIn, rulesFd, rulesOffset, rulesLength); + setAngleInfo(paths, packageName, devOptIn, null, + rulesFd, rulesOffset, rulesLength); stream.close(); @@ -539,12 +539,13 @@ public class GraphicsEnvironment { * True: APK rules file was loaded. * False: APK rules file was *not* loaded. */ - private static boolean setupAngleRulesApk(String anglePkgName, + private boolean setupAngleRulesApk(String anglePkgName, ApplicationInfo angleInfo, PackageManager pm, String packageName, String paths, - String devOptIn) { + String devOptIn, + String[] features) { // Pass the rules file to loader for ANGLE decisions try { final AssetManager angleAssets = pm.getResourcesForApplication(angleInfo).getAssets(); @@ -552,7 +553,7 @@ public class GraphicsEnvironment { try { final AssetFileDescriptor assetsFd = angleAssets.openFd(ANGLE_RULES_FILE); - setAngleInfo(paths, packageName, devOptIn, assetsFd.getFileDescriptor(), + setAngleInfo(paths, packageName, devOptIn, features, assetsFd.getFileDescriptor(), assetsFd.getStartOffset(), assetsFd.getLength()); assetsFd.close(); @@ -572,7 +573,7 @@ public class GraphicsEnvironment { /** * Pull ANGLE allowlist from GlobalSettings and compare against current package */ - private static boolean checkAngleAllowlist(Context context, Bundle bundle, String packageName) { + private boolean checkAngleAllowlist(Context context, Bundle bundle, String packageName) { final ContentResolver contentResolver = context.getContentResolver(); final List angleAllowlist = getGlobalSettingsString(contentResolver, bundle, @@ -658,8 +659,11 @@ public class GraphicsEnvironment { return true; } - if (setupAngleRulesApk(anglePkgName, angleInfo, pm, packageName, paths, devOptIn)) { - // We setup ANGLE with rules from the APK, so we're done here. + String[] features = getAngleEglFeatures(context, bundle); + + if (setupAngleRulesApk( + anglePkgName, angleInfo, pm, packageName, paths, devOptIn, features)) { + // ANGLE with rules is set up from the APK, hence return. return true; } @@ -725,10 +729,23 @@ public class GraphicsEnvironment { } } + private String[] getAngleEglFeatures(Context context, Bundle coreSettings) { + if (mAngleOptInIndex < 0) { + return null; + } + + final List featuresLists = getGlobalSettingsString( + context.getContentResolver(), coreSettings, Settings.Global.ANGLE_EGL_FEATURES); + if (featuresLists.size() <= mAngleOptInIndex) { + return null; + } + return featuresLists.get(mAngleOptInIndex).split(":"); + } + /** * Return the driver package name to use. Return null for system driver. */ - private static String chooseDriverInternal(Bundle coreSettings, ApplicationInfo ai) { + private String chooseDriverInternal(Bundle coreSettings, ApplicationInfo ai) { final String productionDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRODUCTION); final boolean hasProductionDriver = productionDriver != null && !productionDriver.isEmpty(); @@ -827,7 +844,7 @@ public class GraphicsEnvironment { /** * Choose whether the current process should use the builtin or an updated driver. */ - private static boolean chooseDriver( + private boolean chooseDriver( Context context, Bundle coreSettings, PackageManager pm, String packageName, ApplicationInfo ai) { final String driverPackageName = chooseDriverInternal(coreSettings, ai); @@ -907,7 +924,7 @@ public class GraphicsEnvironment { return null; } - private static String getSphalLibraries(Context context, String driverPackageName) { + private String getSphalLibraries(Context context, String driverPackageName) { try { final Context driverContext = context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED); @@ -938,7 +955,13 @@ public class GraphicsEnvironment { private static native void setGpuStats(String driverPackageName, String driverVersionName, long driverVersionCode, long driverBuildTime, String appPackageName, int vulkanVersion); private static native void setAngleInfo(String path, String appPackage, String devOptIn, - FileDescriptor rulesFd, long rulesOffset, long rulesLength); + String[] features, FileDescriptor rulesFd, long rulesOffset, long rulesLength); private static native boolean getShouldUseAngle(String packageName); private static native boolean setInjectLayersPrSetDumpable(); + + /** + * Hint for GraphicsEnvironment that an activity is launching on the process. + * Then the app process is allowed to send stats to GpuStats module. + */ + public static native void hintActivityLaunch(); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 07867e2a9d9b4..4c99ff3f3456c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12324,6 +12324,15 @@ public final class Settings { public static final String GLOBAL_SETTINGS_ANGLE_ALLOWLIST = "angle_allowlist"; + /** + * Lists of ANGLE EGL features for debugging. + * Each list of features is separated by a comma, each feature in each list is separated by + * a colon. + * e.g. feature1:feature2:feature3,feature1:feature3:feature5 + * @hide + */ + public static final String ANGLE_EGL_FEATURES = "angle_egl_features"; + /** * Show the "ANGLE In Use" dialog box to the user when ANGLE is the OpenGL driver. * The value is a boolean (1 or 0). diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp index 4f3f283859b48..b40491a49b142 100644 --- a/core/jni/android_os_GraphicsEnvironment.cpp +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "GraphicsEnvironment" +#include + #include #include #include @@ -47,16 +49,36 @@ void setGpuStats_native(JNIEnv* env, jobject clazz, jstring driverPackageName, appPackageNameChars.c_str(), vulkanVersion); } -void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring devOptIn, - jobject rulesFd, jlong rulesOffset, jlong rulesLength) { +void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, + jstring devOptIn, jobjectArray featuresObj, jobject rulesFd, + jlong rulesOffset, jlong rulesLength) { ScopedUtfChars pathChars(env, path); ScopedUtfChars appNameChars(env, appName); ScopedUtfChars devOptInChars(env, devOptIn); + std::vector features; + if (featuresObj != nullptr) { + jsize length = env->GetArrayLength(featuresObj); + for (jsize i = 0; i < length; ++i) { + jstring jstr = static_cast(env->GetObjectArrayElement(featuresObj, i)); + // null entries are ignored + if (jstr == nullptr) { + continue; + } + const char* cstr = env->GetStringUTFChars(jstr, nullptr); + if (cstr == nullptr) { + continue; + } + features.emplace_back(cstr); + env->ReleaseStringUTFChars(jstr, cstr); + } + } + int rulesFd_native = jniGetFDFromFileDescriptor(env, rulesFd); android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(), - devOptInChars.c_str(), rulesFd_native, rulesOffset, rulesLength); + devOptInChars.c_str(), features, + rulesFd_native, rulesOffset, rulesLength); } bool shouldUseAngle_native(JNIEnv* env, jobject clazz, jstring appName) { @@ -94,16 +116,25 @@ void hintActivityLaunch_native(JNIEnv* env, jobject clazz) { } const JNINativeMethod g_methods[] = { - { "isDebuggable", "()Z", reinterpret_cast(isDebuggable_native) }, - { "setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast(setDriverPathAndSphalLibraries_native) }, - { "setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V", reinterpret_cast(setGpuStats_native) }, - { "setInjectLayersPrSetDumpable", "()Z", reinterpret_cast(setInjectLayersPrSetDumpable_native) }, - { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;JJ)V", reinterpret_cast(setAngleInfo_native) }, - { "getShouldUseAngle", "(Ljava/lang/String;)Z", reinterpret_cast(shouldUseAngle_native) }, - { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast(setLayerPaths_native) }, - { "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast(setDebugLayers_native) }, - { "setDebugLayersGLES", "(Ljava/lang/String;)V", reinterpret_cast(setDebugLayersGLES_native) }, - { "hintActivityLaunch", "()V", reinterpret_cast(hintActivityLaunch_native) }, + {"isDebuggable", "()Z", reinterpret_cast(isDebuggable_native)}, + {"setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", + reinterpret_cast(setDriverPathAndSphalLibraries_native)}, + {"setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V", + reinterpret_cast(setGpuStats_native)}, + {"setInjectLayersPrSetDumpable", "()Z", + reinterpret_cast(setInjectLayersPrSetDumpable_native)}, + {"setAngleInfo", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/io/" + "FileDescriptor;JJ)V", + reinterpret_cast(setAngleInfo_native)}, + {"getShouldUseAngle", "(Ljava/lang/String;)Z", + reinterpret_cast(shouldUseAngle_native)}, + {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", + reinterpret_cast(setLayerPaths_native)}, + {"setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast(setDebugLayers_native)}, + {"setDebugLayersGLES", "(Ljava/lang/String;)V", + reinterpret_cast(setDebugLayersGLES_native)}, + {"hintActivityLaunch", "()V", reinterpret_cast(hintActivityLaunch_native)}, }; const char* const kGraphicsEnvironmentName = "android/os/GraphicsEnvironment"; diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto index 50912702e3d6b..16a691c9c4ec6 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -463,6 +463,8 @@ message GlobalSettingsProto { // Updatable Driver - List of Apps selected to use updatable prerelease driver // i.e. ,,..., optional SettingProto updatable_driver_prerelease_opt_in_apps = 18; + + optional SettingProto angle_egl_features = 19; } optional Gpu gpu = 59; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java index bc6660184fe3b..d2485cc49b6ea 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -763,6 +763,9 @@ class SettingsProtoDumpUtil { dumpSetting(s, p, Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, GlobalSettingsProto.Gpu.ANGLE_ALLOWLIST); + dumpSetting(s, p, + Settings.Global.ANGLE_EGL_FEATURES, + GlobalSettingsProto.Gpu.ANGLE_EGL_FEATURES); dumpSetting(s, p, Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, GlobalSettingsProto.Gpu.SHOW_ANGLE_IN_USE_DIALOG); diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 9788b30f82c4e..ae84ca3023e01 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -502,6 +502,7 @@ public class SettingsBackupTest { Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, + Settings.Global.ANGLE_EGL_FEATURES, Settings.Global.UPDATABLE_DRIVER_ALL_APPS, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS, Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS, diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java index 757b4e83e1202..ec264a88e782c 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -93,6 +93,8 @@ final class CoreSettingsObserver extends ContentObserver { Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES, String.class); sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST, String.class); + sGlobalSettingToTypeMap.put( + Settings.Global.ANGLE_EGL_FEATURES, String.class); sGlobalSettingToTypeMap.put( Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX, String.class); sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class);