Use core-icu4j-for-host instead of core-icu4j am: d6d63816f6 am: 2504038a6b am: 1c79202aa4

Original change: https://android-review.googlesource.com/c/platform/frameworks/layoutlib/+/1682006

Change-Id: Icb2d5d4536ab3785ef46f35c82cdd7bac65e7ee2
diff --git a/.idea/artifacts/studio_android_widgets_jar.xml b/.idea/artifacts/studio_android_widgets_jar.xml
deleted file mode 100644
index 0450be3..0000000
--- a/.idea/artifacts/studio_android_widgets_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_jar</output-path>
-    <root id="archive" name="studio-android-widgets.jar">
-      <element id="module-output" name="studio-android-widgets" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/.idea/artifacts/studio_android_widgets_src_jar.xml b/.idea/artifacts/studio_android_widgets_src_jar.xml
deleted file mode 100644
index a844ca3..0000000
--- a/.idea/artifacts/studio_android_widgets_src_jar.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<component name="ArtifactManager">
-  <artifact type="jar" name="studio-android-widgets-src:jar">
-    <output-path>$PROJECT_DIR$/out/artifacts/studio_android_widgets_src_jar</output-path>
-    <root id="archive" name="studio-android-widgets-src.jar">
-      <element id="dir-copy" path="$PROJECT_DIR$/studio-custom-widgets/src" />
-    </root>
-  </artifact>
-</component>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 50836c1..5210215 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -9,7 +9,6 @@
       <module fileurl="file://$PROJECT_DIR$/remote/common/remote common.iml" filepath="$PROJECT_DIR$/remote/common/remote common.iml" group="remote" />
       <module fileurl="file://$PROJECT_DIR$/remote/server/remote server.iml" filepath="$PROJECT_DIR$/remote/server/remote server.iml" group="remote" />
       <module fileurl="file://$PROJECT_DIR$/remote/tests/remote tests.iml" filepath="$PROJECT_DIR$/remote/tests/remote tests.iml" group="remote" />
-      <module fileurl="file://$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" filepath="$PROJECT_DIR$/studio-custom-widgets/studio-android-widgets.iml" />
       <module fileurl="file://$PROJECT_DIR$/validator/validator.iml" filepath="$PROJECT_DIR$/validator/validator.iml" />
     </modules>
   </component>
diff --git a/bridge/Android.bp b/bridge/Android.bp
index e26f711..6e86073 100644
--- a/bridge/Android.bp
+++ b/bridge/Android.bp
@@ -36,8 +36,11 @@
         "ninepatch-prebuilt",
         "layoutlib-common",
         "layoutlib-validator",
+        "sdk-common",
     ],
 
+    jarjar_rules: "jarjar-rules.txt",
+
     dist: {
         targets: ["layoutlib"],
     },
@@ -62,8 +65,11 @@
         "ninepatch-prebuilt",
         "layoutlib-common",
         "layoutlib-validator",
+        "sdk-common",
     ],
 
+    jarjar_rules: "jarjar-rules.txt",
+
     dist: {
         targets: ["layoutlib"],
     },
diff --git a/bridge/bridge.iml b/bridge/bridge.iml
index 9358a54..c9ce012 100644
--- a/bridge/bridge.iml
+++ b/bridge/bridge.iml
@@ -102,5 +102,16 @@
         <SOURCES />
       </library>
     </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/misc/common/sdk-common/sdk-common-sources.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
   </component>
 </module>
\ No newline at end of file
diff --git a/bridge/jarjar-rules.txt b/bridge/jarjar-rules.txt
new file mode 100644
index 0000000..3318faa
--- /dev/null
+++ b/bridge/jarjar-rules.txt
@@ -0,0 +1 @@
+rule com.google.protobuf.** com.android.layoutlib.protobuf.@1
diff --git a/bridge/src/android/app/ActivityManager_Accessor.java b/bridge/src/android/app/ActivityManager_Accessor.java
new file mode 100644
index 0000000..aa79658
--- /dev/null
+++ b/bridge/src/android/app/ActivityManager_Accessor.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.annotation.NonNull;
+import android.content.Context;
+
+public class ActivityManager_Accessor {
+    @NonNull
+    public static ActivityManager getActivityManagerInstance(@NonNull Context context) {
+        return new ActivityManager(context, null);
+    }
+}
diff --git a/bridge/src/android/content/res/BridgeTypedArray.java b/bridge/src/android/content/res/BridgeTypedArray.java
index 5023dcb..eb603f0 100644
--- a/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/bridge/src/android/content/res/BridgeTypedArray.java
@@ -18,7 +18,7 @@
 
 import com.android.ide.common.rendering.api.ArrayResourceValue;
 import com.android.ide.common.rendering.api.AttrResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceNamespace;
 import com.android.ide.common.rendering.api.ResourceNamespace.Resolver;
@@ -26,6 +26,7 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.ide.common.rendering.api.TextResourceValue;
+import com.android.ide.common.resources.ValueXmlHelper;
 import com.android.internal.util.XmlUtils;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -73,6 +74,8 @@
  * Custom implementation of TypedArray to handle non compiled resources.
  */
 public final class BridgeTypedArray extends TypedArray {
+    private static final String MATCH_PARENT_INT_STRING = String.valueOf(LayoutParams.MATCH_PARENT);
+    private static final String WRAP_CONTENT_INT_STRING = String.valueOf(LayoutParams.WRAP_CONTENT);
 
     private final Resources mBridgeResources;
     private final BridgeContext mContext;
@@ -208,7 +211,9 @@
         ResourceValue resourceValue = mResourceData[index];
         String value = resourceValue.getValue();
         if (resourceValue instanceof TextResourceValue) {
-            String rawValue = resourceValue.getRawXmlValue();
+            String rawValue =
+                    ValueXmlHelper.unescapeResourceString(resourceValue.getRawXmlValue(),
+                            true, false);
             if (rawValue != null && !rawValue.equals(value)) {
                 return Html.fromHtml(rawValue, FROM_HTML_MODE_COMPACT);
             }
@@ -265,7 +270,7 @@
         try {
             return convertValueToInt(s, defValue);
         } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+            Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
                     String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer",
                             s, mNames[index]),
                     null, null);
@@ -288,7 +293,7 @@
                     return Float.parseFloat(s);
             }
         } catch (NumberFormatException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+            Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
                     String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.",
                             s, mNames[index]),
                     null, null);
@@ -382,13 +387,11 @@
             return defValue;
         }
         // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
+        if (MATCH_PARENT_INT_STRING.equals(s)) {
+            return LayoutParams.MATCH_PARENT;
+        }
+        if (WRAP_CONTENT_INT_STRING.equals(s)) {
+            return LayoutParams.WRAP_CONTENT;
         }
 
         if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
@@ -440,21 +443,33 @@
      */
     @Override
     public int getDimensionPixelSize(int index, int defValue) {
-        try {
-            return getDimension(index, null);
-        } catch (RuntimeException e) {
-            String s = getString(index);
-
-            if (s != null) {
-                // looks like we were unable to resolve the dimension value
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
-                                s, mNames[index]),
-                        null, null);
-            }
-
+        String s = getString(index);
+        if (s == null) {
             return defValue;
         }
+
+        if (MATCH_PARENT_INT_STRING.equals(s)) {
+            return LayoutParams.MATCH_PARENT;
+        }
+        if (WRAP_CONTENT_INT_STRING.equals(s)) {
+            return LayoutParams.WRAP_CONTENT;
+        }
+
+        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
+            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
+
+            final int res = (int) (f + 0.5f);
+            if (res != 0) return res;
+            if (f == 0) return 0;
+            if (f > 0) return 1;
+        }
+
+        // looks like we were unable to resolve the dimension value
+        Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
+                String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.", s, mNames[index]),
+                null, null);
+
+        return defValue;
     }
 
     /**
@@ -471,21 +486,34 @@
      */
     @Override
     public int getLayoutDimension(int index, String name) {
-        try {
-            // this will throw an exception if not found.
-            return getDimension(index, name);
-        } catch (RuntimeException e) {
-
-            if (LayoutInflater_Delegate.sIsInInclude) {
-                throw new RuntimeException("Layout Dimension '" + name + "' not found.");
+        String s = getString(index);
+        if (s != null) {
+            // Check if the value is a magic constant that doesn't require a unit.
+            if (MATCH_PARENT_INT_STRING.equals(s)) {
+                return LayoutParams.MATCH_PARENT;
+            }
+            if (WRAP_CONTENT_INT_STRING.equals(s)) {
+                return LayoutParams.WRAP_CONTENT;
             }
 
-            Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                    "You must supply a " + name + " attribute.",
-                    null, null);
+            if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
+                float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
 
-            return 0;
+                final int res = (int) (f + 0.5f);
+                if (res != 0) return res;
+                if (f == 0) return 0;
+                if (f > 0) return 1;
+            }
         }
+
+        if (LayoutInflater_Delegate.sIsInInclude) {
+            throw new RuntimeException("Layout Dimension '" + name + "' not found.");
+        }
+
+        Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
+                "You must supply a " + name + " attribute.", null, null);
+
+        return 0;
     }
 
     @Override
@@ -493,36 +521,6 @@
         return getDimensionPixelSize(index, defValue);
     }
 
-    /** @param name attribute name, used for error reporting. */
-    private int getDimension(int index, @Nullable String name) {
-        String s = getString(index);
-        if (s == null) {
-            if (name != null) {
-                throw new RuntimeException("Attribute '" + name + "' not found");
-            }
-            throw new RuntimeException();
-        }
-        // Check if the value is a magic constant that doesn't require a unit.
-        try {
-            int i = Integer.parseInt(s);
-            if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
-                return i;
-            }
-        } catch (NumberFormatException ignored) {
-            // pass
-        }
-        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
-            float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
-
-            final int res = (int)(f+0.5f);
-            if (res != 0) return res;
-            if (f == 0) return 0;
-            if (f > 0) return 1;
-        }
-
-        throw new RuntimeException();
-    }
-
     /**
      * Retrieve a fractional unit attribute at <var>index</var>.
      *
@@ -550,7 +548,7 @@
         }
 
         // looks like we were unable to resolve the fraction value
-        Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+        Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
                 String.format(
                         "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
                         value, mNames[index]),
@@ -809,57 +807,9 @@
     }
 
     @Override
-    @SuppressWarnings("ResultOfMethodCallIgnored")
     public int getType(int index) {
         String value = getString(index);
-        if (value == null) {
-            return TYPE_NULL;
-        }
-        if (value.startsWith(PREFIX_RESOURCE_REF)) {
-            return TYPE_REFERENCE;
-        }
-        if (value.startsWith(PREFIX_THEME_REF)) {
-            return TYPE_ATTRIBUTE;
-        }
-        try {
-            // Don't care about the value. Only called to check if an exception is thrown.
-            convertValueToInt(value, 0);
-            if (value.startsWith("0x") || value.startsWith("0X")) {
-                return TYPE_INT_HEX;
-            }
-            // is it a color?
-            if (value.startsWith("#")) {
-                int length = value.length() - 1;
-                if (length == 3) {  // rgb
-                    return TYPE_INT_COLOR_RGB4;
-                }
-                if (length == 4) {  // argb
-                    return TYPE_INT_COLOR_ARGB4;
-                }
-                if (length == 6) {  // rrggbb
-                    return TYPE_INT_COLOR_RGB8;
-                }
-                if (length == 8) {  // aarrggbb
-                    return TYPE_INT_COLOR_ARGB8;
-                }
-            }
-            if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
-                return TYPE_INT_BOOLEAN;
-            }
-            return TYPE_INT_DEC;
-        } catch (NumberFormatException ignored) {
-            try {
-                Float.parseFloat(value);
-                return TYPE_FLOAT;
-            } catch (NumberFormatException ignore) {
-            }
-            // Might be a dimension.
-            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
-                return TYPE_DIMENSION;
-            }
-        }
-        // TODO: handle fractions.
-        return TYPE_STRING;
+        return getType(value);
     }
 
     /**
@@ -1031,6 +981,73 @@
         return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
     }
 
+    protected static int getType(@Nullable String value) {
+        if (value == null) {
+            return TYPE_NULL;
+        }
+        if (value.startsWith(PREFIX_RESOURCE_REF)) {
+            return TYPE_REFERENCE;
+        }
+        if (value.startsWith(PREFIX_THEME_REF)) {
+            return TYPE_ATTRIBUTE;
+        }
+        if (value.equals("true") || value.equals("false")) {
+            return TYPE_INT_BOOLEAN;
+        }
+        if (value.startsWith("0x") || value.startsWith("0X")) {
+            try {
+                // Check if it is a hex value.
+                Long.parseLong(value.substring(2), 16);
+                return TYPE_INT_HEX;
+            } catch (NumberFormatException e) {
+                return TYPE_STRING;
+            }
+        }
+        if (value.startsWith("#")) {
+            try {
+                // Check if it is a color.
+                ResourceHelper.getColor(value);
+                int length = value.length() - 1;
+                if (length == 3) {  // rgb
+                    return TYPE_INT_COLOR_RGB4;
+                }
+                if (length == 4) {  // argb
+                    return TYPE_INT_COLOR_ARGB4;
+                }
+                if (length == 6) {  // rrggbb
+                    return TYPE_INT_COLOR_RGB8;
+                }
+                if (length == 8) {  // aarrggbb
+                    return TYPE_INT_COLOR_ARGB8;
+                }
+            } catch (NumberFormatException e) {
+                return TYPE_STRING;
+            }
+        }
+        if (!Character.isDigit(value.charAt(value.length() - 1))) {
+            // Check if it is a dimension.
+            if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
+                return TYPE_DIMENSION;
+            } else {
+                return TYPE_STRING;
+            }
+        }
+        try {
+            // Check if it is an int.
+            convertValueToInt(value, 0);
+            return TYPE_INT_DEC;
+        } catch (NumberFormatException ignored) {
+            try {
+                // Check if it is a float.
+                Float.parseFloat(value);
+                return TYPE_FLOAT;
+            } catch (NumberFormatException ignore) {
+            }
+        }
+        // TODO: handle fractions.
+        return TYPE_STRING;
+    }
+
     static TypedArray obtain(Resources res, int len) {
         return new BridgeTypedArray(res, null, len);
     }
diff --git a/bridge/src/android/content/res/Resources_Delegate.java b/bridge/src/android/content/res/Resources_Delegate.java
index a5216bc..2689acd 100644
--- a/bridge/src/android/content/res/Resources_Delegate.java
+++ b/bridge/src/android/content/res/Resources_Delegate.java
@@ -20,7 +20,7 @@
 import com.android.ide.common.rendering.api.ArrayResourceValue;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.DensityBasedResourceValue;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.PluralsResourceValue;
 import com.android.ide.common.rendering.api.RenderResources;
@@ -42,7 +42,7 @@
 import com.android.resources.ResourceUrl;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 import com.android.tools.layoutlib.annotations.VisibleForTesting;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -71,7 +71,6 @@
 import static com.android.SdkConstants.ANDROID_PKG;
 import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
 
-@SuppressWarnings("deprecation")
 public class Resources_Delegate {
     private static WeakHashMap<Resources, LayoutlibCallback> sLayoutlibCallbacks =
             new WeakHashMap<>();
@@ -226,7 +225,7 @@
                 } else {
                     message = e.getMessage();
                 }
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null, null);
+                Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT, message, e, null, null);
                 return 0;
             }
         }
@@ -372,16 +371,16 @@
                             values[i] = getInt(element);
                         }
                     } catch (NumberFormatException e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                        Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT,
                                 "Integer resource array contains non-integer value: \"" + element +
                                         "\"", null, null);
                     } catch (IllegalArgumentException e) {
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                        Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT,
                                 "Integer resource array contains wrong color format: \"" + element +
                                         "\"", null, null);
                     }
                 } else {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                    Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT,
                             "Integer resource array contains non-integer value: \"" +
                                     resValue.getElement(i) + "\"", null, null);
                 }
@@ -395,13 +394,13 @@
             try {
                 return new int[]{getInt(firstValue)};
             } catch (NumberFormatException e) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+                Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT,
                         "Integer resource array contains non-integer value: \"" + firstValue + "\"",
                         null, null);
                 return new int[1];
             }
         } else {
-            Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+            Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_FORMAT,
                     "Integer resource array contains non-integer value: \"" +
                             rv.getValue() + "\"", null, null);
             return new int[1];
@@ -432,7 +431,7 @@
             if (resValue != null) {
                 final ResourceType type = resValue.getResourceType();
                 if (type != ResourceType.ARRAY) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+                    Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
                             String.format(
                                     "Resource with id 0x%1$X is not an array resource, but %2$s",
                                     id, type == null ? "null" : type.getDisplayName()),
@@ -440,7 +439,7 @@
                     return null;
                 }
                 if (!(resValue instanceof ArrayResourceValue)) {
-                    Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
+                    Bridge.getLog().warning(ILayoutLog.TAG_UNSUPPORTED,
                             "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.",
                             null, null);
                 }
@@ -488,7 +487,7 @@
                     return parser;
                 }
             } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to parse " + value.getValue(), e, null, null /*data*/);
                 // we'll return null below.
             }
@@ -511,7 +510,7 @@
             try {
                 return ResourceHelper.getXmlBlockParser(getContext(resources), value);
             } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to parse " + value.getValue(), e, null, null /*data*/);
                 // we'll return null below.
             }
@@ -946,7 +945,7 @@
             try {
                 return ResourceHelper.getXmlBlockParser(getContext(resources), value);
             } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to parse " + value.getValue(), e, null, null /*data*/);
                 // we'll return null below.
             }
@@ -1078,12 +1077,12 @@
             }
             // We have package but no type
             String pkg = name.substring(0, colonIdx);
-            ResourceType type = ResourceType.getEnum(defType);
+            ResourceType type = ResourceType.fromClassName(defType);
             return type != null ? ResourceUrl.create(pkg, type, name.substring(colonIdx + 1)) :
                     null;
         }
 
-        ResourceType type = ResourceType.getEnum(name.substring(0, slashIdx));
+        ResourceType type = ResourceType.fromClassName(name.substring(0, slashIdx));
         if (type == null) {
             return null;
         }
diff --git a/bridge/src/android/graphics/BaseCanvas_Delegate.java b/bridge/src/android/graphics/BaseCanvas_Delegate.java
index df28305..5a9236c 100644
--- a/bridge/src/android/graphics/BaseCanvas_Delegate.java
+++ b/bridge/src/android/graphics/BaseCanvas_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.layoutlib.bridge.impl.GcSnapshot;
@@ -29,7 +29,11 @@
 import android.util.imagepool.ImagePool;
 import android.util.imagepool.ImagePoolProvider;
 
-import java.awt.*;
+import java.awt.Composite;
+import java.awt.Graphics2D;
+import java.awt.PaintContext;
+import java.awt.RenderingHints;
+import java.awt.Shape;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Arc2D;
 import java.awt.geom.Area;
@@ -167,7 +171,7 @@
     @LayoutlibDelegate
     /*package*/ static void nDrawPaint(long nativeCanvas, long paint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Canvas.drawPaint is not supported.", null,null, null /*data*/);
     }
 
@@ -420,7 +424,7 @@
     /*package*/ static void nDrawRegion(long nativeCanvas, long nativeRegion,
             long nativePaint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Some canvas paths may not be drawn", null, null, null);
     }
 
@@ -512,7 +516,7 @@
             int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
             int colorOffset, long nPaint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Canvas.drawBitmapMesh is not supported.", null, null, null /*data*/);
     }
 
@@ -524,7 +528,7 @@
             short[] indices, int indexOffset,
             int indexCount, long nPaint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Canvas.drawVertices is not supported.", null, null, null /*data*/);
     }
 
@@ -573,7 +577,7 @@
             float vOffset, int bidiFlags,
             long paint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Canvas.drawTextOnPath is not supported.", null, null, null /*data*/);
     }
 
@@ -584,7 +588,7 @@
             float vOffset,
             int bidiFlags, long paint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Canvas.drawTextOnPath is not supported.", null, null, null /*data*/);
     }
 
diff --git a/bridge/src/android/graphics/BidiRenderer.java b/bridge/src/android/graphics/BidiRenderer.java
index 1de2a45..40d350b 100644
--- a/bridge/src/android/graphics/BidiRenderer.java
+++ b/bridge/src/android/graphics/BidiRenderer.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 
 import android.annotation.NonNull;
@@ -222,7 +222,7 @@
     }
 
     private static void logFontWarning() {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN,
                 "Some fonts could not be loaded. The rendering may not be perfect.", null, null,
                 null);
     }
diff --git a/bridge/src/android/graphics/BitmapFactory_Delegate.java b/bridge/src/android/graphics/BitmapFactory_Delegate.java
index b344451..7a12d38 100644
--- a/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ b/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -73,12 +73,9 @@
                         npis, true /*is9Patch*/, false /*convert*/);
 
                 // get the bitmap and chunk objects.
-                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), bitmapCreateFlags,
-                        density);
                 NinePatchChunk chunk = ninePatch.getChunk();
-
-                // put the chunk in the bitmap
-                bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
+                bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
+                        NinePatch_Delegate.serialize(chunk), bitmapCreateFlags, density);
 
                 if (padding != null) {
                     // read the padding
diff --git a/bridge/src/android/graphics/BitmapShader_Delegate.java b/bridge/src/android/graphics/BitmapShader_Delegate.java
index 53b1db6..e763824 100644
--- a/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -118,7 +118,7 @@
             try {
                 canvasMatrix = xform.createInverse();
             } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in BitmapShader", e, null, null /*data*/);
                 canvasMatrix = new AffineTransform();
             }
@@ -127,7 +127,7 @@
             try {
                 localMatrix = localMatrix.createInverse();
             } catch (NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in BitmapShader", e, null, null /*data*/);
                 localMatrix = new AffineTransform();
             }
diff --git a/bridge/src/android/graphics/Bitmap_Delegate.java b/bridge/src/android/graphics/Bitmap_Delegate.java
index 7fc952d..bfd00c5 100644
--- a/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 import com.android.ide.common.rendering.api.AssetRepository;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
@@ -143,7 +143,7 @@
         Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
         delegate.mIsMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
 
-        return createBitmap(delegate, createFlags, density.getDpiValue());
+        return createBitmap(delegate, createFlags, density.getDpiValue(), null);
     }
 
     /**
@@ -172,11 +172,27 @@
      */
     public static Bitmap createBitmap(BufferedImage image, Set<BitmapCreateFlags> createFlags,
             Density density) {
+        return createBitmap(image, null, createFlags, density);
+    }
+
+    /**
+     * Creates and returns a {@link Bitmap} initialized with the given {@link BufferedImage}
+     *
+     * @param image the bitmap content
+     * @param ninePatchChunk serialized ninepatch data
+     * @param density the density associated with the bitmap
+     *
+     * @see Bitmap#isPremultiplied()
+     * @see Bitmap#isMutable()
+     * @see Bitmap#getDensity()
+     */
+    public static Bitmap createBitmap(BufferedImage image, byte[] ninePatchChunk,
+            Set<BitmapCreateFlags> createFlags, Density density) {
         // create a delegate with the given image.
         Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.ARGB_8888);
         delegate.mIsMutable = createFlags.contains(BitmapCreateFlags.MUTABLE);
 
