Merge "Propagate first call to DrawableContainer.setAlpha() to children"
diff --git a/api/current.txt b/api/current.txt
index 241c540..2c22472 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10338,7 +10338,6 @@
     ctor public BitmapDrawable(android.content.res.Resources, java.lang.String);
     ctor public deprecated BitmapDrawable(java.io.InputStream);
     ctor public BitmapDrawable(android.content.res.Resources, java.io.InputStream);
-    method public void draw(android.graphics.Canvas);
     method public final android.graphics.Bitmap getBitmap();
     method public final android.graphics.drawable.Drawable.ConstantState getConstantState();
     method public int getGravity();
@@ -10364,7 +10363,6 @@
 
   public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public ClipDrawable(android.graphics.drawable.Drawable, int, int);
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -10378,7 +10376,6 @@
   public class ColorDrawable extends android.graphics.drawable.Drawable {
     ctor public ColorDrawable();
     ctor public ColorDrawable(int);
-    method public void draw(android.graphics.Canvas);
     method public int getColor();
     method public int getOpacity();
     method public void setAlpha(int);
@@ -10397,7 +10394,7 @@
     method public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream, java.lang.String);
     method public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
-    method public abstract void draw(android.graphics.Canvas);
+    method public void draw(android.graphics.Canvas);
     method public int getAlpha();
     method public final android.graphics.Rect getBounds();
     method public android.graphics.drawable.Drawable.Callback getCallback();
@@ -10421,6 +10418,7 @@
     method public void jumpToCurrentState();
     method public android.graphics.drawable.Drawable mutate();
     method protected void onBoundsChange(android.graphics.Rect);
+    method protected void onDraw(android.graphics.Canvas);
     method protected boolean onLevelChange(int);
     method protected boolean onStateChange(int[]);
     method public static int resolveOpacity(int, int);
@@ -10456,7 +10454,6 @@
 
   public class DrawableContainer extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public DrawableContainer();
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -10497,7 +10494,6 @@
   public class GradientDrawable extends android.graphics.drawable.Drawable {
     ctor public GradientDrawable();
     ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]);
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
     method public boolean onStateChange(int[]);
@@ -10544,7 +10540,6 @@
   public class InsetDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public InsetDrawable(android.graphics.drawable.Drawable, int);
     ctor public InsetDrawable(android.graphics.drawable.Drawable, int, int, int, int);
-    method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
@@ -10556,7 +10551,6 @@
 
   public class LayerDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public LayerDrawable(android.graphics.drawable.Drawable[]);
-    method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable findDrawableByLayerId(int);
     method public android.graphics.drawable.Drawable getDrawable(int);
     method public int getId(int);
@@ -10587,7 +10581,6 @@
     ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.Bitmap, byte[], android.graphics.Rect, java.lang.String);
     ctor public deprecated NinePatchDrawable(android.graphics.NinePatch);
     ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.NinePatch);
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.Paint getPaint();
     method public void setAlpha(int);
