Fix #2018814: System cannot correctly render assets with "wrap_content" attribute in QVGA

It turns out we were not returning the density for anything retrieved from a
TypedArray...  which basically means any bitmap references from a layout or style...!!!

This is now fixed.

Also fiddle with the density compatibility mode to turn on smoothing in certain situations,
helping the look of things when they need to scale and we couldn't do the scaling at
load time.
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 5c7b01f..8ebe093 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -637,12 +637,13 @@
      *  mRetData. */
     private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
                                                boolean resolve);
-    /*package*/ static final int STYLE_NUM_ENTRIES = 5;
+    /*package*/ static final int STYLE_NUM_ENTRIES = 6;
     /*package*/ static final int STYLE_TYPE = 0;
     /*package*/ static final int STYLE_DATA = 1;
     /*package*/ static final int STYLE_ASSET_COOKIE = 2;
     /*package*/ static final int STYLE_RESOURCE_ID = 3;
     /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+    /*package*/ static final int STYLE_DENSITY = 5;
     /*package*/ native static final boolean applyStyle(int theme,
             int defStyleAttr, int defStyleRes, int xmlParser,
             int[] inAttrs, int[] outValues, int[] outIndices);
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 3a32c03..016ee7f 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -654,6 +654,7 @@
         outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
         outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
         outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
+        outValue.density = data[index+AssetManager.STYLE_DENSITY];
         if (type == TypedValue.TYPE_STRING) {
             outValue.string = loadStringValueAt(index);
         }
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index b6119aa..f7cb06b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -21,7 +21,6 @@
 
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
-import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -1213,6 +1212,8 @@
                         if (mTranslator != null) {
                             mTranslator.translateCanvas(canvas);
                         }
+                        canvas.setScreenDensity(scalingRequired
+                                ? DisplayMetrics.DENSITY_DEVICE : 0);
                         mView.draw(canvas);
                         if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
                             mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
@@ -1321,6 +1322,8 @@
                     if (mTranslator != null) {
                         mTranslator.translateCanvas(canvas);
                     }
+                    canvas.setScreenDensity(scalingRequired
+                            ? DisplayMetrics.DENSITY_DEVICE : 0);
                     mView.draw(canvas);
                 } finally {
                     mAttachInfo.mIgnoreDirtyState = false;
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 52acf04..1c2e055 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -463,13 +463,22 @@
                                           SkCanvas* canvas, SkBitmap* bitmap,
                                           jfloat left, jfloat top,
                                           SkPaint* paint, jint canvasDensity,
-                                          jint bitmapDensity) {
+                                          jint screenDensity, jint bitmapDensity) {
         SkScalar left_ = SkFloatToScalar(left);
         SkScalar top_ = SkFloatToScalar(top);
 
         if (canvasDensity == bitmapDensity || canvasDensity == 0
                 || bitmapDensity == 0) {
-            canvas->drawBitmap(*bitmap, left_, top_, paint);
+            if (screenDensity != 0 && screenDensity != bitmapDensity) {
+                SkPaint filteredPaint;
+                if (paint) {
+                    filteredPaint = *paint;
+                }
+                filteredPaint.setFilterBitmap(true);
+                canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
+            } else {
+                canvas->drawBitmap(*bitmap, left_, top_, paint);
+            }
         } else {
             canvas->save();
             SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
@@ -489,30 +498,45 @@
     }
 
     static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
-                        jobject srcIRect, const SkRect& dst, SkPaint* paint) {
+                        jobject srcIRect, const SkRect& dst, SkPaint* paint,
+                        jint screenDensity, jint bitmapDensity) {
         SkIRect    src, *srcPtr = NULL;
 
         if (NULL != srcIRect) {
             GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
             srcPtr = &src;
         }
-        canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+        
+        if (screenDensity != 0 && screenDensity != bitmapDensity) {
+            SkPaint filteredPaint;
+            if (paint) {
+                filteredPaint = *paint;
+            }
+            filteredPaint.setFilterBitmap(true);
+            canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
+        } else {
+            canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+        }
     }
 
     static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
                              SkBitmap* bitmap, jobject srcIRect,
-                             jobject dstRectF, SkPaint* paint) {
+                             jobject dstRectF, SkPaint* paint,
+                             jint screenDensity, jint bitmapDensity) {
         SkRect      dst;
         GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
-        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+                screenDensity, bitmapDensity);
     }
     
     static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
                              SkBitmap* bitmap, jobject srcIRect,