-        return createBitmap(delegate, createFlags, density.getDpiValue());
+        return createBitmap(delegate, createFlags, density.getDpiValue(), ninePatchChunk);
     }
 
     private static int getBufferedImageType() {
@@ -234,7 +250,7 @@
         delegate.mIsMutable = isMutable;
 
         return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                            Bitmap.getDefaultDensity());
+                            Bitmap.getDefaultDensity(), null);
     }
 
     @LayoutlibDelegate
@@ -264,7 +280,7 @@
         delegate.mIsMutable = isMutable;
 
         return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable),
-                Bitmap.getDefaultDensity());
+                Bitmap.getDefaultDensity(), null);
     }
 
     @LayoutlibDelegate
@@ -299,14 +315,14 @@
     @LayoutlibDelegate
     /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height,
             int config, boolean isPremultiplied) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Bitmap.reconfigure() is not supported", null, null /*data*/);
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean nativeCompress(long nativeBitmap, int format, int quality,
             OutputStream stream, byte[] tempStorage) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Bitmap.compress() is not supported", null, null /*data*/);
         return true;
     }
@@ -426,14 +442,14 @@
     @LayoutlibDelegate
     /*package*/ static void nativeCopyPixelsToBuffer(long nativeBitmap, Buffer dst) {
         // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Bitmap.copyPixelsToBuffer is not supported.", null, null, null /*data*/);
     }
 
     @LayoutlibDelegate
     /*package*/ static void nativeCopyPixelsFromBuffer(long nb, Buffer src) {
         // FIXME implement native delegate
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Bitmap.copyPixelsFromBuffer is not supported.", null, null, null /*data*/);
     }
 
@@ -451,7 +467,7 @@
     /*package*/ static Bitmap nativeCreateFromParcel(Parcel p) {
         // This is only called by Bitmap.CREATOR (Parcelable.Creator<Bitmap>), which is only
         // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "AIDL is not suppored, and therefore Bitmaps cannot be created from parcels.",
                 null, null /*data*/);
         return null;
@@ -461,7 +477,7 @@
     /*package*/ static boolean nativeWriteToParcel(long nativeBitmap, int density, Parcel p) {
         // This is only called when sending a bitmap through aidl, so really this should not
         // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "AIDL is not suppored, and therefore Bitmaps cannot be written to parcels.",
                 null, null /*data*/);
         return false;
@@ -479,7 +495,7 @@
         Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
 
         if (paint != null && paint.getMaskFilter() != null) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MASKFILTER,
                     "MaskFilter not supported in Bitmap.extractAlpha",
                     null, null, null /*data*/);
         }
@@ -493,7 +509,7 @@
 
         // the density doesn't matter, it's set by the Java method.
         return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.MUTABLE),
-                Density.DEFAULT_DENSITY /*density*/);
+                Density.DEFAULT_DENSITY /*density*/, null);
     }
 
     @LayoutlibDelegate
@@ -617,47 +633,40 @@
         delegate.mIsMutable = srcBmpDelegate.mIsMutable;
 
         return createBitmap(delegate, EnumSet.of(BitmapCreateFlags.NONE),
-                Bitmap.getDefaultDensity());
+                Bitmap.getDefaultDensity(), null);
     }
 
     @LayoutlibDelegate
     /*package*/ static Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer,
             long nativeColorSpace) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Bitmap.nativeWrapHardwareBufferBitmap() is not supported", null, null, null);
         return null;
     }
 
     @LayoutlibDelegate
-    /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
-                "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
-        return null;
-    }
-
-    @LayoutlibDelegate
     /*package*/ static boolean nativeIsSRGB(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Color spaces are not supported", null, null /*data*/);
         return false;
     }
 
     @LayoutlibDelegate
     /*package*/ static ColorSpace nativeComputeColorSpace(long nativePtr) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Color spaces are not supported", null, null /*data*/);
         return null;
     }
 
     @LayoutlibDelegate
     /*package*/ static void nativeSetColorSpace(long nativePtr, long nativeColorSpace) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Color spaces are not supported", null, null /*data*/);
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean nativeIsSRGBLinear(long nativePtr) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "Color spaces are not supported", null, null /*data*/);
         return false;
     }
@@ -682,7 +691,7 @@
 
     @LayoutlibDelegate
     /*package*/ static HardwareBuffer nativeGetHardwareBuffer(long nativeBitmap) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "HardwareBuffer is not supported", null, null /*data*/);
         return null;
     }
@@ -695,7 +704,7 @@
     }
 
     private static Bitmap createBitmap(Bitmap_Delegate delegate,
-            Set<BitmapCreateFlags> createFlags, int density) {
+            Set<BitmapCreateFlags> createFlags, int density, byte[] ninePatchChunk) {
         // get its native_int
         long nativeInt = sManager.addNewDelegate(delegate);
 
@@ -705,7 +714,7 @@
 
         // and create/return a new Bitmap with it
         return new Bitmap(nativeInt, width, height, density, isPremultiplied,
-                null /*ninePatchChunk*/, null /* layoutBounds */, true /* fromMalloc */);
+                ninePatchChunk, null /* layoutBounds */, true /* fromMalloc */);
     }
 
     private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) {
diff --git a/bridge/src/android/graphics/Canvas_Delegate.java b/bridge/src/android/graphics/Canvas_Delegate.java
index afcb40c..19e88b6 100644
--- a/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/bridge/src/android/graphics/Canvas_Delegate.java
@@ -16,13 +16,12 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.layoutlib.bridge.impl.GcSnapshot;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
-import android.annotation.Nullable;
 import android.graphics.Bitmap.Config;
 
 import java.awt.Graphics2D;
@@ -354,7 +353,7 @@
 
         if (matrixDelegate.hasPerspective()) {
             assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_AFFINE,
                     "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
                     "supports affine transformations.", null, null, null /*data*/);
         }
@@ -401,7 +400,7 @@
         canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
 
         if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_DRAWFILTER,
                     canvasDelegate.mDrawFilter.getSupportMessage(), null, null, null /*data*/);
         }
     }
diff --git a/bridge/src/android/graphics/FontFamily_Delegate.java b/bridge/src/android/graphics/FontFamily_Delegate.java
index afcf9bd..a452aae 100644
--- a/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -183,7 +183,7 @@
                 }
             }
         } catch (FileNotFoundException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Unable to load the list of fonts. Try re-installing the SDK Platform from the SDK Manager.",
                     e, null, null);
         } finally {
@@ -268,12 +268,12 @@
                     // warning.
                     return null;
                 }
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN,
                         String.format("Unable to load font %1$s", relativePath),
                         e, null, null);
             }
         } else {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                     "Only platform fonts located in " + SYSTEM_FONTS + "can be loaded.",
                     null, null, null);
         }
diff --git a/bridge/src/android/graphics/LinearGradient_Delegate.java b/bridge/src/android/graphics/LinearGradient_Delegate.java
index 7b544fe..4574dd7 100644
--- a/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -126,7 +126,7 @@
             try {
                 canvasMatrix = xform.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in LinearGradient", e, null, null /*data*/);
                 canvasMatrix = new java.awt.geom.AffineTransform();
             }
@@ -135,7 +135,7 @@
             try {
                 localMatrix = localMatrix.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in LinearGradient", e, null, null /*data*/);
                 localMatrix = new java.awt.geom.AffineTransform();
             }
diff --git a/bridge/src/android/graphics/Matrix_Delegate.java b/bridge/src/android/graphics/Matrix_Delegate.java
index ca3cc96..d0a0adc 100644
--- a/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/bridge/src/android/graphics/Matrix_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -25,7 +25,6 @@
 import android.graphics.Matrix.ScaleToFit;
 
 import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
 
 import libcore.util.NativeAllocationRegistry_Delegate;
 
@@ -64,7 +63,7 @@
      * Returns an {@link AffineTransform} matching the given Matrix.
      */
     public static AffineTransform getAffineTransform(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
+        Matrix_Delegate delegate = sManager.getDelegate(m.ni());
         if (delegate == null) {
             return null;
         }
@@ -73,7 +72,7 @@
     }
 
     public static boolean hasPerspective(Matrix m) {
-        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
+        Matrix_Delegate delegate = sManager.getDelegate(m.ni());
         if (delegate == null) {
             return false;
         }
@@ -598,7 +597,7 @@
     /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex,
             float[] dst, int dstIndex, int pointCount) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Matrix.setPolyToPoly is not supported.",
                 null, null, null /*data*/);
         return false;
diff --git a/bridge/src/android/graphics/NinePatch_Delegate.java b/bridge/src/android/graphics/NinePatch_Delegate.java
index ca2a9ca..28e682b 100644
--- a/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.ninepatch.NinePatchChunk;
@@ -120,11 +120,11 @@
                     sChunkCache.put(array, new SoftReference<>(chunk));
                 }
             } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to deserialize NinePatchChunk content.", e, null, null /*data*/);
                 return null;
             } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to deserialize NinePatchChunk class.", e, null, null /*data*/);
                 return null;
             }
diff --git a/bridge/src/android/graphics/Paint_Delegate.java b/bridge/src/android/graphics/Paint_Delegate.java
index 0512edf..f6c6d71 100644
--- a/bridge/src/android/graphics/Paint_Delegate.java
+++ b/bridge/src/android/graphics/Paint_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -228,7 +228,7 @@
                     return stroke;
                 }
             } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_PATHEFFECT,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_PATHEFFECT,
                         mPathEffect.getSupportMessage(),
                         null, null, null /*data*/);
             }
@@ -455,14 +455,14 @@
     /*package*/ static void nSetShadowLayer(long paintPtr,
             float radius, float dx, float dy, long colorSpaceHandle,
             long shadowColor) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.setShadowLayer is not supported.", null, null, null /*data*/);
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean nHasShadowLayer(long paint) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.hasShadowLayer is not supported.", null, null, null /*data*/);
         return false;
     }
@@ -847,7 +847,7 @@
 
         // Log warning if it's not supported.
         if (delegate.mColorFilter != null && !delegate.mColorFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_COLORFILTER,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_COLORFILTER,
                     delegate.mColorFilter.getSupportMessage(), null, null, null /*data*/);
         }
 
@@ -888,7 +888,7 @@
 
         // since none of those are supported, display a fidelity warning right away
         if (delegate.mMaskFilter != null && !delegate.mMaskFilter.isSupported()) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MASKFILTER,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MASKFILTER,
                     delegate.mMaskFilter.getSupportMessage(), null, null, null /*data*/);
         }
 
@@ -984,7 +984,7 @@
     /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, char[] text,
             int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextRunCursor is not supported.", null, null, null /*data*/);
         return 0;
     }
@@ -993,7 +993,7 @@
     /*package*/ static int nGetTextRunCursor(Paint paint, long native_object, String text,
             int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextRunCursor is not supported.", null, null, null /*data*/);
         return 0;
     }
@@ -1002,7 +1002,7 @@
     /*package*/ static void nGetTextPath(long native_object, int bidiFlags, char[] text,
             int index, int count, float x, float y, long path) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextPath is not supported.", null, null, null /*data*/);
     }
 
@@ -1010,7 +1010,7 @@
     /*package*/ static void nGetTextPath(long native_object, int bidiFlags, String text, int start,
             int end, float x, float y, long path) {
         // FIXME
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Paint.getTextPath is not supported.", null, null, null /*data*/);
     }
 
@@ -1056,7 +1056,7 @@
 
     @LayoutlibDelegate
     /*package*/ static void nSetLetterSpacing(long nativePaint, float letterSpacing) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING,
                 "Paint.setLetterSpacing() not supported.", null, null, null);
         Paint_Delegate delegate = sManager.getDelegate(nativePaint);
         if (delegate == null) {
@@ -1085,7 +1085,7 @@
 
     @LayoutlibDelegate
     /*package*/ static void nSetFontFeatureSettings(long nativePaint, String settings) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING,
                 "Paint.setFontFeatureSettings() not supported.", null, null, null);
     }
 
@@ -1135,7 +1135,7 @@
             return false;
         }
         if (string.length() > 1) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_TEXT_RENDERING,
                     "Paint.hasGlyph() is not supported for ligatures.", null, null, null);
             return false;
         }
diff --git a/bridge/src/android/graphics/PathMeasure_Delegate.java b/bridge/src/android/graphics/PathMeasure_Delegate.java
index 7276c45..83a4ff1 100644
--- a/bridge/src/android/graphics/PathMeasure_Delegate.java
+++ b/bridge/src/android/graphics/PathMeasure_Delegate.java
@@ -16,13 +16,12 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.layoutlib.bridge.util.CachedPathIteratorFactory;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
 import com.android.layoutlib.bridge.util.CachedPathIteratorFactory.CachedPathIterator;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import java.awt.geom.PathIterator;
 
@@ -79,7 +78,7 @@
     @LayoutlibDelegate
     /*package*/ static boolean native_getPosTan(long native_instance, float distance, float pos[],
             float tan[]) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "PathMeasure.getPostTan is not supported.", null, null, null);
         return false;
     }
@@ -87,14 +86,14 @@
     @LayoutlibDelegate
     /*package*/ static boolean native_getMatrix(long native_instance, float distance, long
             native_matrix, int flags) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "PathMeasure.getMatrix is not supported.", null, null, null);
         return false;
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean native_nextContour(long native_instance) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "PathMeasure.nextContour is not supported.", null, null, null);
         return false;
     }
diff --git a/bridge/src/android/graphics/Path_Delegate.java b/bridge/src/android/graphics/Path_Delegate.java
index df83d65..88f2815 100644
--- a/bridge/src/android/graphics/Path_Delegate.java
+++ b/bridge/src/android/graphics/Path_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -157,7 +157,7 @@
 
     @LayoutlibDelegate
     /*package*/ static boolean nIsConvex(long nPath) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Path.isConvex is not supported.", null, null, null);
         return true;
     }
@@ -475,7 +475,7 @@
 
     @LayoutlibDelegate
     /*package*/ static boolean nOp(long nPath1, long nPath2, int op, long result) {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null, null);
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null, null);
         return false;
     }
 
@@ -889,7 +889,7 @@
     public void transform(Matrix_Delegate matrix, Path_Delegate dst) {
         if (matrix.hasPerspective()) {
             assert false;
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_AFFINE,
                     "android.graphics.Path#transform() only " +
                     "supports affine transformations.", null, null, null /*data*/);
         }
diff --git a/bridge/src/android/graphics/RadialGradient_Delegate.java b/bridge/src/android/graphics/RadialGradient_Delegate.java
index cd46b31..4a18219 100644
--- a/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -116,7 +116,7 @@
             try {
                 canvasMatrix = xform.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in RadialGradient", e, null, null /*data*/);
                 canvasMatrix = new java.awt.geom.AffineTransform();
             }
@@ -125,7 +125,7 @@
             try {
                 localMatrix = localMatrix.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in RadialGradient", e, null, null /*data*/);
                 localMatrix = new java.awt.geom.AffineTransform();
             }
diff --git a/bridge/src/android/graphics/Region_Delegate.java b/bridge/src/android/graphics/Region_Delegate.java
index f1f44b9..254e825 100644
--- a/bridge/src/android/graphics/Region_Delegate.java
+++ b/bridge/src/android/graphics/Region_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -436,7 +436,7 @@
     /*package*/ static long nativeCreateFromParcel(Parcel p) {
         // This is only called by Region.CREATOR (Parcelable.Creator<Region>), which is only
         // used during aidl call so really this should not be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "AIDL is not suppored, and therefore Regions cannot be created from parcels.",
                 null, null /*data*/);
         return 0;
@@ -447,7 +447,7 @@
                                                       Parcel p) {
         // This is only called when sending a region through aidl, so really this should not
         // be called.
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED,
                 "AIDL is not suppored, and therefore Regions cannot be written to parcels.",
                 null, null /*data*/);
         return false;
diff --git a/bridge/src/android/graphics/SweepGradient_Delegate.java b/bridge/src/android/graphics/SweepGradient_Delegate.java
index e02144d..01ef140 100644
--- a/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -111,7 +111,7 @@
             try {
                 canvasMatrix = xform.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in SweepGradient", e, null, null /*data*/);
                 canvasMatrix = new java.awt.geom.AffineTransform();
             }
@@ -120,7 +120,7 @@
             try {
                 localMatrix = localMatrix.createInverse();
             } catch (java.awt.geom.NoninvertibleTransformException e) {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_MATRIX_INVERSE,
                         "Unable to inverse matrix in SweepGradient", e, null, null /*data*/);
                 localMatrix = new java.awt.geom.AffineTransform();
             }
diff --git a/bridge/src/android/graphics/Typeface_Delegate.java b/bridge/src/android/graphics/Typeface_Delegate.java
index fb044d9..6c0ab20 100644
--- a/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/bridge/src/android/graphics/Typeface_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ResourceNamespace;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -142,7 +142,7 @@
         long newInstance = nativeCreateFromTypeface(native_instance, 0);
 
         if (newInstance != 0) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                     "nativeCreateFromTypefaceWithVariation is not supported", null, null, null);
         }
         return newInstance;
@@ -272,7 +272,7 @@
                     blockParser.ensurePopped();
                 }
             } else {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         String.format("File %s does not exist (or is not a file)", path),
                         null, null /*data*/);
             }
diff --git a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
index be78091..9c272fa 100644
--- a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
+++ b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics.drawable;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -99,7 +99,7 @@
     @LayoutlibDelegate
     /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
             long endValuePtr) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
                 "animations are not supported.", null, null, null);
         return 0;
     }
diff --git a/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java b/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java
new file mode 100644
index 0000000..bd73cfb
--- /dev/null
+++ b/bridge/src/android/graphics/drawable/NinePatchDrawable_Delegate.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import com.android.ide.common.rendering.api.ILayoutLog;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import android.graphics.PixelFormat;
+
+public class NinePatchDrawable_Delegate {
+
+    @LayoutlibDelegate
+    static int getOpacity(NinePatchDrawable thisDrawable) {
+        // User-defined nine-patches can have a null underlying bitmap, if incorrectly constructed.
+        // Trying to preview such a nine-patch drawable will trigger a NullPointerException in the
+        // getOpacity, which then get logged by the Studio crash reporting system.
+        // Do not crash here, but let it instead crash during draw, which gets logged by layoutlib
+        // and is then handled better by Studio.
+        try {
+            return thisDrawable.getOpacity_Original();
+        } catch (NullPointerException ignore) {
+            Bridge.getLog().warning(ILayoutLog.TAG_BROKEN, "The source for the nine-patch " +
+                    "drawable has not been correctly defined.", null , null);
+            return PixelFormat.OPAQUE;
+        }
+    }
+}
diff --git a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index 8102894..828df6b 100644
--- a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -1195,7 +1195,7 @@
                     if (shaderDelegate != null) {
                         // If there is a shader, apply the local transformation to make sure
                         // the gradient is transformed to match the viewport
-                        shaderDelegate.setLocalMatrix(mFinalPathMatrix.native_instance);
+                        shaderDelegate.setLocalMatrix(mFinalPathMatrix.ni());
                         shaderDelegate.setAlpha(fullPath.mFillAlpha);
                     }
 
diff --git a/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java b/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java
index 32f1157..018329d 100644
--- a/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java
+++ b/bridge/src/android/graphics/fonts/FontFamily_Builder_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics.fonts;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -189,7 +189,7 @@
             buffer.get(byteArray);
             return Font.createFont(Font.TRUETYPE_FONT, new ByteArrayInputStream(byteArray));
         } catch (Exception e) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, "Unable to load font",
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, "Unable to load font",
                     e, null, null);
         }
 
@@ -201,7 +201,7 @@
             File file = new File(path);
             return Font.createFont(Font.TRUETYPE_FONT, file);
         } catch (Exception e) {
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN, "Unable to load font",
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN, "Unable to load font",
                     e, null, null);
         }
 
diff --git a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
index f58f027..0d3ce3f 100644
--- a/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
+++ b/bridge/src/android/graphics/fonts/Font_Builder_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics.fonts;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -83,7 +83,7 @@
 
     @LayoutlibDelegate
     /*package*/ static void nAddAxis(long builderPtr, int tag, float value) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Font$Builder.nAddAxis is not supported.", null, null, null);
     }
 
diff --git a/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java
index df976d0..3f3e065 100644
--- a/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java
+++ b/bridge/src/android/graphics/fonts/SystemFonts_Delegate.java
@@ -21,10 +21,11 @@
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.text.FontConfig;
-import android.util.ArrayMap;
 
-import java.util.ArrayList;
+import java.io.File;
+import java.util.Map;
 
 import static android.graphics.FontFamily_Delegate.getFontLocation;
 
@@ -43,13 +44,15 @@
 public class SystemFonts_Delegate {
 
     @LayoutlibDelegate
-    /*package*/ static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath,
-            @NonNull String fontDir,
-            @NonNull FontCustomizationParser.Result oemCustomization,
-            @NonNull ArrayMap<String, FontFamily[]> fallbackMap,
-            @NonNull ArrayList<Font> availableFonts) {
+    /*package*/ static FontConfig getSystemFontConfigInternal(
+            String fontsXml,
+            String systemFontDir,
+            String oemXml,
+            String productFontDir,
+            Map<String, File> updatableFontMap) {
         Bridge.sIsTypefaceInitialized = true;
-        return SystemFonts.buildSystemFallback_Original(getFontLocation() + "/standard/fonts.xml",
-                getFontLocation() + "/", oemCustomization, fallbackMap, availableFonts);
+        return SystemFonts.getSystemFontConfigInternal_Original(
+                getFontLocation() + "/standard/fonts.xml", getFontLocation() + "/",
+                null, null, updatableFontMap, 0, 0);
     }
 }
