diff options
7 files changed, 119 insertions, 48 deletions
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 54f80c613f0a..6ba1627dde47 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 */ @@ -146,15 +151,9 @@ public class GraphicsEnvironment { } /** - * 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, @@ -355,11 +354,10 @@ public class GraphicsEnvironment { return valueList; } - private static int getGlobalSettingsPkgIndex(String pkgName, - List<String> globalSettingsDriverPkgs) { - for (int pkgIndex = 0; pkgIndex < globalSettingsDriverPkgs.size(); pkgIndex++) { - if (globalSettingsDriverPkgs.get(pkgIndex).equals(pkgName)) { - return pkgIndex; + private static int getPackageIndex(String packageName, List<String> packages) { + for (int idx = 0; idx < packages.size(); idx++) { + if (packages.get(idx).equals(packageName)) { + return idx; } } @@ -380,7 +378,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 = @@ -402,31 +400,32 @@ public class GraphicsEnvironment { } final ContentResolver contentResolver = context.getContentResolver(); - final List<String> globalSettingsDriverPkgs = + final List<String> optInPackages = getGlobalSettingsString(contentResolver, bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS); - final List<String> globalSettingsDriverValues = + final List<String> 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); } /** @@ -480,7 +479,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) { @@ -516,7 +515,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(); @@ -540,12 +540,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(); @@ -553,7 +554,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(); @@ -573,7 +574,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<String> angleAllowlist = getGlobalSettingsString(contentResolver, bundle, @@ -659,8 +660,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; } @@ -726,10 +730,23 @@ public class GraphicsEnvironment { } } + private String[] getAngleEglFeatures(Context context, Bundle coreSettings) { + if (mAngleOptInIndex < 0) { + return null; + } + + final List<String> 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(); @@ -828,7 +845,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); @@ -908,7 +925,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); @@ -939,7 +956,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 e9786083fc60..1dbf95f7db86 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12329,6 +12329,15 @@ public final class Settings { "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). * @hide diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp index 4f3f283859b4..b40491a49b14 100644 --- a/core/jni/android_os_GraphicsEnvironment.cpp +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -16,6 +16,8 @@ #define LOG_TAG "GraphicsEnvironment" +#include <vector> + #include <graphicsenv/GraphicsEnv.h> #include <nativehelper/ScopedUtfChars.h> #include <nativeloader/native_loader.h> @@ -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<std::string> features; + if (featuresObj != nullptr) { + jsize length = env->GetArrayLength(featuresObj); + for (jsize i = 0; i < length; ++i) { + jstring jstr = static_cast<jstring>(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<void*>(isDebuggable_native) }, - { "setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPathAndSphalLibraries_native) }, - { "setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V", reinterpret_cast<void*>(setGpuStats_native) }, - { "setInjectLayersPrSetDumpable", "()Z", reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native) }, - { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/io/FileDescriptor;JJ)V", reinterpret_cast<void*>(setAngleInfo_native) }, - { "getShouldUseAngle", "(Ljava/lang/String;)Z", reinterpret_cast<void*>(shouldUseAngle_native) }, - { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) }, - { "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native) }, - { "setDebugLayersGLES", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayersGLES_native) }, - { "hintActivityLaunch", "()V", reinterpret_cast<void*>(hintActivityLaunch_native) }, + {"isDebuggable", "()Z", reinterpret_cast<void*>(isDebuggable_native)}, + {"setDriverPathAndSphalLibraries", "(Ljava/lang/String;Ljava/lang/String;)V", + reinterpret_cast<void*>(setDriverPathAndSphalLibraries_native)}, + {"setGpuStats", "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/String;I)V", + reinterpret_cast<void*>(setGpuStats_native)}, + {"setInjectLayersPrSetDumpable", "()Z", + reinterpret_cast<void*>(setInjectLayersPrSetDumpable_native)}, + {"setAngleInfo", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/io/" + "FileDescriptor;JJ)V", + reinterpret_cast<void*>(setAngleInfo_native)}, + {"getShouldUseAngle", "(Ljava/lang/String;)Z", + reinterpret_cast<void*>(shouldUseAngle_native)}, + {"setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", + reinterpret_cast<void*>(setLayerPaths_native)}, + {"setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native)}, + {"setDebugLayersGLES", "(Ljava/lang/String;)V", + reinterpret_cast<void*>(setDebugLayersGLES_native)}, + {"hintActivityLaunch", "()V", reinterpret_cast<void*>(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 50912702e3d6..16a691c9c4ec 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. <pkg1>,<pkg2>,...,<pkgN> 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 bc6660184fe3..d2485cc49b6e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java @@ -764,6 +764,9 @@ class SettingsProtoDumpUtil { 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); dumpSetting(s, p, diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 08109798841f..e027fd397cdd 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -503,6 +503,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 4192455e1c84..dbf91ee64333 100644 --- a/services/core/java/com/android/server/am/CoreSettingsObserver.java +++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java @@ -94,6 +94,8 @@ final class CoreSettingsObserver extends ContentObserver { 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); sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_APP, String.class); |