am cdb87d8d: am a59c27dd: Fix ClassCastException when rendering ListView [DO NOT MERGE]

* commit 'cdb87d8d83e8a76a4cf78d24d5c49ee8548eba1f':
  Fix ClassCastException when rendering ListView [DO NOT MERGE]
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/BaseAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
similarity index 62%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/BaseAdapter.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
index e0414fe..6c998af 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/BaseAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2013 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.
@@ -16,7 +16,6 @@
 
 package com.android.layoutlib.bridge.impl.binding;
 
-import com.android.ide.common.rendering.api.AdapterBinding;
 import com.android.ide.common.rendering.api.DataBindingItem;
 import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.LayoutLog;
@@ -27,7 +26,6 @@
 import com.android.layoutlib.bridge.impl.RenderAction;
 import com.android.util.Pair;
 
-import android.database.DataSetObserver;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
@@ -35,124 +33,27 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
- * Base adapter to do fake data binding in {@link AdapterView} objects.
+ * A Helper class to do fake data binding in {@link AdapterView} objects.
  */
-public class BaseAdapter {
+@SuppressWarnings("deprecation")
+public class AdapterHelper {
 
-    /**
-     * This is the items provided by the adapter. They are dynamically generated.
-     */
-    protected final static class AdapterItem {
-        private final DataBindingItem mItem;
-        private final int mType;
-        private final int mFullPosition;
-        private final int mPositionPerType;
-        private List<AdapterItem> mChildren;
-
-        protected AdapterItem(DataBindingItem item, int type, int fullPosition,
-                int positionPerType) {
-            mItem = item;
-            mType = type;
-            mFullPosition = fullPosition;
-            mPositionPerType = positionPerType;
-        }
-
-        void addChild(AdapterItem child) {
-            if (mChildren == null) {
-                mChildren = new ArrayList<AdapterItem>();
-            }
-
-            mChildren.add(child);
-        }
-
-        List<AdapterItem> getChildren() {
-            if (mChildren != null) {
-                return mChildren;
-            }
-
-            return Collections.emptyList();
-        }
-
-        int getType() {
-            return mType;
-        }
-
-        int getFullPosition() {
-            return mFullPosition;
-        }
-
-        int getPositionPerType() {
-            return mPositionPerType;
-        }
-
-        DataBindingItem getDataBindingItem() {
-            return mItem;
-        }
-    }
-
-    private final AdapterBinding mBinding;
-    private final IProjectCallback mCallback;
-    private final ResourceReference mAdapterRef;
-    private boolean mSkipCallbackParser = false;
-
-    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
-
-    protected BaseAdapter(ResourceReference adapterRef, AdapterBinding binding,
-            IProjectCallback callback) {
-        mAdapterRef = adapterRef;
-        mBinding = binding;
-        mCallback = callback;
-    }
-
-    // ------- Some Adapter method used by all children classes.
-
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    public boolean hasStableIds() {
-        return true;
-    }
-
-    public boolean isEmpty() {
-        return mItems.size() == 0;
-    }
-
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // pass
-    }
-
-    // -------
-
-
-    protected AdapterBinding getBinding() {
-        return mBinding;
-    }
-
-    protected View getView(AdapterItem item, AdapterItem parentItem, View convertView,
-            ViewGroup parent) {
+    static Pair<View, Boolean> getView(AdapterItem item, AdapterItem parentItem, ViewGroup parent,
+            IProjectCallback callback, ResourceReference adapterRef, boolean skipCallbackParser) {
         // we don't care about recycling here because we never scroll.
         DataBindingItem dataBindingItem = item.getDataBindingItem();
 
         BridgeContext context = RenderAction.getCurrentContext();
 
         Pair<View, Boolean> pair = context.inflateView(dataBindingItem.getViewReference(),
-                parent, false /*attachToRoot*/, mSkipCallbackParser);
+                parent, false /*attachToRoot*/, skipCallbackParser);
 
         View view = pair.getFirst();
-        mSkipCallbackParser |= pair.getSecond();
+        skipCallbackParser |= pair.getSecond();
 
         if (view != null) {
-            fillView(context, view, item, parentItem);
+            fillView(context, view, item, parentItem, callback, adapterRef);
         } else {
             // create a text view to display an error.
             TextView tv = new TextView(context);
@@ -160,16 +61,16 @@
             view = tv;
         }
 
-        return view;
+        return Pair.of(view, skipCallbackParser);
     }
 
-    private void fillView(BridgeContext context, View view, AdapterItem item,
-            AdapterItem parentItem) {
+    private static void fillView(BridgeContext context, View view, AdapterItem item,
+            AdapterItem parentItem, IProjectCallback callback, ResourceReference adapterRef) {
         if (view instanceof ViewGroup) {
             ViewGroup group = (ViewGroup) view;
             final int count = group.getChildCount();
             for (int i = 0 ; i < count ; i++) {
-                fillView(context, group.getChildAt(i), item, parentItem);
+                fillView(context, group.getChildAt(i), item, parentItem, callback, adapterRef);
             }
         } else {
             int id = view.getId();
@@ -184,8 +85,8 @@
 
                     if (view instanceof TextView) {
                         TextView tv = (TextView) view;
-                        Object value = mCallback.getAdapterItemValue(
-                                mAdapterRef, context.getViewKey(view),
+                        Object value = callback.getAdapterItemValue(
+                                adapterRef, context.getViewKey(view),
                                 item.getDataBindingItem().getViewReference(),
                                 fullPosition, positionPerType,
                                 fullParentPosition, parentPositionPerType,
@@ -204,8 +105,8 @@
                     if (view instanceof Checkable) {
                         Checkable cb = (Checkable) view;
 
-                        Object value = mCallback.getAdapterItemValue(
-                                mAdapterRef, context.getViewKey(view),
+                        Object value = callback.getAdapterItemValue(
+                                adapterRef, context.getViewKey(view),
                                 item.getDataBindingItem().getViewReference(),
                                 fullPosition, positionPerType,
                                 fullParentPosition, parentPositionPerType,
@@ -224,8 +125,8 @@
                     if (view instanceof ImageView) {
                         ImageView iv = (ImageView) view;
 
-                        Object value = mCallback.getAdapterItemValue(
-                                mAdapterRef, context.getViewKey(view),
+                        Object value = callback.getAdapterItemValue(
+                                adapterRef, context.getViewKey(view),
                                 item.getDataBindingItem().getViewReference(),
                                 fullPosition, positionPerType,
                                 fullParentPosition, parentPositionPerType,
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
new file mode 100644
index 0000000..8e28dba
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/AdapterItem.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 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.impl.binding;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import com.android.ide.common.rendering.api.DataBindingItem;
+
+/**
+ * This is the items provided by the adapter. They are dynamically generated.
+ */
+final class AdapterItem {
+    private final DataBindingItem mItem;
+    private final int mType;
+    private final int mFullPosition;
+    private final int mPositionPerType;
+    private List<AdapterItem> mChildren;
+
+    protected AdapterItem(DataBindingItem item, int type, int fullPosition,
+            int positionPerType) {
+        mItem = item;
+        mType = type;
+        mFullPosition = fullPosition;
+        mPositionPerType = positionPerType;
+    }
+
+    void addChild(AdapterItem child) {
+        if (mChildren == null) {
+            mChildren = new ArrayList<AdapterItem>();
+        }
+
+        mChildren.add(child);
+    }
+
+    List<AdapterItem> getChildren() {
+        if (mChildren != null) {
+            return mChildren;
+        }
+
+        return Collections.emptyList();
+    }
+
+    int getType() {
+        return mType;
+    }
+
+    int getFullPosition() {
+        return mFullPosition;
+    }
+
+    int getPositionPerType() {
+        return mPositionPerType;
+    }
+
+    DataBindingItem getDataBindingItem() {
+        return mItem;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
index 22570b9..9a13f5a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeAdapter.java
@@ -20,10 +20,12 @@
 import com.android.ide.common.rendering.api.DataBindingItem;
 import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.util.Pair;
 
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
+import android.widget.BaseAdapter;
 import android.widget.ListAdapter;
 import android.widget.SpinnerAdapter;
 
@@ -35,17 +37,23 @@
  * and {@link SpinnerAdapter}.
  *
  */
-public class FakeAdapter extends BaseAdapter implements ListAdapter, SpinnerAdapter {
+@SuppressWarnings("deprecation")
+public class FakeAdapter extends BaseAdapter {
 
     // don't use a set because the order is important.
     private final List<ResourceReference> mTypes = new ArrayList<ResourceReference>();
+    private final IProjectCallback mCallback;
+    private final ResourceReference mAdapterRef;
+    private final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
+    private boolean mSkipCallbackParser = false;
 
     public FakeAdapter(ResourceReference adapterRef, AdapterBinding binding,
             IProjectCallback callback) {
-        super(adapterRef, binding, callback);
+        mAdapterRef = adapterRef;
+        mCallback = callback;
 
-        final int repeatCount = getBinding().getRepeatCount();
-        final int itemCount = getBinding().getItemCount();
+        final int repeatCount = binding.getRepeatCount();
+        final int itemCount = binding.getItemCount();
 
         // Need an array to count for each type.
         // This is likely too big, but is the max it can be.
@@ -54,7 +62,7 @@
         // We put several repeating sets.
         for (int r = 0 ; r < repeatCount ; r++) {
             // loop on the type of list items, and add however many for each type.
-            for (DataBindingItem dataBindingItem : getBinding()) {
+            for (DataBindingItem dataBindingItem : binding) {
                 ResourceReference viewRef = dataBindingItem.getViewReference();
                 int typeIndex = mTypes.indexOf(viewRef);
                 if (typeIndex == -1) {
@@ -103,7 +111,11 @@
     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);
-        return getView(item, null /*parentGroup*/, convertView, parent);
+        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentGroup*/, parent,
+                mCallback, mAdapterRef, mSkipCallbackParser);
+        mSkipCallbackParser = pair.getSecond();
+        return pair.getFirst();
+
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
index 199e040..e539579 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/binding/FakeExpandableAdapter.java
@@ -20,7 +20,9 @@
 import com.android.ide.common.rendering.api.DataBindingItem;
 import com.android.ide.common.rendering.api.IProjectCallback;
 import com.android.ide.common.rendering.api.ResourceReference;
+import com.android.util.Pair;
 
+import android.database.DataSetObserver;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ExpandableListAdapter;
@@ -29,8 +31,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class FakeExpandableAdapter extends BaseAdapter implements ExpandableListAdapter,
-        HeterogeneousExpandableList {
+@SuppressWarnings("deprecation")
+public class FakeExpandableAdapter implements ExpandableListAdapter, HeterogeneousExpandableList {
+
+    private final IProjectCallback mCallback;
+    private final ResourceReference mAdapterRef;
+    private boolean mSkipCallbackParser = false;
+
+    protected final List<AdapterItem> mItems = new ArrayList<AdapterItem>();
 
     // don't use a set because the order is important.
     private final List<ResourceReference> mGroupTypes = new ArrayList<ResourceReference>();
@@ -38,7 +46,8 @@
 
     public FakeExpandableAdapter(ResourceReference adapterRef, AdapterBinding binding,
             IProjectCallback callback) {
-        super(adapterRef, binding, callback);
+        mAdapterRef = adapterRef;
+        mCallback = callback;
 
         createItems(binding, binding.getItemCount(), binding.getRepeatCount(), mGroupTypes, 1);
     }
@@ -125,7 +134,10 @@
             ViewGroup parent) {
         // we don't care about recycling here because we never scroll.
         AdapterItem item = mItems.get(groupPosition);
-        return getView(item, null /*parentItem*/, convertView, parent);
+        Pair<View, Boolean> pair = AdapterHelper.getView(item, null /*parentItem*/, parent,
+                mCallback, mAdapterRef, mSkipCallbackParser);
+        mSkipCallbackParser = pair.getSecond();
+        return pair.getFirst();
     }
 
     @Override
@@ -134,7 +146,10 @@
         // we don't care about recycling here because we never scroll.
         AdapterItem parentItem = mItems.get(groupPosition);
         AdapterItem item = getChildItem(groupPosition, childPosition);
-        return getView(item, parentItem, convertView, parent);
+        Pair<View, Boolean> pair = AdapterHelper.getView(item, parentItem, parent, mCallback,
+                mAdapterRef, mSkipCallbackParser);
+        mSkipCallbackParser = pair.getSecond();
+        return pair.getFirst();
     }
 
     @Override
@@ -172,6 +187,31 @@
         // pass
     }
 
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        // pass
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        // pass
+    }
+
+    @Override
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    @Override
+    public boolean areAllItemsEnabled() {
+        return true;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mItems.isEmpty();
+    }
+
     // ---- HeterogeneousExpandableList
 
     @Override