-                             jobject dstRect, SkPaint* paint) {
+                             jobject dstRect, SkPaint* paint,
+                             jint screenDensity, jint bitmapDensity) {
         SkRect      dst;
         GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
-        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+                screenDensity, bitmapDensity);
     }
     
     static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
@@ -906,11 +930,11 @@
     {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
         (void*) SkCanvasGlue::drawRoundRect},
     {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
-    {"native_drawBitmap","(IIFFIII)V",
+    {"native_drawBitmap","(IIFFIIII)V",
         (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
-    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;I)V",
+    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
         (void*) SkCanvasGlue::drawBitmapRF},
-    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;I)V",
+    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
         (void*) SkCanvasGlue::drawBitmapRR},
     {"native_drawBitmap", "(I[IIIFFIIZI)V",
     (void*)SkCanvasGlue::drawBitmapArray},
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 59f4067..66b2506 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -74,12 +74,13 @@
 }
 
 enum {
-    STYLE_NUM_ENTRIES = 5,
+    STYLE_NUM_ENTRIES = 6,
     STYLE_TYPE = 0,
     STYLE_DATA = 1,
     STYLE_ASSET_COOKIE = 2,
     STYLE_RESOURCE_ID = 3,
-    STYLE_CHANGING_CONFIGURATIONS = 4
+    STYLE_CHANGING_CONFIGURATIONS = 4,
+    STYLE_DENSITY = 5
 };
 
 static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
@@ -896,6 +897,7 @@
     ResTable::Theme* theme = (ResTable::Theme*)themeToken;
     const ResTable& res = theme->getResTable();
     ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+    ResTable_config config;
     Res_value value;
 
     const jsize NI = env->GetArrayLength(attrs);
@@ -995,6 +997,7 @@
         value.dataType = Res_value::TYPE_NULL;
         value.data = 0;
         typeSetFlags = 0;
+        config.density = 0;
 
         // Skip through XML attributes until the end or the next possible match.
         while (ix < NX && curIdent > curXmlAttr) {
@@ -1042,7 +1045,8 @@
         if (value.dataType != Res_value::TYPE_NULL) {
             // Take care of resolving the found resource to its final value.
             //printf("Resolving attribute reference\n");
-            ssize_t newBlock = theme->resolveAttributeReference(&value, block, &resid, &typeSetFlags);
+            ssize_t newBlock = theme->resolveAttributeReference(&value, block,
+                    &resid, &typeSetFlags, &config);
             if (newBlock >= 0) block = newBlock;
         } else {
             // If we still don't have a value for this attribute, try to find
@@ -1051,7 +1055,8 @@
             ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
             if (newBlock >= 0) {
                 //printf("Resolving resource reference\n");
-                newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+                newBlock = res.resolveReference(&value, block, &resid,
+                        &typeSetFlags, &config);
                 if (newBlock >= 0) block = newBlock;
             }
         }
@@ -1070,6 +1075,7 @@
             block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
         dest[STYLE_RESOURCE_ID] = resid;
         dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+        dest[STYLE_DENSITY] = config.density;
         
         if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
             indicesIdx++;
@@ -1108,6 +1114,7 @@
     }
     const ResTable& res(am->getResources());
     ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+    ResTable_config config;
     Res_value value;
     
     const jsize NI = env->GetArrayLength(attrs);
@@ -1160,6 +1167,7 @@
         value.dataType = Res_value::TYPE_NULL;
         value.data = 0;
         typeSetFlags = 0;
+        config.density = 0;
         
         // Skip through XML attributes until the end or the next possible match.
         while (ix < NX && curIdent > curXmlAttr) {
@@ -1179,7 +1187,8 @@
         if (value.dataType != Res_value::TYPE_NULL) {
             // Take care of resolving the found resource to its final value.
             //printf("Resolving attribute reference\n");
-            ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+            ssize_t newBlock = res.resolveReference(&value, block, &resid,
+                    &typeSetFlags, &config);
             if (newBlock >= 0) block = newBlock;
         }
         
@@ -1197,6 +1206,7 @@
             block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
         dest[STYLE_RESOURCE_ID] = resid;
         dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+        dest[STYLE_DENSITY] = config.density;
         
         if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
             indicesIdx++;
@@ -1250,6 +1260,7 @@
         return JNI_FALSE;
     }
     const ResTable& res(am->getResources());
+    ResTable_config config;
     Res_value value;
     ssize_t block;
     
