Loading core/java/android/os/GraphicsEnvironment.java +115 −112 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; Loading @@ -43,11 +44,14 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** @hide */ /** * GraphicsEnvironment sets up necessary properties for the graphics environment of the * application process. * * @hide */ public class GraphicsEnvironment { private static final GraphicsEnvironment sInstance = new GraphicsEnvironment(); Loading @@ -64,27 +68,35 @@ public class GraphicsEnvironment { private static final String SYSTEM_DRIVER_NAME = "system"; private static final String SYSTEM_DRIVER_VERSION_NAME = ""; private static final long SYSTEM_DRIVER_VERSION_CODE = 0; // System properties related to updatable graphics drivers. private static final String PROPERTY_GFX_DRIVER_PRODUCTION = "ro.gfx.driver.0"; private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; // Metadata flags within the <application> tag in the AndroidManifest.xml file. private static final String METADATA_DRIVER_BUILD_TIME = "com.android.graphics.driver.build_time"; private static final String METADATA_DEVELOPER_DRIVER_ENABLE = "com.android.graphics.developerdriver.enable"; private static final String METADATA_INJECT_LAYERS_ENABLE = "com.android.graphics.injectLayers.enable"; private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*"; private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; // ANGLE related properties. private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; private static final String ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE = "android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE"; private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message"; private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*"; private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; private static final int VULKAN_1_0 = 0x00400000; private static final int VULKAN_1_1 = 0x00401000; // UPDATABLE_DRIVER_ALL_APPS // Values for UPDATABLE_DRIVER_ALL_APPS // 0: Default (Invalid values fallback to default as well) // 1: All apps use updatable production driver // 2: All apps use updatable prerelease driver Loading @@ -94,6 +106,15 @@ public class GraphicsEnvironment { private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2; private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3; // Values for GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE private static final int ANGLE_GL_DRIVER_ALL_ANGLE_ON = 1; private static final int ANGLE_GL_DRIVER_ALL_ANGLE_OFF = 0; // Values for GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES private static final String ANGLE_GL_DRIVER_CHOICE_DEFAULT = "default"; private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle"; private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native"; private ClassLoader mClassLoader; private String mLibrarySearchPaths; private String mLibraryPermittedPaths; Loading @@ -106,12 +127,15 @@ public class GraphicsEnvironment { final String packageName = context.getPackageName(); final ApplicationInfo appInfoWithMetaData = getAppInfoWithMetadata(context, pm, packageName); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupGpuLayers"); setupGpuLayers(context, coreSettings, pm, packageName, appInfoWithMetaData); Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupAngle"); setupAngle(context, coreSettings, pm, packageName); Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "chooseDriver"); if (!chooseDriver(context, coreSettings, pm, packageName, appInfoWithMetaData)) { setGpuStats(SYSTEM_DRIVER_NAME, SYSTEM_DRIVER_VERSION_NAME, SYSTEM_DRIVER_VERSION_CODE, Loading @@ -132,36 +156,30 @@ public class GraphicsEnvironment { */ public static boolean shouldUseAngle(Context context, Bundle coreSettings, String packageName) { if (packageName.isEmpty()) { Log.v(TAG, "No package name available yet, ANGLE should not be used"); if (TextUtils.isEmpty(packageName)) { Log.v(TAG, "No package name specified, ANGLE should not be used"); return false; } final String devOptIn = getDriverForPkg(context, coreSettings, packageName); if (DEBUG) { final String devOptIn = getDriverForPackage(context, coreSettings, packageName); Log.v(TAG, "ANGLE Developer option for '" + packageName + "' " + "set to: '" + devOptIn + "'"); } // We only want to use ANGLE if the app is allowlisted or the developer has // We only want to use ANGLE if the app is in the allowlist, or the developer has // explicitly chosen something other than default driver. // The allowlist 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. final boolean allowlisted = checkAngleAllowlist(context, coreSettings, packageName); final boolean requested = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.ANGLE)); final boolean useAngle = (allowlisted || requested); if (!useAngle) { return false; } final boolean allowed = checkAngleAllowlist(context, coreSettings, packageName); final boolean requested = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE); if (allowlisted) { if (allowed) { Log.v(TAG, "ANGLE allowlist includes " + packageName); } if (requested) { Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn); } return true; return allowed || requested; } private static int getVulkanVersion(PackageManager pm) { Loading Loading @@ -315,23 +333,6 @@ public class GraphicsEnvironment { setLayerPaths(mClassLoader, layerPaths); } enum OpenGlDriverChoice { DEFAULT, NATIVE, ANGLE } private static final Map<OpenGlDriverChoice, String> sDriverMap = buildMap(); private static Map<OpenGlDriverChoice, String> buildMap() { final Map<OpenGlDriverChoice, String> map = new HashMap<>(); map.put(OpenGlDriverChoice.DEFAULT, "default"); map.put(OpenGlDriverChoice.ANGLE, "angle"); map.put(OpenGlDriverChoice.NATIVE, "native"); return map; } private static List<String> getGlobalSettingsString(ContentResolver contentResolver, Bundle bundle, String globalSetting) { Loading Loading @@ -378,18 +379,25 @@ public class GraphicsEnvironment { return ai; } private static String getDriverForPkg(Context context, Bundle bundle, String packageName) { final String allUseAngle; private static String getDriverForPackage(Context context, Bundle bundle, String packageName) { final int allUseAngle; if (bundle != null) { allUseAngle = bundle.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); bundle.getInt(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); } else { ContentResolver contentResolver = context.getContentResolver(); allUseAngle = Settings.Global.getString(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); allUseAngle = Settings.Global.getInt(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, ANGLE_GL_DRIVER_ALL_ANGLE_OFF); } if ((allUseAngle != null) && allUseAngle.equals("1")) { return sDriverMap.get(OpenGlDriverChoice.ANGLE); if (allUseAngle == ANGLE_GL_DRIVER_ALL_ANGLE_ON) { Log.v(TAG, "Turn on ANGLE for all applications."); return ANGLE_GL_DRIVER_CHOICE_ANGLE; } // Make sure we have a good package name if (TextUtils.isEmpty(packageName)) { return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } final ContentResolver contentResolver = context.getContentResolver(); Loading @@ -400,25 +408,21 @@ public class GraphicsEnvironment { getGlobalSettingsString(contentResolver, bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES); // Make sure we have a good package name if ((packageName == null) || (packageName.isEmpty())) { return sDriverMap.get(OpenGlDriverChoice.DEFAULT); } // Make sure we have good settings to use if (globalSettingsDriverPkgs.size() != globalSettingsDriverValues.size()) { Log.w(TAG, "Global.Settings values are invalid: " + "globalSettingsDriverPkgs.size = " + "number of packages: " + globalSettingsDriverPkgs.size() + ", " + "globalSettingsDriverValues.size = " + "number of values: " + globalSettingsDriverValues.size()); return sDriverMap.get(OpenGlDriverChoice.DEFAULT); return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } final int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs); if (pkgIndex < 0) { return sDriverMap.get(OpenGlDriverChoice.DEFAULT); return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } return globalSettingsDriverValues.get(pkgIndex); Loading Loading @@ -446,11 +450,15 @@ public class GraphicsEnvironment { } /** * Check for ANGLE debug package, but only for apps that can load them (dumpable) * Check for ANGLE debug package, but only for apps that can load them. * An application can load ANGLE debug package if it is a debuggable application, or * the device is debuggable. */ private String getAngleDebugPackage(Context context, Bundle coreSettings) { if (isDebuggable()) { String debugPackage; if (!isDebuggable()) { return ""; } final String debugPackage; if (coreSettings != null) { debugPackage = Loading @@ -460,14 +468,11 @@ public class GraphicsEnvironment { debugPackage = Settings.Global.getString(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE); } if ((debugPackage != null) && (!debugPackage.isEmpty())) { return debugPackage; } } if (TextUtils.isEmpty(debugPackage)) { return ""; } return debugPackage; } /** * Attempt to setup ANGLE with a temporary rules file. Loading @@ -491,7 +496,7 @@ public class GraphicsEnvironment { final String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES); if ((angleTempRules == null) || angleTempRules.isEmpty()) { if (TextUtils.isEmpty(angleTempRules)) { Log.v(TAG, "System property '" + ANGLE_TEMP_RULES + "' is not set or is empty"); return false; } Loading Loading @@ -583,11 +588,12 @@ public class GraphicsEnvironment { * * @param context * @param bundle * @param packageName * @param pm * @param packageName - package name of the application. * @return true: ANGLE setup successfully * false: ANGLE not setup (not on allowlist, ANGLE not present, etc.) */ public boolean setupAngle(Context context, Bundle bundle, PackageManager pm, private boolean setupAngle(Context context, Bundle bundle, PackageManager pm, String packageName) { if (!shouldUseAngle(context, bundle, packageName)) { Loading @@ -612,7 +618,11 @@ public class GraphicsEnvironment { // Otherwise, check to see if ANGLE is properly installed if (angleInfo == null) { anglePkgName = getAnglePackageName(pm); if (!anglePkgName.isEmpty()) { if (TextUtils.isEmpty(anglePkgName)) { Log.w(TAG, "Failed to find ANGLE package."); return false; } Log.i(TAG, "ANGLE package enabled: " + anglePkgName); try { // Production ANGLE libraries must be pre-installed as a system app Loading @@ -622,10 +632,6 @@ public class GraphicsEnvironment { Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed"); return false; } } else { Log.e(TAG, "Failed to find ANGLE package."); return false; } } final String abi = chooseAbi(angleInfo); Loading @@ -645,7 +651,7 @@ public class GraphicsEnvironment { // load a driver, GraphicsEnv::getShouldUseAngle() has seen the package name before // and can confidently answer yes/no based on the previously set developer // option value. final String devOptIn = getDriverForPkg(context, bundle, packageName); final String devOptIn = getDriverForPackage(context, bundle, packageName); if (setupAngleWithTempRulesFile(context, packageName, paths, devOptIn)) { // We setup ANGLE with a temp rules file, so we're done here. Loading Loading @@ -730,18 +736,18 @@ public class GraphicsEnvironment { final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty(); if (!hasProductionDriver && !hasPrereleaseDriver) { if (DEBUG) { Log.v(TAG, "Neither updatable production driver nor prerelease driver is supported."); } Log.v(TAG, "Neither updatable production driver nor prerelease driver is supported."); return null; } // To minimize risk of driver updates crippling the device beyond user repair, never use an // updated driver for privileged or non-updated system apps. Presumably pre-installed apps // were tested thoroughly with the pre-installed driver. // To minimize risk of driver updates crippling the device beyond user repair, never use the // updatable drivers for privileged or non-updated system apps. Presumably pre-installed // apps were tested thoroughly with the system driver. if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) { if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app."); if (DEBUG) { Log.v(TAG, "Ignore updatable driver package for privileged/non-updated system app."); } return null; } Loading @@ -758,13 +764,13 @@ public class GraphicsEnvironment { // 6. UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST switch (coreSettings.getInt(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, 0)) { case UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF: if (DEBUG) Log.v(TAG, "updatable driver is turned off on this device."); Log.v(TAG, "The updatable driver is turned off on this device."); return null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER: if (DEBUG) Log.v(TAG, "All apps opt in to use updatable production driver."); Log.v(TAG, "All apps opt in to use updatable production driver."); return hasProductionDriver ? productionDriver : null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER: if (DEBUG) Log.v(TAG, "All apps opt in to use updatable prerelease driver."); Log.v(TAG, "All apps opt in to use updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT: default: Loading @@ -775,20 +781,20 @@ public class GraphicsEnvironment { if (getGlobalSettingsString(null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App opts out for updatable production driver."); Log.v(TAG, "App opts out for updatable production driver."); return null; } if (getGlobalSettingsString( null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App opts in for updatable prerelease driver."); Log.v(TAG, "App opts in for updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; } // Early return here since the rest logic is only for updatable production Driver. if (!hasProductionDriver) { if (DEBUG) Log.v(TAG, "Updatable production driver is not supported on the device."); Log.v(TAG, "Updatable production driver is not supported on the device."); return null; } Loading @@ -801,7 +807,7 @@ public class GraphicsEnvironment { Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST); if (!isOptIn && allowlist.indexOf(UPDATABLE_DRIVER_ALLOWLIST_ALL) != 0 && !allowlist.contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App is not on the allowlist for updatable production driver."); Log.v(TAG, "App is not on the allowlist for updatable production driver."); return null; } Loading @@ -811,7 +817,7 @@ public class GraphicsEnvironment { && getGlobalSettingsString( null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App is on the denylist for updatable production driver."); Log.v(TAG, "App is on the denylist for updatable production driver."); return null; } Loading @@ -834,7 +840,7 @@ public class GraphicsEnvironment { driverPackageInfo = pm.getPackageInfo(driverPackageName, PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); Log.w(TAG, "updatable driver package '" + driverPackageName + "' not installed"); return false; } Loading @@ -843,7 +849,7 @@ public class GraphicsEnvironment { final ApplicationInfo driverAppInfo = driverPackageInfo.applicationInfo; if (driverAppInfo.targetSdkVersion < Build.VERSION_CODES.O) { if (DEBUG) { Log.w(TAG, "updated driver package is not known to be compatible with O"); Log.w(TAG, "updatable driver package is not compatible with O"); } return false; } Loading @@ -853,7 +859,7 @@ public class GraphicsEnvironment { if (DEBUG) { // This is the normal case for the pre-installed empty driver package, don't spam if (driverAppInfo.isUpdatedSystemApp()) { Log.w(TAG, "updated driver package has no compatible native libraries"); Log.w(TAG, "Updatable driver package has no compatible native libraries"); } } return false; Loading @@ -867,11 +873,8 @@ public class GraphicsEnvironment { .append(abi); final String paths = sb.toString(); final String sphalLibraries = getSphalLibraries(context, driverPackageName); if (DEBUG) { Log.v(TAG, "gfx driver package search path: " + paths Log.v(TAG, "Updatable driver package search path: " + paths + ", required sphal libraries: " + sphalLibraries); } setDriverPathAndSphalLibraries(paths, sphalLibraries); if (driverAppInfo.metaData == null) { Loading @@ -880,7 +883,7 @@ public class GraphicsEnvironment { String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); if (driverBuildTime == null || driverBuildTime.length() <= 1) { Log.v(TAG, "com.android.graphics.driver.build_time is not set"); Log.w(TAG, "com.android.graphics.driver.build_time is not set"); driverBuildTime = "L0"; } // driver_build_time in the meta-data is in "L<Unix epoch timestamp>" format. e.g. L123456. Loading Loading
core/java/android/os/GraphicsEnvironment.java +115 −112 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.pm.ResolveInfo; import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; Loading @@ -43,11 +44,14 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** @hide */ /** * GraphicsEnvironment sets up necessary properties for the graphics environment of the * application process. * * @hide */ public class GraphicsEnvironment { private static final GraphicsEnvironment sInstance = new GraphicsEnvironment(); Loading @@ -64,27 +68,35 @@ public class GraphicsEnvironment { private static final String SYSTEM_DRIVER_NAME = "system"; private static final String SYSTEM_DRIVER_VERSION_NAME = ""; private static final long SYSTEM_DRIVER_VERSION_CODE = 0; // System properties related to updatable graphics drivers. private static final String PROPERTY_GFX_DRIVER_PRODUCTION = "ro.gfx.driver.0"; private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1"; private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time"; // Metadata flags within the <application> tag in the AndroidManifest.xml file. private static final String METADATA_DRIVER_BUILD_TIME = "com.android.graphics.driver.build_time"; private static final String METADATA_DEVELOPER_DRIVER_ENABLE = "com.android.graphics.developerdriver.enable"; private static final String METADATA_INJECT_LAYERS_ENABLE = "com.android.graphics.injectLayers.enable"; private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*"; private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; // ANGLE related properties. private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private static final String ANGLE_TEMP_RULES = "debug.angle.rules"; private static final String ACTION_ANGLE_FOR_ANDROID = "android.app.action.ANGLE_FOR_ANDROID"; private static final String ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE = "android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE"; private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message"; private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*"; private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt"; private static final int VULKAN_1_0 = 0x00400000; private static final int VULKAN_1_1 = 0x00401000; // UPDATABLE_DRIVER_ALL_APPS // Values for UPDATABLE_DRIVER_ALL_APPS // 0: Default (Invalid values fallback to default as well) // 1: All apps use updatable production driver // 2: All apps use updatable prerelease driver Loading @@ -94,6 +106,15 @@ public class GraphicsEnvironment { private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2; private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3; // Values for GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE private static final int ANGLE_GL_DRIVER_ALL_ANGLE_ON = 1; private static final int ANGLE_GL_DRIVER_ALL_ANGLE_OFF = 0; // Values for GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES private static final String ANGLE_GL_DRIVER_CHOICE_DEFAULT = "default"; private static final String ANGLE_GL_DRIVER_CHOICE_ANGLE = "angle"; private static final String ANGLE_GL_DRIVER_CHOICE_NATIVE = "native"; private ClassLoader mClassLoader; private String mLibrarySearchPaths; private String mLibraryPermittedPaths; Loading @@ -106,12 +127,15 @@ public class GraphicsEnvironment { final String packageName = context.getPackageName(); final ApplicationInfo appInfoWithMetaData = getAppInfoWithMetadata(context, pm, packageName); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupGpuLayers"); setupGpuLayers(context, coreSettings, pm, packageName, appInfoWithMetaData); Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setupAngle"); setupAngle(context, coreSettings, pm, packageName); Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "chooseDriver"); if (!chooseDriver(context, coreSettings, pm, packageName, appInfoWithMetaData)) { setGpuStats(SYSTEM_DRIVER_NAME, SYSTEM_DRIVER_VERSION_NAME, SYSTEM_DRIVER_VERSION_CODE, Loading @@ -132,36 +156,30 @@ public class GraphicsEnvironment { */ public static boolean shouldUseAngle(Context context, Bundle coreSettings, String packageName) { if (packageName.isEmpty()) { Log.v(TAG, "No package name available yet, ANGLE should not be used"); if (TextUtils.isEmpty(packageName)) { Log.v(TAG, "No package name specified, ANGLE should not be used"); return false; } final String devOptIn = getDriverForPkg(context, coreSettings, packageName); if (DEBUG) { final String devOptIn = getDriverForPackage(context, coreSettings, packageName); Log.v(TAG, "ANGLE Developer option for '" + packageName + "' " + "set to: '" + devOptIn + "'"); } // We only want to use ANGLE if the app is allowlisted or the developer has // We only want to use ANGLE if the app is in the allowlist, or the developer has // explicitly chosen something other than default driver. // The allowlist 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. final boolean allowlisted = checkAngleAllowlist(context, coreSettings, packageName); final boolean requested = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.ANGLE)); final boolean useAngle = (allowlisted || requested); if (!useAngle) { return false; } final boolean allowed = checkAngleAllowlist(context, coreSettings, packageName); final boolean requested = devOptIn.equals(ANGLE_GL_DRIVER_CHOICE_ANGLE); if (allowlisted) { if (allowed) { Log.v(TAG, "ANGLE allowlist includes " + packageName); } if (requested) { Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn); } return true; return allowed || requested; } private static int getVulkanVersion(PackageManager pm) { Loading Loading @@ -315,23 +333,6 @@ public class GraphicsEnvironment { setLayerPaths(mClassLoader, layerPaths); } enum OpenGlDriverChoice { DEFAULT, NATIVE, ANGLE } private static final Map<OpenGlDriverChoice, String> sDriverMap = buildMap(); private static Map<OpenGlDriverChoice, String> buildMap() { final Map<OpenGlDriverChoice, String> map = new HashMap<>(); map.put(OpenGlDriverChoice.DEFAULT, "default"); map.put(OpenGlDriverChoice.ANGLE, "angle"); map.put(OpenGlDriverChoice.NATIVE, "native"); return map; } private static List<String> getGlobalSettingsString(ContentResolver contentResolver, Bundle bundle, String globalSetting) { Loading Loading @@ -378,18 +379,25 @@ public class GraphicsEnvironment { return ai; } private static String getDriverForPkg(Context context, Bundle bundle, String packageName) { final String allUseAngle; private static String getDriverForPackage(Context context, Bundle bundle, String packageName) { final int allUseAngle; if (bundle != null) { allUseAngle = bundle.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); bundle.getInt(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); } else { ContentResolver contentResolver = context.getContentResolver(); allUseAngle = Settings.Global.getString(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE); allUseAngle = Settings.Global.getInt(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE, ANGLE_GL_DRIVER_ALL_ANGLE_OFF); } if ((allUseAngle != null) && allUseAngle.equals("1")) { return sDriverMap.get(OpenGlDriverChoice.ANGLE); if (allUseAngle == ANGLE_GL_DRIVER_ALL_ANGLE_ON) { Log.v(TAG, "Turn on ANGLE for all applications."); return ANGLE_GL_DRIVER_CHOICE_ANGLE; } // Make sure we have a good package name if (TextUtils.isEmpty(packageName)) { return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } final ContentResolver contentResolver = context.getContentResolver(); Loading @@ -400,25 +408,21 @@ public class GraphicsEnvironment { getGlobalSettingsString(contentResolver, bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES); // Make sure we have a good package name if ((packageName == null) || (packageName.isEmpty())) { return sDriverMap.get(OpenGlDriverChoice.DEFAULT); } // Make sure we have good settings to use if (globalSettingsDriverPkgs.size() != globalSettingsDriverValues.size()) { Log.w(TAG, "Global.Settings values are invalid: " + "globalSettingsDriverPkgs.size = " + "number of packages: " + globalSettingsDriverPkgs.size() + ", " + "globalSettingsDriverValues.size = " + "number of values: " + globalSettingsDriverValues.size()); return sDriverMap.get(OpenGlDriverChoice.DEFAULT); return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } final int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs); if (pkgIndex < 0) { return sDriverMap.get(OpenGlDriverChoice.DEFAULT); return ANGLE_GL_DRIVER_CHOICE_DEFAULT; } return globalSettingsDriverValues.get(pkgIndex); Loading Loading @@ -446,11 +450,15 @@ public class GraphicsEnvironment { } /** * Check for ANGLE debug package, but only for apps that can load them (dumpable) * Check for ANGLE debug package, but only for apps that can load them. * An application can load ANGLE debug package if it is a debuggable application, or * the device is debuggable. */ private String getAngleDebugPackage(Context context, Bundle coreSettings) { if (isDebuggable()) { String debugPackage; if (!isDebuggable()) { return ""; } final String debugPackage; if (coreSettings != null) { debugPackage = Loading @@ -460,14 +468,11 @@ public class GraphicsEnvironment { debugPackage = Settings.Global.getString(contentResolver, Settings.Global.GLOBAL_SETTINGS_ANGLE_DEBUG_PACKAGE); } if ((debugPackage != null) && (!debugPackage.isEmpty())) { return debugPackage; } } if (TextUtils.isEmpty(debugPackage)) { return ""; } return debugPackage; } /** * Attempt to setup ANGLE with a temporary rules file. Loading @@ -491,7 +496,7 @@ public class GraphicsEnvironment { final String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES); if ((angleTempRules == null) || angleTempRules.isEmpty()) { if (TextUtils.isEmpty(angleTempRules)) { Log.v(TAG, "System property '" + ANGLE_TEMP_RULES + "' is not set or is empty"); return false; } Loading Loading @@ -583,11 +588,12 @@ public class GraphicsEnvironment { * * @param context * @param bundle * @param packageName * @param pm * @param packageName - package name of the application. * @return true: ANGLE setup successfully * false: ANGLE not setup (not on allowlist, ANGLE not present, etc.) */ public boolean setupAngle(Context context, Bundle bundle, PackageManager pm, private boolean setupAngle(Context context, Bundle bundle, PackageManager pm, String packageName) { if (!shouldUseAngle(context, bundle, packageName)) { Loading @@ -612,7 +618,11 @@ public class GraphicsEnvironment { // Otherwise, check to see if ANGLE is properly installed if (angleInfo == null) { anglePkgName = getAnglePackageName(pm); if (!anglePkgName.isEmpty()) { if (TextUtils.isEmpty(anglePkgName)) { Log.w(TAG, "Failed to find ANGLE package."); return false; } Log.i(TAG, "ANGLE package enabled: " + anglePkgName); try { // Production ANGLE libraries must be pre-installed as a system app Loading @@ -622,10 +632,6 @@ public class GraphicsEnvironment { Log.w(TAG, "ANGLE package '" + anglePkgName + "' not installed"); return false; } } else { Log.e(TAG, "Failed to find ANGLE package."); return false; } } final String abi = chooseAbi(angleInfo); Loading @@ -645,7 +651,7 @@ public class GraphicsEnvironment { // load a driver, GraphicsEnv::getShouldUseAngle() has seen the package name before // and can confidently answer yes/no based on the previously set developer // option value. final String devOptIn = getDriverForPkg(context, bundle, packageName); final String devOptIn = getDriverForPackage(context, bundle, packageName); if (setupAngleWithTempRulesFile(context, packageName, paths, devOptIn)) { // We setup ANGLE with a temp rules file, so we're done here. Loading Loading @@ -730,18 +736,18 @@ public class GraphicsEnvironment { final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty(); if (!hasProductionDriver && !hasPrereleaseDriver) { if (DEBUG) { Log.v(TAG, "Neither updatable production driver nor prerelease driver is supported."); } Log.v(TAG, "Neither updatable production driver nor prerelease driver is supported."); return null; } // To minimize risk of driver updates crippling the device beyond user repair, never use an // updated driver for privileged or non-updated system apps. Presumably pre-installed apps // were tested thoroughly with the pre-installed driver. // To minimize risk of driver updates crippling the device beyond user repair, never use the // updatable drivers for privileged or non-updated system apps. Presumably pre-installed // apps were tested thoroughly with the system driver. if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) { if (DEBUG) Log.v(TAG, "Ignoring driver package for privileged/non-updated system app."); if (DEBUG) { Log.v(TAG, "Ignore updatable driver package for privileged/non-updated system app."); } return null; } Loading @@ -758,13 +764,13 @@ public class GraphicsEnvironment { // 6. UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST switch (coreSettings.getInt(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, 0)) { case UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF: if (DEBUG) Log.v(TAG, "updatable driver is turned off on this device."); Log.v(TAG, "The updatable driver is turned off on this device."); return null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER: if (DEBUG) Log.v(TAG, "All apps opt in to use updatable production driver."); Log.v(TAG, "All apps opt in to use updatable production driver."); return hasProductionDriver ? productionDriver : null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER: if (DEBUG) Log.v(TAG, "All apps opt in to use updatable prerelease driver."); Log.v(TAG, "All apps opt in to use updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; case UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT: default: Loading @@ -775,20 +781,20 @@ public class GraphicsEnvironment { if (getGlobalSettingsString(null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App opts out for updatable production driver."); Log.v(TAG, "App opts out for updatable production driver."); return null; } if (getGlobalSettingsString( null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App opts in for updatable prerelease driver."); Log.v(TAG, "App opts in for updatable prerelease driver."); return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null; } // Early return here since the rest logic is only for updatable production Driver. if (!hasProductionDriver) { if (DEBUG) Log.v(TAG, "Updatable production driver is not supported on the device."); Log.v(TAG, "Updatable production driver is not supported on the device."); return null; } Loading @@ -801,7 +807,7 @@ public class GraphicsEnvironment { Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST); if (!isOptIn && allowlist.indexOf(UPDATABLE_DRIVER_ALLOWLIST_ALL) != 0 && !allowlist.contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App is not on the allowlist for updatable production driver."); Log.v(TAG, "App is not on the allowlist for updatable production driver."); return null; } Loading @@ -811,7 +817,7 @@ public class GraphicsEnvironment { && getGlobalSettingsString( null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST) .contains(appPackageName)) { if (DEBUG) Log.v(TAG, "App is on the denylist for updatable production driver."); Log.v(TAG, "App is on the denylist for updatable production driver."); return null; } Loading @@ -834,7 +840,7 @@ public class GraphicsEnvironment { driverPackageInfo = pm.getPackageInfo(driverPackageName, PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); Log.w(TAG, "updatable driver package '" + driverPackageName + "' not installed"); return false; } Loading @@ -843,7 +849,7 @@ public class GraphicsEnvironment { final ApplicationInfo driverAppInfo = driverPackageInfo.applicationInfo; if (driverAppInfo.targetSdkVersion < Build.VERSION_CODES.O) { if (DEBUG) { Log.w(TAG, "updated driver package is not known to be compatible with O"); Log.w(TAG, "updatable driver package is not compatible with O"); } return false; } Loading @@ -853,7 +859,7 @@ public class GraphicsEnvironment { if (DEBUG) { // This is the normal case for the pre-installed empty driver package, don't spam if (driverAppInfo.isUpdatedSystemApp()) { Log.w(TAG, "updated driver package has no compatible native libraries"); Log.w(TAG, "Updatable driver package has no compatible native libraries"); } } return false; Loading @@ -867,11 +873,8 @@ public class GraphicsEnvironment { .append(abi); final String paths = sb.toString(); final String sphalLibraries = getSphalLibraries(context, driverPackageName); if (DEBUG) { Log.v(TAG, "gfx driver package search path: " + paths Log.v(TAG, "Updatable driver package search path: " + paths + ", required sphal libraries: " + sphalLibraries); } setDriverPathAndSphalLibraries(paths, sphalLibraries); if (driverAppInfo.metaData == null) { Loading @@ -880,7 +883,7 @@ public class GraphicsEnvironment { String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME); if (driverBuildTime == null || driverBuildTime.length() <= 1) { Log.v(TAG, "com.android.graphics.driver.build_time is not set"); Log.w(TAG, "com.android.graphics.driver.build_time is not set"); driverBuildTime = "L0"; } // driver_build_time in the meta-data is in "L<Unix epoch timestamp>" format. e.g. L123456. Loading