diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index f2e0bddb93aa3..b1408f46635ea 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -19,6 +19,7 @@ package android.os; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.res.AssetManager; import android.opengl.EGL14; import android.os.Build; import android.os.SystemProperties; @@ -27,7 +28,13 @@ import android.util.Log; import dalvik.system.VMRuntime; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashSet; +import java.util.Set; /** @hide */ public class GraphicsEnvironment { @@ -44,6 +51,7 @@ public class GraphicsEnvironment { private static final boolean DEBUG = false; private static final String TAG = "GraphicsEnvironment"; private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0"; + private static final String PROPERTY_GFX_DRIVER_WHITELIST = "ro.gfx.driver.whitelist.0"; private ClassLoader mClassLoader; private String mLayerPath; @@ -146,6 +154,15 @@ public class GraphicsEnvironment { if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app"); return; } + Set whitelist = loadWhitelist(context, driverPackageName); + + // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed + // updatable graphics driver is supposed to be a place holder and contains no graphics + // driver and whitelist. + if (whitelist == null || whitelist.isEmpty()) { + return; + } + ApplicationInfo driverInfo; try { driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName, @@ -154,6 +171,22 @@ public class GraphicsEnvironment { Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); return; } + if (!whitelist.contains(context.getPackageName())) { + if (DEBUG) { + Log.w(TAG, context.getPackageName() + " is not on the whitelist."); + } + return; + } + + // O drivers are restricted to the sphal linker namespace, so don't try to use + // packages unless they declare they're compatible with that restriction. + if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) { + if (DEBUG) { + Log.w(TAG, "updated driver package is not known to be compatible with O"); + } + return; + } + String abi = chooseAbi(driverInfo); if (abi == null) { if (DEBUG) { @@ -164,12 +197,6 @@ public class GraphicsEnvironment { } return; } - if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) { - // O drivers are restricted to the sphal linker namespace, so don't try to use - // packages unless they declare they're compatible with that restriction. - Log.w(TAG, "updated driver package is not known to be compatible with O"); - return; - } StringBuilder sb = new StringBuilder(); sb.append(driverInfo.nativeLibraryDir) @@ -215,6 +242,34 @@ public class GraphicsEnvironment { return null; } + private static Set loadWhitelist(Context context, String driverPackageName) { + String whitelistName = SystemProperties.get(PROPERTY_GFX_DRIVER_WHITELIST); + if (whitelistName == null || whitelistName.isEmpty()) { + return null; + } + try { + Context driverContext = context.createPackageContext(driverPackageName, + Context.CONTEXT_RESTRICTED); + AssetManager assets = driverContext.getAssets(); + InputStream stream = assets.open(whitelistName); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + Set whitelist = new HashSet<>(); + for (String line; (line = reader.readLine()) != null; ) { + whitelist.add(line); + } + return whitelist; + } catch (PackageManager.NameNotFoundException e) { + if (DEBUG) { + Log.w(TAG, "driver package '" + driverPackageName + "' not installed"); + } + } catch (IOException e) { + if (DEBUG) { + Log.w(TAG, "Failed to load whitelist driver package, abort."); + } + } + return null; + } + private static native void setLayerPaths(ClassLoader classLoader, String layerPaths); private static native void setDebugLayers(String layers); private static native void setDriverPath(String path); diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto index 8bf3772a6a5d2..973fa5a5e1bd3 100644 --- a/core/proto/android/os/system_properties.proto +++ b/core/proto/android/os/system_properties.proto @@ -460,7 +460,9 @@ message SystemPropertiesProto { optional int32 vts_coverage = 43; optional string zygote = 44; - // Next Tag: 45 + optional string gfx_driver_whitelist_0 = 45; + + // Next Tag: 46 } optional Ro ro = 21;