Fix issue #2116977: buttons are huge and bent

Now that we are using preloaded drawables in compatibilty mode, when
constructing them from their constant state we need to set the new
drawable's target density appropriately.

Change-Id: I3665cbea09d38b9ac5f45f8c380dc8641f86b266
diff --git a/api/current.xml b/api/current.xml
index 04823e5..ee82e00 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -63352,7 +63352,7 @@
  type="android.graphics.drawable.BitmapDrawable"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="filepath" type="java.lang.String">
@@ -63365,6 +63365,30 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="res" type="android.content.res.Resources">
+</parameter>
+<parameter name="filepath" type="java.lang.String">
+</parameter>
+</constructor>
+<constructor name="BitmapDrawable"
+ type="android.graphics.drawable.BitmapDrawable"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="is" type="java.io.InputStream">
+</parameter>
+</constructor>
+<constructor name="BitmapDrawable"
+ type="android.graphics.drawable.BitmapDrawable"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="res" type="android.content.res.Resources">
+</parameter>
 <parameter name="is" type="java.io.InputStream">
 </parameter>
 </constructor>
@@ -64543,6 +64567,19 @@
  visibility="public"
 >
 </method>
+<method name="newDrawable"
+ return="android.graphics.drawable.Drawable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="res" type="android.content.res.Resources">
+</parameter>
+</method>
 </class>
 <class name="DrawableContainer"
  extends="android.graphics.drawable.Drawable"
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 8730288..8f7e8ca 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -395,7 +395,7 @@
             Drawable.ConstantState cachedBg = mBackgroundsCache.get(backgroundColor);
             if (cachedBg != null) {
                 if (DBG) Log.d(LOG_TAG, "Background cache hit for color " + backgroundColor);
-                return cachedBg.newDrawable();
+                return cachedBg.newDrawable(mProviderContext.getResources());
             }
             if (DBG) Log.d(LOG_TAG, "Creating new background for color " + backgroundColor);
             ColorDrawable transparent = new ColorDrawable(0);
@@ -572,7 +572,7 @@
         Drawable.ConstantState cached = mOutsideDrawablesCache.get(drawableId);
         if (cached != null) {
             if (DBG) Log.d(LOG_TAG, "Found icon in cache: " + drawableId);
-            return cached.newDrawable();
+            return cached.newDrawable(mProviderContext.getResources());
         }
 
         Drawable drawable = null;