@@ -1276,13 +1287,15 @@
     while (i < NV && arrayEnt < endArrayEnt) {
         block = arrayEnt->stringBlock;
         typeSetFlags = arrayTypeSetFlags;
+        config.density = 0;
         value = arrayEnt->map.value;
                 
         uint32_t resid = 0;
         if (value.dataType != Res_value::TYPE_NULL) {
             // Take care of resolving the found resource to its final value.
             //printf("Resolving attribute reference\n");
-            ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+            ssize_t newBlock = res.resolveReference(&value, block, &resid,
+                    &typeSetFlags, &config);
             if (newBlock >= 0) block = newBlock;
         }
 
@@ -1299,6 +1312,7 @@
         dest[STYLE_ASSET_COOKIE] = (jint)res.getTableCookie(block);
         dest[STYLE_RESOURCE_ID] = resid;
         dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+        dest[STYLE_DENSITY] = config.density;
         dest += STYLE_NUM_ENTRIES;
         i+= STYLE_NUM_ENTRIES;
         arrayEnt++;
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index bc2e42e..345f810 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -50,6 +50,9 @@
 
     // Package-scoped for quick access.
     /*package*/ int mDensity = Bitmap.DENSITY_NONE;
+
+    // Used to determine when compatibility scaling is in effect.
+    private int mScreenDensity = Bitmap.DENSITY_NONE;
     
     // Used by native code
     @SuppressWarnings({"UnusedDeclaration"})
@@ -219,6 +222,11 @@
         mDensity = density;
     }
 
+    /** @hide */
+    public void setScreenDensity(int density) {
+        mScreenDensity = density;
+    }
+    
     // the SAVE_FLAG constants must match their native equivalents
 
     /** restore the current matrix when restore() is called */
@@ -971,7 +979,8 @@
     public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
         throwIfRecycled(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top,
-                paint != null ? paint.mNativePaint : 0, mDensity, bitmap.mDensity);
+                paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity,
+                bitmap.mDensity);
     }
 
     /**
@@ -1002,7 +1011,8 @@
         }
         throwIfRecycled(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
-                          paint != null ? paint.mNativePaint : 0);
+                          paint != null ? paint.mNativePaint : 0,
+                          mScreenDensity, bitmap.mDensity);
     }
 
     /**
@@ -1033,7 +1043,8 @@
         }
         throwIfRecycled(bitmap);
         native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
-                          paint != null ? paint.mNativePaint : 0);
+                          paint != null ? paint.mNativePaint : 0,
+                          mScreenDensity, bitmap.mDensity);
     }
     
     /**
@@ -1513,13 +1524,19 @@
     private native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                  float left, float top,
                                                  int nativePaintOrZero,
-                                                 int canvasDensity, int bitmapDensity);
+                                                 int canvasDensity,
+                                                 int screenDensity,
+                                                 int bitmapDensity);
     private native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                  Rect src, RectF dst,
-                                                 int nativePaintOrZero);
+                                                 int nativePaintOrZero,
+                                                 int screenDensity,
+                                                 int bitmapDensity);
     private static native void native_drawBitmap(int nativeCanvas, int bitmap,
                                                  Rect src, Rect dst,
-                                                 int nativePaintOrZero);
+                                                 int nativePaintOrZero,
+                                                 int screenDensity,
+                                                 int bitmapDensity);
     private static native void native_drawBitmap(int nativeCanvas, int[] colors,
                                                 int offset, int stride, float x,
                                                  float y, int width, int height,
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index edd0cae6..e524e2a 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1655,7 +1655,8 @@
     ssize_t resolveReference(Res_value* inOutValue,
                              ssize_t blockIndex,
                              uint32_t* outLastRef = NULL,
-                             uint32_t* inoutTypeSpecFlags = NULL) const;
+                             uint32_t* inoutTypeSpecFlags = NULL,
+                             ResTable_config* outConfig = NULL) const;
 
     enum {
         TMP_BUFFER_SIZE = 16
@@ -1729,7 +1730,8 @@
          */
         ssize_t resolveAttributeReference(Res_value* inOutValue,
                 ssize_t blockIndex, uint32_t* outLastRef = NULL,
-                uint32_t* inoutTypeSpecFlags = NULL) const;
+                uint32_t* inoutTypeSpecFlags = NULL,
+                ResTable_config* inoutConfig = NULL) const;
 
         void dumpToLog() const;
         
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 4dca8bd..0831f4a 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1486,7 +1486,7 @@
 
 ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
         ssize_t blockIndex, uint32_t* outLastRef,
-        uint32_t* inoutTypeSpecFlags) const
+        uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
 {
     //printf("Resolving type=0x%x\n", inOutValue->dataType);
     if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
@@ -1498,7 +1498,8 @@
             return blockIndex;
         }
     }
