From 7fd4421f7f85874efe0083cc7853f85e3d9d4e51 Mon Sep 17 00:00:00 2001 From: Cody Northrop Date: Thu, 6 Sep 2018 10:30:28 -0600 Subject: [PATCH] Find and load ANGLE rules, pass to libEGL In order to load a text file from an APK, it must be present in the assets folder and be uncompressed. The AssetManager can find assets from any application, so we point it at ANGLE. We then pass the file descriptor, offset, and size, down to the loader so it can parse json from the asset. Bug: 80239516 Test: Manual build, ensure we can inspect rules from modified APK Test: cts-tradefed run singleCommand cts -m CtsAngleIntegrationHostTestCases Change-Id: Ib3ecce34b043753b2894915975b6dd8440154ae2 (cherry-picked from commit cfaa0ba52fcf60578acdd64bc4dc9a00f6e300ed) --- core/java/android/os/GraphicsEnvironment.java | 40 ++++++++++++++++++- core/jni/android_os_GraphicsEnvironment.cpp | 10 +++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java index 384115b2d8f12..0c56d48841057 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.AssetFileDescriptor; import android.content.res.AssetManager; import android.opengl.EGL14; import android.os.Build; @@ -30,6 +31,7 @@ import dalvik.system.VMRuntime; import java.io.BufferedReader; import java.io.File; +import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -54,6 +56,7 @@ public class GraphicsEnvironment { private static final String PROPERTY_GFX_DRIVER_WHITELIST = "ro.gfx.driver.whitelist.0"; private static final String ANGLE_PACKAGE_NAME = "com.android.angle"; private static final String GLES_MODE_METADATA_KEY = "com.android.angle.GLES_MODE"; + private static final String ANGLE_RULES_FILE = "a4a_rules.json"; private ClassLoader mClassLoader; private String mLayerPath; @@ -250,8 +253,40 @@ public class GraphicsEnvironment { if (DEBUG) Log.v(TAG, "ANGLE package libs: " + paths); + // Pass the rules file to loader for ANGLE decisions + AssetManager angleAssets = null; + try { + angleAssets = + context.getPackageManager().getResourcesForApplication(angleInfo).getAssets(); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Failed to get AssetManager for '" + ANGLE_PACKAGE_NAME + "'"); + return; + } + + AssetFileDescriptor assetsFd = null; + try { + assetsFd = angleAssets.openFd(ANGLE_RULES_FILE); + } catch (IOException e) { + Log.w(TAG, "Failed to get AssetFileDescriptor for " + ANGLE_RULES_FILE + " from " + + "'" + ANGLE_PACKAGE_NAME + "'"); + return; + } + + FileDescriptor rulesFd = null; + long rulesOffset = 0; + long rulesLength = 0; + if (assetsFd != null) { + rulesFd = assetsFd.getFileDescriptor(); + rulesOffset = assetsFd.getStartOffset(); + rulesLength = assetsFd.getLength(); + } else { + Log.w(TAG, "Failed to get file descriptor for " + ANGLE_RULES_FILE); + return; + } + // Further opt-in logic is handled in native, so pass relevant info down - setAngleInfo(paths, packageName, appPref, devOptIn); + setAngleInfo(paths, packageName, appPref, devOptIn, + rulesFd, rulesOffset, rulesLength); } /** @@ -391,5 +426,6 @@ public class GraphicsEnvironment { private static native void setDebugLayers(String layers); private static native void setDriverPath(String path); private static native void setAngleInfo(String path, String appPackage, String appPref, - boolean devOptIn); + boolean devOptIn, FileDescriptor rulesFd, + long rulesOffset, long rulesLength); } diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp index 92235ad494a79..e64da5ca0b243 100644 --- a/core/jni/android_os_GraphicsEnvironment.cpp +++ b/core/jni/android_os_GraphicsEnvironment.cpp @@ -32,12 +32,16 @@ void setDriverPath(JNIEnv* env, jobject clazz, jstring path) { android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str()); } -void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring appPref, jboolean devOptIn) { +void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring appPref, jboolean devOptIn, + jobject rulesFd, jlong rulesOffset, jlong rulesLength) { ScopedUtfChars pathChars(env, path); ScopedUtfChars appNameChars(env, appName); ScopedUtfChars appPrefChars(env, appPref); + + int rulesFd_native = jniGetFDFromFileDescriptor(env, rulesFd); + android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(), - appPrefChars.c_str(), devOptIn); + appPrefChars.c_str(), devOptIn, rulesFd_native, rulesOffset, rulesLength); } void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) { @@ -57,7 +61,7 @@ void setDebugLayers_native(JNIEnv* env, jobject clazz, jstring layers) { const JNINativeMethod g_methods[] = { { "getCanLoadSystemLibraries", "()I", reinterpret_cast(getCanLoadSystemLibraries_native) }, { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast(setDriverPath) }, - { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", reinterpret_cast(setAngleInfo_native) }, + { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/io/FileDescriptor;JJ)V", reinterpret_cast(setAngleInfo_native) }, { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast(setLayerPaths_native) }, { "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast(setDebugLayers_native) }, };