Simplification of the poolable management utils.

   Before to implement a pool of objects, the pooled class had to implement an
   interface which was leaking the pool management APIs. This requires
   hiding APIs - inconvenient at best. Further, each client had to
   implement the chaining of pooled instances which means adding a couple
   of member variables which are manipulated by the implemented interface
   methods. As a consequence the client is aware of how pooling is
   implemented which is error prone and breaks encapsulation. Now the
   pool objects are responsible for managing pooling state via reusable
   wrapper objects and the clients are oblivious of how pooling is done.
   Creating a thin cached wrapper for each pooled object has minimal
   performance impact while making the code more maintainable. Actually
   implementing of the old version of the APIs was taking as much code
   as implementing the pooling yourself.

   Also clients had to implement a poolable manager whose responsibility
   was to create new instances and provide callbacks when an instance
   is added to or removed from the pool. Now, the clinet class should
   create a static member for the pool and expose obtain/aquire and
   release/recycle methods in which it should create a new instance if
   the pool did not return one and clear the state of the host when
   it is returned to the pool. Updated the JavaDoc with a best practice.

   The pooling was composed of several interfaces and classes scattered
   over a few files, now all this is in a single small file.

   Update all usages of the pooling APIs in the framework.

Also one had to write a poolable
   manager which

Change-Id: Ib8dc286040eb3d7cb7d9668ba76fead05cb97647
diff --git a/core/java/android/util/FinitePool.java b/core/java/android/util/FinitePool.java
deleted file mode 100644
index b30f2bf..0000000
--- a/core/java/android/util/FinitePool.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2009 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.util;
-
-/**
- * @hide
- */
-class FinitePool<T extends Poolable<T>> implements Pool<T> {
-    private static final String LOG_TAG = "FinitePool";
-
-    /**
-     * Factory used to create new pool objects
-     */
-    private final PoolableManager<T> mManager;
-    /**
-     * Maximum number of objects in the pool
-     */
-    private final int mLimit;
-    /**
-     * If true, mLimit is ignored
-     */
-    private final boolean mInfinite;
-
-    /**
-     * Next object to acquire
-     */
-    private T mRoot;
-    /**
-     * Number of objects in the pool
-     */
-    private int mPoolCount;
-
-    FinitePool(PoolableManager<T> manager) {
-        mManager = manager;
-        mLimit = 0;
-        mInfinite = true;
-    }
-
-    FinitePool(PoolableManager<T> manager, int limit) {
-        if (limit <= 0) throw new IllegalArgumentException("The pool limit must be > 0");
-
-        mManager = manager;
-        mLimit = limit;
-        mInfinite = false;
-    }
-
-    public T acquire() {
-        T element;
-
-        if (mRoot != null) {
-            element = mRoot;
-            mRoot = element.getNextPoolable();
-            mPoolCount--;
-        } else {
-            element = mManager.newInstance();
-        }
-
-        if (element != null) {
-            element.setNextPoolable(null);
-            element.setPooled(false);
-            mManager.onAcquired(element);            
-        }
-
-        return element;
-    }
-
-    public void release(T element) {
-        if (!element.isPooled()) {
-            if (mInfinite || mPoolCount < mLimit) {
-                mPoolCount++;
-                element.setNextPoolable(mRoot);
-                element.setPooled(true);
-                mRoot = element;
-            }
-            mManager.onReleased(element);
-        } else {
-            Log.w(LOG_TAG, "Element is already in pool: " + element);
-        }
-    }
-}
diff --git a/core/java/android/util/Pool.java b/core/java/android/util/Pool.java
deleted file mode 100644
index 8cd4f3e..0000000
--- a/core/java/android/util/Pool.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2009 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.util;
-
-/**
- * @hide
- */
-public interface Pool<T extends Poolable<T>> {
-    public abstract T acquire();
-    public abstract void release(T element);
-}
diff --git a/core/java/android/util/Poolable.java b/core/java/android/util/Poolable.java
deleted file mode 100644
index 87e0529..0000000
--- a/core/java/android/util/Poolable.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 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.util;
-
-/**
- * @hide
- */
-public interface Poolable<T> {
-    void setNextPoolable(T element);
-    T getNextPoolable();
-    boolean isPooled();
-    void setPooled(boolean isPooled);
-}
diff --git a/core/java/android/util/PoolableManager.java b/core/java/android/util/PoolableManager.java
deleted file mode 100644
index 8773e63..0000000
--- a/core/java/android/util/PoolableManager.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2009 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.util;
-
-/**
- * @hide
- */
-public interface PoolableManager<T extends Poolable<T>> {
-    T newInstance();
-
-    void onAcquired(T element);
-    void onReleased(T element);
-}
diff --git a/core/java/android/util/Pools.java b/core/java/android/util/Pools.java
index 8edb3e6..908ede4 100644
--- a/core/java/android/util/Pools.java
+++ b/core/java/android/util/Pools.java
@@ -17,25 +17,178 @@
 package android.util;
 
 /**
+ * Helper class for crating pools of objects. An example use looks like this:
+ * <pre>
+ * public class MyPooledClass {
+ *
+ *     private static final Pool<MyPooledClass> sPool =
+ *             new SynchronizedPool<MyPooledClass>(Pools.POOL_SIZE_INFINITE);
+ *
+ *     public static MyPooledClass obtain() {
+ *         MyPooledClass instance = sPool.acquire();
+ *         return (instance != null) ? instance : new MyPooledClass();
+ *     }
+ *
+ *     public void recycle() {
+ *          // Clear state if needed.
+ *          sPool.release(this);
+ *     }
+ *
+ *     . . .
+ * }
+ * </pre>
+ *
  * @hide
  */
