Tools attribute improvements for RecyclerView LayoutManager.

1. Change tools attribute for layout manager from layoutManagerType to
LayoutManager.
2. Support classnames in the tools attribute.

This change doesn't try to supprt arbitrary classnames for now. The
reason for this is that the new layoutlib API is supposed to contain a
new method for inflating custom classes that are not views. This will
allow us to throw better error messages. Without the new API, trying for
different constructors, will result in a error messages being logged.

Change-Id: I3a31359c06b7452bfd973c3e5e54f9038acccfaa
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index fbd5e2a..8192b5f 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -233,11 +233,13 @@
                 String type = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES,
                                 BridgeConstants.ATTR_LAYOUT_MANAGER_TYPE);
                 if (type != null) {
-                    LayoutManagerType layoutManagerType = LayoutManagerType.getByDisplayName(type);
+                    LayoutManagerType layoutManagerType = LayoutManagerType.getByLogicalName(type);
                     if (layoutManagerType == null) {
-                        Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
-                                "LayoutManager (" + type + ") not found, falling back to " +
-                                        "LinearLayoutManager", null);
+                        layoutManagerType = LayoutManagerType.getByClassName(type);
+                    }
+                    if (layoutManagerType == null) {
+                        // add the classname itself.
+                        bc.addCookie(view, type);
                     } else {
                         bc.addCookie(view, layoutManagerType);
                     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
index fdb4567..1af6998 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeConstants.java
@@ -50,5 +50,5 @@
     public final static String WRAP_CONTENT = "wrap_content";
 
     /** Attribute in the tools namespace used to specify layout manager for RecyclerView. */
-    public static final String ATTR_LAYOUT_MANAGER_TYPE = "layoutManagerType";
+    public static final String ATTR_LAYOUT_MANAGER_TYPE = "layoutManager";
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
index 2feab7a..1d47333 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/support/RecyclerViewUtil.java
@@ -73,8 +73,15 @@
     private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
             @NonNull IProjectCallback callback) throws ReflectionException {
         Object cookie = context.getCookie(recyclerView);
-        assert cookie == null || cookie instanceof LayoutManagerType;
-        if (cookie == null) {
+        assert cookie == null || cookie instanceof LayoutManagerType || cookie instanceof String;
+        if (!(cookie instanceof LayoutManagerType)) {
+            if (cookie != null) {
+                // TODO: When layoutlib API is updated, try to load the class with a null
+                // constructor or a constructor taking one argument - the context.
+                Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
+                        "LayoutManager (" + cookie + ") not found, falling back to " +
+                                "LinearLayoutManager", null);
+            }
             cookie = LayoutManagerType.getDefault();
         }
         Object layoutManager = createLayoutManager((LayoutManagerType) cookie, context, callback);
@@ -152,22 +159,13 @@
                 "android.support.v7.widget.StaggeredGridLayoutManager",
                 new Class[]{int.class, int.class}, new Object[]{2, LinearLayout.VERTICAL});
 
-        private String mDisplayName;
+        private String mLogicalName;
         private String mClassName;
         private Class[] mSignature;
         private Object[] mArgs;
 
-        private static final HashMap<String, LayoutManagerType> sDisplayNameLookup =
-                new HashMap<String, LayoutManagerType>();
-
-        static {
-            for (LayoutManagerType type : LayoutManagerType.values()) {
-                sDisplayNameLookup.put(type.mDisplayName, type);
-            }
-        }
-
-        LayoutManagerType(String displayName, String className, Class[] signature, Object[] args) {
-            mDisplayName = displayName;
+        LayoutManagerType(String logicalName, String className, Class[] signature, Object[] args) {
+            mLogicalName = logicalName;
             mClassName = className;
             mSignature = signature;
             mArgs = args;
@@ -199,8 +197,23 @@
         }
 
         @Nullable
-        public static LayoutManagerType getByDisplayName(@Nullable String className) {
-            return sDisplayNameLookup.get(className);
+        public static LayoutManagerType getByLogicalName(@NonNull String logicalName) {
+            for (LayoutManagerType type : values()) {
+                if (logicalName.equals(type.mLogicalName)) {
+                    return type;
+                }
+            }
+            return null;
+        }
+
+        @Nullable
+        public static LayoutManagerType getByClassName(@NonNull String className) {
+            for (LayoutManagerType type : values()) {
+                if (className.equals(type.mClassName)) {
+                    return type;
+                }
+            }
+            return null;
         }
     }
 }