[layout compilation] Disable precompiled layouts when preferCodeIntegrity is set
This feature involves generating and loading code on the
application. Applications may use the preferCodeIntegrity flag to indicate they
do not want this behavior, so we need to respect this preference. We also
disable loading precompiled layouts for privapps.
Bug: 111895153
Change-Id: I5c563e9f6eb7dd5eb7aac7df3838888f71b38866
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 878b6b6..dc7c343 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -22,6 +22,7 @@
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
@@ -398,19 +399,31 @@
}
private void initPrecompiledViews() {
+ // Check if precompiled layouts are enabled by a system property.
+ mUseCompiledView =
+ SystemProperties.getBoolean(USE_PRECOMPILED_LAYOUT_SYSTEM_PROPERTY, false);
+ if (!mUseCompiledView) {
+ return;
+ }
+
+ // Make sure the application allows code generation
+ ApplicationInfo appInfo = mContext.getApplicationInfo();
+ if ((appInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PREFER_CODE_INTEGRITY) != 0
+ || appInfo.isPrivilegedApp()) {
+ mUseCompiledView = false;
+ return;
+ }
+
+ // Try to load the precompiled layout file.
try {
- mUseCompiledView =
- SystemProperties.getBoolean(USE_PRECOMPILED_LAYOUT_SYSTEM_PROPERTY, false);
- if (mUseCompiledView) {
- mPrecompiledClassLoader = mContext.getClassLoader();
- String dexFile = mContext.getCodeCacheDir() + COMPILED_VIEW_DEX_FILE_NAME;
- if (new File(dexFile).exists()) {
- mPrecompiledClassLoader = new PathClassLoader(dexFile, mPrecompiledClassLoader);
- } else {
- // If the precompiled layout file doesn't exist, then disable precompiled
- // layouts.
- mUseCompiledView = false;
- }
+ mPrecompiledClassLoader = mContext.getClassLoader();
+ String dexFile = mContext.getCodeCacheDir() + COMPILED_VIEW_DEX_FILE_NAME;
+ if (new File(dexFile).exists()) {
+ mPrecompiledClassLoader = new PathClassLoader(dexFile, mPrecompiledClassLoader);
+ } else {
+ // If the precompiled layout file doesn't exist, then disable precompiled
+ // layouts.
+ mUseCompiledView = false;
}
} catch (Throwable e) {
if (DEBUG) {