@@ -10606,7 +10599,6 @@
 
   public class PictureDrawable extends android.graphics.drawable.Drawable {
     ctor public PictureDrawable(android.graphics.Picture);
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.Picture getPicture();
     method public void setAlpha(int);
@@ -10620,7 +10612,6 @@
 
   public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public RotateDrawable();
-    method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
@@ -10632,7 +10623,6 @@
 
   public class ScaleDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public ScaleDrawable(android.graphics.drawable.Drawable, int, float, float);
-    method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
     method public int getOpacity();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
@@ -10645,7 +10635,6 @@
   public class ShapeDrawable extends android.graphics.drawable.Drawable {
     ctor public ShapeDrawable();
     ctor public ShapeDrawable(android.graphics.drawable.shapes.Shape);
-    method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.Paint getPaint();
     method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory();
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 56bfdf8..d5476fc 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -181,7 +181,18 @@
 
     /**
      * <p>List of AF modes that can be
-     * selected</p>
+     * selected with {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}.</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * <p>Not all the auto-focus modes may be supported by a
+     * given camera device. This entry lists the valid modes for
+     * {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} for this camera device.</p>
+     * <p>All camera devices will support OFF mode, and all camera devices with
+     * adjustable focuser units (<code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>)
+     * will support AUTO mode.</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      */
     public static final Key<byte[]> CONTROL_AF_AVAILABLE_MODES =
             new Key<byte[]>("android.control.afAvailableModes", byte[].class);
@@ -251,9 +262,11 @@
 
     /**
      * <p>List of supported aperture
-     * values</p>
-     * <p>If variable aperture not available, only setting
-     * should be for the fixed aperture</p>
+     * values.</p>
+     * <p>If the camera device doesn't support variable apertures,
+     * listed value will be the fixed aperture.</p>
+     * <p>If the camera device supports variable apertures, the aperture value
+     * in this list will be sorted in ascending order.</p>
      */
     public static final Key<float[]> LENS_INFO_AVAILABLE_APERTURES =
             new Key<float[]>("android.lens.info.availableApertures", float[].class);
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 58e9323..64d055f 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -318,8 +318,8 @@
      * device, along with android.flash.* fields, if there's
      * a flash unit for this camera device.</p>
      *
-     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see CaptureRequest#CONTROL_AE_MODE
      */
@@ -334,8 +334,8 @@
      * application has control over the various
      * android.flash.* fields.</p>
      *
-     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see CaptureRequest#CONTROL_AE_MODE
      */
@@ -351,8 +351,8 @@
      * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
      * STILL_CAPTURE</p>
      *
-     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureRequest#CONTROL_AE_MODE
      */
     public static final int CONTROL_AE_MODE_ON_AUTO_FLASH = 2;
@@ -367,8 +367,8 @@
      * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
      * STILL_CAPTURE</p>
      *
-     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureRequest#CONTROL_AE_MODE
      */
     public static final int CONTROL_AE_MODE_ON_ALWAYS_FLASH = 3;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 9ba3eea..d642076 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -399,9 +399,9 @@
      * issues. The {@link CaptureResult#STATISTICS_SCENE_FLICKER android.statistics.sceneFlicker} key can assist
      * the application in this.</p>
      *
-     * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES
-     * @see CaptureResult#STATISTICS_SCENE_FLICKER
      * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureResult#STATISTICS_SCENE_FLICKER
+     * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES
      * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_AE_ANTIBANDING_MODE_OFF
      * @see #CONTROL_AE_ANTIBANDING_MODE_50HZ
@@ -453,12 +453,12 @@
      * fields for a given capture will be available in its
      * CaptureResult.</p>
      *
-     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
-     * @see CaptureRequest#SENSOR_FRAME_DURATION
-     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see CaptureRequest#FLASH_MODE
      * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see #CONTROL_AE_MODE_OFF
      * @see #CONTROL_AE_MODE_ON
      * @see #CONTROL_AE_MODE_ON_AUTO_FLASH
@@ -523,12 +523,11 @@
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
      * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
-     * <p>If lens is controlled by HAL auto-focus algorithm, the HAL should
-     * report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState} in
-     * result metadata.</p>
+     * <p>If the lens is controlled by the camera device auto-focus algorithm,
+     * the camera device will report the current AF status in android.control.afState
+     * in result metadata.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
-     * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -810,9 +809,27 @@
             new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
 
     /**
-     * <p>Size of the lens aperture</p>
-     * <p>Will not be supported on most devices. Can only
-     * pick from supported list</p>
+     * <p>The ratio of lens focal length to the effective
+     * aperture diameter.</p>
+     * <p>This will only be supported on the camera devices that
+     * have variable aperture lens. The aperture value can only be
+     * one of the values listed in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures}.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is OFF,
+     * this can be set along with {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and android.sensor.frameDuration
+     * to achieve manual exposure control.</p>
+     * <p>The requested aperture value may take several frames to reach the
+     * requested value; the camera device will report the current (intermediate)
+     * aperture size in capture result metadata while the aperture is changing.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of
+     * the ON modes, this will be overridden by the camera device
+     * auto-exposure algorithm, the overridden values are then provided
+     * back to the user in the corresponding result.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
     public static final Key<Float> LENS_APERTURE =
             new Key<Float>("android.lens.aperture", float.class);
@@ -979,8 +996,8 @@
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is CONTRAST_CURVE.</p>
      * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
      *
-     * @see CaptureRequest#TONEMAP_MODE
      * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_BLUE =
             new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -992,8 +1009,8 @@
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is CONTRAST_CURVE.</p>
      * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
      *
-     * @see CaptureRequest#TONEMAP_MODE
      * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_GREEN =
             new Key<float[]>("android.tonemap.curveGreen", float[].class);
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3b5d6b0..8e5af6d 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -195,12 +195,12 @@
      * fields for a given capture will be available in its
      * CaptureResult.</p>
      *
-     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
-     * @see CaptureRequest#SENSOR_FRAME_DURATION
-     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see CaptureRequest#FLASH_MODE
      * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see #CONTROL_AE_MODE_OFF
      * @see #CONTROL_AE_MODE_ON
      * @see #CONTROL_AE_MODE_ON_AUTO_FLASH
@@ -253,12 +253,11 @@
      * <p>Whether AF is currently enabled, and what
      * mode it is set to</p>
      * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO.</p>
-     * <p>If lens is controlled by HAL auto-focus algorithm, the HAL should
-     * report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState} in
-     * result metadata.</p>
+     * <p>If the lens is controlled by the camera device auto-focus algorithm,
+     * the camera device will report the current AF status in android.control.afState
+     * in result metadata.</p>
      *
      * @see CaptureRequest#CONTROL_MODE
-     * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -492,9 +491,27 @@
             new Key<android.hardware.camera2.Size>("android.jpeg.thumbnailSize", android.hardware.camera2.Size.class);
 
     /**
-     * <p>Size of the lens aperture</p>
-     * <p>Will not be supported on most devices. Can only
-     * pick from supported list</p>
+     * <p>The ratio of lens focal length to the effective
+     * aperture diameter.</p>
+     * <p>This will only be supported on the camera devices that
+     * have variable aperture lens. The aperture value can only be
+     * one of the values listed in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures}.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is OFF,
+     * this can be set along with {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and android.sensor.frameDuration
+     * to achieve manual exposure control.</p>
+     * <p>The requested aperture value may take several frames to reach the
+     * requested value; the camera device will report the current (intermediate)
+     * aperture size in capture result metadata while the aperture is changing.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of
+     * the ON modes, this will be overridden by the camera device
+     * auto-exposure algorithm, the overridden values are then provided
+     * back to the user in the corresponding result.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
     public static final Key<Float> LENS_APERTURE =
             new Key<Float>("android.lens.aperture", float.class);
@@ -782,8 +799,8 @@
      * image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p>
      * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
      *
-     * @see CaptureRequest#COLOR_CORRECTION_MODE
      * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
      * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
      */
     public static final Key<float[]> STATISTICS_LENS_SHADING_MAP =
@@ -845,8 +862,8 @@
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is CONTRAST_CURVE.</p>
      * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
      *
-     * @see CaptureRequest#TONEMAP_MODE
      * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_BLUE =
             new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -858,8 +875,8 @@
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is CONTRAST_CURVE.</p>
      * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
      *
-     * @see CaptureRequest#TONEMAP_MODE
      * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_GREEN =
             new Key<float[]>("android.tonemap.curveGreen", float[].class);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 90866d6..4d8975c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2104,16 +2104,17 @@
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
         mInLayout = true;
+        final int childCount = getChildCount();
         if (changed) {
-            int childCount = getChildCount();
             for (int i = 0; i < childCount; i++) {
                 getChildAt(i).forceLayout();
             }
             mRecycler.markChildrenDirty();
         }
 
-        if (mFastScroll != null && (mItemCount != mOldItemCount || mDataChanged)) {
-            mFastScroll.onItemCountChanged(mItemCount);
+        // TODO: Move somewhere sane. This doesn't belong in onLayout().
+        if (mFastScroll != null) {
+            mFastScroll.onItemCountChanged(childCount, mItemCount);
         }
 
         layoutChildren();
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 323d7c0..c0961fd 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -205,6 +205,9 @@
     private long mPendingDrag = -1;
     private int mScaledTouchSlop;
 
+    private int mOldItemCount;
+    private int mOldChildCount;
+
     /**
      * Used to delay hiding fast scroll decorations.
      */
@@ -227,6 +230,8 @@
 
     public FastScroller(AbsListView listView, int styleResId) {
         mList = listView;
+        mOldItemCount = listView.getCount();
+        mOldChildCount = listView.getChildCount();
 
         final Context context = listView.getContext();
         mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
@@ -258,7 +263,7 @@
         overlay.add(mSecondaryText);
 
         getSectionsFromIndexer();
-        updateLongList(listView.getChildCount(), listView.getCount());
+        updateLongList(mOldChildCount, mOldItemCount);
         setScrollbarPosition(listView.getVerticalScrollbarPosition());
         postAutoHide();
     }
@@ -484,20 +489,23 @@
         updateLayout();
     }
 
-    public void onItemCountChanged(int totalItemCount) {
-        final int visibleItemCount = mList.getChildCount();
-        final boolean hasMoreItems = totalItemCount - visibleItemCount > 0;
-        if (hasMoreItems && mState != STATE_DRAGGING) {
-            final int firstVisibleItem = mList.getFirstVisiblePosition();
-            setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
-        }
+    public void onItemCountChanged(int childCount, int itemCount) {
+        if (mOldItemCount != itemCount || mOldChildCount != childCount) {
+            mOldItemCount = itemCount;
+            mOldChildCount = childCount;
 
-        updateLongList(visibleItemCount, totalItemCount);
+            final boolean hasMoreItems = itemCount - childCount > 0;
+            if (hasMoreItems && mState != STATE_DRAGGING) {
+                final int firstVisibleItem = mList.getFirstVisiblePosition();
+                setThumbPos(getPosFromItemCount(firstVisibleItem, childCount, itemCount));
+            }
+
+            updateLongList(childCount, itemCount);
+        }
     }
 
-    private void updateLongList(int visibleItemCount, int totalItemCount) {
-        final boolean longList = visibleItemCount > 0
-                && totalItemCount / visibleItemCount >= MIN_PAGES;
+    private void updateLongList(int childCount, int itemCount) {
+        final boolean longList = childCount > 0 && itemCount / childCount >= MIN_PAGES;
         if (mLongList != longList) {
             mLongList = longList;
 
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 9360558..52e5b5b 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -456,7 +456,7 @@
     }
 
     @Override
-    public void draw(Canvas canvas) {
+    protected void onDraw(Canvas canvas) {
         Bitmap bitmap = mBitmap;
         if (bitmap != null) {
             final BitmapState state = mBitmapState;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index b8365aa..cfb1983 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -39,6 +39,9 @@
 import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.DisplayList;
+import android.view.HardwareCanvas;
+import android.view.HardwareRenderer;
 import android.view.View;
 
 import java.io.IOException;
@@ -139,16 +142,96 @@
     private Rect mBounds = ZERO_BOUNDS_RECT;  // lazily becomes a new Rect()
     private WeakReference<Callback> mCallback = null;
     private boolean mVisible = true;
+    private DisplayList mDisplayList;
 
     private int mLayoutDirection;
 
     /**
      * Draw in its bounds (set via setBounds) respecting optional effects such
      * as alpha (set via setAlpha) and color filter (set via setColorFilter).
+     * <p>
+     * Overriding this method will prevent caching optimizations. To enable
+     * optimizations, override {@link #onDraw} instead.
      *
      * @param canvas The canvas to draw into
      */
-    public abstract void draw(Canvas canvas);
+    public void draw(Canvas canvas) {
+        if (canvas != null && canvas.isHardwareAccelerated()) {
+            final HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
+            final DisplayList displayList = getDisplayList(hardwareCanvas);
+            if (displayList != null) {
+                final int restoreCount = hardwareCanvas.save(Canvas.MATRIX_SAVE_FLAG);
+                hardwareCanvas.translate(mBounds.left, mBounds.top);
+                hardwareCanvas.drawDisplayList(displayList);
+                hardwareCanvas.restoreToCount(restoreCount);
+                return;
+            }
+        }
+
+        onDraw(canvas);
+    }
+
+    /**
+     * Draw in its bounds (set via setBounds) respecting optional effects such
+     * as alpha (set via setAlpha) and color filter (set via setColorFilter).
+     * <p>
+     * Overriding this method, rather than {@link #draw}, enables caching
+     * optimizations that avoid re-drawing when unnecessary.
+     *
+     * @param canvas The canvas to draw into
+     */
+    protected void onDraw(Canvas canvas) {
+        throw new UnsupportedOperationException(
+                "Drawable subclasses must implement either draw or onDraw");
+    }
+
+    /**
+     * Gets a display list that can be used to draw this drawable again without
+     * invoking its draw method.
+     *
+     * @param hardwareCanvas The hardware canvas.
+     * @return A DisplayList ready to replay, or null if caching is not enabled.
+     * @hide
+     */
+    private DisplayList getDisplayList(HardwareCanvas hardwareCanvas) {
+        DisplayList displayList = mDisplayList;
+        if (displayList != null && displayList.isValid()) {
+            // Note: This code assumes that the display list previously generated
+            // is compatible with the given hardware canvas.  That might not be true
+            // if we start using multiple different types of hardware canvas
+            // in the system someday.
+            return displayList;
+        }
+
+        displayList = DisplayList.create(getClass().getName());
+        mDisplayList = displayList;
+
+        final Rect bounds = mBounds;
+        final int width = bounds.width();
+        final int height = bounds.height();
+        final HardwareCanvas canvas = displayList.start(width, height);
+        canvas.onPreDraw(null);
+
+        // Draw the display list with origin (0,0) so that if the position
+        // changes then we can translate without recreating the display list.
+        final int restoreCount = canvas.save();
+        try {
+            canvas.translate(-bounds.left, -bounds.top);
+            onDraw(canvas);
+        } finally {
+            canvas.restoreToCount(restoreCount);
+            canvas.onPostDraw();
+            displayList.end();
+        }
+
+        displayList.setLeftTopRightBottom(0, 0, width, height);
+        displayList.setClipToBounds(false);
+        return displayList;
+    }
+
+    private void invalidateDisplayList() {
+        mDisplayList = null;
+    }
 
     /**
      * Specify a bounding rectangle for the Drawable. This is where the drawable
@@ -163,10 +246,11 @@
 
         if (oldBounds.left != left || oldBounds.top != top ||
                 oldBounds.right != right || oldBounds.bottom != bottom) {
-            if (!oldBounds.isEmpty()) {
-                // first invalidate the previous bounds
-                invalidateSelf();
+            if (oldBounds.right - oldBounds.left != right - left
+                    || oldBounds.bottom - oldBounds.top != bottom - top) {
+                invalidateDisplayList();
             }
+
             mBounds.set(left, top, right, bottom);
             onBoundsChange(mBounds);
         }
@@ -354,6 +438,8 @@
      * @see #setCallback(android.graphics.drawable.Drawable.Callback) 
      */
     public void invalidateSelf() {
+        invalidateDisplayList();
+
         final Callback callback = getCallback();
         if (callback != null) {
             callback.invalidateDrawable(this);
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 75184e0..6a9454c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -472,7 +472,7 @@
     }
 
     @Override
-    public void draw(Canvas canvas) {
+    protected void onDraw(Canvas canvas) {
         if (!ensureValidRect()) {
             // nothing to draw
             return;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 515d3c1..ee64d7a 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -223,7 +223,7 @@
     }
 
     @Override
-    public void draw(Canvas canvas) {
+    protected void onDraw(Canvas canvas) {
         final Rect bounds = getBounds();
         final boolean needsMirroring = needsMirroring();
         if (needsMirroring) {
diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java
index cb2d8f6..2118b23 100644
--- a/graphics/java/android/graphics/drawable/PictureDrawable.java
+++ b/graphics/java/android/graphics/drawable/PictureDrawable.java
@@ -60,7 +60,7 @@
     }
     
     @Override
-    public void draw(Canvas canvas) {
+    protected void onDraw(Canvas canvas) {
         if (mPicture != null) {
             Rect bounds = getBounds();
             canvas.save();
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 93f2dc6..9ca3bbf 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -210,7 +210,7 @@
     }
 
     @Override
-    public void draw(Canvas canvas) {
+    protected void onDraw(Canvas canvas) {
         Rect r = getBounds();
         Paint paint = mShapeState.mPaint;
 
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 53afb6b..0947d3e 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -179,7 +179,7 @@
     /**
      * Audio session ID
      */
-    private int mSessionId = 0;
+    private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
 
     //---------------------------------------------------------
     // Constructor, Finalize
@@ -224,7 +224,7 @@
 
         // native initialization
         int[] session = new int[1];
-        session[0] = 0;
+        session[0] = AudioSystem.AUDIO_SESSION_ALLOCATE;
         //TODO: update native initialization when information about hardware init failure
         //      due to capture device already open is available.
         int initResult = native_setup( new WeakReference<AudioRecord>(this),
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 661b0fd..9c67bae 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -103,6 +103,9 @@
     /** @deprecated */
     @Deprecated public static final int ROUTE_ALL               = 0xFFFFFFFF;
 
+    // Keep in sync with system/core/include/system/audio.h
+    public static final int AUDIO_SESSION_ALLOCATE = 0;
+
     /*
      * Checks whether the specified stream type is active.
      *
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 8756806..56e1d4a 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -211,7 +211,7 @@
     /**
      * Audio session ID
      */
-    private int mSessionId = 0;
+    private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
 
 
     //--------------------------------
@@ -263,7 +263,7 @@
             int bufferSizeInBytes, int mode)
     throws IllegalArgumentException {
         this(streamType, sampleRateInHz, channelConfig, audioFormat,
-                bufferSizeInBytes, mode, 0 /*session*/);
+                bufferSizeInBytes, mode, AudioSystem.AUDIO_SESSION_ALLOCATE);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index ff79f04..bd5e5e8 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -21,6 +21,8 @@
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
+import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.ImageView;
@@ -67,9 +69,15 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Window window = getWindow();
-        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-        window.getAttributes().privateFlags |=
+        window.setGravity(Gravity.TOP);
+        WindowManager.LayoutParams lp = window.getAttributes();
+        // Offset from the top
+        lp.y = getContext().getResources().getDimensionPixelOffset(
+                com.android.internal.R.dimen.volume_panel_top);
+        lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+        lp.privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        window.setAttributes(lp);
         window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         window.requestFeature(Window.FEATURE_NO_TITLE);
 
@@ -108,4 +116,13 @@
         mHandler.removeCallbacks(mDismissDialogRunnable);
     }
 
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+            dismiss();
+        }
+        return super.onKeyDown(keyCode, event);
+    }
 }
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index 5ab18f7..a1f2287 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -188,6 +188,13 @@
     public void bindAllocation(Allocation va, int slot) {
         mRS.validate();
         if (va != null) {
+            if (mRS.getApplicationContext().getApplicationInfo().targetSdkVersion >= 20) {
+                final Type t = va.mType;
+                if (t.hasMipmaps() || t.hasFaces() || (t.getY() != 0) || (t.getZ() != 0)) {
+                    throw new RSIllegalArgumentException(
+                        "API 20+ only allows simple 1D allocations to be used with bind.");
+                }
+            }
             mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot);
         } else {
             mRS.nScriptBindAllocation(getID(mRS), 0, slot);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 4e97700..98bb357 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -487,7 +487,7 @@
     void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) {
         if (task != null && task.removeActivity(this)) {
             if (task != newTask) {
-                mStackSupervisor.removeTask(task);
+                task.stack.removeTask(task);
             } else {
                 Slog.d(TAG, "!!! REMOVE THIS LOG !!! setTask: nearly removed stack=" +
                         (newTask == null ? null : newTask.stack));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ca6a649..287765d 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2711,7 +2711,7 @@
         r.finishLaunchTickingLocked();
     }
 
-    final void removeActivityFromHistoryLocked(ActivityRecord r) {
+    private void removeActivityFromHistoryLocked(ActivityRecord r) {
         finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
         r.makeFinishing();
         if (DEBUG_ADD_REMOVE) {
@@ -2726,7 +2726,7 @@
             if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) {
                 mStackSupervisor.moveHomeToTop();
             }
-            mStackSupervisor.removeTask(task);
+            removeTask(task);
         }
         r.takeFromHistory();
         removeTimeoutsForActivityLocked(r);
@@ -3633,14 +3633,28 @@
         return starting;
     }
 
-    boolean removeTask(TaskRecord task) {
+    void removeTask(TaskRecord task) {
+        mWindowManager.removeTask(task.taskId);
+        final ActivityRecord r = mResumedActivity;
+        if (r != null && r.task == task) {
+            mResumedActivity = null;
+        }
+
         final int taskNdx = mTaskHistory.indexOf(task);
         final int topTaskNdx = mTaskHistory.size() - 1;
         if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
             mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
         }
         mTaskHistory.remove(task);
-        return mTaskHistory.isEmpty();
+
+        if (mTaskHistory.isEmpty()) {
+            if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
+            if (isOnHomeDisplay()) {
+                mStackSupervisor.moveHomeStack(!isHomeStack());
+            }
+            mStacks.remove(this);
+            mStacks.add(0, this);
+        }
     }
 
     TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, boolean toTop) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 7c3e474..6ab59a7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -364,25 +364,6 @@
         return mCurTaskId;
     }
 
-    void removeTask(TaskRecord task) {
-        mWindowManager.removeTask(task.taskId);
-        final ActivityStack stack = task.stack;
-        final ActivityRecord r = stack.mResumedActivity;
-        if (r != null && r.task == task) {
-            stack.mResumedActivity = null;
-        }
-        if (stack.removeTask(task) && !stack.isHomeStack()) {
-            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
-            stack.mActivityContainer.detachLocked();
-            final int stackId = stack.mStackId;
-            final int nextStackId = mWindowManager.removeStack(stackId);
-            // TODO: Perhaps we need to let the ActivityManager determine the next focus...
-            if (stack.isOnHomeDisplay()) {
-                mFocusedStack = getStack(nextStackId);
-            }
-        }
-    }
-
     ActivityRecord resumedAppLocked() {
         ActivityStack stack = getFocusedStack();
         if (stack == null) {
@@ -2184,7 +2165,7 @@
             Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId);
             return;
         }
-        removeTask(task);
+        task.stack.removeTask(task);
         stack.addTask(task, toTop);
         mWindowManager.addTask(taskId, stackId, toTop);
         resumeTopActivitiesLocked();
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ef245f9..aa6b0c9 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -191,14 +191,18 @@
     }
 
     /**
-     * Delete a Task from this stack. If it is the last Task in the stack, remove this stack from
-     * its parent StackBox and merge the parent.
+     * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
+     * back.
      * @param task The Task to delete.
      */
     void removeTask(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
         mTasks.remove(task);
         mDisplayContent.removeTask(task);
+        if (mTasks.isEmpty()) {
+            mDisplayContent.moveStack(this, false);
+        }
+        mDisplayContent.layoutNeeded = true;
     }
 
     int remove() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f3b040e..7889247 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4836,23 +4836,6 @@
         }
     }
 
-    public int removeStack(int stackId) {
-        synchronized (mWindowMap) {
-            final TaskStack stack = mStackIdToStack.get(stackId);
-            if (stack != null) {
-                mStackIdToStack.delete(stackId);
-                int nextStackId = stack.remove();
-                stack.getDisplayContent().layoutNeeded = true;
-                requestTraversalLocked();
-                if (nextStackId > HOME_STACK_ID) {
-                    return nextStackId;
-                }
-            }
-            if (DEBUG_STACK) Slog.i(TAG, "removeStack: could not find stackId=" + stackId);
-        }
-        return HOME_STACK_ID;
-    }
-
     public void removeTask(int taskId) {
         synchronized (mWindowMap) {
             Task task = mTaskIdToTask.get(taskId);