Merge "Allow to load implicit layer from /vendor/app." into rvc-dev am: 1371b76afd

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11688191

Change-Id: I9c2d8ff45956fd8c6b922d2dc13272b6c1711ee5
This commit is contained in:
Peiyong Lin
2020-06-04 00:53:46 +00:00
committed by Automerger Merge Worker
3 changed files with 136 additions and 78 deletions

View File

@@ -7388,6 +7388,10 @@ public final class ActivityThread extends ClientTransactionHandler {
} }
} }
public Bundle getCoreSettings() {
return mCoreSettings;
}
public int getIntCoreSetting(String key, int defaultValue) { public int getIntCoreSetting(String key, int defaultValue) {
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
if (mCoreSettings != null) { if (mCoreSettings != null) {
@@ -7397,6 +7401,18 @@ public final class ActivityThread extends ClientTransactionHandler {
} }
} }
/**
* Get the string value of the given key from core settings.
*/
public String getStringCoreSetting(String key, String defaultValue) {
synchronized (mResourcesManager) {
if (mCoreSettings != null) {
return mCoreSettings.getString(key, defaultValue);
}
return defaultValue;
}
}
float getFloatCoreSetting(String key, float defaultValue) { float getFloatCoreSetting(String key, float defaultValue) {
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
if (mCoreSettings != null) { if (mCoreSettings != null) {

View File

@@ -38,6 +38,7 @@ import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.FileUtils; import android.os.FileUtils;
import android.os.GraphicsEnvironment;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Process; import android.os.Process;
@@ -46,6 +47,7 @@ import android.os.StrictMode;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings;
import android.security.net.config.NetworkSecurityConfigProvider; import android.security.net.config.NetworkSecurityConfigProvider;
import android.sysprop.VndkProperties; import android.sysprop.VndkProperties;
import android.text.TextUtils; import android.text.TextUtils;
@@ -824,6 +826,32 @@ public final class LoadedApk {
final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths); final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
if (mActivityThread != null) {
final String gpuDebugApp = mActivityThread.getStringCoreSetting(
Settings.Global.GPU_DEBUG_APP, "");
if (!gpuDebugApp.isEmpty() && mPackageName.equals(gpuDebugApp)) {
// The current application is used to debug, attempt to get the debug layers.
try {
// Get the ApplicationInfo from PackageManager so that metadata fields present.
final ApplicationInfo ai = ActivityThread.getPackageManager()
.getApplicationInfo(mPackageName, PackageManager.GET_META_DATA,
UserHandle.myUserId());
final String debugLayerPath = GraphicsEnvironment.getInstance()
.getDebugLayerPathsFromSettings(mActivityThread.getCoreSettings(),
ActivityThread.getPackageManager(), mPackageName, ai);
if (debugLayerPath != null) {
libraryPermittedPath += File.pathSeparator + debugLayerPath;
}
} catch (RemoteException e) {
// Unlikely to fail for applications, but in case of failure, something is wrong
// inside the system server, hence just skip.
Slog.e(ActivityThread.TAG,
"RemoteException when fetching debug layer paths for: " + mPackageName);
}
}
}
// If we're not asked to include code, we construct a classloader that has // If we're not asked to include code, we construct a classloader that has
// no code path included. We still need to set up the library search paths // no code path included. We still need to set up the library search paths
// and permitted path because NativeActivity relies on it (it attempts to // and permitted path because NativeActivity relies on it (it attempts to

View File

@@ -22,6 +22,7 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
@@ -93,8 +94,8 @@ public class GraphicsEnvironment {
private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3; private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3;
private ClassLoader mClassLoader; private ClassLoader mClassLoader;
private String mLayerPath; private String mLibrarySearchPaths;
private String mDebugLayerPath; private String mLibraryPermittedPaths;
/** /**
* Set up GraphicsEnvironment * Set up GraphicsEnvironment
@@ -185,118 +186,131 @@ public class GraphicsEnvironment {
} }
/** /**
* Store the layer paths available to the loader. * Store the class loader for namespace lookup later.
*/ */
public void setLayerPaths(ClassLoader classLoader, public void setLayerPaths(ClassLoader classLoader,
String layerPath, String searchPaths,
String debugLayerPath) { String permittedPaths) {
// We have to store these in the class because they are set up before we // We have to store these in the class because they are set up before we
// have access to the Context to properly set up GraphicsEnvironment // have access to the Context to properly set up GraphicsEnvironment
mClassLoader = classLoader; mClassLoader = classLoader;
mLayerPath = layerPath; mLibrarySearchPaths = searchPaths;
mDebugLayerPath = debugLayerPath; mLibraryPermittedPaths = permittedPaths;
}
/**
* Returns the debug layer paths from settings.
* Returns null if:
* 1) The application process is not debuggable or layer injection metadata flag is not
* true; Or
* 2) ENABLE_GPU_DEBUG_LAYERS is not true; Or
* 3) Package name is not equal to GPU_DEBUG_APP.
*/
public String getDebugLayerPathsFromSettings(
Bundle coreSettings, IPackageManager pm, String packageName,
ApplicationInfo ai) {
if (!debugLayerEnabled(coreSettings, packageName, ai)) {
return null;
}
Log.i(TAG, "GPU debug layers enabled for " + packageName);
String debugLayerPaths = "";
// Grab all debug layer apps and add to paths.
final String gpuDebugLayerApps =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP, "");
if (!gpuDebugLayerApps.isEmpty()) {
Log.i(TAG, "GPU debug layer apps: " + gpuDebugLayerApps);
// If a colon is present, treat this as multiple apps, so Vulkan and GLES
// layer apps can be provided at the same time.
final String[] layerApps = gpuDebugLayerApps.split(":");
for (int i = 0; i < layerApps.length; i++) {
String paths = getDebugLayerAppPaths(pm, layerApps[i]);
if (!paths.isEmpty()) {
// Append the path so files placed in the app's base directory will
// override the external path
debugLayerPaths += paths + File.pathSeparator;
}
}
}
return debugLayerPaths;
} }
/** /**
* Return the debug layer app's on-disk and in-APK lib directories * Return the debug layer app's on-disk and in-APK lib directories
*/ */
private static String getDebugLayerAppPaths(PackageManager pm, String app) { private static String getDebugLayerAppPaths(IPackageManager pm, String packageName) {
final ApplicationInfo appInfo; final ApplicationInfo appInfo;
try { try {
appInfo = pm.getApplicationInfo(app, PackageManager.MATCH_ALL); appInfo = pm.getApplicationInfo(packageName, PackageManager.MATCH_ALL,
} catch (PackageManager.NameNotFoundException e) { UserHandle.myUserId());
Log.w(TAG, "Debug layer app '" + app + "' not installed"); } catch (RemoteException e) {
return "";
return null; }
if (appInfo == null) {
Log.w(TAG, "Debug layer app '" + packageName + "' not installed");
} }
final String abi = chooseAbi(appInfo); final String abi = chooseAbi(appInfo);
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append(appInfo.nativeLibraryDir) sb.append(appInfo.nativeLibraryDir)
.append(File.pathSeparator); .append(File.pathSeparator)
sb.append(appInfo.sourceDir) .append(appInfo.sourceDir)
.append("!/lib/") .append("!/lib/")
.append(abi); .append(abi);
final String paths = sb.toString(); final String paths = sb.toString();
if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths); if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths);
return paths; return paths;
} }
/** private boolean debugLayerEnabled(Bundle coreSettings, String packageName, ApplicationInfo ai) {
* Set up layer search paths for all apps
* If debuggable, check for additional debug settings
*/
private void setupGpuLayers(
Context context, Bundle coreSettings, PackageManager pm, String packageName,
ApplicationInfo ai) {
String layerPaths = "";
// Only enable additional debug functionality if the following conditions are met: // Only enable additional debug functionality if the following conditions are met:
// 1. App is debuggable or device is rooted or layer injection metadata flag is true // 1. App is debuggable or device is rooted or layer injection metadata flag is true
// 2. ENABLE_GPU_DEBUG_LAYERS is true // 2. ENABLE_GPU_DEBUG_LAYERS is true
// 3. Package name is equal to GPU_DEBUG_APP // 3. Package name is equal to GPU_DEBUG_APP
if (!isDebuggable() && !canInjectLayers(ai)) {
return false;
}
final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
if (enable == 0) {
return false;
}
final String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP, "");
if (packageName == null
|| (gpuDebugApp.isEmpty() || packageName.isEmpty())
|| !gpuDebugApp.equals(packageName)) {
return false;
}
return true;
}
if (isDebuggable() || canInjectLayers(ai)) { /**
* Set up layer search paths for all apps
*/
private void setupGpuLayers(
Context context, Bundle coreSettings, PackageManager pm, String packageName,
ApplicationInfo ai) {
final boolean enabled = debugLayerEnabled(coreSettings, packageName, ai);
String layerPaths = "";
if (enabled) {
layerPaths = mLibraryPermittedPaths;
final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0); final String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
Log.i(TAG, "Vulkan debug layer list: " + layers);
if (layers != null && !layers.isEmpty()) {
setDebugLayers(layers);
}
if (enable != 0) { final String layersGLES =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS_GLES);
final String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP); Log.i(TAG, "GLES debug layer list: " + layersGLES);
if (layersGLES != null && !layersGLES.isEmpty()) {
if ((gpuDebugApp != null && packageName != null) setDebugLayersGLES(layersGLES);
&& (!gpuDebugApp.isEmpty() && !packageName.isEmpty())
&& gpuDebugApp.equals(packageName)) {
Log.i(TAG, "GPU debug layers enabled for " + packageName);
// Prepend the debug layer path as a searchable path.
// This will ensure debug layers added will take precedence over
// the layers specified by the app.
layerPaths = mDebugLayerPath + ":";
// If there is a debug layer app specified, add its path.
final String gpuDebugLayerApp =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP);
if (gpuDebugLayerApp != null && !gpuDebugLayerApp.isEmpty()) {
Log.i(TAG, "GPU debug layer app: " + gpuDebugLayerApp);
// If a colon is present, treat this as multiple apps, so Vulkan and GLES
// layer apps can be provided at the same time.
String[] layerApps = gpuDebugLayerApp.split(":");
for (int i = 0; i < layerApps.length; i++) {
String paths = getDebugLayerAppPaths(pm, layerApps[i]);
if (paths != null) {
// Append the path so files placed in the app's base directory will
// override the external path
layerPaths += paths + ":";
}
}
}
final String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
Log.i(TAG, "Vulkan debug layer list: " + layers);
if (layers != null && !layers.isEmpty()) {
setDebugLayers(layers);
}
final String layersGLES =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS_GLES);
Log.i(TAG, "GLES debug layer list: " + layersGLES);
if (layersGLES != null && !layersGLES.isEmpty()) {
setDebugLayersGLES(layersGLES);
}
}
} }
} }
// Include the app's lib directory in all cases // Include the app's lib directory in all cases
layerPaths += mLayerPath; layerPaths += mLibrarySearchPaths;
setLayerPaths(mClassLoader, layerPaths); setLayerPaths(mClassLoader, layerPaths);
} }