diff --git a/bridge/src/android/net/ConnectivityManager.java b/bridge/src/android/net/ConnectivityManager.java
new file mode 100644
index 0000000..74ac8f5
--- /dev/null
+++ b/bridge/src/android/net/ConnectivityManager.java
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+import android.net.SocketKeepalive.Callback;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Messenger;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+import static android.os._Original_Build.VERSION_CODES.BASE;
+
+/**
+ * Stub ConnectivityManager for layoutlib
+ */
+public class ConnectivityManager {
+    @Deprecated
+    public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
+
+    public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
+
+    @Deprecated
+    public static final String EXTRA_NETWORK_INFO = "networkInfo";
+    @Deprecated
+    public static final String EXTRA_NETWORK_TYPE = "networkType";
+
+    @Deprecated
+    public static final String EXTRA_IS_FAILOVER = "isFailover";
+    @Deprecated
+    public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
+    public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
+    public static final String EXTRA_REASON = "reason";
+    @Deprecated
+    public static final String EXTRA_EXTRA_INFO = "extraInfo";
+    public static final String EXTRA_INET_CONDITION = "inetCondition";
+    public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
+
+    public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
+
+    public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC =
+            "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
+
+    public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
+            "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
+
+    public static final String ACTION_DATA_ACTIVITY_CHANGE =
+            "android.net.conn.DATA_ACTIVITY_CHANGE";
+    public static final String EXTRA_DEVICE_TYPE = "deviceType";
+    public static final String EXTRA_IS_ACTIVE = "isActive";
+    public static final String EXTRA_REALTIME_NS = "tsNanos";
+
+    @Deprecated
+    public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
+            "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
+
+    public static final String INET_CONDITION_ACTION =
+            "android.net.conn.INET_CONDITION_ACTION";
+
+    public static final String ACTION_TETHER_STATE_CHANGED =
+            TetheringManager.ACTION_TETHER_STATE_CHANGED;
+
+    public static final String EXTRA_AVAILABLE_TETHER = TetheringManager.EXTRA_AVAILABLE_TETHER;
+
+    public static final String EXTRA_ACTIVE_LOCAL_ONLY = TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
+
+    public static final String EXTRA_ACTIVE_TETHER = TetheringManager.EXTRA_ACTIVE_TETHER;
+
+    public static final String EXTRA_ERRORED_TETHER = TetheringManager.EXTRA_ERRORED_TETHER;
+
+    public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
+            "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
+    public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
+
+    public static final String ACTION_PROMPT_UNVALIDATED = "android.net.conn.PROMPT_UNVALIDATED";
+
+    public static final String ACTION_PROMPT_LOST_VALIDATION =
+            "android.net.conn.PROMPT_LOST_VALIDATION";
+
+    public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY =
+            "android.net.conn.PROMPT_PARTIAL_CONNECTIVITY";
+
+    public static final int TETHERING_INVALID   = TetheringManager.TETHERING_INVALID;
+
+    public static final int TETHERING_WIFI      = TetheringManager.TETHERING_WIFI;
+
+    public static final int TETHERING_USB       = TetheringManager.TETHERING_USB;
+
+    public static final int TETHERING_BLUETOOTH = TetheringManager.TETHERING_BLUETOOTH;
+
+    public static final int TETHERING_WIFI_P2P = TetheringManager.TETHERING_WIFI_P2P;
+
+    public static final int TYPE_NONE        = -1;
+
+    @Deprecated
+    public static final int TYPE_MOBILE      = 0;
+
+    @Deprecated
+    public static final int TYPE_WIFI        = 1;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_MMS  = 2;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_SUPL = 3;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_DUN  = 4;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_HIPRI = 5;
+
+    @Deprecated
+    public static final int TYPE_WIMAX       = 6;
+
+    @Deprecated
+    public static final int TYPE_BLUETOOTH   = 7;
+
+    @Deprecated
+    public static final int TYPE_DUMMY       = 8;
+
+    @Deprecated
+    public static final int TYPE_ETHERNET    = 9;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_FOTA = 10;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_IMS  = 11;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_CBS  = 12;
+
+    @Deprecated
+    public static final int TYPE_WIFI_P2P    = 13;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_IA = 14;
+
+    @Deprecated
+    public static final int TYPE_MOBILE_EMERGENCY = 15;
+
+    @Deprecated
+    public static final int TYPE_PROXY = 16;
+
+    @Deprecated
+    public static final int TYPE_VPN = 17;
+
+    @Deprecated
+    public static final int TYPE_TEST = 18; // TODO: Remove this once NetworkTypes are unused.
+
+    @Deprecated
+    public @interface LegacyNetworkType {}
+
+    public static final int MAX_RADIO_TYPE = TYPE_TEST;
+
+    public static final int MAX_NETWORK_TYPE = TYPE_TEST;
+
+    @Deprecated
+    public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
+
+    public static final int REQUEST_ID_UNSET = 0;
+
+    public static final int NETID_UNSET = 0;
+    public static final String PRIVATE_DNS_MODE_OFF = "off";
+    public static final String PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic";
+    public static final String PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = "hostname";
+    public static final String PRIVATE_DNS_DEFAULT_MODE_FALLBACK = PRIVATE_DNS_MODE_OPPORTUNISTIC;
+
+    private static ConnectivityManager sInstance;
+
+    @Deprecated
+    public static boolean isNetworkTypeValid(int networkType) {
+        return false;
+    }
+
+    @Deprecated
+    public static String getNetworkTypeName(int type) {
+        return null;
+    }
+
+    @Deprecated
+    public static boolean isNetworkTypeMobile(int networkType) {
+        return false;
+    }
+
+    @Deprecated
+    public static boolean isNetworkTypeWifi(int networkType) {
+        return false;
+    }
+
+    @Deprecated
+    public void setNetworkPreference(int preference) {
+    }
+
+    @Deprecated
+    public int getNetworkPreference() {
+        return TYPE_NONE;
+    }
+
+    @Deprecated
+    @Nullable
+    public NetworkInfo getActiveNetworkInfo() {
+        return null;
+    }
+
+    @Nullable
+    public Network getActiveNetwork() {
+        return null;
+    }
+
+    @Nullable
+    public Network getActiveNetworkForUid(int uid) {
+        return null;
+    }
+
+    public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
+        return null;
+    }
+
+    public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
+        return false;
+    }
+
+    public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
+            boolean lockdownEnabled, @Nullable List<String> lockdownList) {
+        return false;
+    }
+
+    public String getAlwaysOnVpnPackageForUser(int userId) {
+        return null;
+    }
+
+    public boolean isVpnLockdownEnabled(int userId) {
+        return false;
+    }
+
+    public List<String> getVpnLockdownWhitelist(int userId) {
+        return null;
+    }
+
+    public NetworkInfo getActiveNetworkInfoForUid(int uid) {
+        return null;
+    }
+
+    public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
+        return null;
+    }
+
+    @Deprecated
+    @Nullable
+    public NetworkInfo getNetworkInfo(int networkType) {
+        return null;
+    }
+
+    @Deprecated
+    @Nullable
+    public NetworkInfo getNetworkInfo(@Nullable Network network) {
+        return null;
+    }
+
+    public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
+        return null;
+    }
+
+    @Deprecated
+    @NonNull
+    public NetworkInfo[] getAllNetworkInfo() {
+        return new NetworkInfo[0];
+    }
+
+    @Deprecated
+    public Network getNetworkForType(int networkType) {
+        return null;
+    }
+
+    @NonNull
+    public Network[] getAllNetworks() {
+        return new Network[0];
+    }
+
+    public NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId) {
+        return null;
+    }
+
+    public LinkProperties getActiveLinkProperties() {
+        return null;
+    }
+
+    @Deprecated
+    public LinkProperties getLinkProperties(int networkType) {
+        return null;
+    }
+
+    @Nullable
+    public LinkProperties getLinkProperties(@Nullable Network network) {
+        return null;
+    }
+
+    @Nullable
+    public NetworkCapabilities getNetworkCapabilities(@Nullable Network network) {
+        return null;
+    }
+
+    @Deprecated
+    public String getCaptivePortalServerUrl() {
+        return null;
+    }
+
+    @Deprecated
+    public int startUsingNetworkFeature(int networkType, String feature) {
+        return -1;
+    }
+
+    @Deprecated
+    public int stopUsingNetworkFeature(int networkType, String feature) {
+        return -1;
+    }
+
+    public static NetworkCapabilities networkCapabilitiesForType(int type) {
+        return null;
+    }
+
+    public static class PacketKeepaliveCallback {
+        public PacketKeepaliveCallback() {
+        }
+        public void onStarted() {}
+        public void onStopped() {}
+        public void onError(int error) {}
+    }
+
+    public class PacketKeepalive {
+        public static final int SUCCESS = 0;
+
+        public static final int NO_KEEPALIVE = -1;
+
+        public static final int BINDER_DIED = -10;
+
+        public static final int ERROR_INVALID_NETWORK = -20;
+        public static final int ERROR_INVALID_IP_ADDRESS = -21;
+        public static final int ERROR_INVALID_PORT = -22;
+        public static final int ERROR_INVALID_LENGTH = -23;
+        public static final int ERROR_INVALID_INTERVAL = -24;
+
+        public static final int ERROR_HARDWARE_UNSUPPORTED = -30;
+        public static final int ERROR_HARDWARE_ERROR = -31;
+
+        public static final int NATT_PORT = 4500;
+
+        public static final int MIN_INTERVAL = 10;
+
+        public void stop() {}
+    }
+
+    public PacketKeepalive startNattKeepalive(
+            Network network, int intervalSeconds, PacketKeepaliveCallback callback,
+            InetAddress srcAddr, int srcPort, InetAddress dstAddr) {
+        return null;
+    }
+
+    public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
+            @NonNull UdpEncapsulationSocket socket,
+            @NonNull InetAddress source,
+            @NonNull InetAddress destination,
+            @NonNull Executor executor,
+            @NonNull Callback callback) {
+        throw new UnsupportedOperationException(
+                "createSocketKeepalive is not supported in layoutlib");
+    }
+
+    public @NonNull SocketKeepalive createNattKeepalive(@NonNull Network network,
+            @NonNull ParcelFileDescriptor pfd,
+            @NonNull InetAddress source,
+            @NonNull InetAddress destination,
+            @NonNull Executor executor,
+            @NonNull Callback callback) {
+        throw new UnsupportedOperationException(
+                "createSocketKeepalive is not supported in layoutlib");
+    }
+
+    public @NonNull SocketKeepalive createSocketKeepalive(@NonNull Network network,
+            @NonNull Socket socket,
+            @NonNull Executor executor,
+            @NonNull Callback callback) {
+        throw new UnsupportedOperationException(
+                "createSocketKeepalive is not supported in layoutlib");
+    }
+
+    @Deprecated
+    public boolean requestRouteToHost(int networkType, int hostAddress) {
+        return false;
+    }
+
+    @Deprecated
+    public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
+        return false;
+    }
+
+    @Deprecated
+    public boolean getBackgroundDataSetting() {
+        return false;
+    }
+
+    @Deprecated
+    public void setBackgroundDataSetting(boolean allowBackgroundData) {}
+
+    @Deprecated
+    public boolean getMobileDataEnabled() {
+        return false;
+    }
+
+    public interface OnNetworkActiveListener {
+        void onNetworkActive();
+    }
+
+    public void addDefaultNetworkActiveListener(final OnNetworkActiveListener l) {}
+
+    public void removeDefaultNetworkActiveListener(@NonNull OnNetworkActiveListener l) {}
+
+    public boolean isDefaultNetworkActive() {
+        return false;
+    }
+
+    public ConnectivityManager(Context context, IConnectivityManager service) {
+        sInstance = this;
+    }
+
+    public static ConnectivityManager from(Context context) {
+        return new ConnectivityManager(context, null);
+    }
+
+    public NetworkRequest getDefaultRequest() {
+        return null;
+    }
+
+    public static final void enforceChangePermission(Context context) {}
+
+    @Deprecated
+    static ConnectivityManager getInstanceOrNull() {
+        return sInstance;
+    }
+
+    @Deprecated
+    private static ConnectivityManager getInstance() {
+        if (getInstanceOrNull() == null) {
+            throw new IllegalStateException("No ConnectivityManager yet constructed");
+        }
+        return getInstanceOrNull();
+    }
+
+    @Deprecated
+    public String[] getTetherableIfaces() {
+        return null;
+    }
+
+    @Deprecated
+    public String[] getTetheredIfaces() {
+        return null;
+    }
+
+    @Deprecated
+    public String[] getTetheringErroredIfaces() {
+        return null;
+    }
+
+    @Deprecated
+    public String[] getTetheredDhcpRanges() {
+        throw new UnsupportedOperationException("getTetheredDhcpRanges is not supported");
+    }
+
+    @Deprecated
+    public int tether(String iface) {
+        return 0;
+    }
+
+    @Deprecated
+    public int untether(String iface) {
+        return 0;
+    }
+
+    public boolean isTetheringSupported() {
+        return false;
+    }
+
+    @Deprecated
+    public static abstract class OnStartTetheringCallback {
+        public void onTetheringStarted() {}
+
+        public void onTetheringFailed() {}
+    }
+
+    @Deprecated
+    public void startTethering(int type, boolean showProvisioningUi,
+            final OnStartTetheringCallback callback) {}
+
+    @Deprecated
+    public void startTethering(int type, boolean showProvisioningUi,
+            final OnStartTetheringCallback callback, Handler handler) {}
+
+    @Deprecated
+    public void stopTethering(int type) {}
+
+    @Deprecated
+    public abstract static class OnTetheringEventCallback {
+
+        public void onUpstreamChanged(@Nullable Network network) {}
+    }
+
+    @Deprecated
+    public void registerTetheringEventCallback(
+            @NonNull Executor executor,
+            @NonNull final OnTetheringEventCallback callback) {}
+
+    @Deprecated
+    public void unregisterTetheringEventCallback(
+            @NonNull final OnTetheringEventCallback callback) {}
+
+
+    @Deprecated
+    public String[] getTetherableUsbRegexs() {
+        return null;
+    }
+
+    @Deprecated
+    public String[] getTetherableWifiRegexs() {
+        return null;
+    }
+
+    @Deprecated
+    public String[] getTetherableBluetoothRegexs() {
+        return null;
+    }
+
+    @Deprecated
+    public int setUsbTethering(boolean enable) {
+        return 0;
+    }
+
+    @Deprecated
+    public static final int TETHER_ERROR_NO_ERROR = TetheringManager.TETHER_ERROR_NO_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_UNKNOWN_IFACE =
+            TetheringManager.TETHER_ERROR_UNKNOWN_IFACE;
+    @Deprecated
+    public static final int TETHER_ERROR_SERVICE_UNAVAIL =
+            TetheringManager.TETHER_ERROR_SERVICE_UNAVAIL;
+    @Deprecated
+    public static final int TETHER_ERROR_UNSUPPORTED = TetheringManager.TETHER_ERROR_UNSUPPORTED;
+    @Deprecated
+    public static final int TETHER_ERROR_UNAVAIL_IFACE =
+            TetheringManager.TETHER_ERROR_UNAVAIL_IFACE;
+    @Deprecated
+    public static final int TETHER_ERROR_MASTER_ERROR =
+            TetheringManager.TETHER_ERROR_INTERNAL_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_TETHER_IFACE_ERROR =
+            TetheringManager.TETHER_ERROR_TETHER_IFACE_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR =
+            TetheringManager.TETHER_ERROR_UNTETHER_IFACE_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_ENABLE_NAT_ERROR =
+            TetheringManager.TETHER_ERROR_ENABLE_FORWARDING_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_DISABLE_NAT_ERROR =
+            TetheringManager.TETHER_ERROR_DISABLE_FORWARDING_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_IFACE_CFG_ERROR =
+            TetheringManager.TETHER_ERROR_IFACE_CFG_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_PROVISION_FAILED =
+            TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
+    @Deprecated
+    public static final int TETHER_ERROR_DHCPSERVER_ERROR =
+            TetheringManager.TETHER_ERROR_DHCPSERVER_ERROR;
+    @Deprecated
+    public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN =
+            TetheringManager.TETHER_ERROR_ENTITLEMENT_UNKNOWN;
+
+    @Deprecated
+    public int getLastTetherError(String iface) {
+        return 0;
+    }
+
+    public @interface EntitlementResultCode {
+    }
+
+    @Deprecated
+    public interface OnTetheringEntitlementResultListener  {
+        void onTetheringEntitlementResult(@EntitlementResultCode int resultCode);
+    }
+
+    @Deprecated
+    public void getLatestTetheringEntitlementResult(int type, boolean showEntitlementUi,
+            @NonNull Executor executor,
+            @NonNull final OnTetheringEntitlementResultListener listener) {}
+
+    public void reportInetCondition(int networkType, int percentage) {}
+
+    @Deprecated
+    public void reportBadNetwork(@Nullable Network network) {}
+
+    public void reportNetworkConnectivity(@Nullable Network network, boolean hasConnectivity) {}
+
+    public void setGlobalProxy(ProxyInfo p) {}
+
+    public ProxyInfo getGlobalProxy() {
+        return null;
+    }
+
+    public ProxyInfo getProxyForNetwork(Network network) {
+        return null;
+    }
+
+    @Nullable
+    public ProxyInfo getDefaultProxy() {
+        return null;
+    }
+
+    @Deprecated
+    public boolean isNetworkSupported(int networkType) {
+        return false;
+    }
+
+    public boolean isActiveNetworkMetered() {
+        return false;
+    }
+
+    public boolean updateLockdownVpn() {
+        return false;
+    }
+
+    public int checkMobileProvisioning(int suggestedTimeOutMs) {
+        return 0;
+    }
+
+    public String getMobileProvisioningUrl() {
+        return null;
+    }
+
+    @Deprecated
+    public void setProvisioningNotificationVisible(boolean visible, int networkType,
+            String action) {}
+
+    public void setAirplaneMode(boolean enable) {}
+
+    public int registerNetworkFactory(Messenger messenger, String name) {
+        return 0;
+    }
+
+    public void unregisterNetworkFactory(Messenger messenger) {}
+
+    public int registerNetworkProvider(@NonNull NetworkProvider provider) {
+        return 0;
+    }
+
+    public void unregisterNetworkProvider(@NonNull NetworkProvider provider) {}
+
+    public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {}
+
+    public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
+            NetworkCapabilities nc, int score, NetworkAgentConfig config) {
+        return null;
+    }
+
+    public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp,
+            NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
+        return null;
+    }
+
+    public static class NetworkCallback {
+        public void onPreCheck(@NonNull Network network) {}
+
+        public void onAvailable(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities,
+                @NonNull LinkProperties linkProperties, boolean blocked) {}
+
+        public void onAvailable(@NonNull Network network) {}
+
+        public void onLosing(@NonNull Network network, int maxMsToLive) {}
+
+        public void onLost(@NonNull Network network) {}
+
+        public void onUnavailable() {}
+
+        public void onCapabilitiesChanged(@NonNull Network network,
+                @NonNull NetworkCapabilities networkCapabilities) {}
+
+        public void onLinkPropertiesChanged(@NonNull Network network,
+                @NonNull LinkProperties linkProperties) {}
+
+        public void onNetworkSuspended(@NonNull Network network) {}
+
+        public void onNetworkResumed(@NonNull Network network) {}
+
+        public void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {}
+    }
+
+    public interface Errors {
+        int TOO_MANY_REQUESTS = 1;
+    }
+
+    public static class TooManyRequestsException extends RuntimeException {}
+
+    public static final int CALLBACK_PRECHECK            = BASE + 1;
+    public static final int CALLBACK_AVAILABLE           = BASE + 2;
+    public static final int CALLBACK_LOSING              = BASE + 3;
+    public static final int CALLBACK_LOST                = BASE + 4;
+    public static final int CALLBACK_UNAVAIL             = BASE + 5;
+    public static final int CALLBACK_CAP_CHANGED         = BASE + 6;
+    public static final int CALLBACK_IP_CHANGED          = BASE + 7;
+    private static final int EXPIRE_LEGACY_REQUEST       = BASE + 8;
+    public static final int CALLBACK_SUSPENDED           = BASE + 9;
+    public static final int CALLBACK_RESUMED             = BASE + 10;
+    public static final int CALLBACK_BLK_CHANGED         = BASE + 11;
+
+    public static String getCallbackName(int whichCallback) {
+        switch (whichCallback) {
+            case CALLBACK_PRECHECK:     return "CALLBACK_PRECHECK";
+            case CALLBACK_AVAILABLE:    return "CALLBACK_AVAILABLE";
+            case CALLBACK_LOSING:       return "CALLBACK_LOSING";
+            case CALLBACK_LOST:         return "CALLBACK_LOST";
+            case CALLBACK_UNAVAIL:      return "CALLBACK_UNAVAIL";
+            case CALLBACK_CAP_CHANGED:  return "CALLBACK_CAP_CHANGED";
+            case CALLBACK_IP_CHANGED:   return "CALLBACK_IP_CHANGED";
+            case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
+            case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
+            case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
+            case CALLBACK_BLK_CHANGED:  return "CALLBACK_BLK_CHANGED";
+            default:
+                return Integer.toString(whichCallback);
+        }
+    }
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            int timeoutMs, int legacyType, @NonNull Handler handler,
+            @NonNull NetworkCallback networkCallback) {}
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback) {}
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {}
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback, int timeoutMs) {}
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {}
+
+    public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
+
+    public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
+
+
+    public void requestNetwork(@NonNull NetworkRequest request,
+            @NonNull PendingIntent operation) {}
+
+    public void releaseNetworkRequest(@NonNull PendingIntent operation) {}
+
+    public void registerNetworkCallback(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback) {}
+
+    public void registerNetworkCallback(@NonNull NetworkRequest request,
+            @NonNull NetworkCallback networkCallback, @NonNull Handler handler) {}
+
+    public void registerNetworkCallback(@NonNull NetworkRequest request,
+            @NonNull PendingIntent operation) {}
+
+    public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) {}
+
+    public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback,
+            @NonNull Handler handler) {}
+
+    public boolean requestBandwidthUpdate(@NonNull Network network) {
+        return false;
+    }
+
+    public void unregisterNetworkCallback(@NonNull NetworkCallback networkCallback) {}
+
+    public void unregisterNetworkCallback(@NonNull PendingIntent operation) {}
+
+    public void setAcceptUnvalidated(Network network, boolean accept, boolean always) {}
+
+    public void setAcceptPartialConnectivity(Network network, boolean accept, boolean always) {}
+
+    public void setAvoidUnvalidated(Network network) {}
+
+    public void startCaptivePortalApp(Network network) {}
+
+    public void startCaptivePortalApp(@NonNull Network network, @NonNull Bundle appExtras) {}
+
+    public boolean shouldAvoidBadWifi() {
+        return false;
+    }
+
+    public static final int MULTIPATH_PREFERENCE_HANDOVER = 1 << 0;
+
+    public static final int MULTIPATH_PREFERENCE_RELIABILITY = 1 << 1;
+
+    public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2;
+
+    public static final int MULTIPATH_PREFERENCE_UNMETERED =
+            MULTIPATH_PREFERENCE_HANDOVER |
+                    MULTIPATH_PREFERENCE_RELIABILITY |
+                    MULTIPATH_PREFERENCE_PERFORMANCE;
+
+    public @interface MultipathPreference {
+    }
+
+    public @MultipathPreference int getMultipathPreference(@Nullable Network network) {
+        return 0;
+    }
+
+    public void factoryReset() {}
+
+    public boolean bindProcessToNetwork(@Nullable Network network) {
+        return false;
+    }
+
+    public static boolean setProcessDefaultNetwork(@Nullable Network network) {
+        return false;
+    }
+
+    @Nullable
+    public Network getBoundNetworkForProcess() {
+        return null;
+    }
+
+    @Deprecated
+    @Nullable
+    public static Network getProcessDefaultNetwork() {
+        return null;
+    }
+
+    @Deprecated
+    public static boolean setProcessDefaultNetworkForHostResolution(Network network) {
+        return false;
+    }
+
+    public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
+
+    public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
+
+    public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
+
+    public static final String ACTION_RESTRICT_BACKGROUND_CHANGED =
+            "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
+
+    public @interface RestrictBackgroundStatus {
+    }
+
+    public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
+        return 0;
+    }
+
+    @Nullable
+    public byte[] getNetworkWatchlistConfigHash() {
+        return null;
+    }
+
+    public int getConnectionOwnerUid(
+            int protocol, @NonNull InetSocketAddress local, @NonNull InetSocketAddress remote) {
+        return 0;
+    }
+
+    public void simulateDataStall(int detectionMethod, long timestampMillis,
+            @NonNull Network network, @NonNull PersistableBundle extras) {}
+}
+
diff --git a/bridge/src/android/os/SystemClock_Delegate.java b/bridge/src/android/os/SystemClock_Delegate.java
index 9677aaf..b6a85f8 100644
--- a/bridge/src/android/os/SystemClock_Delegate.java
+++ b/bridge/src/android/os/SystemClock_Delegate.java
@@ -54,6 +54,16 @@
     }
 
     /**
+     * Returns nanoseconds since boot, not counting time spent in deep sleep.
+     *
+     * @return nanoseconds of non-sleep uptime since boot.
+     */
+    @LayoutlibDelegate
+    /*package*/ static long uptimeNanos() {
+        return System_Delegate.nanoTime() - System_Delegate.bootTime();
+    }
+
+    /**
      * Returns nanoseconds since boot, including time spent in sleep.
      *
      * @return elapsed nanoseconds since boot.
diff --git a/bridge/src/android/os/SystemProperties_Delegate.java b/bridge/src/android/os/SystemProperties_Delegate.java
index c6a7657..b5c8294 100644
--- a/bridge/src/android/os/SystemProperties_Delegate.java
+++ b/bridge/src/android/os/SystemProperties_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -106,35 +106,35 @@
 
     @LayoutlibDelegate
     /*package*/ static String native_get(long handle) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Layoutlib does not support SystemProperties Handle", null, null, null);
         return null;
     }
 
     @LayoutlibDelegate
     /*package*/ static int native_get_int(long handle, int def) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Layoutlib does not support SystemProperties Handle", null, null, null);
         return def;
     }
 
     @LayoutlibDelegate
     /*package*/ static long native_get_long(long handle, long def) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Layoutlib does not support SystemProperties Handle", null, null, null);
         return def;
     }
 
     @LayoutlibDelegate
     /*package*/ static boolean native_get_boolean(long handle, boolean def) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Layoutlib does not support SystemProperties Handle", null, null, null);
         return def;
     }
 
     @LayoutlibDelegate
     /*package*/ static long native_find(String name) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                 "Layoutlib does not support SystemProperties Handle", null, null, null);
         return 0;
     }