-public class Pools {
+public final class Pools {
+
+    /**
+     * Pool with an infinite size.
+     */
+    public static final int POOL_SIZE_INFINITE = -1;
+
+    /**
+     * Interface for managing a pool of objects.
+     *
+     * @param <T> The pooled type.
+     */
+    public static interface Pool<T> {
+
+        /**
+         * @return An instance from the pool if such, null otherwise.
+         */
+        public T acquire();
+
+        /**
+         * Release an instance to the pool.
+         *
+         * @param instance The instance to release.
+         * @return Whether the instance was put in the pool.
+         *
+         * @throws IllegalStateException If the instance is already in the pool.
+         */
+        public boolean release(T instance);
+    }
+
     private Pools() {
+        /* do nothing - hiding constructor */
     }
 
-    public static <T extends Poolable<T>> Pool<T> simplePool(PoolableManager<T> manager) {
-        return new FinitePool<T>(manager);
-    }
-    
-    public static <T extends Poolable<T>> Pool<T> finitePool(PoolableManager<T> manager, int limit) {
-        return new FinitePool<T>(manager, limit);
+    private static class PoolableHolder<T> {
+        T mPoolable;
+        PoolableHolder<T> mNext;
     }
 
-    public static <T extends Poolable<T>> Pool<T> synchronizedPool(Pool<T> pool) {
-        return new SynchronizedPool<T>(pool);
+    /**
+     * Simple (non-synchronized) pool of objects.
+     *
+     * @param <T> The pooled type.
+     */
+    public static class SimplePool<T> implements Pool<T> {
+        private final int mMaxPoolSize;
+
+        private int mPoolSize;
+
+        private PoolableHolder<T> mEmptyHolders;
+        private PoolableHolder<T> mPool;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param maxPoolSize The max pool size.
+         *
+         * @throws IllegalArgumentException If the max pool size is less than zero.
+         *
+         * @see Pools#POOL_SIZE_INFINITE
+         */
+        public SimplePool(int maxPoolSize) {
+            if (maxPoolSize <= 0 && maxPoolSize != POOL_SIZE_INFINITE) {
+                throw new IllegalArgumentException("The max pool size must be > 0");
+            }
+            mMaxPoolSize = maxPoolSize;
+        }
+
+        @Override
+        public T acquire() {
+            if (mPool != null) {
+                PoolableHolder<T> holder = mPool;
+                mPool = holder.mNext;
+                T poolable = holder.mPoolable;
+                holder.mPoolable = null;
+                holder.mNext = mEmptyHolders;
+                mEmptyHolders = holder;
+                mPoolSize--;
+                return poolable;
+            }
+            return null;
+        }
+
+        @Override
+        public boolean release(T instance) {
+            if (isInPool(instance)) {
+                throw new IllegalStateException("Already in the pool!");
+            }
+            if (mMaxPoolSize == POOL_SIZE_INFINITE || mPoolSize < mMaxPoolSize) {
+                PoolableHolder<T> holder = mEmptyHolders;
+                if (holder == null) {
+                    holder = new PoolableHolder<T>();
+                } else {
+                    mEmptyHolders = holder.mNext;
+                }
+                holder.mPoolable = instance;
+                holder.mNext = mPool;
+                mPool = holder;
+                mPoolSize++;
+                return true;
+            }
+            return false;
+        }
+
+        private boolean isInPool(T instance) {
+            PoolableHolder<T> current = mPool;
+            while (current != null) {
+                if (current.mPoolable == instance) {
+                    return true;
+                }
+                current = current.mNext;
+            }
+            return false;
+        }
     }
 
-    public static <T extends Poolable<T>> Pool<T> synchronizedPool(Pool<T> pool, Object lock) {
-        return new SynchronizedPool<T>(pool, lock);
+    /**
+     * Synchronized) pool of objects.
+     *
+     * @param <T> The pooled type.
+     */
+    public static class SynchronizedPool<T> extends SimplePool<T> {
+        private final Object mLock = new Object();
+
+        /**
+         * Creates a new instance.
+         *
+         * @param maxPoolSize The max pool size.
+         *
+         * @throws IllegalArgumentException If the max pool size is less than zero.
+         *
+         * @see Pools#POOL_SIZE_INFINITE
+         */
+        public SynchronizedPool(int maxPoolSize) {
+            super(maxPoolSize);
+        }
+
+        @Override
+        public T acquire() {
+            synchronized (mLock) {
+                return super.acquire();
+            }
+        }
+
+        @Override
+        public boolean release(T element) {
+            synchronized (mLock) {
+                return super.release(element);
+            }
+        }
     }
 }
diff --git a/core/java/android/util/SynchronizedPool.java b/core/java/android/util/SynchronizedPool.java
deleted file mode 100644
index 651e0c3..0000000
--- a/core/java/android/util/SynchronizedPool.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2009 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.util;
-
-/**
- *
- * @hide
- */
-class SynchronizedPool<T extends Poolable<T>> implements Pool<T> {
-    private final Pool<T> mPool;
-    private final Object mLock;
-
-    public SynchronizedPool(Pool<T> pool) {
-        mPool = pool;
-        mLock = this;
-    }
-
-    public SynchronizedPool(Pool<T> pool, Object lock) {
-        mPool = pool;
-        mLock = lock;
-    }
-
-    public T acquire() {
-        synchronized (mLock) {
-            return mPool.acquire();
-        }
-    }
-
-    public void release(T element) {
-        synchronized (mLock) {
-            mPool.release(element);
-        }
-    }
-}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index d2df45a..168ae81 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -24,10 +24,7 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Shader;
-import android.util.Pool;
-import android.util.Poolable;
-import android.util.PoolableManager;
-import android.util.Pools;
+import android.util.Pools.SynchronizedPool;
 
 /**
  * An implementation of a GL canvas that records drawing operations.
@@ -35,26 +32,13 @@
  * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
  * the DisplayList is still holding a native reference to the memory.
  */
-class GLES20RecordingCanvas extends GLES20Canvas implements Poolable<GLES20RecordingCanvas> {
+class GLES20RecordingCanvas extends GLES20Canvas {
     // The recording canvas pool should be large enough to handle a deeply nested
     // view hierarchy because display lists are generated recursively.
     private static final int POOL_LIMIT = 25;
 
-    private static final Pool<GLES20RecordingCanvas> sPool = Pools.synchronizedPool(
-            Pools.finitePool(new PoolableManager<GLES20RecordingCanvas>() {
-                public GLES20RecordingCanvas newInstance() {
-                    return new GLES20RecordingCanvas();
-                }
-                @Override
-                public void onAcquired(GLES20RecordingCanvas element) {
-                }
-                @Override
-                public void onReleased(GLES20RecordingCanvas element) {
-                }
-            }, POOL_LIMIT));
-
-    private GLES20RecordingCanvas mNextPoolable;
-    private boolean mIsPooled;
+    private static final SynchronizedPool<GLES20RecordingCanvas> sPool =
+            new SynchronizedPool<GLES20RecordingCanvas>(POOL_LIMIT);
 
     private GLES20DisplayList mDisplayList;
 
@@ -64,6 +48,9 @@
 
     static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
         GLES20RecordingCanvas canvas = sPool.acquire();
+        if (canvas == null) {
+            canvas = new GLES20RecordingCanvas();
+        }
         canvas.mDisplayList = displayList;
         return canvas;
     }
@@ -300,24 +287,4 @@
                 colorOffset, indices, indexOffset, indexCount, paint);
         recordShaderBitmap(paint);
     }
-
-    @Override
-    public GLES20RecordingCanvas getNextPoolable() {
-        return mNextPoolable;
-    }
-
-    @Override
-    public void setNextPoolable(GLES20RecordingCanvas element) {
-        mNextPoolable = element;
-    }
-
-    @Override
-    public boolean isPooled() {
-        return mIsPooled;
-    }
-
-    @Override
-    public void setPooled(boolean isPooled) {
-        mIsPooled = isPooled;
-    }
 }
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 82b3963..eb81f72 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -16,10 +16,7 @@
 
 package android.view;
 
-import android.util.Poolable;
-import android.util.Pool;
-import android.util.Pools;
-import android.util.PoolableManager;
+import android.util.Pools.SynchronizedPool;
 
 /**
  * Helper for tracking the velocity of touch events, for implementing
@@ -31,30 +28,15 @@
  * {@link #computeCurrentVelocity(int)} and then call {@link #getXVelocity(int)}
  * and {@link #getYVelocity(int)} to retrieve the velocity for each pointer id.
  */
-public final class VelocityTracker implements Poolable<VelocityTracker> {
-    private static final Pool<VelocityTracker> sPool = Pools.synchronizedPool(
-            Pools.finitePool(new PoolableManager<VelocityTracker>() {
-                public VelocityTracker newInstance() {
-                    return new VelocityTracker(null);
-                }
-
-                public void onAcquired(VelocityTracker element) {
-                    // Intentionally empty
-                }
-
-                public void onReleased(VelocityTracker element) {
-                    element.clear();
-                }
-            }, 2));
+public final class VelocityTracker {
+    private static final SynchronizedPool<VelocityTracker> sPool =
+            new SynchronizedPool<VelocityTracker>(2);
 
     private static final int ACTIVE_POINTER_ID = -1;
 
     private int mPtr;
     private final String mStrategy;
 
-    private VelocityTracker mNext;
-    private boolean mIsPooled;
-
     private static native int nativeInitialize(String strategy);
     private static native void nativeDispose(int ptr);
     private static native void nativeClear(int ptr);
@@ -73,7 +55,8 @@
      * @return Returns a new VelocityTracker.
      */
     static public VelocityTracker obtain() {
-        return sPool.acquire();
+        VelocityTracker instance = sPool.acquire();
+        return (instance != null) ? instance : new VelocityTracker(null);
     }
 
     /**
@@ -98,38 +81,11 @@
      */
     public void recycle() {
         if (mStrategy == null) {
+            clear();
             sPool.release(this);
         }
     }
 
-    /**
-     * @hide
-     */
-    public void setNextPoolable(VelocityTracker element) {
-        mNext = element;
-    }
-
-    /**
-     * @hide
-     */
-    public VelocityTracker getNextPoolable() {
-        return mNext;
-    }
-
-    /**
-     * @hide
-     */
-    public boolean isPooled() {
-        return mIsPooled;
-    }
-
-    /**
-     * @hide
-     */
-    public void setPooled(boolean isPooled) {
-        mIsPooled = isPooled;
-    }
-
     private VelocityTracker(String strategy) {
         mPtr = nativeInitialize(strategy);
         mStrategy = strategy;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 181fce9..23c3ad3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -52,10 +52,7 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
-import android.util.Pool;
-import android.util.Poolable;
-import android.util.PoolableManager;
-import android.util.Pools;
+import android.util.Pools.SynchronizedPool;
 import android.util.Property;
 import android.util.SparseArray;
 import android.util.TypedValue;
@@ -10748,7 +10745,7 @@
         // if we are not attached to our window
         final AttachInfo attachInfo = mAttachInfo;
         if (attachInfo != null) {
-            final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.acquire();
+            final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
             info.target = this;
             info.left = left;
             info.top = top;
@@ -10797,7 +10794,7 @@
         // if we are not attached to our window
         final AttachInfo attachInfo = mAttachInfo;
         if (attachInfo != null) {
-            final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.acquire();
+            final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.obtain();
             info.target = this;
             info.left = left;
             info.top = top;
@@ -17696,25 +17693,11 @@
          * POOL_LIMIT objects that get reused. This reduces memory allocations
          * whenever possible.
          */
-        static class InvalidateInfo implements Poolable<InvalidateInfo> {
+        static class InvalidateInfo {
             private static final int POOL_LIMIT = 10;
-            private static final Pool<InvalidateInfo> sPool = Pools.synchronizedPool(
-                    Pools.finitePool(new PoolableManager<InvalidateInfo>() {
-                        public InvalidateInfo newInstance() {
-                            return new InvalidateInfo();
-                        }
 
-                        public void onAcquired(InvalidateInfo element) {
-                        }
-
-                        public void onReleased(InvalidateInfo element) {
-                            element.target = null;
-                        }
-                    }, POOL_LIMIT)
-            );
-
-            private InvalidateInfo mNext;
-            private boolean mIsPooled;
+            private static final SynchronizedPool<InvalidateInfo> sPool =
+                    new SynchronizedPool<InvalidateInfo>(POOL_LIMIT);
 
             View target;
 
@@ -17723,29 +17706,15 @@
             int right;
             int bottom;
 
-            public void setNextPoolable(InvalidateInfo element) {
-                mNext = element;
+            public static InvalidateInfo obtain() {
+                InvalidateInfo instance = sPool.acquire();
+                return (instance != null) ? instance : new InvalidateInfo();
             }
 
-            public InvalidateInfo getNextPoolable() {
-                return mNext;
-            }
-
-            static InvalidateInfo acquire() {
-                return sPool.acquire();
-            }
-
-            void release() {
+            public void recycle() {
+                target = null;
                 sPool.release(this);
             }
-
-            public boolean isPooled() {
-                return mIsPooled;
-            }
-
-            public void setPooled(boolean isPooled) {
-                mIsPooled = isPooled;
-            }
         }
 
         final IWindowSession mSession;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fbaec71..d4b80ff 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2873,7 +2873,7 @@
             case MSG_INVALIDATE_RECT:
                 final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj;
                 info.target.invalidate(info.left, info.top, info.right, info.bottom);
-                info.release();
+                info.recycle();
                 break;
             case MSG_IME_FINISHED_EVENT:
                 handleImeFinishedEvent(msg.arg1, msg.arg2 != 0);
@@ -4488,7 +4488,7 @@
                     AttachInfo.InvalidateInfo info = mViewRects.get(i);
                     if (info.target == view) {
                         mViewRects.remove(i);
-                        info.release();
+                        info.recycle();
                     }
                 }
 
@@ -4529,7 +4529,7 @@
             for (int i = 0; i < viewRectCount; i++) {
                 final View.AttachInfo.InvalidateInfo info = mTempViewRects[i];
                 info.target.invalidate(info.left, info.top, info.right, info.bottom);
-                info.release();
+                info.recycle();
             }
         }
 
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index ea50e2e..f2d2c65 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -38,10 +38,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
-import android.util.Pool;
-import android.util.Poolable;
-import android.util.PoolableManager;
-import android.util.Pools;
+import android.util.Pools.SynchronizedPool;
 import android.view.Gravity;
 import android.view.RemotableViewMethod;
 import android.view.View;
@@ -604,33 +601,20 @@
         }
     }
 
-    private static class RefreshData implements Poolable<RefreshData> {
+    private static class RefreshData {
+        private static final int POOL_MAX = 24;
+        private static final SynchronizedPool<RefreshData> sPool =
+                new SynchronizedPool<RefreshData>(POOL_MAX);
+
         public int id;
         public int progress;
         public boolean fromUser;
-        
-        private RefreshData mNext;
-        private boolean mIsPooled;
-        
-        private static final int POOL_MAX = 24;
-        private static final Pool<RefreshData> sPool = Pools.synchronizedPool(
-                Pools.finitePool(new PoolableManager<RefreshData>() {
-                    @Override
-                    public RefreshData newInstance() {
-                        return new RefreshData();
-                    }
-
-                    @Override
-                    public void onAcquired(RefreshData element) {
-                    }
-
-                    @Override
-                    public void onReleased(RefreshData element) {
-                    }
-                }, POOL_MAX));
 
         public static RefreshData obtain(int id, int progress, boolean fromUser) {
             RefreshData rd = sPool.acquire();
+            if (rd == null) {
+                rd = new RefreshData();
+            }
             rd.id = id;
             rd.progress = progress;
             rd.fromUser = fromUser;
@@ -640,28 +624,8 @@
         public void recycle() {
             sPool.release(this);
         }
-
-        @Override
-        public void setNextPoolable(RefreshData element) {
-            mNext = element;
-        }
-
-        @Override
-        public RefreshData getNextPoolable() {
-            return mNext;
-        }
-
-        @Override
-        public boolean isPooled() {
-            return mIsPooled;
-        }
-
-        @Override
-        public void setPooled(boolean isPooled) {
-            mIsPooled = isPooled;
-        }
     }
-    
+
     private synchronized void doRefreshProgress(int id, int progress, boolean fromUser,
             boolean callBackToApp) {
         float scale = mMax > 0 ? (float) progress / (float) mMax : 0;
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 3d1b6b3..83b6a00 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -30,10 +30,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.util.Pool;
-import android.util.Poolable;
-import android.util.PoolableManager;
-import android.util.Pools;
+import android.util.Pools.SimplePool;
 import android.util.SparseArray;
 import android.view.Gravity;
 import android.view.View;
@@ -1631,7 +1628,7 @@
          *
          * A node with no dependent is considered a root of the graph.
          */
-        static class Node implements Poolable<Node> {
+        static class Node {
             /**
              * The view representing this node in the layout.
              */
@@ -1654,43 +1651,14 @@
             // The pool is static, so all nodes instances are shared across
             // activities, that's why we give it a rather high limit
             private static final int POOL_LIMIT = 100;
-            private static final Pool<Node> sPool = Pools.synchronizedPool(
-                    Pools.finitePool(new PoolableManager<Node>() {
-                        public Node newInstance() {
-                            return new Node();
-                        }
-
-                        public void onAcquired(Node element) {
-                        }
-
-                        public void onReleased(Node element) {
-                        }
-                    }, POOL_LIMIT)
-            );
-
-            private Node mNext;
-            private boolean mIsPooled;
-
-            public void setNextPoolable(Node element) {
-                mNext = element;
-            }
-
-            public Node getNextPoolable() {
-                return mNext;
-            }
-
-            public boolean isPooled() {
-                return mIsPooled;
-            }
-
-            public void setPooled(boolean isPooled) {
-                mIsPooled = isPooled;
-            }
+            private static final SimplePool<Node> sPool = new SimplePool<Node>(POOL_LIMIT);
 
             static Node acquire(View view) {
-                final Node node = sPool.acquire();
+                Node node = sPool.acquire();
+                if (node == null) {
+                    node = new Node();
+                }
                 node.view = view;
-
                 return node;
             }