-    return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
+    return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
+            inoutTypeSpecFlags, inoutConfig);
 }
 
 void ResTable::Theme::dumpToLog() const
@@ -1891,7 +1892,8 @@
 }
 
 ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
-        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
+        uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
+        ResTable_config* outConfig) const
 {
     int count=0;
     while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
@@ -1899,7 +1901,8 @@
         if (outLastRef) *outLastRef = value->data;
         uint32_t lastRef = value->data;
         uint32_t newFlags = 0;
-        const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
+        const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
+                outConfig);
         //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
         //     (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
         //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);
diff --git a/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png b/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png
new file mode 100644
index 0000000..4d717a8
--- /dev/null
+++ b/tests/DpiTest/res/drawable-hdpi/reslogo240dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png b/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png
new file mode 100644
index 0000000..4d717a8
--- /dev/null
+++ b/tests/DpiTest/res/drawable-hdpi/stylogo240dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png b/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png
new file mode 100644
index 0000000..46bbd5b
--- /dev/null
+++ b/tests/DpiTest/res/drawable-ldpi/reslogo120dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png b/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png
new file mode 100644
index 0000000..46bbd5b
--- /dev/null
+++ b/tests/DpiTest/res/drawable-ldpi/stylogo120dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable/reslogo160dpi.png b/tests/DpiTest/res/drawable/reslogo160dpi.png
new file mode 100644
index 0000000..c23b2ce
--- /dev/null
+++ b/tests/DpiTest/res/drawable/reslogo160dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/drawable/stylogo160dpi.png b/tests/DpiTest/res/drawable/stylogo160dpi.png
new file mode 100644
index 0000000..c23b2ce
--- /dev/null
+++ b/tests/DpiTest/res/drawable/stylogo160dpi.png
Binary files differ
diff --git a/tests/DpiTest/res/layout/image_views.xml b/tests/DpiTest/res/layout/image_views.xml
new file mode 100644
index 0000000..6a91497
--- /dev/null
+++ b/tests/DpiTest/res/layout/image_views.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/reslogo120dpi" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/reslogo160dpi" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/reslogo240dpi" />
+
+</LinearLayout>
diff --git a/tests/DpiTest/res/layout/styled_image_views.xml b/tests/DpiTest/res/layout/styled_image_views.xml
new file mode 100644
index 0000000..86c63bf
--- /dev/null
+++ b/tests/DpiTest/res/layout/styled_image_views.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <ImageView style="@style/ImageView120dpi" />
+    <ImageView style="@style/ImageView160dpi" />
+    <ImageView style="@style/ImageView240dpi" />
+
+</LinearLayout>
diff --git a/tests/DpiTest/res/values/styles.xml b/tests/DpiTest/res/values/styles.xml
new file mode 100644
index 0000000..bb4b13c
--- /dev/null
+++ b/tests/DpiTest/res/values/styles.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <style name="ImageView120dpi">
+        <item name="android:src">@drawable/stylogo120dpi</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+
+    <style name="ImageView160dpi">
+        <item name="android:src">@drawable/stylogo160dpi</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+
+    <style name="ImageView240dpi">
+        <item name="android:src">@drawable/stylogo240dpi</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+</resources>
diff --git a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
index 68220a1..ae53b76 100644
--- a/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
+++ b/tests/DpiTest/src/com/google/android/test/dpi/DpiTestActivity.java
@@ -28,6 +28,7 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.ScrollView;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -71,6 +72,9 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        final LayoutInflater li = (LayoutInflater)getSystemService(
+                LAYOUT_INFLATER_SERVICE);
+        
         this.setTitle(R.string.act_title);
         LinearLayout root = new LinearLayout(this);
         root.setOrientation(LinearLayout.VERTICAL);
@@ -96,6 +100,14 @@
         addLabelToRoot(root, "Prescaled resource drawable");
         addChildToRoot(root, layout);
 
+        layout = (LinearLayout)li.inflate(R.layout.image_views, null);
+        addLabelToRoot(root, "Inflated layout");
+        addChildToRoot(root, layout);
+        
+        layout = (LinearLayout)li.inflate(R.layout.styled_image_views, null);
+        addLabelToRoot(root, "Inflated styled layout");
+        addChildToRoot(root, layout);
+        
         layout = new LinearLayout(this);
         addCanvasBitmap(layout, R.drawable.logo120dpi, true);
         addCanvasBitmap(layout, R.drawable.logo160dpi, true);