diff --git a/bridge/src/android/util/PathParser_Delegate.java b/bridge/src/android/util/PathParser_Delegate.java
index 96c093c..46e94a7 100644
--- a/bridge/src/android/util/PathParser_Delegate.java
+++ b/bridge/src/android/util/PathParser_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.util;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -121,7 +121,7 @@
         }
         int length = from.mPathDataNodes.length;
         if (length != to.mPathDataNodes.length) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Cannot interpolate path data with different lengths (from " + length + " to " +
                             to.mPathDataNodes.length + ").", null, null);
             return false;
diff --git a/bridge/src/android/view/BridgeInflater.java b/bridge/src/android/view/BridgeInflater.java
index f2cbfa0..dfb46f2 100644
--- a/bridge/src/android/view/BridgeInflater.java
+++ b/bridge/src/android/view/BridgeInflater.java
@@ -17,7 +17,7 @@
 package android.view;
 
 import com.android.SdkConstants;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.MergeCookie;
 import com.android.ide.common.rendering.api.ResourceNamespace;
@@ -264,7 +264,7 @@
                                         true /*readAppTheme*/,
                                         true /*wrapContext*/);
                             } catch (IllegalAccessException | InvocationTargetException e) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e,
+                                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, e.getMessage(), e,
                                         null, null);
                             }
                             return null;
@@ -295,7 +295,7 @@
             name = attrs.getAttributeValue(null, "class");
 
             if (name == null) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to inflate view tag without " +
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to inflate view tag without " +
                   "class attribute", null, null);
                 // We weren't able to resolve the view so we just pass a mock View to be able to
                 // continue rendering.
@@ -323,7 +323,7 @@
                 // There is some unknown inflation exception in inflating a View that was found.
                 view = new MockView(context, attrs);
                 ((MockView) view).setText(name);
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, e.getMessage(), e, null, null);
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, e.getMessage(), e, null, null);
             } else {
                 final Object lastContext = mConstructorArgs[0];
                 mConstructorArgs[0] = context;
@@ -382,7 +382,7 @@
 
                     return inflate(bridgeParser, root);
                 } catch (Exception e) {
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                    Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ,
                             "Failed to parse file " + path, e, null, null);
 
                     return null;
diff --git a/bridge/src/android/view/Choreographer_Delegate.java b/bridge/src/android/view/Choreographer_Delegate.java
index 1dc7778..3a8839f 100644
--- a/bridge/src/android/view/Choreographer_Delegate.java
+++ b/bridge/src/android/view/Choreographer_Delegate.java
@@ -33,6 +33,8 @@
 public class Choreographer_Delegate {
     private static final AtomicReference<Choreographer> mInstance = new AtomicReference<Choreographer>();
 
+    private static final int MS_16 = 16000000;
+
     @LayoutlibDelegate
     public static Choreographer getInstance() {
         if (mInstance.get() == null) {
@@ -60,15 +62,15 @@
         try {
             thisChoreographer.mLastFrameTimeNanos = frameTimeNanos - thisChoreographer.getFrameIntervalNanos();
             thisChoreographer.mFrameInfo.markInputHandlingStart();
-            thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos);
+            thisChoreographer.doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, MS_16);
 
             thisChoreographer.mFrameInfo.markAnimationsStart();
-            thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos);
+            thisChoreographer.doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, MS_16);
 
             thisChoreographer.mFrameInfo.markPerformTraversalsStart();
-            thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos);
+            thisChoreographer.doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, MS_16);
 
-            thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos);
+            thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, MS_16);
         } finally {
             AnimationUtils.unlockAnimationClock();
         }
diff --git a/bridge/src/android/view/LayoutInflater_Delegate.java b/bridge/src/android/view/LayoutInflater_Delegate.java
index 66a94fa..cb446e7 100644
--- a/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
@@ -106,7 +106,7 @@
             if (layout == 0) {
                 final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
                 if (value == null || value.length() <= 0) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
+                    Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a layout in the"
                             + " include tag: <include layout=\"@layout/layoutID\" />", null, null);
                     LayoutInflater.consumeChildElements(parser);
                     return;
@@ -129,10 +129,10 @@
             if (layout == 0) {
                 final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
                 if (value == null) {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a layout in the"
+                    Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a layout in the"
                             + " include tag: <include layout=\"@layout/layoutID\" />", null, null);
                 } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN, "You must specify a valid layout "
+                    Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "You must specify a valid layout "
                             + "reference. The layout ID " + value + " is not valid.", null, null);
                 }
             } else {
@@ -148,7 +148,7 @@
                     }
 
                     if (type != XmlPullParser.START_TAG) {
-                        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                                 childParser.getPositionDescription() + ": No start tag found!",
                                 null, null);
                         LayoutInflater.consumeChildElements(parser);
@@ -226,7 +226,7 @@
                 }
             }
         } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "<include /> can only be used inside of a ViewGroup",
                     null, null);
         }
diff --git a/bridge/src/android/view/MenuInflater_Delegate.java b/bridge/src/android/view/MenuInflater_Delegate.java
index 83586a1..818d741 100644
--- a/bridge/src/android/view/MenuInflater_Delegate.java
+++ b/bridge/src/android/view/MenuInflater_Delegate.java
@@ -16,8 +16,7 @@
 
 package android.view;
 
-import android.content.Context;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ViewInfo;
 import com.android.internal.view.menu.BridgeMenuItemImpl;
 import com.android.internal.view.menu.MenuView;
@@ -25,6 +24,7 @@
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
+import android.content.Context;
 import android.util.AttributeSet;
 
 /**
@@ -64,7 +64,7 @@
             // This is most likely a bug in the LayoutLib code.
             // We suppress this error for AppCompat menus since we do not support them in the menu
             // editor yet.
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().warning(ILayoutLog.TAG_BROKEN,
                     "Action Bar Menu rendering may be incorrect.", null, null);
         }
 
diff --git a/bridge/src/android/view/View_Delegate.java b/bridge/src/android/view/View_Delegate.java
index 9aae4ae..6d82e8a 100644
--- a/bridge/src/android/view/View_Delegate.java
+++ b/bridge/src/android/view/View_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
@@ -55,7 +55,7 @@
             // all the layout.
             thisView.draw_Original(canvas);
         } catch (Throwable t) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View draw failed", t, null, null);
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View draw failed", t, null, null);
         }
     }
 
@@ -67,7 +67,7 @@
             // all the layout.
             return thisView.draw_Original(canvas, parent, drawingTime);
         } catch (Throwable t) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View draw failed", t, null, null);
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View draw failed", t, null, null);
         }
         return false;
     }
@@ -79,7 +79,7 @@
             // all the layout.
             thisView.measure_Original(widthMeasureSpec, heightMeasureSpec);
         } catch (Throwable t) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View measure failed", t, null, null);
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View measure failed", t, null, null);
         }
     }
 
@@ -90,7 +90,7 @@
             // all the layout.
             thisView.layout_Original(l, t, r, b);
         } catch (Throwable th) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "View layout failed", th, null, null);
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "View layout failed", th, null, null);
         }
     }
 
diff --git a/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/bridge/src/android/view/WindowManagerImpl.java
similarity index 62%
rename from bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
rename to bridge/src/android/view/WindowManagerImpl.java
index 3cd95be..36b7165 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
+++ b/bridge/src/android/view/WindowManagerImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,30 +11,27 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
  */
-package com.android.layoutlib.bridge.android.view;
+package android.view;
+
+import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import android.app.ResourcesManager;
 import android.content.Context;
-import android.graphics.Insets;
+import android.content.res.Configuration;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
-import android.util.Size;
-import android.view.Display;
 import android.view.Display.Mode;
-import android.view.DisplayAdjustments;
-import android.view.DisplayCutout;
-import android.view.DisplayInfo;
-import android.view.InsetsState;
-import android.view.View;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.WindowMetrics;
+
+import com.android.ide.common.rendering.api.ILayoutLog;
+import com.android.layoutlib.bridge.Bridge;
 
 public class WindowManagerImpl implements WindowManager {
 
@@ -57,6 +54,30 @@
                 DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
     }
 
+    public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
+                "The preview does not support multiple windows.",
+                null, null, null);
+        return this;
+    }
+
+    public WindowManagerImpl createPresentationWindowManager(Context displayContext) {
+        Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
+                "The preview does not support multiple windows.",
+                null, null, null);
+        return this;
+    }
+
+    /**
+     * Sets the window token to assign when none is specified by the client or
+     * available from the parent window.
+     *
+     * @param token The default token to assign.
+     */
+    public void setDefaultToken(IBinder token) {
+
+    }
+
     @Override
     public Display getDefaultDisplay() {
         return mDisplay;
@@ -105,7 +126,7 @@
     }
 
     @Override