@@ -663,7 +663,7 @@
         // Using containsKey() since we also store null values.
         if (mOutsideDrawablesCache.containsKey(componentIconKey)) {
             Drawable.ConstantState cached = mOutsideDrawablesCache.get(componentIconKey);
-            return cached == null ? null : cached.newDrawable();
+            return cached == null ? null : cached.newDrawable(mProviderContext.getResources());
         }
         // Then try the activity or application icon
         Drawable drawable = getActivityIcon(component);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 9d370fc..3796201 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1662,7 +1662,7 @@
 
         Drawable.ConstantState cs = sPreloadedDrawables.get(key);
         if (cs != null) {
-            dr = cs.newDrawable();
+            dr = cs.newDrawable(this);
         } else {
             if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
                     value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
@@ -1743,7 +1743,7 @@
                     //Log.i(TAG, "Returning cached drawable @ #" +
                     //        Integer.toHexString(((Integer)key).intValue())
                     //        + " in " + this + ": " + entry);
-                    return entry.newDrawable();
+                    return entry.newDrawable(this);
                 }
                 else {  // our entry has been purged
                     mDrawableCache.delete(key);
diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java
index b81c2b3..bba2ee2 100644
--- a/core/java/com/android/internal/view/menu/IconMenuView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuView.java
@@ -282,7 +282,9 @@
         itemView.setIconMenuView(this);
         
         // Apply the background to the item view
-        itemView.setBackgroundDrawable(mItemBackground.getConstantState().newDrawable());
+        itemView.setBackgroundDrawable(
+                mItemBackground.getConstantState().newDrawable(
+                        getContext().getResources()));
 
         // This class is the invoker for all its item views 
         itemView.setItemInvoker(this);
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index ac96f20..58206d4 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -45,11 +45,11 @@
     private boolean mRunning;
 
     public AnimatedRotateDrawable() {
-        this(null);
+        this(null, null);
     }
 
-    private AnimatedRotateDrawable(AnimatedRotateState rotateState) {
-        mState = new AnimatedRotateState(rotateState, this);
+    private AnimatedRotateDrawable(AnimatedRotateState rotateState, Resources res) {
+        mState = new AnimatedRotateState(rotateState, this, res);
         init();
     }
 
@@ -296,9 +296,14 @@
         private boolean mCanConstantState;
         private boolean mCheckedConstantState;        
 
-        public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner) {
+        public AnimatedRotateState(AnimatedRotateState source, AnimatedRotateDrawable owner,
+                Resources res) {
             if (source != null) {
-                mDrawable = source.mDrawable.getConstantState().newDrawable();
+                if (res != null) {
+                    mDrawable = source.mDrawable.getConstantState().newDrawable(res);
+                } else {
+                    mDrawable = source.mDrawable.getConstantState().newDrawable();
+                }
                 mDrawable.setCallback(owner);
                 mPivotXRel = source.mPivotXRel;
                 mPivotX = source.mPivotX;
@@ -312,7 +317,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new AnimatedRotateDrawable(this);
+            return new AnimatedRotateDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new AnimatedRotateDrawable(this, res);
         }
         
         @Override
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 68718c9..fdc4c92 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -77,7 +77,7 @@
     private boolean mMutated;
 
     public AnimationDrawable() {
-        this(null);
+        this(null, null);
     }
 
     @Override
@@ -297,8 +297,9 @@
         private int[] mDurations;
         private boolean mOneShot;
 
-        AnimationState(AnimationState orig, AnimationDrawable owner) {
-            super(orig, owner);
+        AnimationState(AnimationState orig, AnimationDrawable owner,
+                Resources res) {
+            super(orig, owner, res);
 
             if (orig != null) {
                 mDurations = orig.mDurations;
@@ -311,7 +312,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new AnimationDrawable(this);
+            return new AnimationDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new AnimationDrawable(this, res);
         }
 
         public void addFrame(Drawable dr, int dur) {
@@ -330,8 +336,8 @@
         }
     }
 
-    private AnimationDrawable(AnimationState state) {
-        AnimationState as = new AnimationState(state, this);
+    private AnimationDrawable(AnimationState state, Resources res) {
+        AnimationState as = new AnimationState(state, this, res);
         mAnimationState = as;
         setConstantState(as);
         if (state != null) {
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 30cef67..e82f297 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -60,15 +60,15 @@
             Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
     private BitmapState mBitmapState;
     private Bitmap mBitmap;
+    private int mTargetDensity;
+
     private final Rect mDstRect = new Rect();   // Gravity.apply() sets this
 
     private boolean mApplyGravity;
     private boolean mRebuildShader;
     private boolean mMutated;
     
-    private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
-
-    // These are scaled to match the target density.
+     // These are scaled to match the target density.
     private int mBitmapWidth;
     private int mBitmapHeight;
     
@@ -88,10 +88,7 @@
      */
     public BitmapDrawable(Resources res) {
         mBitmapState = new BitmapState((Bitmap) null);
-        if (res != null) {
-            setTargetDensity(res.getDisplayMetrics());
-            mBitmapState.mTargetDensity = mTargetDensity;
-        }
+        mBitmapState.mTargetDensity = mTargetDensity;
     }
 
     /**
@@ -101,7 +98,7 @@
      */
     @Deprecated
     public BitmapDrawable(Bitmap bitmap) {
-        this(new BitmapState(bitmap));
+        this(new BitmapState(bitmap), null);
     }
 
     /**
@@ -109,22 +106,51 @@
      * the display metrics of the resources.
      */
     public BitmapDrawable(Resources res, Bitmap bitmap) {
-        this(new BitmapState(bitmap));
-        if (res != null) {
-            setTargetDensity(res.getDisplayMetrics());
-            mBitmapState.mTargetDensity = mTargetDensity;
-        }
+        this(new BitmapState(bitmap), res);
+        mBitmapState.mTargetDensity = mTargetDensity;
     }
 
+    /**
+     * Create a drawable by opening a given file path and decoding the bitmap.
+     * @deprecated Use {@link #BitmapDrawable(Resources, String)} to ensure
+     * that the drawable has correctly set its target density.
+     */
     public BitmapDrawable(String filepath) {
-        this(new BitmapState(BitmapFactory.decodeFile(filepath)));
+        this(new BitmapState(BitmapFactory.decodeFile(filepath)), null);
         if (mBitmap == null) {
             android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath);
         }
     }
 
+    /**
+     * Create a drawable by opening a given file path and decoding the bitmap.
+     */
+    public BitmapDrawable(Resources res, String filepath) {
+        this(new BitmapState(BitmapFactory.decodeFile(filepath)), null);
+        mBitmapState.mTargetDensity = mTargetDensity;
+        if (mBitmap == null) {
+            android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath);
+        }
+    }
+
+    /**
+     * Create a drawable by decoding a bitmap from the given input stream.
+     * @deprecated Use {@link #BitmapDrawable(Resources, java.io.InputStream)} to ensure
+     * that the drawable has correctly set its target density.
+     */
     public BitmapDrawable(java.io.InputStream is) {
-        this(new BitmapState(BitmapFactory.decodeStream(is)));
+        this(new BitmapState(BitmapFactory.decodeStream(is)), null);
+        if (mBitmap == null) {
+            android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is);
+        }
+    }
+
+    /**
+     * Create a drawable by decoding a bitmap from the given input stream.
+     */
+    public BitmapDrawable(Resources res, java.io.InputStream is) {
+        this(new BitmapState(BitmapFactory.decodeStream(is)), null);
+        mBitmapState.mTargetDensity = mTargetDensity;
         if (mBitmap == null) {
             android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is);
         }
@@ -425,7 +451,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new BitmapDrawable(this);
+            return new BitmapDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new BitmapDrawable(this, res);
         }
         
         @Override
@@ -434,9 +465,15 @@
         }
     }
 
-    private BitmapDrawable(BitmapState state) {
+    private BitmapDrawable(BitmapState state, Resources res) {
         mBitmapState = state;
-        mTargetDensity = state.mTargetDensity;
+        if (res != null) {
+            mTargetDensity = res.getDisplayMetrics().densityDpi;
+        } else if (state != null) {
+            mTargetDensity = state.mTargetDensity;
+        } else {
+            mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+        }
         setBitmap(state.mBitmap);
     }
 }
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index 95d4dd0..c387a9b 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -48,14 +48,14 @@
     public static final int VERTICAL = 2;
     
     ClipDrawable() {
-        this(null);
+        this(null, null);
     }
 
     /**
      * @param orientation Bitwise-or of {@link #HORIZONTAL} and/or {@link #VERTICAL}
      */
     public ClipDrawable(Drawable drawable, int gravity, int orientation) {
-        this(null);
+        this(null, null);
 
         mClipState.mDrawable = drawable;
         mClipState.mGravity = gravity;
@@ -241,9 +241,13 @@
         private boolean mCheckedConstantState;
         private boolean mCanConstantState;
 
-        ClipState(ClipState orig, ClipDrawable owner) {
+        ClipState(ClipState orig, ClipDrawable owner, Resources res) {
             if (orig != null) {
-                mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                if (res != null) {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+                } else {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                }
                 mDrawable.setCallback(owner);
                 mOrientation = orig.mOrientation;
                 mGravity = orig.mGravity;
@@ -253,7 +257,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new ClipDrawable(this);
+            return new ClipDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new ClipDrawable(this, res);
         }
 
         @Override
@@ -271,8 +280,8 @@
         }
     }
 
-    private ClipDrawable(ClipState state) {
-        mClipState = new ClipState(state, this);
+    private ClipDrawable(ClipState state, Resources res) {
+        mClipState = new ClipState(state, this, res);
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 226cc04..604c602 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -146,6 +146,11 @@
         }
 
         @Override
+        public Drawable newDrawable(Resources res) {
+            return new ColorDrawable(this);
+        }
+
+        @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 21b5e39..6a7b2d1 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -822,7 +822,26 @@
     }
 
     public static abstract class ConstantState {
+        /**
+         * Create a new drawable without supplying resources the caller
+         * is running in.  Note that using this means the density-dependent
+         * drawables (like bitmaps) will not be able to update their target
+         * density correctly.
+         */
         public abstract Drawable newDrawable();
+        /**
+         * Create a new Drawable instance from its constant state.  This
+         * must be implemented for drawables that change based on the target
+         * density of their caller (that is depending on whether it is
+         * in compatibility mode).
+         */
+        public Drawable newDrawable(Resources res) {
+            return newDrawable();
+        }
+        /**
+         * Return a bit mask of configuration changes that will impact
+         * this drawable (and thus require completely reloading it).
+         */
         public abstract int getChangingConfigurations();
     }
 
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index af1a289..3266f1e 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.Resources;
 import android.graphics.*;
 
 public class DrawableContainer extends Drawable implements Drawable.Callback {
@@ -285,7 +286,8 @@
 
         boolean     mPaddingChecked = false;
 
-        DrawableContainerState(DrawableContainerState orig, DrawableContainer owner) {
+        DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
+                Resources res) {
             mOwner = owner;
 
             if (orig != null) {
@@ -299,7 +301,11 @@
 
                 final int N = mNumChildren;
                 for (int i=0; i<N; i++) {
-                    mDrawables[i] = origDr[i].getConstantState().newDrawable();
+                    if (res != null) {
+                        mDrawables[i] = origDr[i].getConstantState().newDrawable(res);
+                    } else {
+                        mDrawables[i] = origDr[i].getConstantState().newDrawable();
+                    }
                     mDrawables[i].setCallback(owner);
                 }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index a7a8708..ddbbaf1 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -917,6 +917,11 @@
         }
         
         @Override
+        public Drawable newDrawable(Resources res) {
+            return new GradientDrawable(this);
+        }
+        
+        @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 6047726..4fa9d44 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -49,7 +49,7 @@
     private boolean mMutated;
 
     /*package*/ InsetDrawable() {
-        this(null);
+        this(null, null);
     }
 
     public InsetDrawable(Drawable drawable, int inset) {
@@ -58,7 +58,7 @@
 
     public InsetDrawable(Drawable drawable, int insetLeft, int insetTop,
                          int insetRight, int insetBottom) {
-        this(null);
+        this(null, null);
         
         mInsetState.mDrawable = drawable;
         mInsetState.mInsetLeft = insetLeft;
@@ -263,9 +263,13 @@
         boolean mCheckedConstantState;
         boolean mCanConstantState;
 
-        InsetState(InsetState orig, InsetDrawable owner) {
+        InsetState(InsetState orig, InsetDrawable owner, Resources res) {
             if (orig != null) {
-                mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                if (res != null) {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+                } else {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                }
                 mDrawable.setCallback(owner);
                 mInsetLeft = orig.mInsetLeft;
                 mInsetTop = orig.mInsetTop;
@@ -277,7 +281,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new InsetDrawable(this);
+            return new InsetDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new InsetDrawable(this, res);
         }
         
         @Override
@@ -295,8 +304,8 @@
         }
     }
 
-    private InsetDrawable(InsetState state) {
-        mInsetState = new InsetState(state, this);
+    private InsetDrawable(InsetState state, Resources res) {
+        mInsetState = new InsetState(state, this, res);
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index c777205..389fd40 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -70,7 +70,7 @@
      * @param state The constant drawable state.
      */
     LayerDrawable(Drawable[] layers, LayerState state) {
-        this(state);
+        this(state, null);
         int length = layers.length;
         ChildDrawable[] r = new ChildDrawable[length];
 
@@ -87,19 +87,19 @@
     }
     
     LayerDrawable() {
-        this((LayerState) null);
+        this((LayerState) null, null);
     }
 
-    LayerDrawable(LayerState state) {
-        LayerState as = createConstantState(state);
+    LayerDrawable(LayerState state, Resources res) {
+        LayerState as = createConstantState(state, res);
         mLayerState = as;
         if (as.mNum > 0) {
             ensurePadding();
         }
     }
 
-    LayerState createConstantState(LayerState state) {
-        return new LayerState(state, this);
+    LayerState createConstantState(LayerState state, Resources res) {
+        return new LayerState(state, this, res);
     }
 
     @Override
@@ -563,7 +563,7 @@
         private boolean mCheckedConstantState;
         private boolean mCanConstantState;
 
-        LayerState(LayerState orig, LayerDrawable owner) {
+        LayerState(LayerState orig, LayerDrawable owner, Resources res) {
             if (orig != null) {
                 final ChildDrawable[] origChildDrawable = orig.mChildren;
                 final int N = orig.mNum;
@@ -577,7 +577,11 @@
                 for (int i = 0; i < N; i++) {
                     final ChildDrawable r = mChildren[i] = new ChildDrawable();
                     final ChildDrawable or = origChildDrawable[i];
-                    r.mDrawable = or.mDrawable.getConstantState().newDrawable();
+                    if (res != null) {
+                        r.mDrawable = or.mDrawable.getConstantState().newDrawable(res);
+                    } else {
+                        r.mDrawable = or.mDrawable.getConstantState().newDrawable();
+                    }
                     r.mDrawable.setCallback(owner);
                     r.mInsetL = or.mInsetL;
                     r.mInsetT = or.mInsetT;
@@ -599,7 +603,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new LayerDrawable(this);
+            return new LayerDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new LayerDrawable(this, res);
         }
         
         @Override
diff --git a/graphics/java/android/graphics/drawable/LevelListDrawable.java b/graphics/java/android/graphics/drawable/LevelListDrawable.java
index 7ae649f..ae8f224 100644
--- a/graphics/java/android/graphics/drawable/LevelListDrawable.java
+++ b/graphics/java/android/graphics/drawable/LevelListDrawable.java
@@ -57,7 +57,7 @@
     private boolean mMutated;
 
     public LevelListDrawable() {
-        this(null);
+        this(null, null);
     }
 
     public void addLevel(int low, int high, Drawable drawable) {
@@ -154,8 +154,8 @@
         private int[] mLows;
         private int[] mHighs;
 
-        LevelListState(LevelListState orig, LevelListDrawable owner) {
-            super(orig, owner);
+        LevelListState(LevelListState orig, LevelListDrawable owner, Resources res) {
+            super(orig, owner, res);
 
             if (orig != null) {
                 mLows = orig.mLows;
@@ -186,7 +186,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new LevelListDrawable(this);
+            return new LevelListDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new LevelListDrawable(this, res);
         }
 
         @Override
@@ -201,8 +206,8 @@
         }
     }
 
-    private LevelListDrawable(LevelListState state) {
-        LevelListState as = new LevelListState(state, this);
+    private LevelListDrawable(LevelListState state, Resources res) {
+        LevelListState as = new LevelListState(state, this, res);
         mLevelListState = as;
         setConstantState(as);
         onLevelChange(getLevel());
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 997efb8..803e7b1 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -61,7 +61,7 @@
      */
     @Deprecated
     public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) {
-        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding));
+        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null);
     }
     
     /**
@@ -70,11 +70,8 @@
      */
     public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
             Rect padding, String srcName) {
-        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding));
-        if (res != null) {
-            setTargetDensity(res.getDisplayMetrics());
-            mNinePatchState.mTargetDensity = mTargetDensity;
-        }
+        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res);
+        mNinePatchState.mTargetDensity = mTargetDensity;
     }
     
     /**
@@ -84,7 +81,7 @@
      */
     @Deprecated
     public NinePatchDrawable(NinePatch patch) {
-        this(new NinePatchState(patch, null));
+        this(new NinePatchState(patch, null), null);
     }
 
     /**
@@ -92,18 +89,16 @@
      * based on the display metrics of the resources.
      */
     public NinePatchDrawable(Resources res, NinePatch patch) {
-        this(new NinePatchState(patch, null));
-        if (res != null) {
-            setTargetDensity(res.getDisplayMetrics());
-            mNinePatchState.mTargetDensity = mTargetDensity;
-        }
+        this(new NinePatchState(patch, null), res);
+        mNinePatchState.mTargetDensity = mTargetDensity;
     }
 
-    private void setNinePatchState(NinePatchState state) {
+    private void setNinePatchState(NinePatchState state, Resources res) {
         mNinePatchState = state;
         mNinePatch = state.mNinePatch;
         mPadding = state.mPadding;
-        mTargetDensity = state.mTargetDensity;
+        mTargetDensity = res != null ? res.getDisplayMetrics().densityDpi
+                : state.mTargetDensity;
         if (DEFAULT_DITHER != state.mDither) {
             // avoid calling the setter unless we need to, since it does a
             // lazy allocation of a paint
@@ -258,7 +253,8 @@
         }
 
         setNinePatchState(new NinePatchState(
-                new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"), padding, dither));
+                new NinePatch(bitmap, bitmap.getNinePatchChunk(), "XML 9-patch"),
+                padding, dither), r);
         mNinePatchState.mTargetDensity = mTargetDensity;
 
         a.recycle();
@@ -357,7 +353,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new NinePatchDrawable(this);
+            return new NinePatchDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new NinePatchDrawable(this, res);
         }
         
         @Override
@@ -366,8 +367,7 @@
         }
     }
 
-    private NinePatchDrawable(NinePatchState state) {
-        setNinePatchState(state);
+    private NinePatchDrawable(NinePatchState state, Resources res) {
+        setNinePatchState(state, res);
     }
 }
-
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index cb16cb7..c4a7822 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -54,7 +54,7 @@
      * <p>Create a new rotating drawable with an empty state.</p>
      */
     public RotateDrawable() {
-        this(null);
+        this(null, null);
     }
 
     /**
@@ -64,8 +64,8 @@
      *
      * @param rotateState the state for this drawable
      */
-    private RotateDrawable(RotateState rotateState) {
-        mState = new RotateState(rotateState, this);
+    private RotateDrawable(RotateState rotateState, Resources res) {
+        mState = new RotateState(rotateState, this, res);
     }
 
     public void draw(Canvas canvas) {
@@ -291,9 +291,13 @@
         private boolean mCanConstantState;
         private boolean mCheckedConstantState;        
 
-        public RotateState(RotateState source, RotateDrawable owner) {
+        public RotateState(RotateState source, RotateDrawable owner, Resources res) {
             if (source != null) {
-                mDrawable = source.mDrawable.getConstantState().newDrawable();
+                if (res != null) {
+                    mDrawable = source.mDrawable.getConstantState().newDrawable(res);
+                } else {
+                    mDrawable = source.mDrawable.getConstantState().newDrawable();
+                }
                 mDrawable.setCallback(owner);
                 mPivotXRel = source.mPivotXRel;
                 mPivotX = source.mPivotX;
@@ -307,7 +311,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new RotateDrawable(this);
+            return new RotateDrawable(this, null);
+        }
+        
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new RotateDrawable(this, res);
         }
         
         @Override
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 7125ab1..275e36f 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -47,11 +47,11 @@
     private final Rect mTmpRect = new Rect();
 
     ScaleDrawable() {
-        this(null);
+        this(null, null);
     }
 
     public ScaleDrawable(Drawable drawable, int gravity, float scaleWidth, float scaleHeight) {
-        this(null);
+        this(null, null);
 
         mScaleState.mDrawable = drawable;
         mScaleState.mGravity = gravity;
@@ -260,9 +260,13 @@
         private boolean mCheckedConstantState;
         private boolean mCanConstantState;
 
-        ScaleState(ScaleState orig, ScaleDrawable owner) {
+        ScaleState(ScaleState orig, ScaleDrawable owner, Resources res) {
             if (orig != null) {
-                mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                if (res != null) {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable(res);
+                } else {
+                    mDrawable = orig.mDrawable.getConstantState().newDrawable();
+                }
                 mDrawable.setCallback(owner);
                 mScaleWidth = orig.mScaleWidth;
                 mScaleHeight = orig.mScaleHeight;
@@ -273,7 +277,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new ScaleDrawable(this);
+            return new ScaleDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new ScaleDrawable(this, res);
         }
 
         @Override
@@ -291,8 +300,8 @@
         }
     }
 
-    private ScaleDrawable(ScaleState state) {
-        mScaleState = new ScaleState(state, this);
+    private ScaleDrawable(ScaleState state, Resources res) {
+        mScaleState = new ScaleState(state, this, res);
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 6677a35..c699a82 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -396,6 +396,11 @@
         }
         
         @Override
+        public Drawable newDrawable(Resources res) {
+            return new ShapeDrawable(this);
+        }
+        
+        @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 59cb226..b1d588e 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -65,7 +65,7 @@
     private boolean mMutated;
 
     public StateListDrawable() {
-        this(null);
+        this(null, null);
     }
 
     /**
@@ -248,8 +248,8 @@
     static final class StateListState extends DrawableContainerState {
         private int[][] mStateSets;
 
-        StateListState(StateListState orig, StateListDrawable owner) {
-            super(orig, owner);
+        StateListState(StateListState orig, StateListDrawable owner, Resources res) {
+            super(orig, owner, res);
 
             if (orig != null) {
                 mStateSets = orig.mStateSets;
@@ -277,7 +277,12 @@
 
         @Override
         public Drawable newDrawable() {
-            return new StateListDrawable(this);
+            return new StateListDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new StateListDrawable(this, res);
         }
 
         @Override
@@ -289,8 +294,8 @@
         }
     }
 
-    private StateListDrawable(StateListState state) {
-        StateListState as = new StateListState(state, this);
+    private StateListDrawable(StateListState state, Resources res) {
+        StateListState as = new StateListState(state, this, res);
         mStateListState = as;
         setConstantState(as);
         onStateChange(getState());
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 358f889..97b45d8 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.os.SystemClock;
 
@@ -72,7 +73,7 @@
      * 2 layers are required for this drawable to work properly.
      */
     public TransitionDrawable(Drawable[] layers) {
-        this(new TransitionState(null, null), layers);
+        this(new TransitionState(null, null, null), layers);
     }
 
     /**
@@ -82,11 +83,11 @@
      * @see #TransitionDrawable(Drawable[])
      */
     TransitionDrawable() {
-        this(new TransitionState(null, null));
+        this(new TransitionState(null, null, null), (Resources)null);
     }
 
-    private TransitionDrawable(TransitionState state) {
-        super(state);
+    private TransitionDrawable(TransitionState state, Resources res) {
+        super(state, res);
     }
 
     private TransitionDrawable(TransitionState state, Drawable[] layers) {
@@ -94,8 +95,8 @@
     }
 
     @Override
-    LayerState createConstantState(LayerState state) {
-        return new TransitionState((TransitionState) state, this);
+    LayerState createConstantState(LayerState state, Resources res) {
+        return new TransitionState((TransitionState) state, this, res);
     }
     
     /**
@@ -229,13 +230,19 @@
     }
 
     static class TransitionState extends LayerState {
-        TransitionState(TransitionState orig, TransitionDrawable owner) {
-            super(orig, owner);
+        TransitionState(TransitionState orig, TransitionDrawable owner,
+                Resources res) {
+            super(orig, owner, res);
         }
 
         @Override
         public Drawable newDrawable() {
-            return new TransitionDrawable(this);
+            return new TransitionDrawable(this, (Resources)null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new TransitionDrawable(this, res);
         }
 
         @Override