-    public void setShouldShowIme(int displayId, boolean shouldShow) {
+    public void setDisplayImePolicy(int displayId, int imePolicy) {
         // pass
     }
 
@@ -135,18 +156,17 @@
 
     private WindowInsets computeWindowInsets() {
         try {
-            final Rect systemWindowInsets = new Rect();
-            final Rect stableInsets = new Rect();
-            final DisplayCutout.ParcelableWrapper displayCutout =
-                    new DisplayCutout.ParcelableWrapper();
             final InsetsState insetsState = new InsetsState();
-            WindowManagerGlobal.getWindowManagerService().getWindowInsets(
-                    new WindowManager.LayoutParams(), mContext.getDisplayId(), systemWindowInsets,
-                    stableInsets, displayCutout, insetsState);
-            return new WindowInsets.Builder()
-                    .setSystemWindowInsets(Insets.of(systemWindowInsets))
-                    .setStableInsets(Insets.of(stableInsets))
-                    .setDisplayCutout(displayCutout.get()).build();
+            final boolean alwaysConsumeSystemBars =
+                    WindowManagerGlobal.getWindowManagerService().getWindowInsets(
+                            new WindowManager.LayoutParams(), mContext.getDisplayId(), insetsState);
+            final Configuration config = mContext.getResources().getConfiguration();
+            final boolean isScreenRound = config.isScreenRound();
+            final int windowingMode = config.windowConfiguration.getWindowingMode();
+            return insetsState.calculateInsets(getCurrentBounds(mContext),
+                    null /* ignoringVisibilityState*/, isScreenRound, alwaysConsumeSystemBars,
+                    SOFT_INPUT_ADJUST_NOTHING, 0, SYSTEM_UI_FLAG_VISIBLE, TYPE_APPLICATION,
+                    windowingMode, null /* typeSideMap */);
         } catch (RemoteException ignore) {
         }
         return null;
diff --git a/bridge/src/android/view/accessibility/AccessibilityManager.java b/bridge/src/android/view/accessibility/AccessibilityManager.java
index d5e60a9..4454f29 100644
--- a/bridge/src/android/view/accessibility/AccessibilityManager.java
+++ b/bridge/src/android/view/accessibility/AccessibilityManager.java
@@ -156,6 +156,9 @@
 
                 public void setRelevantEventTypes(int eventTypes) {
                 }
+
+                public void setFocusAppearance(int strokeWidth, int color) {
+                }
             };
 
     /**
diff --git a/bridge/src/android/view/shadow/AmbientShadowTriangulator.java b/bridge/src/android/view/shadow/AmbientShadowTriangulator.java
index 630ec30..d768fa3 100644
--- a/bridge/src/android/view/shadow/AmbientShadowTriangulator.java
+++ b/bridge/src/android/view/shadow/AmbientShadowTriangulator.java
@@ -16,7 +16,7 @@
 
 package android.view.shadow;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 
 /**
@@ -43,11 +43,11 @@
             mCalculator.generateVertex();
             mValid = true;
         } catch (IndexOutOfBoundsException|ArithmeticException mathError) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Arithmetic error while drawing " +
+            Bridge.getLog().warning(ILayoutLog.TAG_INFO,  "Arithmetic error while drawing " +
                             "ambient shadow",
                     null, mathError);
         } catch (Exception ex) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Error while drawing shadow",
+            Bridge.getLog().warning(ILayoutLog.TAG_INFO,  "Error while drawing shadow",
                     null, ex);
         }
     }
diff --git a/bridge/src/android/view/shadow/SpotShadowTriangulator.java b/bridge/src/android/view/shadow/SpotShadowTriangulator.java
index 854a4d5..d666153 100644
--- a/bridge/src/android/view/shadow/SpotShadowTriangulator.java
+++ b/bridge/src/android/view/shadow/SpotShadowTriangulator.java
@@ -16,12 +16,8 @@
 
 package android.view.shadow;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
-import com.android.tools.layoutlib.annotations.VisibleForTesting;
-
-import android.graphics.Bitmap;
-import android.view.math.Math3DHelper;
 
 /**
  * Generate spot shadow bitmap.
@@ -58,11 +54,11 @@
                     mShadowConfig.getShadowStrength(),
                     mStrips);
         } catch (IndexOutOfBoundsException|ArithmeticException mathError) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Arithmetic error while drawing " +
+            Bridge.getLog().warning(ILayoutLog.TAG_INFO,  "Arithmetic error while drawing " +
                             "spot shadow",
                     null, mathError);
         } catch (Exception ex) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,  "Error while drawing shadow",
+            Bridge.getLog().warning(ILayoutLog.TAG_INFO,  "Error while drawing shadow",
                     null, ex);
         }
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/Bridge.java b/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 88298d6..aa76e75 100644
--- a/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -17,7 +17,7 @@
 package com.android.layoutlib.bridge;
 
 import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.ResourceNamespace;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -33,7 +33,7 @@
 import com.android.tools.layoutlib.annotations.Nullable;
 import com.android.tools.layoutlib.create.MethodAdapter;
 import com.android.tools.layoutlib.create.OverrideMethod;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import android.animation.PropertyValuesHolder;
 import android.animation.PropertyValuesHolder_Delegate;
@@ -56,7 +56,6 @@
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.EnumMap;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -94,7 +93,6 @@
     /**
      * Maps from id to resource type/name. This is for com.android.internal.R
      */
-    @SuppressWarnings("deprecation")
     private final static Map<Integer, Pair<ResourceType, String>> sRMap = new HashMap<>();
 
     /**
@@ -124,7 +122,7 @@
     /**
      * A default log than prints to stdout/stderr.
      */
-    private final static LayoutLog sDefaultLog = new LayoutLog() {
+    private final static ILayoutLog sDefaultLog = new ILayoutLog() {
         @Override
         public void error(String tag, String message, Object viewCookie, Object data) {
             System.err.println(message);
@@ -145,7 +143,7 @@
     /**
      * Current log.
      */
-    private static LayoutLog sCurrentLog = sDefaultLog;
+    private static ILayoutLog sCurrentLog = sDefaultLog;
 
     public static boolean sIsTypefaceInitialized;
 
@@ -155,7 +153,7 @@
             String nativeLibPath,
             String icuDataPath,
             Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
+            ILayoutLog log) {
         sPlatformProperties = platformProperties;
         sEnumValueMap = enumValueMap;
 
@@ -208,7 +206,7 @@
                     continue;
                 }
                 String resTypeName = inner.getSimpleName();
-                ResourceType resType = ResourceType.getEnum(resTypeName);
+                ResourceType resType = ResourceType.fromClassName(resTypeName);
                 if (resType != null) {
                     Map<String, Integer> fullMap = null;
                     switch (resType) {
@@ -236,7 +234,6 @@
                         Class<?> type = f.getType();
                         if (!type.isArray()) {
                             Integer value = (Integer) f.get(null);
-                            //noinspection deprecation
                             sRMap.put(value, Pair.of(resType, f.getName()));
                             fullMap.put(f.getName(), value);
                         }
@@ -245,7 +242,7 @@
             }
         } catch (Exception throwable) {
             if (log != null) {
-                log.error(LayoutLog.TAG_BROKEN,
+                log.error(ILayoutLog.TAG_BROKEN,
                         "Failed to load com.android.internal.R from the layout library jar",
                         throwable, null, null);
             }
@@ -327,11 +324,9 @@
             if (arrayValue != null) {
                 String attrName = name.substring(arrayName.length() + 1);
                 int attrValue = arrayValue[index];
-                //noinspection deprecation
                 sRMap.put(attrValue, Pair.of(ResourceType.ATTR, attrName));
                 revRAttrMap.put(attrName, attrValue);
             }
-            //noinspection deprecation
             sRMap.put(index, Pair.of(ResourceType.STYLEABLE, name));
             revRStyleableMap.put(name, index);
         }
@@ -512,11 +507,11 @@
         Looper_Accessor.cleanupThread();
     }
 
-    public static LayoutLog getLog() {
+    public static ILayoutLog getLog() {
         return sCurrentLog;
     }
 
-    public static void setLog(LayoutLog log) {
+    public static void setLog(ILayoutLog log) {
         // check only the thread currently owning the lock can do this.
         if (!sLock.isHeldByCurrentThread()) {
             throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
diff --git a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
index 442a77b..5584708 100644
--- a/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
+++ b/bridge/src/com/android/layoutlib/bridge/BridgeRenderSession.java
@@ -74,11 +74,6 @@
     }
 
     @Override
-    public Map<Object, String> getDefaultStyles() {
-        return mSession != null ? mSession.getDefaultStyles() : Collections.emptyMap();
-    }
-
-    @Override
     public Map<Object, ResourceReference> getDefaultNamespacedStyles() {
         return mSession != null ? mSession.getDefaultNamespacedStyles() : Collections.emptyMap();
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/MockView.java b/bridge/src/com/android/layoutlib/bridge/MockView.java
index 9856cf6..a1d1bbc 100644
--- a/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/bridge/src/com/android/layoutlib/bridge/MockView.java
@@ -111,7 +111,6 @@
         mView.setText(text);
     }
 
-    @SuppressWarnings("WeakerAccess") // This method is used from Studio
     public void setGravity(int gravity) {
         mView.setGravity(gravity);
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index ce613e0..8934b12 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.layoutlib.bridge.android;
 
+import android.content.AttributionSource;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
@@ -44,7 +45,7 @@
  */
 public final class BridgeContentProvider implements IContentProvider {
     @Override
-    public ContentProviderResult[] applyBatch(String callingPackage, String callingFeatureId,
+    public ContentProviderResult[] applyBatch(AttributionSource attributionSource,
             String authority, ArrayList<ContentProviderOperation> arg0)
             throws RemoteException, OperationApplicationException {
         // TODO Auto-generated method stub
@@ -52,21 +53,21 @@
     }
 
     @Override
-    public int bulkInsert(String callingPackage, String callingFeatureId, Uri arg0,
+    public int bulkInsert(AttributionSource attributionSource, Uri arg0,
             ContentValues[] arg1) throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
     }
 
     @Override
-    public Bundle call(String callingPackage, String callingFeatureId, String authority,
+    public Bundle call(AttributionSource attributionSource, String authority,
             String arg0, String arg1, Bundle arg2) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public int delete(String callingPackage, String callingFeatureId, Uri arg0, Bundle arg1)
+    public int delete(AttributionSource attributionSource, Uri arg0, Bundle arg1)
             throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
@@ -93,14 +94,14 @@
     }
 
     @Override
-    public Uri insert(String callingPackage, String callingFeatureId, Uri arg0, ContentValues arg1,
+    public Uri insert(AttributionSource attributionSource, Uri arg0, ContentValues arg1,
             Bundle arg2) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public AssetFileDescriptor openAssetFile(String callingPackage, String callingFeatureId,
+    public AssetFileDescriptor openAssetFile(AttributionSource attributionSource,
             Uri arg0, String arg1, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
@@ -108,22 +109,22 @@
     }
 
     @Override
-    public ParcelFileDescriptor openFile(String callingPackage, String callingFeatureId, Uri arg0,
-            String arg1, ICancellationSignal signal, IBinder token)
+    public ParcelFileDescriptor openFile(AttributionSource attributionSource, Uri arg0,
+            String arg1, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public Cursor query(String callingPackage, String callingFeatureId, Uri arg0, String[] arg1,
+    public Cursor query(AttributionSource attributionSource, Uri arg0, String[] arg1,
             Bundle arg3, ICancellationSignal arg4) throws RemoteException {
         // TODO Auto-generated method stub
         return null;
     }
 
     @Override
-    public int update(String callingPackage, String callingFeatureId, Uri arg0, ContentValues arg1,
+    public int update(AttributionSource attributionSource, Uri arg0, ContentValues arg1,
             Bundle arg2) throws RemoteException {
         // TODO Auto-generated method stub
         return 0;
@@ -142,7 +143,7 @@
     }
 
     @Override
-    public AssetFileDescriptor openTypedAssetFile(String callingPackage, String callingFeatureId,
+    public AssetFileDescriptor openTypedAssetFile(AttributionSource attributionSource,
             Uri arg0, String arg1, Bundle arg2, ICancellationSignal signal)
             throws RemoteException, FileNotFoundException {
         // TODO Auto-generated method stub
@@ -157,20 +158,20 @@
 
 
     @Override
-    public Uri canonicalize(String callingPkg, String callingFeatureId, Uri uri)
+    public Uri canonicalize(AttributionSource attributionSource, Uri uri)
             throws RemoteException {
         return null;
     }
 
     @SuppressWarnings("deprecation")
     @Override
-    public void canonicalizeAsync(String callingPkg, String callingFeatureId, Uri uri,
+    public void canonicalizeAsync(AttributionSource attributionSource, Uri uri,
             RemoteCallback remoteCallback) {
         AsyncTask.SERIAL_EXECUTOR.execute(() -> {
             try {
                 final Bundle bundle = new Bundle();
                 bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
-                        canonicalize(callingPkg, callingFeatureId, uri));
+                        canonicalize(attributionSource, uri));
                 remoteCallback.sendResult(bundle);
             } catch (RemoteException e) {
               // Ignore
@@ -179,19 +180,35 @@
     }
 
     @Override
-    public Uri uncanonicalize(String callingPkg, String callingFeatureId, Uri uri)
+    public Uri uncanonicalize(AttributionSource attributionSource, Uri uri)
             throws RemoteException {
         return null;
     }
 
+    @SuppressWarnings("deprecation")
     @Override
-    public boolean refresh(String callingPkg, String callingFeatureId, Uri url, Bundle args,
+    public void uncanonicalizeAsync(AttributionSource attributionSource, Uri uri,
+            RemoteCallback remoteCallback) {
+        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+            try {
+                final Bundle bundle = new Bundle();
+                bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
+                        uncanonicalize(attributionSource, uri));
+                remoteCallback.sendResult(bundle);
+            } catch (RemoteException e) {
+              // Ignore
+            }
+        });
+    }
+
+    @Override
+    public boolean refresh(AttributionSource attributionSource, Uri url, Bundle args,
             ICancellationSignal cancellationSignal) throws RemoteException {
         return false;
     }
 
     @Override
-    public int checkUriPermission(String callingPkg, String callingFeatureId, Uri uri, int uid,
+    public int checkUriPermission(AttributionSource attributionSource, Uri uri, int uid,
             int modeFlags) throws RemoteException {
         return PackageManager.PERMISSION_DENIED;
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 9a076f5..73a73d0 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -18,8 +18,8 @@
 
 import com.android.SdkConstants;
 import com.android.ide.common.rendering.api.AssetRepository;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceNamespace;
@@ -30,21 +30,23 @@
 import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
 import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.layoutlib.bridge.impl.Stack;
 import com.android.resources.ResourceType;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityManager_Accessor;
 import android.app.SystemServiceRegistry;
 import android.content.BroadcastReceiver;
 import android.content.ClipboardManager;
+import android.content.ComponentCallbacks;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -69,6 +71,7 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
+import android.net.ConnectivityManager;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -90,6 +93,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.WindowManagerImpl;
 import android.view.accessibility.AccessibilityManager;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.IAutoFillManager.Default;
@@ -116,7 +120,6 @@
 /**
  * Custom implementation of Context/Activity to handle non compiled resources.
  */
-@SuppressWarnings("deprecation")  // For use of Pair.
 public class BridgeContext extends Context {
     private static final String PREFIX_THEME_APPCOMPAT = "Theme.AppCompat";
 
@@ -166,6 +169,8 @@
     private final DisplayManager mDisplayManager;
     private final AutofillManager mAutofillManager;
     private final ClipboardManager mClipboardManager;
+    private final ActivityManager mActivityManager;
+    private final ConnectivityManager mConnectivityManager;
     private final HashMap<View, Integer> mScrollYPos = new HashMap<>();
     private final HashMap<View, Integer> mScrollXPos = new HashMap<>();
 
@@ -253,6 +258,8 @@
         mDisplayManager = new DisplayManager(this);
         mAutofillManager = new AutofillManager(this, new Default());
         mClipboardManager = new ClipboardManager(this, null);
+        mActivityManager = ActivityManager_Accessor.getActivityManagerInstance(this);
+        mConnectivityManager = new ConnectivityManager(this, null);
 
         if (mLayoutlibCallback.isResourceNamespacingRequired()) {
             if (mLayoutlibCallback.hasAndroidXAppCompat()) {
@@ -522,18 +529,18 @@
                         popParser();
                     }
                 } else {
-                    Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                    Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                             String.format("File %s is missing!", path), null, null);
                 }
             } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                         "Failed to parse file " + path, e, null, null /*data*/);
                 // we'll return null below.
             } finally {
                 mBridgeInflater.setResourceReference(null);
             }
         } else {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     String.format("Layout %s%s does not exist.", isPlatformLayout ? "android:" : "",
                             layout.getName()), null, null);
         }
@@ -648,6 +655,12 @@
             case CLIPBOARD_SERVICE:
                 return mClipboardManager;
 
+            case ACTIVITY_SERVICE:
+                return mActivityManager;
+
+            case CONNECTIVITY_SERVICE:
+                return mConnectivityManager;
+
             case AUDIO_SERVICE:
             case TEXT_CLASSIFICATION_SERVICE:
             case CONTENT_CAPTURE_MANAGER_SERVICE:
@@ -685,7 +698,7 @@
             }
 
             if (style == null) {
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+                Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
                         "Failed to find style with " + resId, null, null);
                 return null;
             }
@@ -754,7 +767,7 @@
             resolver = Resolver.EMPTY_RESOLVER;
         } else if (set != null) {
             // really this should not be happening since its instantiated in Bridge
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Parser is not a BridgeXmlBlockParser!", null, null);
             return null;
         } else {
@@ -793,7 +806,7 @@
                 // This should be rare. Happens trying to map R.style.foo to @style/foo fails.
                 // This will happen if the user explicitly used a non existing int value for
                 // defStyleAttr or there's something wrong with the project structure/build.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+                Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
                         "Failed to find the style corresponding to the id " + defStyleAttr, null,
                         null);
             } else {
@@ -952,7 +965,7 @@
                                 if (reference != null) {
                                     val = reference.getResourceUrl().toString();
                                 }
-                                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
+                                Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_RESOLVE_THEME_ATTR,
                                         String.format("Failed to find '%s' in current theme.", val),
                                         null, val);
                             }
@@ -1005,6 +1018,12 @@
         return mPackageManager;
     }
 
+    @Override
+    public void registerComponentCallbacks(ComponentCallbacks callback) {}
+
+    @Override
+    public void unregisterComponentCallbacks(ComponentCallbacks callback) {}
+
     // ------------- private new methods
 
     /**
@@ -1965,7 +1984,7 @@
 
     @Override
     public File getObbDir() {
-        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null, null);
+        Bridge.getLog().error(ILayoutLog.TAG_UNSUPPORTED, "OBB not supported", null, null);
         return null;
     }
 
diff --git a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
index 92d7fdb..41e4e2d 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/BridgePowerManager.java
@@ -17,6 +17,7 @@
 package com.android.layoutlib.bridge.android;
 
 import android.os.BatterySaverPolicyConfig;
+import android.os.ParcelDuration;
 import android.os.IBinder;
 import android.os.IPowerManager;
 import android.os.PowerManager;
@@ -46,6 +47,16 @@
     }
 
     @Override
+    public BatterySaverPolicyConfig getFullPowerSavePolicy() {
+        return new BatterySaverPolicyConfig.Builder().build();
+    }
+
+    @Override
+    public boolean setFullPowerSavePolicy(BatterySaverPolicyConfig config) {
+        return false;
+    }
+
+    @Override
     public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold)
             throws RemoteException {
         return false;
@@ -72,25 +83,44 @@
     }
 
     @Override
+    public void setBatteryDischargePrediction(ParcelDuration timeRemaining,
+            boolean isPersonalized) {
+        // pass for now
+    }
+
+    @Override
+    public ParcelDuration getBatteryDischargePrediction() {
+        return null;
+    }
+
+    @Override
+    public boolean isBatteryDischargePredictionPersonalized() {
+        return false;
+    }
+
+    @Override
     public IBinder asBinder() {
         // pass for now.
         return null;
     }
 
     @Override
-    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
+    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3,
+            String arg4, int arg5)
             throws RemoteException {
         // pass for now.
     }
 
     @Override
-    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5, int arg3)
-            throws RemoteException {
+    public void acquireWakeLockAsync(IBinder arg0, int arg1, String arg2, String arg2_5,
+            WorkSource arg3, String arg4) throws RemoteException {
         // pass for now.
     }
 
     @Override
-    public void powerHint(int hintId, int data) {
+    public void acquireWakeLockWithUid(IBinder arg0, int arg1, String arg2, String arg2_5,
+            int arg3, int arg4)
+            throws RemoteException {
         // pass for now.
     }
 
@@ -150,11 +180,21 @@
     }
 
     @Override
+    public void releaseWakeLockAsync(IBinder arg0, int arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    @Override
     public void updateWakeLockUids(IBinder arg0, int[] arg1) throws RemoteException {
         // pass for now.
     }
 
     @Override
+    public void updateWakeLockUidsAsync(IBinder arg0, int[] arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    @Override
     public void setAttentionLight(boolean arg0, int arg1) throws RemoteException {
         // pass for now.
     }
@@ -176,7 +216,8 @@
     }
 
     @Override
-    public void userActivity(long time, int event, int flags) throws RemoteException {
+    public void userActivity(int displayId, long time, int event, int flags)
+            throws RemoteException {
         // pass for now.
     }
 
diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
index 5f785f5..92693c6 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/support/DesignLibUtil.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.android.support;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
 
@@ -61,7 +61,7 @@
         try {
             invoke(getMethod(view.getClass(), "setTitle", CharSequence.class), view, title);
         } catch (ReflectionException e) {
-            Bridge.getLog().warning(LayoutLog.TAG_INFO,
+            Bridge.getLog().warning(ILayoutLog.TAG_INFO,
                     "Error occurred while trying to set title.", null, e);
         }
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
index c41bcae..08e7419 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/support/DrawerLayoutUtil.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.android.support;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
 
@@ -59,7 +59,7 @@
             invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout,
                     gravity);
         } catch (ReflectionException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
                     getCause(e), null, null);
         }
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java
index c77cb57..a426b27 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/support/FragmentTabHostUtil.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.android.support;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
 
@@ -59,7 +59,7 @@
         }
 
         if (fragmentManager == null) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Unable to find FragmentManager.", null, null);
             return;
         }
@@ -70,7 +70,7 @@
                     android.R.id.tabcontent);
         } catch (ReflectionException e) {
             Throwable cause = getCause(e);
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Error occurred while trying to setup FragmentTabHost.", cause, null, null);
         }
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index 6fc8009..ff20fbf 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.android.support;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -72,7 +72,7 @@
             }
         } catch (ReflectionException e) {
             Throwable cause = getCause(e);
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Error occurred while trying to setup RecyclerView.", cause, null, null);
         }
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java b/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
index 171edb9..f195a5e 100644
--- a/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
+++ b/bridge/src/com/android/layoutlib/bridge/android/support/SupportPreferencesUtil.java
@@ -298,8 +298,8 @@
                     preferenceGroupAdapter);
 
             ScrollView scrollView = new ScrollView(context);
-            scrollView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
-                    LayoutParams.WRAP_CONTENT));
+            scrollView.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
+                    LayoutParams.MATCH_PARENT));
             scrollView.addView(listView);
 
             if (root != null) {
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java b/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
index ab88f15..8ca809e 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/AppCompatActionBar.java
@@ -15,7 +15,7 @@
  */
 package com.android.layoutlib.bridge.bars;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -118,7 +118,7 @@
             setupActionBar();
             getContentRoot().setId(id.content);
         } catch (Exception e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().warning(ILayoutLog.TAG_BROKEN,
                     "Failed to load AppCompat ActionBar with unknown error.", null, e);
         }
     }
@@ -201,7 +201,7 @@
         if (menuIds.size() > 1) {
             // Supporting multiple menus means that we would need to instantiate our own supportlib
             // MenuInflater instances using reflection
-            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+            Bridge.getLog().fidelityWarning(ILayoutLog.TAG_UNSUPPORTED,
                     "Support Toolbar does not currently support multiple menus in the preview.",
                     null, null, null);
         }
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java b/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
index 8790cb5..1f7b187 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/BridgeActionBar.java
@@ -45,7 +45,7 @@
     private final View mDecorContent;
     private final ActionBarCallback mCallback;
 
-    @SuppressWarnings("NullableProblems")  // Should be initialized by subclasses.
+    @SuppressWarnings("NotNullFieldNotInitialized") // Should be initialized by subclasses.
     @NonNull private FrameLayout mContentRoot;
 
     public BridgeActionBar(@NonNull BridgeContext context, @NonNull SessionParams params) {
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 7813844..a49a664 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -92,8 +92,8 @@
     }
 
     public static String getTime(int platformVersion) {
-        if (isGreaterOrEqual(platformVersion, Q)) {
-            return "10:00";
+        if (isGreaterOrEqual(platformVersion, R)) {
+            return "11:00";
         }
         if (platformVersion < GINGERBREAD) {
             return "2:20";
@@ -134,6 +134,9 @@
         if (platformVersion < Q) {
             return "9:00";
         }
+        if (platformVersion < R) {
+            return "10:00";
+        }
         // Should never happen.
         return "4:04";
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 3a5f633..0bb72ed 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.bars;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.rendering.api.StyleResourceValue;
@@ -256,7 +256,7 @@
                     return ResourceHelper.getColor(resource.getValue());
                 } catch (NumberFormatException e) {
                     // Conversion failed.
-                    Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
+                    Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
                             "Theme attribute @android:" + attr +
                                     " does not reference a color, instead is '" +
                                     resource.getValue() + "'.", null, resource);
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index f58443a..dc823f7 100644
--- a/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.bars;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ResourceNamespace;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
@@ -90,7 +90,7 @@
         }
 
         if (icons.size() != 2 || clockView == null) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to initialize statusbar", null,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to initialize statusbar", null,
                     null, null);
             return;
         }
@@ -126,10 +126,10 @@
                 imageView.setImageDrawable(
                         Drawable.createFromXml(mContext.getResources(), parser));
             } catch (XmlPullParserException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
                         null, null);
             } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
+                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, "Unable to draw wifi icon", e,
                         null, null);
             }
         }
diff --git a/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java b/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
deleted file mode 100644
index 523f140..0000000
--- a/bridge/src/com/android/layoutlib/bridge/bars/ThemePreviewNavigationBar.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.layoutlib.bridge.bars;
-
-import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.resources.Density;
-
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-
-/**
- * Navigation Bar for the Theme Editor preview.
- *
- * For small bars, it is identical to {@link NavigationBar}.
- * But wide bars from {@link NavigationBar} are too wide for the Theme Editor preview.
- * To solve that problem, {@link ThemePreviewNavigationBar} use the layout for small bars,
- * and have no padding on the sides. That way, they have a similar look as the true ones,
- * and they fit in the Theme Editor preview.
- */
-public class ThemePreviewNavigationBar extends NavigationBar {
-    private static final int PADDING_WIDTH_SW600 = 0;
-
-    @SuppressWarnings("unused")
-    public ThemePreviewNavigationBar(Context context, AttributeSet attrs) {
-        super((BridgeContext) context,
-                Density.getEnum(((BridgeContext) context).getMetrics().densityDpi),
-                LinearLayout.HORIZONTAL, // In this mode, it doesn't need to be render vertically
-                ((BridgeContext) context).getConfiguration().getLayoutDirection() ==
-                        View.LAYOUT_DIRECTION_RTL,
-                (context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
-                0, LAYOUT_XML, false);
-    }
-
-    @Override
-    protected int getSidePadding(float sw) {
-        if (sw >= 600) {
-            return PADDING_WIDTH_SW600;
-        }
-        return super.getSidePadding(sw);
-    }
-}
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index b71a0e2..5991eb0 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -111,7 +111,6 @@
     @GuardedBy("sNativeAllocations")
     private static long sNativeAllocationsCount = 0;
 
-    @SuppressWarnings("FieldCanBeLocal")
     private final Class<T> mClass;
 
     public DelegateManager(Class<T> theClass) {
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java b/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
index 959ba77..f3ebd40 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/GcSnapshot.java
@@ -16,12 +16,7 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
-import static java.awt.image.BufferedImage.TYPE_INT_RGB;
-import static java.lang.Math.min;
-import static java.lang.Math.max;
-
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 
 import android.graphics.Bitmap_Delegate;
@@ -51,6 +46,11 @@
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
 /**
  * Class representing a graphics context snapshot, as well as a context stack as a linked list.
  * <p>
@@ -846,7 +846,7 @@
                 g.setPaint(shaderPaint);
                 return;
             } else {
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_SHADER,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_SHADER,
                         shaderDelegate.getSupportMessage(), null, null, null);
             }
         }
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/Layout.java b/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
index 45accb9..c2fb3e1 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/Layout.java
@@ -543,7 +543,6 @@
             }
         }
 
-        @SuppressWarnings("SameParameterValue")
         private int getDimension(@NonNull ResourceReference attrRef, int defaultValue) {
             ResourceValue value = mResources.findItemInTheme(attrRef);
             value = mResources.resolveResValue(value);
@@ -557,7 +556,6 @@
             return defaultValue;
         }
 
-        @SuppressWarnings("SameParameterValue")
         private int getFrameworkAttrDimension(@NonNull String attr, int defaultValue) {
             return getDimension(BridgeContext.createFrameworkAttrReference(attr), defaultValue);
         }
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java b/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
index dcbd272..86f80fe 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/PorterDuffUtility.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.impl;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layoutlib.bridge.Bridge;
 
 import android.graphics.BlendComposite;
@@ -47,7 +47,7 @@
         if (porterDuffMode >= 0 && porterDuffMode < MODES_COUNT) {
             return PorterDuff.intToMode(porterDuffMode);
         }
-        Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+        Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                 String.format("Unknown PorterDuff.Mode: %1$d", porterDuffMode), null, null);
         assert false;
         return Mode.SRC_OVER;
@@ -97,7 +97,7 @@
             case OVERLAY:
                 return BlendComposite.getInstance(BlendingMode.OVERLAY, alpha1);
             default:
-                Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+                Bridge.getLog().fidelityWarning(ILayoutLog.TAG_BROKEN,
                         String.format("Unsupported PorterDuff Mode: %1$s", mode.name()),
                         null, null, null /*data*/);
 
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index b24c383..2ab0509 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -17,7 +17,7 @@
 package com.android.layoutlib.bridge.impl;
 
 import com.android.ide.common.rendering.api.HardwareConfig;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderParams;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.Result;
@@ -252,7 +252,7 @@
                 getContext().getMetrics(), Surface.ROTATION_0, hasNavigationBar);
         WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
 
-        LayoutLog currentLog = mParams.getLog();
+        ILayoutLog currentLog = mParams.getLog();
         Bridge.setLog(currentLog);
         mContext.getRenderResources().setLogger(currentLog);
     }
@@ -307,7 +307,7 @@
      * Returns the log associated with the session.
      * @return the log or null if there are none.
      */
-    public LayoutLog getLog() {
+    public ILayoutLog getLog() {
         if (mParams != null) {
             return mParams.getLog();
         }
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index 98299c3..93d3df8 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -18,8 +18,8 @@
 
 import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.HardwareConfig;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -46,16 +46,14 @@
 import com.android.layoutlib.bridge.android.support.SupportPreferencesUtil;
 import com.android.layoutlib.bridge.impl.binding.FakeAdapter;
 import com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter;
-import com.android.tools.layoutlib.java.System_Delegate;
-import com.android.tools.idea.validator.ValidatorResult;
 import com.android.tools.idea.validator.LayoutValidator;
 import com.android.tools.idea.validator.ValidatorResult;
 import com.android.tools.idea.validator.ValidatorResult.Builder;
-import com.android.util.Pair;
+import com.android.tools.layoutlib.java.System_Delegate;
+import com.android.utils.Pair;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.Fragment_Delegate;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap_Delegate;
 import android.graphics.Canvas;
@@ -93,6 +91,8 @@
 import java.util.List;
 import java.util.Map;
 
+import com.google.android.apps.common.testing.accessibility.framework.uielement.AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate;
+
 import static com.android.ide.common.rendering.api.Result.Status.ERROR_INFLATION;
 import static com.android.ide.common.rendering.api.Result.Status.ERROR_NOT_INFLATED;
 import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
@@ -119,7 +119,6 @@
     private Canvas mCanvas;
     private int mMeasuredScreenWidth = -1;
     private int mMeasuredScreenHeight = -1;
-    private boolean mIsAlphaChannelImage;
     /** If >= 0, a frame will be executed */
     private long mElapsedFrameTimeNanos = -1;
     /** True if one frame has been already executed to start the animations */
@@ -175,11 +174,6 @@
         SessionParams params = getParams();
         BridgeContext context = getContext();
 
-        // use default of true in case it's not found to use alpha by default
-        mIsAlphaChannelImage =
-                ResourceHelper.getBooleanThemeFrameworkAttrValue(params.getResources(),
-                        "windowIsFloating", true);
-
         mLayoutBuilder = new Layout.Builder(params, context);
 
         // build the inflater and parser.
@@ -209,10 +203,10 @@
         mMeasuredScreenHeight = hardwareConfig.getScreenHeight();
 
         if (renderingMode != RenderingMode.NORMAL) {
-            int widthMeasureSpecMode = renderingMode.isHorizExpand() ?
+            int widthMeasureSpecMode = renderingMode.getHorizAction() == SizeAction.EXPAND ?
                     MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                     : MeasureSpec.EXACTLY;
-            int heightMeasureSpecMode = renderingMode.isVertExpand() ?
+            int heightMeasureSpecMode = renderingMode.getVertAction() == SizeAction.EXPAND ?
                     MeasureSpec.UNSPECIFIED // this lets us know the actual needed size
                     : MeasureSpec.EXACTLY;
 
@@ -233,7 +227,6 @@
 
             // first measure the full layout, with EXACTLY to get the size of the
             // content as it is inside the decor/dialog
-            @SuppressWarnings("deprecation")
             Pair<Integer, Integer> exactMeasure = measureView(
                     mViewRoot, measuredView,
                     mMeasuredScreenWidth, MeasureSpec.EXACTLY,
@@ -241,7 +234,6 @@
 
             // now measure the content only using UNSPECIFIED (where applicable, based on
             // the rendering mode). This will give us the size the content needs.
-            @SuppressWarnings("deprecation")
             Pair<Integer, Integer> neededMeasure = measureView(
                     mContentRoot, mContentRoot.getChildAt(0),
                     mMeasuredScreenWidth, widthMeasureSpecMode,
@@ -303,14 +295,14 @@
 
             if (Bridge.isLocaleRtl(params.getLocale())) {
                 if (!params.isRtlSupported()) {
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_ENABLED,
+                    Bridge.getLog().warning(ILayoutLog.TAG_RTL_NOT_ENABLED,
                             "You are using a right-to-left " +
                                     "(RTL) locale but RTL is not enabled", null, null);
                 } else if (params.getSimulatedPlatformVersion() !=0 &&
                         params.getSimulatedPlatformVersion() < 17) {
                     // This will render ok because we are using the latest layoutlib but at least
                     // warn the user that this might fail in a real device.
-                    Bridge.getLog().warning(LayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
+                    Bridge.getLog().warning(ILayoutLog.TAG_RTL_NOT_SUPPORTED, "You are using a " +
                             "right-to-left " +
                             "(RTL) locale but RTL is not supported for API level < 17", null, null);
                 }
@@ -505,11 +497,11 @@
                         newImage = true;
                     }
 
-                    if (params.isBgColorOverridden()) {
+                    if (params.isTransparentBackground()) {
                         // since we override the content, it's the same as if it was a new image.
                         newImage = true;
                         Graphics2D gc = mImage.createGraphics();
-                        gc.setColor(new Color(params.getOverrideBgColor(), true));
+                        gc.setColor(new Color(0, true));
                         gc.setComposite(AlphaComposite.Src);
                         gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
                         gc.dispose();
@@ -580,6 +572,9 @@
                          params.getFlag(RenderParamsFlags.FLAG_ENABLE_LAYOUT_VALIDATOR_IMAGE_CHECK));
 
                 if (enableLayoutValidation && !getViewInfos().isEmpty()) {
+                    AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.sLayoutlibCallback =
+                            getContext().getLayoutlibCallback();
+
                     BufferedImage imageToPass =
                             enableLayoutValidationImageCheck ? getImage() : null;
                     ValidatorResult validatorResult =
@@ -590,6 +585,8 @@
                 ValidatorResult.Builder builder = new Builder();
                 builder.mMetric.mErrorMessage = e.getMessage();
                 setValidatorResult(builder.build());
+            } finally {
+                AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.sLayoutlibCallback = null;
             }
 
             // success!
@@ -620,7 +617,6 @@
      * @param heightMode the MeasureSpec mode to use for the height.
      * @return the measured width/height if measuredView is non-null, null otherwise.
      */
-    @SuppressWarnings("deprecation")  // For the use of Pair
     private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView,
             int width, int widthMode, int height, int heightMode) {
         int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode);
@@ -644,7 +640,6 @@
      * @param layoutlibCallback callback to the project.
      * @param skip the view and it's children are not processed.
      */
-    @SuppressWarnings("deprecation")  // For the use of Pair
     private void postInflateProcess(View view, LayoutlibCallback layoutlibCallback, View skip)
             throws PostInflateException {
         if (view == skip) {
@@ -883,9 +878,7 @@
             for (int i = 0 ; i < count ; i++) {
                 View child = content.getChildAt(i);
                 String tabSpec = String.format("tab_spec%d", i+1);
-                @SuppressWarnings("ConstantConditions")  // child cannot be null.
                 int id = child.getId();
-                @SuppressWarnings("deprecation")
                 ResourceReference resource = layoutlibCallback.resolveResourceId(id);
                 String name;
                 if (resource != null) {
@@ -1123,10 +1116,6 @@
         return mImage;
     }
 
-    public boolean isAlphaChannelImage() {
-        return mIsAlphaChannelImage;
-    }
-
     public List<ViewInfo> getViewInfos() {
         return mViewInfoList;
     }
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index 8e2ecd6..0a36359 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -18,8 +18,8 @@
 import com.android.SdkConstants;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.DensityBasedResourceValue;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.ILayoutPullParser;
-import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceNamespace;
@@ -161,10 +161,16 @@
         }
 
         // try to load the color state list from an int
-        try {
-            int color = getColor(value);
-            return ColorStateList.valueOf(color);
-        } catch (NumberFormatException ignored) {
+        if (value.trim().startsWith("#")) {
+            try {
+                int color = getColor(value);
+                return ColorStateList.valueOf(color);
+            } catch (NumberFormatException e) {
+                Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
+                        String.format("\"%1$s\" cannot be interpreted as a color.", value),
+                        null, null);
+                return null;
+            }
         }
 
         try {
@@ -202,13 +208,13 @@
                 }
             }
         } catch (XmlPullParserException e) {
-            Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+            Bridge.getLog().error(ILayoutLog.TAG_BROKEN,
                     "Failed to configure parser for " + value, e, null,null /*data*/);
             // we'll return null below.
         } catch (Exception e) {
             // this is an error and not warning since the file existence is
             // checked before attempting to parse it.
-            Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+            Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ,
                     "Failed to parse file " + value, e, null, null /*data*/);
 
             return null;
@@ -311,12 +317,17 @@
             return null;
         }
 
-        String lowerCaseValue = stringValue.toLowerCase();
         // try the simple case first. Attempt to get a color from the value
-        try {
-            int color = getColor(stringValue);
-            return new ColorDrawable(color);
-        } catch (NumberFormatException ignore) {
+        if (stringValue.trim().startsWith("#")) {
+            try {
+                int color = getColor(stringValue);
+                return new ColorDrawable(color);
+            } catch (NumberFormatException e) {
+                Bridge.getLog().warning(ILayoutLog.TAG_RESOURCES_FORMAT,
+                        String.format("\"%1$s\" cannot be interpreted as a color.", stringValue),
+                        null, null);
+                return null;
+            }
         }
 
         Density density = Density.MEDIUM;
@@ -327,12 +338,13 @@
             }
         }
 
+        String lowerCaseValue = stringValue.toLowerCase();
         if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
             try {
                 return getNinePatchDrawable(density, value.isFramework(), stringValue, context);
             } catch (IOException e) {
                 // failed to read the file, we'll return null below.
-                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ,
                         "Failed to load " + stringValue, e, null, null /*data*/);
             }
 
@@ -393,7 +405,7 @@
                     return new BitmapDrawable(context.getResources(), bitmap);
                 } catch (IOException e) {
                     // we'll return null below
-                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                    Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_READ,
                             "Failed to load " + stringValue, e, null, null /*data*/);
                 }
             }
@@ -633,7 +645,7 @@
                         applyUnit(sUnitNames[1], outValue, sFloatOut);
                         computeTypedValue(outValue, f, sFloatOut[0]);
 
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+                        Bridge.getLog().error(ILayoutLog.TAG_RESOURCES_RESOLVE,
                                 String.format(
                                         "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
                                         value, attribute),
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
index 76c5942..b7f59c4 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
@@ -17,14 +17,14 @@
 package com.android.layoutlib.bridge.impl.binding;
 
 import com.android.ide.common.rendering.api.DataBindingItem;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
-import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback.ViewAttribute;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.impl.RenderAction;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import android.view.View;
 import android.view.ViewGroup;
@@ -38,7 +38,6 @@
  */
 public class AdapterHelper {
 
-    @SuppressWarnings("deprecation")
     static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
             LayoutlibCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
         // we don't care about recycling here because we never scroll.
@@ -93,7 +92,7 @@
                                 resolvedRef, ViewAttribute.TEXT, tv.getText().toString());
                         if (value != null) {
                             if (value.getClass() != ViewAttribute.TEXT.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
+                                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format(
                                         "Wrong Adapter Item value class for TEXT. Expected String, got %s",
                                         value.getClass().getName()), null, null);
                             } else {
@@ -113,7 +112,7 @@
                                 resolvedRef, ViewAttribute.IS_CHECKED, cb.isChecked());
                         if (value != null) {
                             if (value.getClass() != ViewAttribute.IS_CHECKED.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
+                                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format(
                                         "Wrong Adapter Item value class for IS_CHECKED. Expected Boolean, got %s",
                                         value.getClass().getName()), null, null);
                             } else {
@@ -133,7 +132,7 @@
                                 resolvedRef, ViewAttribute.SRC, iv.getDrawable());
                         if (value != null) {
                             if (value.getClass() != ViewAttribute.SRC.getAttributeClass()) {
-                                Bridge.getLog().error(LayoutLog.TAG_BROKEN, String.format(
+                                Bridge.getLog().error(ILayoutLog.TAG_BROKEN, String.format(
                                         "Wrong Adapter Item value class for SRC. Expected Boolean, got %s",
                                         value.getClass().getName()), null, null);
                             } else {
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
index 142eac1..83ff28d 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
@@ -20,7 +20,7 @@
 import com.android.ide.common.rendering.api.DataBindingItem;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import android.view.View;
 import android.view.ViewGroup;
@@ -110,7 +110,6 @@
     public View getView(int position, View convertView, ViewGroup parent) {
         // we don't care about recycling here because we never scroll.
         AdapterItem item = mItems.get(position);
-        @SuppressWarnings("deprecation")
         Pair<View, Boolean> pair = AdapterHelper.getView(item, null, parent, mCallback,
                 mAdapterRef, mSkipCallbackParser);
         mSkipCallbackParser = pair.getSecond();
diff --git a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
index 344b17e..21679f7 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
@@ -20,7 +20,7 @@
 import com.android.ide.common.rendering.api.DataBindingItem;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import android.database.DataSetObserver;
 import android.view.View;
@@ -31,7 +31,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-@SuppressWarnings("deprecation")
 public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
 
     private final LayoutlibCallback mCallback;
diff --git a/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java b/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
index 161bf41..16aa058 100644
--- a/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
+++ b/bridge/src/com/android/layoutlib/bridge/util/DynamicIdMap.java
@@ -17,7 +17,7 @@
 package com.android.layoutlib.bridge.util;
 
 import com.android.resources.ResourceType;
-import com.android.util.Pair;
+import com.android.utils.Pair;
 
 import android.annotation.NonNull;
 import android.util.SparseArray;
diff --git a/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java b/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
index a2a8aa9..dd06e80 100644
--- a/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
+++ b/bridge/src/com/android/layoutlib/bridge/util/SparseWeakArray.java
@@ -133,6 +133,7 @@
                 if (i != o) {
                     keys[o] = keys[i];
                     values[o] = val;
+                    values[i] = null;
                 }
 
                 o++;
diff --git a/bridge/src/libcore/icu/ICU_Delegate.java b/bridge/src/libcore/icu/ICU_Delegate.java
index 708cf62..7bb82ad 100644
--- a/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/bridge/src/libcore/icu/ICU_Delegate.java
@@ -18,9 +18,6 @@
 
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
-import android.icu.text.DateTimePatternGenerator;
-import android.icu.util.ULocale;
-
 import java.util.Locale;
 
 /**
@@ -34,22 +31,11 @@
     // --- Native methods accessing ICU's database.
 
     @LayoutlibDelegate
-    /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) {
-        return DateTimePatternGenerator.getInstance(new ULocale(localeName))
-                .getBestPattern(skeleton);
-    }
-
-    @LayoutlibDelegate
     /*package*/ static String[] getAvailableLocalesNative() {
         return new String[0];
     }
 
     @LayoutlibDelegate
-    /*package*/ static String getCurrencyCode(String locale) {
-        return "";
-    }
-
-    @LayoutlibDelegate
     /*package*/ static String getISO3Country(String locale) {
         return "";
     }
@@ -75,12 +61,22 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void setDefaultLocale(String locale) {
-        ICU.setDefaultLocale(locale);
+    /*package*/ static String getDefaultLocale() {
+        return Locale.getDefault().toString();
     }
 
     @LayoutlibDelegate
-    /*package*/ static String getDefaultLocale() {
-        return ICU.getDefaultLocale();
+    /*package*/ static String getCldrVersion() {
+        return "";
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static String getIcuVersion() {
+        return "";
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static String getUnicodeVersion() {
+        return "";
     }
 }
diff --git a/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java b/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java
new file mode 100644
index 0000000..0be3423
--- /dev/null
+++ b/bridge/tests/src/android/content/res/BridgeTypedArrayTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import org.junit.Test;
+
+import static android.util.TypedValue.TYPE_ATTRIBUTE;
+import static android.util.TypedValue.TYPE_DIMENSION;
+import static android.util.TypedValue.TYPE_FLOAT;
+import static android.util.TypedValue.TYPE_INT_BOOLEAN;
+import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
+import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
+import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
+import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
+import static android.util.TypedValue.TYPE_INT_DEC;
+import static android.util.TypedValue.TYPE_INT_HEX;
+import static android.util.TypedValue.TYPE_NULL;
+import static android.util.TypedValue.TYPE_REFERENCE;
+import static android.util.TypedValue.TYPE_STRING;
+import static org.junit.Assert.assertEquals;
+
+public class BridgeTypedArrayTest {
+
+    @Test
+    public void getType() {
+        assertEquals(TYPE_NULL, BridgeTypedArray.getType(null));
+        assertEquals(TYPE_REFERENCE, BridgeTypedArray.getType("@drawable/my_drawable"));
+        assertEquals(TYPE_ATTRIBUTE, BridgeTypedArray.getType("?attr/colorPrimary"));
+        assertEquals(TYPE_INT_BOOLEAN, BridgeTypedArray.getType("true"));
+        assertEquals(TYPE_STRING, BridgeTypedArray.getType("False"));
+        assertEquals(TYPE_INT_HEX, BridgeTypedArray.getType("0xffa39d"));
+        assertEquals(TYPE_STRING, BridgeTypedArray.getType("0xnothex"));
+        assertEquals(TYPE_INT_COLOR_RGB4, BridgeTypedArray.getType("#f34"));
+        assertEquals(TYPE_INT_COLOR_ARGB4, BridgeTypedArray.getType("#2f34"));
+        assertEquals(TYPE_INT_COLOR_RGB8, BridgeTypedArray.getType("#f34ab4"));
+        assertEquals(TYPE_INT_COLOR_ARGB8, BridgeTypedArray.getType("#1f34dc28"));
+        assertEquals(TYPE_STRING, BridgeTypedArray.getType("#notacolor"));
+        assertEquals(TYPE_DIMENSION, BridgeTypedArray.getType("16dp"));
+        assertEquals(TYPE_STRING, BridgeTypedArray.getType("16notaunit"));
+        assertEquals(TYPE_INT_DEC, BridgeTypedArray.getType("98543"));
+        assertEquals(TYPE_FLOAT, BridgeTypedArray.getType("43.364"));
+        assertEquals(TYPE_STRING, BridgeTypedArray.getType("5432dp342"));
+    }
+}
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
index 2408fa6..2624df0 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/FrameworkResources.java
@@ -53,7 +53,7 @@
     private final Map<ResourceType, List<ResourceItem>> mPublicResourceMap =
         new EnumMap<>(ResourceType.class);
 
-    public FrameworkResources(@NotNull IAbstractFolder resFolder) {
+    public FrameworkResources(@NotNull TestFolderWrapper resFolder) {
         super(resFolder, true /*isFrameworkRepository*/);
     }
 
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
index 90d6d64..5434cad 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/IdGeneratingResourceFile.java
@@ -53,7 +53,7 @@
 
     private final ResourceValue mFileValue;
 
-    public IdGeneratingResourceFile(IAbstractFile file, ResourceFolder folder, ResourceType type) {
+    public IdGeneratingResourceFile(TestFileWrapper file, ResourceFolder folder, ResourceType type) {
         super(file, folder);
 
         mFileType = type;
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
index 3a51134..016c6b4 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/MultiResourceFile.java
@@ -52,7 +52,7 @@
 
     private Collection<ResourceType> mResourceTypeList = null;
 
-    public MultiResourceFile(IAbstractFile file, ResourceFolder folder) {
+    public MultiResourceFile(TestFileWrapper file, ResourceFolder folder) {
         super(file, folder);
     }
 
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java
index c7eaa81..30fbd0b 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFile.java
@@ -19,7 +19,6 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.resources.configuration.Configurable;
 import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.io.IAbstractFile;
 import com.android.resources.ResourceType;
 
 /**
@@ -29,10 +28,10 @@
 @Deprecated
 public abstract class ResourceFile implements Configurable {
 
-    private final IAbstractFile mFile;
+    private final TestFileWrapper mFile;
     private final ResourceFolder mFolder;
 
-    protected ResourceFile(IAbstractFile file, ResourceFolder folder) {
+    protected ResourceFile(TestFileWrapper file, ResourceFolder folder) {
         mFile = file;
         mFolder = folder;
     }
@@ -48,7 +47,7 @@
     /**
      * Returns the IFile associated with the ResourceFile.
      */
-    public final IAbstractFile getFile() {
+    public final TestFileWrapper getFile() {
         return mFile;
     }
 
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
index fe708f3..5fc2c19 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceFolder.java
@@ -63,7 +63,7 @@
      *            as a place to stash errors encountered
      * @return the {@link ResourceFile} that was created.
      */
-    public ResourceFile processFile(IAbstractFile file, ResourceDeltaKind kind,
+    public ResourceFile processFile(TestFileWrapper file, ResourceDeltaKind kind,
             ScanningContext context) {
         // look for this file if it's already been created
         ResourceFile resFile = getFile(file, context);
@@ -84,7 +84,7 @@
         return resFile;
     }
 
-    private ResourceFile createResourceFile(IAbstractFile file) {
+    private ResourceFile createResourceFile(TestFileWrapper file) {
         // check if that's a single or multi resource type folder. We have a special case
         // for ID generating resource types (layout/menu, and XML drawables, etc.).
         // MultiResourceFile handles the case when several resource types come from a single file
@@ -130,7 +130,7 @@
      *            as a place to stash errors encountered
      * @return the {@link ResourceFile} or null if no match was found.
      */
-    private ResourceFile getFile(IAbstractFile file, ScanningContext context) {
+    private ResourceFile getFile(TestFileWrapper file, ScanningContext context) {
         assert mFolder.equals(file.getParentFolder());
 
         // If the file actually exists, the resource folder  may not have been
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
index d8204d5..fca0862 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/ResourceRepository.java
@@ -19,7 +19,6 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.ide.common.resources.ResourceValueMap;
 import com.android.ide.common.resources.configuration.FolderConfiguration;
-import com.android.io.IAbstractFile;
 import com.android.io.IAbstractFolder;
 import com.android.io.IAbstractResource;
 import com.android.resources.ResourceFolderType;
@@ -40,7 +39,7 @@
  */
 @Deprecated
 public abstract class ResourceRepository {
-    private final IAbstractFolder mResourceFolder;
+    private final TestFolderWrapper mResourceFolder;
 
     private Map<ResourceFolderType, List<ResourceFolder>> mFolderMap =
             new EnumMap<>(ResourceFolderType.class);
@@ -58,13 +57,13 @@
      * @param resFolder the resource folder of the repository.
      * @param isFrameworkRepository whether the repository is for framework resources.
      */
-    protected ResourceRepository(@NotNull IAbstractFolder resFolder,
+    protected ResourceRepository(@NotNull TestFolderWrapper resFolder,
             boolean isFrameworkRepository) {
         mResourceFolder = resFolder;
         mFrameworkRepository = isFrameworkRepository;
     }
 
-    public IAbstractFolder getResFolder() {
+    public TestFolderWrapper getResFolder() {
         return mResourceFolder;
     }
 
@@ -92,8 +91,8 @@
             IAbstractResource[] resources = mResourceFolder.listMembers();
 
             for (IAbstractResource res : resources) {
-                if (res instanceof IAbstractFolder) {
-                    IAbstractFolder folder = (IAbstractFolder)res;
+                if (res instanceof TestFolderWrapper) {
+                    TestFolderWrapper folder = (TestFolderWrapper)res;
                     ResourceFolder resFolder = processFolder(folder);
 
                     if (resFolder != null) {
@@ -101,8 +100,8 @@
                         IAbstractResource[] files = folder.listMembers();
 
                         for (IAbstractResource fileRes : files) {
-                            if (fileRes instanceof IAbstractFile) {
-                                IAbstractFile file = (IAbstractFile)fileRes;
+                            if (fileRes instanceof TestFileWrapper) {
+                                TestFileWrapper file = (TestFileWrapper) fileRes;
 
                                 resFolder.processFile(file, ResourceDeltaKind.ADDED, context);
                             }
@@ -250,7 +249,7 @@
      * @return the ResourceFolder created from this folder, or null if the process failed.
      */
     @Nullable
-    private ResourceFolder processFolder(@NotNull IAbstractFolder folder) {
+    private ResourceFolder processFolder(@NotNull TestFolderWrapper folder) {
         ensureInitialized();
 
         // split the name of the folder in segments.
@@ -308,7 +307,7 @@
         return map;
     }
 
-   /**
+    /**
      * Loads the resources.
      */
     public void loadResources() {
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
index e7a3f90..38d975d 100644
--- a/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/SingleResourceFile.java
@@ -42,7 +42,7 @@
     private final ResourceType mType;
     private final ResourceValue mValue;
 
-    public SingleResourceFile(IAbstractFile file, ResourceFolder folder) {
+    public SingleResourceFile(TestFileWrapper file, ResourceFolder folder) {
         super(file, folder);
 
         // we need to infer the type of the resource from the folder type.
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java
new file mode 100644
index 0000000..f1f3f17
--- /dev/null
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFileWrapper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.common.resources.deprecated;
+
+import com.android.io.FileWrapper;
+import com.android.io.IAbstractFolder;
+
+import java.io.File;
+
+public class TestFileWrapper extends FileWrapper {
+    public TestFileWrapper(File file) {
+        super(file);
+    }
+
+    public IAbstractFolder getParentFolder() {
+        String p = this.getParent();
+        if (p == null) {
+            return null;
+        }
+        return new TestFolderWrapper(p);
+    }
+}
diff --git a/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java
new file mode 100644
index 0000000..f945d3c
--- /dev/null
+++ b/bridge/tests/src/com/android/ide/common/resources/deprecated/TestFolderWrapper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.common.resources.deprecated;
+
+import com.android.io.FolderWrapper;
+import com.android.io.IAbstractResource;
+
+import java.io.File;
+
+public class TestFolderWrapper extends FolderWrapper {
+
+    public TestFolderWrapper(String pathname) {
+        super(pathname);
+    }
+
+    public TestFolderWrapper(File file) {
+        super(file.getAbsolutePath());
+    }
+
+    public IAbstractResource[] listMembers() {
+        File[] files = listFiles();
+        final int count = files == null ? 0 : files.length;
+        IAbstractResource[] afiles = new IAbstractResource[count];
+
+        if (files != null) {
+            for (int i = 0 ; i < count ; i++) {
+                File f = files[i];
+                if (f.isFile()) {
+                    afiles[i] = new TestFileWrapper(f);
+                } else if (f.isDirectory()) {
+                    afiles[i] = new TestFolderWrapper(f);
+                }
+            }
+        }
+
+        return afiles;
+    }
+
+    public TestFolderWrapper getFolder(String name) {
+        return new TestFolderWrapper(new File(this, name));
+    }
+}
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index e43531a..be57b88 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -29,6 +29,7 @@
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
+import android.content.res.BridgeTypedArrayTest;
 import android.content.res.Resources_DelegateTest;
 import android.graphics.Color_DelegateTest;
 import android.graphics.Matrix_DelegateTest;
@@ -47,7 +48,7 @@
         BridgeRenderSessionTest.class, ResourceHelperTest.class, BridgeContextTest.class,
         Resources_DelegateTest.class, Color_DelegateTest.class, ImagePoolHelperTest.class,
         ImagePoolImplTest.class, HighQualityShadowsRenderTests.class,
-        LayoutValidatorTests.class, AccessibilityValidatorTests.class
+        LayoutValidatorTests.class, AccessibilityValidatorTests.class, BridgeTypedArrayTest.class
 })
 public class Main {
 }
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
index a22c3bc..67bb7af 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.intensive;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.Result;
 import com.android.ide.common.rendering.api.SessionParams;
@@ -24,7 +24,7 @@
 import com.android.ide.common.resources.deprecated.FrameworkResources;
 import com.android.ide.common.resources.deprecated.ResourceItem;
 import com.android.ide.common.resources.deprecated.ResourceRepository;
-import com.android.io.FolderWrapper;
+import com.android.ide.common.resources.deprecated.TestFolderWrapper;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.RenderParamsFlags;
 import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -115,7 +115,7 @@
     protected static Bridge sBridge;
     /** List of log messages generated by a render call. It can be used to find specific errors */
     protected static ArrayList<String> sRenderMessages = Lists.newArrayList();
-    private static LayoutLog sLayoutLibLog;
+    private static ILayoutLog sLayoutLibLog;
     private static FrameworkResources sFrameworkRepo;
     private static ResourceRepository sProjectResources;
     private static ILogger sLogger;
@@ -303,12 +303,12 @@
     public static void beforeClass() {
         File data_dir = new File(PLATFORM_DIR, "data");
         File res = new File(data_dir, "res");
-        sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
+        sFrameworkRepo = new FrameworkResources(new TestFolderWrapper(res));
         sFrameworkRepo.loadResources();
         sFrameworkRepo.loadPublicResources(getLogger());
 
         sProjectResources =
-                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
+                new ResourceRepository(new TestFolderWrapper(TEST_RES_DIR + "/" + APP_TEST_RES),
                         false) {
                     @NonNull
                     @Override
@@ -433,9 +433,9 @@
         return RenderTestBase.renderAndVerify(params, goldenFileName, -1);
     }
 
-    protected static LayoutLog getLayoutLog() {
+    protected static ILayoutLog getLayoutLog() {
         if (sLayoutLibLog == null) {
-            sLayoutLibLog = new LayoutLog() {
+            sLayoutLibLog = new ILayoutLog() {
                 @Override
                 public void warning(String tag, String message, Object cookie, Object data) {
                     System.out.println("Warning " + tag + ": " + message);
@@ -474,7 +474,7 @@
     }
 
     protected static void ignoreAllLogging() {
-        sLayoutLibLog = new LayoutLog();
+        sLayoutLibLog = new ILayoutLog() {};
         sLogger = new ILogger() {
             @Override
             public void error(Throwable t, String msgFormat, Object... args) {
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index a6389ac..9faa0a6 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -72,7 +72,7 @@
         Class<?> rClass = mModuleClassLoader.loadClass(PACKAGE_NAME + ".R");
         Class<?>[] nestedClasses = rClass.getDeclaredClasses();
         for (Class<?> resClass : nestedClasses) {
-            final ResourceType resType = ResourceType.getEnum(resClass.getSimpleName());
+            final ResourceType resType = ResourceType.fromClassName(resClass.getSimpleName());
 
             if (resType != null) {
                 for (Field field : resClass.getDeclaredFields()) {
diff --git a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java b/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
index baadc62..396880e 100644
--- a/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
+++ b/bridge/tests/src/com/android/layoutlib/bridge/intensive/util/SessionParamsBuilder.java
@@ -19,7 +19,7 @@
 import com.android.SdkConstants;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.IImageFactory;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.LayoutlibCallback;
 import com.android.ide.common.rendering.api.ResourceNamespace;
 import com.android.ide.common.rendering.api.ResourceReference;
@@ -56,7 +56,7 @@
     private LayoutlibCallback mLayoutlibCallback;
     private int mTargetSdk;
     private int mMinSdk = 0;
-    private LayoutLog mLayoutLog;
+    private ILayoutLog mLayoutLog;
     private Map<SessionParams.Key, Object> mFlags = new HashMap<>();
     private AssetRepository mAssetRepository = null;
     private boolean mDecor = true;
@@ -136,7 +136,7 @@
     }
 
     @NonNull
-    public SessionParamsBuilder setLayoutLog(@NonNull LayoutLog layoutLog) {
+    public SessionParamsBuilder setLayoutLog(@NonNull ILayoutLog layoutLog) {
         mLayoutLog = layoutLog;
         return this;
     }
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index bbe985e..44046eb 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -168,11 +168,14 @@
         "android.graphics.drawable.GradientDrawable#buildRing",
         "android.graphics.drawable.AdaptiveIconDrawable#<init>",
         "android.graphics.drawable.DrawableInflater#inflateFromClass",
+        "android.graphics.drawable.NinePatchDrawable#getOpacity",
         "android.graphics.FontFamily#addFont",
+        "com.google.android.apps.common.testing.accessibility.framework.uielement" +
+                ".AccessibilityHierarchyAndroid$ViewElementClassNamesAndroid#getClassByName",
         "android.graphics.Typeface#create",
         "android.graphics.Typeface$Builder#createAssetUid",
         "android.graphics.fonts.Font$Builder#createBuffer",
-        "android.graphics.fonts.SystemFonts#buildSystemFallback",
+        "android.graphics.fonts.SystemFonts#getSystemFontConfigInternal",
         "android.os.Binder#getNativeBBinderHolder",
         "android.os.Binder#getNativeFinalizer",
         "android.os.Handler#sendMessageAtTime",
@@ -314,6 +317,7 @@
             "android.os.ServiceManager",                       "android.os._Original_ServiceManager",
             "android.view.textservice.TextServicesManager",    "android.view.textservice._Original_TextServicesManager",
             "android.view.SurfaceView",                        "android.view._Original_SurfaceView",
+            "android.view.WindowManagerImpl",                  "android.view._Original_WindowManagerImpl",
             "android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
             "android.view.accessibility.AccessibilityNodeIdManager", "android.view.accessibility._Original_AccessibilityNodeIdManager",
             "android.webkit.WebView",                          "android.webkit._Original_WebView",
diff --git a/create/tests/res/data/mock_android.jar b/create/tests/res/data/mock_android.jar
index 580e6f1..3fd6999 100644
--- a/create/tests/res/data/mock_android.jar
+++ b/create/tests/res/data/mock_android.jar
Binary files differ
diff --git a/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java b/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
index ad9055c..327bbb7 100644
--- a/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
+++ b/create/tests/src/com/android/tools/layoutlib/create/AsmAnalyzerTest.java
@@ -129,22 +129,22 @@
                 DEFAULT_INCLUDE_FILES);
         Result result = analyzer.analyze();
         assertArrayEquals(new String[] {
+                        "mock_android.fake.InnerTest$NotStaticInner1",
                         "mock_android.fake.FakeClass",
-                        "mock_android.fake.InnerTest$MyIntEnum",
                         "mock_android.util.EmptyArray",
-                        "mock_android.fake.InnerTest$DerivingClass",
                         "mock_android.fake2.FakeClass",
+                        "mock_android.fake.InnerTest$DerivingClass",
+                        "mock_android.fake.InnerTest$NotStaticInner2",
                         "mock_android.fake.subpackage.SubpackageClassC$InnerClass",
                         "mock_android.fake.InnerTest$MyGenerics1",
-                        "mock_android.fake.subpackage.SubpackageClassC$StaticInnerClass",
+                        "mock_android.fake.InnerTest$MyIntEnum",
                         "mock_android.fake.InnerTest$MyStaticInnerClass",
-                        "mock_android.fake.InnerTest$NotStaticInner1",
-                        "mock_android.fake.InnerTest$NotStaticInner2",
-                        "mock_android.fake.subpackage.SubpackageClassA",
                         "mock_android.fake.InnerTest",
-                        "mock_android.fake.InnerTest$1",
-                        "mock_android.fake.subpackage.SubpackageClassC",
                         "mock_android.fake.subpackage.SubpackageClassB",
+                        "mock_android.fake.subpackage.SubpackageClassA",
+                        "mock_android.fake.InnerTest$1",
+                        "mock_android.fake.subpackage.SubpackageClassC$StaticInnerClass",
+                        "mock_android.fake.subpackage.SubpackageClassC",
                 },
                 result.getFound().keySet().toArray());
     }
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java
index 051fb85..d63c9f6 100644
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java
+++ b/remote/client/src/com/android/layoutlib/bridge/remote/client/RemoteBridgeClient.java
@@ -18,12 +18,11 @@
 
 import com.android.ide.common.rendering.api.Bridge;
 import com.android.ide.common.rendering.api.DrawableParams;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.Result;
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.layout.remote.api.RemoteBridge;
-import com.android.layout.remote.api.RemoteDrawableParams;
 import com.android.layout.remote.api.RemoteSessionParams;
 import com.android.layoutlib.bridge.remote.client.adapters.RemoteDrawableParamsAdapter;
 import com.android.layoutlib.bridge.remote.client.adapters.RemoteLayoutLogAdapter;
@@ -60,7 +59,7 @@
             String nativeLibPath,
             String icuDataPath,
             Map<String, Map<String, Integer>> enumValueMap,
-            LayoutLog log) {
+            ILayoutLog log) {
         try {
             return mDelegate.init(platformProperties, fontLocation, nativeLibPath, icuDataPath,
                     enumValueMap, RemoteLayoutLogAdapter.create(log));
diff --git a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java
index 23d36bc..2ea9102 100644
--- a/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java
+++ b/remote/client/src/com/android/layoutlib/bridge/remote/client/adapters/RemoteLayoutLogAdapter.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.remote.client.adapters;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layout.remote.api.RemoteLayoutLog;
 import com.android.tools.layoutlib.annotations.NotNull;
 
@@ -25,13 +25,13 @@
 import java.rmi.server.UnicastRemoteObject;
 
 public class RemoteLayoutLogAdapter implements RemoteLayoutLog {
-    private final LayoutLog mLog;
+    private final ILayoutLog mLog;
 
-    private RemoteLayoutLogAdapter(@NotNull LayoutLog log) {
+    private RemoteLayoutLogAdapter(@NotNull ILayoutLog log) {
         mLog = log;
     }
 
-    public static RemoteLayoutLog create(@NotNull LayoutLog log) throws RemoteException {
+    public static RemoteLayoutLog create(@NotNull ILayoutLog log) throws RemoteException {
         return (RemoteLayoutLog) UnicastRemoteObject.exportObject(new RemoteLayoutLogAdapter(log),
                 0);
     }
@@ -56,4 +56,9 @@
     public void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data) {
         mLog.error(tag, message, throwable, viewCookie, null);
     }
+
+    @Override
+    public void logAndroidFramework(int priority, String tag, String message) {
+        mLog.logAndroidFramework(priority, tag, message);
+    }
 }
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java b/remote/common/src/com/android/layout/remote/api/RemoteBridge.java
index 3634fff..4ef9d97 100644
--- a/remote/common/src/com/android/layout/remote/api/RemoteBridge.java
+++ b/remote/common/src/com/android/layout/remote/api/RemoteBridge.java
@@ -17,7 +17,7 @@
 package com.android.layout.remote.api;
 
 import com.android.ide.common.rendering.api.Bridge;
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.Result;
 import com.android.tools.layoutlib.annotations.NotNull;
@@ -43,7 +43,7 @@
      * @param icuDataPath the location of the ICU data used natively.
      * @param enumValueMap map attrName ⇒ { map enumFlagName ⇒ Integer value }. This is typically
      * read from attrs.xml in the SDK target.
-     * @param log a {@link LayoutLog} object. Can be null.
+     * @param log a {@link ILayoutLog} object. Can be null.
      *
      * @return true if success.
      */
diff --git a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java b/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java
index 01add53..335cf9d 100644
--- a/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java
+++ b/remote/common/src/com/android/layout/remote/api/RemoteLayoutLog.java
@@ -16,14 +16,14 @@
 
 package com.android.layout.remote.api;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 
 import java.io.Serializable;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 
 /**
- * Remote version of the {@link LayoutLog} class
+ * Remote version of the {@link ILayoutLog} class
  */
 public interface RemoteLayoutLog extends Remote {
     /**
@@ -72,4 +72,13 @@
      */
     void error(String tag, String message, Throwable throwable, Object viewCookie, Serializable data)
             throws RemoteException;
+
+    /** 
+     * Logs messages coming from the Android Framework. 
+     *
+     * @param priority the priority level of the message 
+     * @param tag a tag describing the type of the error
+     * @param message the message of the error
+     */
+    void logAndroidFramework(int priority, String tag, String message) throws RemoteException;
 }
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java
index 90da083..5c48aef 100644
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java
+++ b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteLayoutLogAdapter.java
@@ -16,13 +16,13 @@
 
 package com.android.layoutlib.bridge.remote.server.adapters;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.layout.remote.api.RemoteLayoutLog;
 import com.android.tools.layoutlib.annotations.NotNull;
 
 import java.rmi.RemoteException;
 
-public class RemoteLayoutLogAdapter extends LayoutLog {
+public class RemoteLayoutLogAdapter implements ILayoutLog {
     private final RemoteLayoutLog mLog;
 
     public RemoteLayoutLogAdapter(@NotNull RemoteLayoutLog log) {
@@ -66,4 +66,13 @@
             throw new RuntimeException(e);
         }
     }
+
+    @Override
+    public void logAndroidFramework(int priority, String tag, String message) {
+        try {
+            mLog.logAndroidFramework(priority, tag, message);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java
index 2e19bf7..0b9797a 100644
--- a/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java
+++ b/remote/server/src/com/android/layoutlib/bridge/remote/server/adapters/RemoteRenderResourcesAdapter.java
@@ -16,7 +16,7 @@
 
 package com.android.layoutlib.bridge.remote.server.adapters;
 
-import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.ide.common.rendering.api.ILayoutLog;
 import com.android.ide.common.rendering.api.RenderResources;
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
@@ -37,7 +37,7 @@
     }
 
     @Override
-    public void setLogger(LayoutLog logger) {
+    public void setLogger(ILayoutLog logger) {
         // Ignored for remote operations.
     }
 
diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java b/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
deleted file mode 100644
index 519b127..0000000
--- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ErrorCatcher.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * {@link ViewGroup} that wraps another view and catches any possible exceptions that the child view
- * might generate.
- * This is used by the theme editor to stop custom views from breaking the preview.
- */
-// TODO: This view is just a temporary solution that will be replaced by adding a try / catch
-// for custom views in the ClassConverter
-public class ErrorCatcher extends ViewGroup {
-    public ErrorCatcher(Context context) {
-        super(context);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public ErrorCatcher(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            measureChild(child, widthMeasureSpec, heightMeasureSpec);
-
-            setMeasuredDimension(resolveSize(child.getMeasuredWidth(), widthMeasureSpec),
-                    resolveSize(child.getMeasuredHeight(), heightMeasureSpec));
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onMeasure for view " +
-                    child.getClass().getCanonicalName(), null, t);
-            setMeasuredDimension(resolveSize(0, widthMeasureSpec),
-                    resolveSize(0, heightMeasureSpec));
-        }
-    }
-
-    @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        try {
-            return super.drawChild(canvas, child, drawingTime);
-        } catch (Throwable t) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to draw for view " +
-                    child.getClass().getCanonicalName(), null, t);
-        }
-
-        return false;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        assert getChildCount() == 1 : "ErrorCatcher can only have one child";
-
-        View child = getChildAt(0);
-        try {
-            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
-        } catch (Throwable e) {
-            Bridge.getLog().warning(LayoutLog.TAG_BROKEN, "Failed to do onLayout for view " +
-                    child.getClass().getCanonicalName(), null, e);
-        }
-    }
-}
diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java b/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
deleted file mode 100644
index 4320157..0000000
--- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/PressedButton.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.Button;
-
-@SuppressWarnings("unused")
-public class PressedButton extends Button {
-    public PressedButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setPressed(true);
-        jumpDrawablesToCurrentState();
-    }
-}
diff --git a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java b/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
deleted file mode 100644
index af89910..0000000
--- a/studio-custom-widgets/src/com/android/tools/idea/editors/theme/widgets/ThemePreviewLayout.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tools.idea.editors.theme.widgets;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * Custom layout used in the theme editor to display the component preview. It arranges the child
- * Views as a grid of cards.
- * <p/>
- * The Views are measured and the maximum width and height are used to dimension all the child
- * components. Any margin attributes from the children are ignored and only the item_margin element
- * is used.
- */
-@SuppressWarnings("unused")
-public class ThemePreviewLayout extends ViewGroup {
-    private final int mMaxColumns;
-    private final int mMaxColumnWidth;
-    private final int mMinColumnWidth;
-    private final int mItemHorizontalMargin;
-    private final int mItemVerticalMargin;
-
-    /** Item width to use for every card component. This includes margins. */
-    private int mItemWidth;
-    /** Item height to use for every card component. This includes margins. */
-    private int mItemHeight;
-
-    /** Calculated number of columns */
-    private int mNumColumns;
-
-    public ThemePreviewLayout(Context context) {
-        this(context, null);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public ThemePreviewLayout(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        if (attrs == null) {
-            mMaxColumnWidth = Integer.MAX_VALUE;
-            mMinColumnWidth = 0;
-            mMaxColumns = Integer.MAX_VALUE;
-            mItemHorizontalMargin = 0;
-            mItemVerticalMargin = 0;
-            return;
-        }
-
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int maxColumnWidth = attrs.getAttributeIntValue(null, "max_column_width", Integer
-                .MAX_VALUE);
-        int minColumnWidth = attrs.getAttributeIntValue(null, "min_column_width", 0);
-        int itemHorizontalMargin = attrs.getAttributeIntValue(null, "item_horizontal_margin", 0);
-        int itemVerticalMargin = attrs.getAttributeIntValue(null, "item_vertical_margin", 0);
-
-        mMaxColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                maxColumnWidth,
-                dm);
-        mMinColumnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                minColumnWidth,
-                dm);
-        mItemHorizontalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemHorizontalMargin,
-                dm);
-        mItemVerticalMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                itemVerticalMargin,
-                dm);
-        mMaxColumns = attrs.getAttributeIntValue(null, "max_columns", Integer.MAX_VALUE);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Measure the column size.
-        // The column has a minimum width that will be used to calculate the maximum number of
-        // columns that we can fit in the available space.
-        //
-        // Once we have the maximum number of columns, we will span all columns width evenly to fill
-        // all the available space.
-        int wSize = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight;
-
-        // Calculate the desired width of all columns and take the maximum.
-        // This step can be skipped if we have a fixed column height so we do not have to
-        // dynamically calculate it.
-        int childWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        int itemWidth = 0;
-        int itemHeight = 0;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-
-            itemWidth = Math.max(itemWidth, v.getMeasuredWidth());
-            itemHeight = Math.max(itemHeight, v.getMeasuredHeight());
-        }
-
-        itemWidth = Math.min(Math.max(itemWidth, mMinColumnWidth), mMaxColumnWidth);
-        mNumColumns = Math.min((int) Math.ceil((double) wSize / itemWidth), mMaxColumns);
-
-        // Check how much space this distribution would take taking into account the margins.
-        // If it's bigger than what we have, remove one column.
-        int wSizeNeeded = mNumColumns * itemWidth + (mNumColumns - 1) * mItemHorizontalMargin;
-        if (wSizeNeeded > wSize && mNumColumns > 1) {
-            mNumColumns--;
-        }
-
-        if (getChildCount() < mNumColumns) {
-            mNumColumns = getChildCount();
-        }
-        if (mNumColumns == 0) {
-            mNumColumns = 1;
-        }
-
-        // Inform each child of the measurement
-        childWidthSpec = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
-        childHeightSpec = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            measureChild(v, childWidthSpec, childHeightSpec);
-        }
-
-        // Calculate the height of the first column to measure our own size
-        int firstColumnItems = getChildCount() / mNumColumns + ((getChildCount() % mNumColumns) > 0
-                ? 1 : 0);
-
-        int horizontalMarginsTotalWidth = (mNumColumns - 1) * mItemHorizontalMargin;
-        int verticalMarginsTotalHeight = (firstColumnItems - 1) * mItemVerticalMargin;
-        int totalWidth = mNumColumns * itemWidth + horizontalMarginsTotalWidth +
-                mPaddingRight + mPaddingLeft;
-        int totalHeight = firstColumnItems * itemHeight + verticalMarginsTotalHeight +
-                mPaddingBottom + mPaddingTop;
-
-        setMeasuredDimension(resolveSize(totalWidth, widthMeasureSpec),
-                resolveSize(totalHeight, heightMeasureSpec));
-
-        mItemWidth = itemWidth;
-        mItemHeight = itemHeight;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        int itemsPerColumn = getChildCount() / mNumColumns;
-        // The remainder items are distributed one per column.
-        int remainderItems = getChildCount() % mNumColumns;
-
-        int x = mPaddingLeft;
-        int y = mPaddingTop;
-        int position = 1;
-        for (int i = 0; i < getChildCount(); i++) {
-            View v = getChildAt(i);
-            v.layout(x,
-                    y,
-                    x + mItemWidth,
-                    y + mItemHeight);
-
-            if (position == itemsPerColumn + (remainderItems > 0 ? 1 : 0)) {
-                // Break column
-                position = 1;
-                remainderItems--;
-                x += mItemWidth + mItemHorizontalMargin;
-                y = mPaddingTop;
-            } else {
-                position++;
-                y += mItemHeight + mItemVerticalMargin;
-            }
-        }
-    }
-}
-
-
diff --git a/studio-custom-widgets/studio-android-widgets.iml b/studio-custom-widgets/studio-android-widgets.iml
deleted file mode 100644
index b0363d7..0000000
--- a/studio-custom-widgets/studio-android-widgets.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
-  <component name="NewModuleRootManager" inherit-compiler-output="true">
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
-    <orderEntry type="library" name="framework.jar" level="project" />
-    <orderEntry type="module" module-name="bridge" />
-  </component>
-</module>
\ No newline at end of file
diff --git a/validator/Android.bp b/validator/Android.bp
index d26c7ef..ca68179 100644
--- a/validator/Android.bp
+++ b/validator/Android.bp
@@ -27,6 +27,7 @@
     libs: [
         "tools-common-prebuilt",
         "temp_layoutlib",
+        "layoutlib_api-prebuilt",
         "layoutlib-common",
         "guava",
     ],
diff --git a/validator/resources/strings.properties b/validator/resources/strings.properties
index af7d020..7855142 100644
--- a/validator/resources/strings.properties
+++ b/validator/resources/strings.properties
@@ -32,8 +32,15 @@
 check_title_text_style = Text Style
 check_title_touch_target_size = Touch target
 check_view_banned_word = Banned word
+checkbox_item_type = checkbox
+checkbox_item_type_separate_words = check box
+checked_state = checked
+click_action = click
 clickable = clickable
 clickable_and_long_clickable = clickable and long clickable
+description_remove_view_attribute = Remove the view attribute <tt>%1$s</tt>.
+description_set_view_attribute = Set the view attribute <tt>%1$s</tt> to <tt>%2$s</tt>.
+description_set_view_attribute_with_an_empty_string = Set the view attribute <tt>%1$s</tt> to a meaningful non-empty string or resource reference.
 italic_text = italic
 italic_underline_text = italic and underline
 long_clickable = long clickable
@@ -74,7 +81,9 @@
 result_message_class_name_not_supported_brief = This item\'s type may not be supported.
 result_message_class_name_not_supported_detail = This item\'s type <tt>%1$s</tt> may not be resolvable by accessibility services. Consider using a type defined by the Android SDK.
 result_message_clickablespan_no_determined_type = This item\'s type is undetermined.
+result_message_content_desc_contains_action = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\", contains the action \"<tt>%2$s</tt>\".
 result_message_content_desc_contains_redundant_word = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\" contains the item type \"<tt>%2$s</tt>\".
+result_message_content_desc_contains_state = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\", contains the state \"<tt>%2$s</tt>\".
 result_message_content_desc_ends_with_view_type = This item\'s <tt>android:contentDescription</tt>, \"<tt>%1$s</tt>\" ends with the item\'s type.
 result_message_could_not_get_background_color = This item\'s background color could not be determined.
 result_message_could_not_get_text_color = This item\'s text color could not be determined.
@@ -121,11 +130,16 @@
 result_message_textview_heuristic_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider using colors that result in a contrast ratio greater than %4$.2f for small text, or %5$.2f for large text.
 result_message_textview_heuristic_customized_contrast_not_sufficient = The item\'s text contrast ratio is %1$.2f. This ratio is based on an estimated foreground color of <tt>#%2$06X</tt> and an estimated background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the configured ratio of %4$.2f or greater.
 result_message_textview_heuristic_customized_contrast_not_sufficient_confirmed = The item\'s text contrast ratio is %1$.2f. This ratio is based on the provided foreground color of <tt>#%2$06X</tt> and provided background color of <tt>#%3$06X</tt>. Consider increasing this item\'s text contrast ratio to the configured ratio of %4$.2f or greater.
-result_message_traversal_cycle = This item may be part of a traversal ordering cycle due to its <tt>%1$s</tt> attribute.  Traversal behavior with screen readers may be unpredictable.
+result_message_traversal_cycle = This item may be part of a traversal ordering cycle due to its <tt>%1$s</tt> attribute. Traversal behavior with screen readers may be unpredictable.
 result_message_traversal_over_constrained = Traversal ordering for this item may be over constrained based on its <tt>android:accessibilityTraversalBefore</tt> and <tt>android:accessibilityTraversalAfter</tt> attributes. Traversal behavior with screen readers may be unpredictable.
 result_message_urlspan_invalid_url = Verify that the URL within this item\'s <tt>URLSpan</tt> is valid.
 result_message_urlspan_not_clickablespan = This item should use a <tt>URLSpan</tt> in place of a <tt>ClickableSpan</tt>.
 result_message_view_bounds = This %1$s item also has an on-screen location of <tt>%2$s</tt>.
 result_message_view_not_within_screencapture = This item\'s on-screen location (<tt>%1$s</tt>) were not within the screen capture on-screen location (<tt>%2$s</tt>).
 result_message_web_content = Web content is not evaluated.
+selected_state = selected
+swipe_action = swipe
+tap_action = tap
+unchecked_state = unchecked
 underline_text = underline
+unselected_state = unselected
diff --git a/validator/resources/values.xml b/validator/resources/values.xml
index ae49a3c..55dcf57 100644
--- a/validator/resources/values.xml
+++ b/validator/resources/values.xml
@@ -33,8 +33,15 @@
     <string description="The title of a check on the styling of text. [CHAR LIMIT=50]" name="check_title_text_style">Text Style</string>
     <string description="The title of a check describing that the size of this clickable view (UI element) is below minimum requirements. [CHAR LIMIT=50]" name="check_title_touch_target_size">Touch target</string>
     <string description="The title of a check used to detect banned words within the text of a view. [CHAR LIMIT=50]" name="check_view_banned_word">Banned word</string>
+    <string description="The term for a UI element that functions as a checkbox, as a single word (ex. &apos;checkbox&apos; instead of &apos;check box&apos; in English). If there isn&apos;t a single word representation in the target language, use multiple words. [CHAR LIMIT=NONE]" name="checkbox_item_type">checkbox</string>
+    <string description="The term for a UI element that functions as a checkbox, as separate words (ex. &apos;check box&apos; instead of &apos;checkbox&apos; in English). If there isn&apos;t a multiple word representation in the target language, use a single word. [CHAR LIMIT=NONE]" name="checkbox_item_type_separate_words">check box</string>
+    <string description="Adjective describing a checkbox that is selected. [CHAR LIMIT=NONE]" name="checked_state">checked</string>
+    <string description="An action in a UI, as in the imperative &apos;click to send&apos;. [CHAR LIMIT=NONE]" name="click_action">click</string>
     <string description="Describes a UI element that is clickable [CHAR LIMIT=NONE]" name="clickable">clickable</string>
     <string description="Describes a UI element that is both clickable and long clickable [CHAR LIMIT=NONE]" name="clickable_and_long_clickable">clickable and long clickable</string>
+    <string description="The description for a fix suggestion which recommends removing a view attribute [CHAR LIMIT=NONE]" name="description_remove_view_attribute" translatable="false">Remove the view attribute &lt;tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g>&lt;/tt>.</string>
+    <string description="The description for a fix suggestion which recommends setting a value to a view attribute [CHAR LIMIT=NONE]" name="description_set_view_attribute" translatable="false">Set the view attribute &lt;tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g>&lt;/tt> to &lt;tt><ns1:g example="#FFFFFF" id="suggested_value">%2$s</ns1:g>&lt;/tt>.</string>
+    <string description="The description for a fix suggestion which recommends asking the developer to set the view attribute to a meaningful non-empty String literal or relevant resource [CHAR LIMIT=NONE]" name="description_set_view_attribute_with_an_empty_string" translatable="false">Set the view attribute &lt;tt><ns1:g example="android:contentDescription" id="view_attribute_fully_qualified_name">%1$s</ns1:g>&lt;/tt> to a meaningful non-empty string or resource reference.</string>
     <string description="Describes italic text styling. [CHAR LIMIT=NONE]" name="italic_text">italic</string>
     <string description="Describes text with both italic and underlined styling. [CHAR LIMIT=NONE]" name="italic_underline_text">italic and underline</string>
     <string description="Describes a UI element that is long clickable [CHAR LIMIT=NONE]" name="long_clickable">long clickable</string>
@@ -64,7 +71,7 @@
     <string description="The brief result message of a check describing that an element is not exposed to accessibility services [CHAR LIMIT=NONE]" name="result_message_brief_is_unexposed_item_screen_region">Consider exposing items in this region to accessibility services.</string>
     <string description="The brief result message of a check describing that link text is not descriptive. [CHAR LIMIT=NONE]" name="result_message_brief_link_text_not_descriptive">Consider using more descriptive text in the link.</string>
     <string description="The brief result message if text has a low readability score. [CHAR LIMIT=NONE]" name="result_message_brief_low_reading_score">This text may have a low readability score.</string>
-    <string description="The brief result message of a check describing that multiple items (UI elements) share the same description that would be spoken by a screen reader. [CHAR LIMIT=NONE}" name="result_message_brief_same_speakable_text">Multiple items have the same description.</string>
+    <string description="The brief result message of a check describing that multiple items (UI elements) share the same description that would be spoken by a screen reader. [CHAR LIMIT=NONE]" name="result_message_brief_same_speakable_text">Multiple items have the same description.</string>
     <string description="The brief result message of a check describing that multiple actionable items (UI elements) share the same space on the screen. [CHAR LIMIT=NONE]" name="result_message_brief_same_view_bounds">Multiple <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> items share this location on the screen.</string>
     <string description="The brief result message of a check describing that the size of this view (UI element) may be too small to be touched or interacted with reliably. [CHAR LIMIT=NONE]" name="result_message_brief_small_touch_target">Consider making this clickable item larger.</string>
     <string description="The brief message describing that using bold typeface is ideal. [CHAR LIMIT=NONE]" name="result_message_brief_styled_text">Consider removing <ns1:g example="italic" id="style_info">%1$s</ns1:g> styling on longer passages of text.</string>
@@ -75,7 +82,17 @@
     <string description="The result message of a check describing that the class name is not supported by the accessibility service. [CHAR LIMIT=NONE]" name="result_message_class_name_not_supported_brief">This item\'s type may not be supported.</string>
     <string description="The result message of a check describing that the class name is not supported by the accessibility service. [CHAR LIMIT=NONE]" name="result_message_class_name_not_supported_detail">This item\'s type <ns1:g example="com.example.MyButton" id="class_name">&lt;tt>%1$s&lt;/tt></ns1:g> may not be resolvable by accessibility services. Consider using a type defined by the Android SDK.</string>
     <string description="The result message of a check describing the specific android class of the view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_clickablespan_no_determined_type">This item\'s type is undetermined.</string>
+    <string description="The result message of a check stating that a description of a view (UI element) might specify an available action within its &apos;android:contentDescription&apos; attribute. [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_action">
+    This item\'s <ns1:g example="android:contentDescription" id="content_description_attr">&lt;tt>android:contentDescription&lt;/tt></ns1:g>,
+    \"<ns1:g example="Tap to send" id="content_desc">&lt;tt>%1$s&lt;/tt></ns1:g>\",
+    contains the action \"<ns1:g example="tap" id="item_action">&lt;tt>%2$s&lt;/tt></ns1:g>\".
+  </string>
     <string description="The result message of a check stating that a description of a view (UI element) has redundant or unnecessary text (ex: a view of type Button whose &apos;android:contentDescription&apos; is &apos;Save button&apos;). [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_redundant_word">This item\'s <ns1:g example="android:contentDescription" id="content_description_attr">&lt;tt>android:contentDescription&lt;/tt></ns1:g>, \"<ns1:g example="Save button" id="content_desc">&lt;tt>%1$s&lt;/tt></ns1:g>\" contains the item type \"<ns1:g example="button" id="item_type">&lt;tt>%2$s&lt;/tt></ns1:g>\".</string>
+    <string description="The result message of a check stating that a description of a view (UI element) might specify an element state within its &apos;android:contentDescription&apos; attribute. [CHAR LIMIT=NONE]" name="result_message_content_desc_contains_state">
+    This item\'s <ns1:g example="android:contentDescription" id="content_description_attr">&lt;tt>android:contentDescription&lt;/tt></ns1:g>,
+    \"<ns1:g example="Rush delivery selected" id="content_desc">&lt;tt>%1$s&lt;/tt></ns1:g>\",
+    contains the state \"<ns1:g example="selected" id="item_state">&lt;tt>%2$s&lt;/tt></ns1:g>\".
+  </string>
     <string description="The result message of a check stating that a description of a view (UI element) ends with that view&apos;s type (ex: a view of type Button whose &apos;android:contentDescription&apos; is &apos;Save button&apos;). [CHAR LIMIT=NONE]" name="result_message_content_desc_ends_with_view_type">This item\'s <ns1:g example="android:contentDescription" id="content_description_attr">&lt;tt>android:contentDescription&lt;/tt></ns1:g>, \"<ns1:g example="Save button" id="content_desc">&lt;tt>%1$s&lt;/tt></ns1:g>\" ends with the item\'s type.</string>
     <string description="The result message of a check describing that the background color of a view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_could_not_get_background_color">This item\'s background color could not be determined.</string>
     <string description="The result message of a check describing that the color of the text within a view (UI element) could not be determined. [CHAR LIMIT=NONE]" name="result_message_could_not_get_text_color">This item\'s text color could not be determined.</string>
@@ -126,8 +143,13 @@
     <string description="The result message of a check describing that this view (UI element) may be presented incorrectly to the user when traversed with a screen reader. [CHAR LIMIT=NONE]" name="result_message_traversal_over_constrained">Traversal ordering for this item may be over constrained based on its <ns1:g example="android:accessibilityTraversalBefore" id="traversal_before_attr">&lt;tt>android:accessibilityTraversalBefore&lt;/tt></ns1:g> and <ns1:g example="android:accessibilityTraversalAfter" id="traversal_after_attr">&lt;tt>android:accessibilityTraversalAfter&lt;/tt></ns1:g> attributes. Traversal behavior with screen readers may be unpredictable.</string>
     <string description="The result message of a check describing that the view has text marked up with an android URLSpan (a hyperlink), which has an invalid URL. [CHAR LIMIT=NONE]" name="result_message_urlspan_invalid_url">Verify that the URL within this item\'s <ns1:g example="URLSpan" id="url_span_class">&lt;tt>URLSpan&lt;/tt></ns1:g> is valid.</string>
     <string description="The result message of a check describing that views should use the android concept of a &apos;URLSpan&apos; instead of a &apos;ClickableSpan&apos;, for improved accessibility. [CHAR LIMIT=NONE]" name="result_message_urlspan_not_clickablespan">This item should use a <ns1:g example="URLSpan" id="url_span_class">&lt;tt>URLSpan&lt;/tt></ns1:g> in place of a <ns1:g example="ClickableSpan" id="clickable_span_class">&lt;tt>ClickableSpan&lt;/tt></ns1:g>.</string>
-    <string description="The result message of a check describing the position of this view (UI element) on the screen." name="result_message_view_bounds">This <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> item also has an on-screen location of <ns1:g example="[0,0][100,100]" id="view_bounds">&lt;tt>%2$s&lt;/tt></ns1:g>.</string>
+    <string description="The result message of a check describing the position of this view (UI element) on the screen. [CHAR LIMIT=NONE]" name="result_message_view_bounds">This <ns1:g example="clickable and long clickable" id="clickability">%1$s</ns1:g> item also has an on-screen location of <ns1:g example="[0,0][100,100]" id="view_bounds">&lt;tt>%2$s&lt;/tt></ns1:g>.</string>
     <string description="The result message of a check describing that all or part of the view (UI element) was off the screen when the screenshot was taken. [CHAR LIMIT=NONE]" name="result_message_view_not_within_screencapture">This item\'s on-screen location (<ns1:g example="[0,0][100,100]" id="view_bounds">&lt;tt>%1$s&lt;/tt></ns1:g>) were not within the screen capture on-screen location (<ns1:g example="[0,0][1920,1080]" id="capture_bounds">&lt;tt>%2$s&lt;/tt></ns1:g>).</string>
     <string description="The result message of a check describing that web content (UI element shown within a browser) was not evaluated. [CHAR LIMIT=NONE]" name="result_message_web_content">Web content is not evaluated.</string>
+    <string description="Adjective describing a view that is selected. [CHAR LIMIT=NONE]" name="selected_state">selected</string>
+    <string description="An action in a UI, as in the imperative &apos;swipe to unlock&apos;. [CHAR LIMIT=NONE]" name="swipe_action">swipe</string>
+    <string description="An action in a UI, as in the imperative &apos;tap to select&apos;. [CHAR LIMIT=NONE]" name="tap_action">tap</string>
+    <string description="Adjective describing a checkbox that is not selected. [CHAR LIMIT=NONE]" name="unchecked_state">unchecked</string>
     <string description="Describes underlined text styling. [CHAR LIMIT=NONE]" name="underline_text">underline</string>
+    <string description="Adjective describing a view that is not selected. [CHAR LIMIT=NONE]" name="unselected_state">unselected</string>
 </resources>
\ No newline at end of file
diff --git a/validator/src/ResourceConverter.java b/validator/src/ResourceConverter.java
index 18ffda8..6b9d73e 100644
--- a/validator/src/ResourceConverter.java
+++ b/validator/src/ResourceConverter.java
@@ -102,13 +102,19 @@
              */
             for (int j = 0; j < node.getChildNodes().getLength(); j++) {
                 Node child = node.getChildNodes().item(j);
+                String toAdd = null;
                 if ("ns1:g".equals(child.getNodeName())) {
-                    valueBuilder.append(child.getFirstChild().getNodeValue());
+                    toAdd = child.getFirstChild().getNodeValue();
                 } else {
-                    valueBuilder.append(child.getNodeValue());
+                    toAdd = child.getNodeValue();
                 }
+                // Replace all tab, newline and multi indentations.
+                toAdd = toAdd.replaceAll("[\n\t]", "");
+                toAdd = toAdd.replaceAll("[ ]+", " ");
+                valueBuilder.append(toAdd);
             }
-            toReturn.put(name, valueBuilder.toString());
+            String finalString = valueBuilder.toString().trim();
+            toReturn.put(name, finalString);
         }
         return toReturn;
     }
diff --git a/validator/src/com/android/tools/idea/validator/ValidatorData.java b/validator/src/com/android/tools/idea/validator/ValidatorData.java
index 6d9d6b6..49f0e30 100644
--- a/validator/src/com/android/tools/idea/validator/ValidatorData.java
+++ b/validator/src/com/android/tools/idea/validator/ValidatorData.java
@@ -79,6 +79,8 @@
      */
     public static class Issue {
         @NotNull
+        public final String mCategory;
+        @NotNull
         public final Type mType;
         @NotNull
         public final String mMsg;
@@ -94,6 +96,7 @@
         public final String mHelpfulUrl;
 
         private Issue(
+                @NotNull String category,
                 @NotNull Type type,
                 @NotNull String msg,
                 @NotNull Level level,
@@ -101,6 +104,7 @@
                 @Nullable Fix fix,
                 @NotNull String sourceClass,
                 @Nullable String helpfulUrl) {
+            mCategory = category;
             mType = type;
             mMsg = msg;
             mLevel = level;
@@ -111,6 +115,7 @@
         }
 
         public static class IssueBuilder {
+            private String mCategory;
             private Type mType = Type.ACCESSIBILITY;
             private String mMsg;
             private Level mLevel;
@@ -119,6 +124,11 @@
             private String mSourceClass;
             private String mHelpfulUrl;
 
+            public IssueBuilder setCategory(String category) {
+                mCategory = category;
+                return this;
+            }
+
             public IssueBuilder setType(Type type) {
                 mType = type;
                 return this;
@@ -155,11 +165,19 @@
             }
 
             public Issue build() {
+                assert(mCategory != null);
                 assert(mType != null);
                 assert(mMsg != null);
                 assert(mLevel != null);
                 assert(mSourceClass != null);
-                return new Issue(mType, mMsg, mLevel, mSrcId, mFix, mSourceClass, mHelpfulUrl);
+                return new Issue(mCategory,
+                        mType,
+                        mMsg,
+                        mLevel,
+                        mSrcId,
+                        mFix,
+                        mSourceClass,
+                        mHelpfulUrl);
             }
         }
     }
diff --git a/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java b/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java
index a2ec2c4..859e5bc 100644
--- a/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java
+++ b/validator/src/com/android/tools/idea/validator/accessibility/AccessibilityValidator.java
@@ -95,6 +95,8 @@
                 policy.mChecks);
 
         for (AccessibilityHierarchyCheckResult result : results) {
+            String category = getCheckClassCategory(result.getSourceCheckClass());
+
             ValidatorData.Level level = convertLevel(result.getType());
             if (!filter.contains(level)) {
                 continue;
@@ -102,6 +104,7 @@
 
             try {
                 IssueBuilder issueBuilder = new IssueBuilder()
+                        .setCategory(category)
                         .setMsg(result.getMessage(Locale.ENGLISH).toString())
                         .setLevel(level)
                         .setFix(generateFix(result))
@@ -119,6 +122,7 @@
                 builder.mIssues.add(issueBuilder.build());
             } catch (Exception e) {
                 builder.mIssues.add(new IssueBuilder()
+                        .setCategory(category)
                         .setType(Type.INTERNAL_ERROR)
                         .setMsg(e.getMessage())
                         .setLevel(Level.ERROR)
@@ -130,6 +134,19 @@
     }
 
     @NotNull
+    private static String getCheckClassCategory(@NotNull Class<?> checkClass) {
+        try {
+            Class<? extends AccessibilityHierarchyCheck> subClass =
+                    checkClass.asSubclass(AccessibilityHierarchyCheck.class);
+            AccessibilityHierarchyCheck check =
+                    AccessibilityCheckPreset.getHierarchyCheckForClass(subClass);
+            return (check == null) ? "Accessibility" : check.getCategory().name();
+        } catch (ClassCastException e) {
+            return "Accessibility";
+        }
+    }
+
+    @NotNull
     private static ValidatorData.Level convertLevel(@NotNull AccessibilityCheckResultType type) {
         switch (type) {
             case ERROR:
diff --git a/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java b/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java
new file mode 100644
index 0000000..025bd77
--- /dev/null
+++ b/validator/src/com/google/android/apps/common/testing/accessibility/framework/uielement/AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.apps.common.testing.accessibility.framework.uielement;
+
+import com.android.ide.common.rendering.api.LayoutlibCallback;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+public class AccessibilityHierarchyAndroid_ViewElementClassNamesAndroid_Delegate {
+
+    public static LayoutlibCallback sLayoutlibCallback;
+
+    @LayoutlibDelegate
+    public static Class<?> getClassByName(ViewHierarchyElementAndroid view, String className) {
+        Class toReturn = AccessibilityHierarchyAndroid
+                .ViewElementClassNamesAndroid.getClassByName_Original(view, className);
+        if (toReturn == null && sLayoutlibCallback != null) {
+            try {
+                return sLayoutlibCallback.findClass(className);
+            } catch (ClassNotFoundException ignore) {
+            }
+        }
+
+        return toReturn;
+    }
+}
diff --git a/validator/validator.iml b/validator/validator.iml
index f580aa3..6d92c11 100644
--- a/validator/validator.iml
+++ b/validator/validator.iml
@@ -41,5 +41,6 @@
         <SOURCES />
       </library>
     </orderEntry>
+    <orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
   </component>
 </module>
\ No newline at end of file