Merge "LayoutLib: Handle color state list in methods returning an int." into honeycomb
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 13ea13f..ac3df79 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -500,7 +500,7 @@
                         choosehtv, fm, hasTabOrEmoji,
                         needMultiply, paraStart, chdirs, dir, easy,
                         paraEnd == bufend, includepad, trackpad,
-                        chs, widths, paraStart,
+                        chs, widths, here - paraStart,
                         ellipsize, ellipsizedWidth, w, paint);
             }
 
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index a37f12e..f051b77 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -330,8 +330,8 @@
 
     /**
      * Sets a listener to inform when the search button is pressed. This is only
-     * relevant when the text field is not visible by default. Calling #setIconified(false)
-     * can also cause this listener to be informed.
+     * relevant when the text field is not visible by default. Calling {@link #setIconified
+     * setIconified(false)} can also cause this listener to be informed.
      *
      * @param listener the listener to inform when the search button is clicked or
      * the text field is programmatically de-iconified.
@@ -386,7 +386,7 @@
      * if the default state is iconified, then it collapses to that state when the close button
      * is pressed. Changes to this property will take effect immediately.
      *
-     * <p>The default value is false.</p>
+     * <p>The default value is true.</p>
      *
      * @param iconified whether the search field should be iconified by default
      */
diff --git a/libs/rs/java/Balls/AndroidManifest.xml b/libs/rs/java/Balls/AndroidManifest.xml
index 2fffc5f..f3384ec 100644
--- a/libs/rs/java/Balls/AndroidManifest.xml
+++ b/libs/rs/java/Balls/AndroidManifest.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.balls">
+    <uses-sdk android:minSdkVersion="11" />
     <application 
         android:label="Balls"
         android:icon="@drawable/test_pattern">
diff --git a/libs/rs/java/Fountain/AndroidManifest.xml b/libs/rs/java/Fountain/AndroidManifest.xml
index 951c451..5126e5c 100644
--- a/libs/rs/java/Fountain/AndroidManifest.xml
+++ b/libs/rs/java/Fountain/AndroidManifest.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.fountain">
+    <uses-sdk android:minSdkVersion="11" />
     <application 
         android:label="Fountain"
         android:icon="@drawable/test_pattern">
diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/libs/rs/java/ImageProcessing/AndroidManifest.xml
index d6a2db4..0fcbf1e 100644
--- a/libs/rs/java/ImageProcessing/AndroidManifest.xml
+++ b/libs/rs/java/ImageProcessing/AndroidManifest.xml
@@ -3,8 +3,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.rs.image">
 
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    
+    <uses-sdk android:minSdkVersion="11" />
     <application android:label="Image Processing">
         <activity android:name="ImageProcessingActivity"
                   android:screenOrientation="portrait">
diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml
index 9646a77..8dad161 100644
--- a/libs/rs/java/Samples/AndroidManifest.xml
+++ b/libs/rs/java/Samples/AndroidManifest.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.samples">
+    <uses-sdk android:minSdkVersion="11" />
     <application android:label="Samples"
     android:icon="@drawable/test_pattern">
         <activity android:name="RsList"
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 806b284..8214e7f 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -2555,6 +2555,14 @@
 
         final List<Effect> effects = m.getAllEffects();
         final List<Overlay> overlays = m.getAllOverlays();
+
+        for (Overlay overlay : overlays) {
+            effectSettings[i] = getOverlaySettings((OverlayFrame)overlay);
+            adjustEffectsStartTimeAndDuration(effectSettings[i], beginCutTime, endCutTime);
+            effectSettings[i].startTime += storyBoardTime;
+            i++;
+        }
+
         for (Effect effect : effects) {
             if (effect instanceof EffectColor) {
                 effectSettings[i] = getEffectSettings((EffectColor)effect);
@@ -2564,12 +2572,6 @@
             }
         }
 
-        for (Overlay overlay : overlays) {
-            effectSettings[i] = getOverlaySettings((OverlayFrame)overlay);
-            adjustEffectsStartTimeAndDuration(effectSettings[i], beginCutTime, endCutTime);
-            effectSettings[i].startTime += storyBoardTime;
-            i++;
-        }
         return i;
     }
 
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index 4d1bafb..95f002c 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -288,6 +288,16 @@
         List<EffectSettings> effectSettings = new ArrayList<EffectSettings>();
         EffectSettings tmpEffectSettings;
 
+        overlays = m.getAllOverlays();
+        for (Overlay overlay : overlays) {
+            tmpEffectSettings = mNativeHelper.getOverlaySettings((OverlayFrame)overlay);
+            mNativeHelper.adjustEffectsStartTimeAndDuration(tmpEffectSettings,
+                    clipSettings.beginCutTime, clipSettings.endCutTime);
+            if (tmpEffectSettings.duration != 0) {
+                effectSettings.add(tmpEffectSettings);
+            }
+        }
+
         effects = m.getAllEffects();
         for (Effect effect : effects) {
             if (effect instanceof EffectColor) {
@@ -303,15 +313,7 @@
                 }
             }
         }
-        overlays = m.getAllOverlays();
-        for (Overlay overlay : overlays) {
-            tmpEffectSettings = mNativeHelper.getOverlaySettings((OverlayFrame)overlay);
-            mNativeHelper.adjustEffectsStartTimeAndDuration(tmpEffectSettings,
-                    clipSettings.beginCutTime, clipSettings.endCutTime);
-            if (tmpEffectSettings.duration != 0) {
-                effectSettings.add(tmpEffectSettings);
-            }
-        }
+
          return effectSettings;
     }
 
diff --git a/tools/layoutlib/bridge/resources/bars/action_bar.xml b/tools/layoutlib/bridge/resources/bars/action_bar.xml
index cd99a09..51983f2 100644
--- a/tools/layoutlib/bridge/resources/bars/action_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/action_bar.xml
@@ -2,10 +2,8 @@
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 	<ImageView
 			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_gravity="center"/>
+			android:layout_width="wrap_content"/>
 	<TextView
 			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_gravity="center"/>
+			android:layout_height="wrap_content"/>
 </merge>
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
new file mode 100644
index 0000000..bd44b52
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_wifi_signal_4_fully.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
new file mode 100644
index 0000000..a4be298
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/hdpi/status_bar_background.9.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png b/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
new file mode 100644
index 0000000..eb7c1a4
--- /dev/null
+++ b/tools/layoutlib/bridge/resources/bars/mdpi/status_bar_background.9.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
index 29df909..5211b0a 100644
--- a/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
@@ -3,10 +3,11 @@
 	<TextView
 			android:layout_width="wrap_content"
 			android:layout_height="wrap_content"
-			android:layout_weight="1"
-			android:text=" "/>
+			android:layout_weight="1"/>
 	<ImageView
 			android:layout_height="wrap_content"
-			android:layout_width="wrap_content"
-			android:layout_gravity="center"/>
+			android:layout_width="wrap_content"/>
+	<ImageView
+			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"/>
 </merge>
diff --git a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml b/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
index 8a3b87a..c5acddb 100644
--- a/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
@@ -15,6 +15,10 @@
 			android:layout_weight="1"/>
 	<ImageView
 			android:layout_height="wrap_content"
+			android:layout_width="wrap_content"/>
+	<ImageView
+			android:layout_height="wrap_content"
 			android:layout_width="wrap_content"
-			android:layout_gravity="center"/>
+			android:layout_marginLeft="3dip"
+			android:layout_marginRight="15dip"/>
 </merge>
diff --git a/tools/layoutlib/bridge/resources/bars/title_bar.xml b/tools/layoutlib/bridge/resources/bars/title_bar.xml
index 29fcc4b..76d78d9 100644
--- a/tools/layoutlib/bridge/resources/bars/title_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/title_bar.xml
@@ -2,6 +2,5 @@
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 	<TextView
 			android:layout_width="wrap_content"
-			android:layout_height="wrap_content"
-			android:layout_gravity="center"/>
+			android:layout_height="wrap_content"/>
 </merge>
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
index 44b14dc..c4fffc86 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java
@@ -40,6 +40,46 @@
  */
 /*package*/ class BitmapFactory_Delegate {
 
+    // ------ Java delegates ------
+
+    /*package*/ static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) {
+        if (bm == null || opts == null) {
+            return bm;
+        }
+
+        final int density = opts.inDensity;
+        if (density == 0) {
+            return bm;
+        }
+
+        bm.setDensity(density);
+        final int targetDensity = opts.inTargetDensity;
+        if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
+            return bm;
+        }
+
+        byte[] np = bm.getNinePatchChunk();
+        final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
+        // DELEGATE CHANGE: never scale 9-patch
+        if (opts.inScaled && isNinePatch == false) {
+            float scale = targetDensity / (float)density;
+            // TODO: This is very inefficient and should be done in native by Skia
+            final Bitmap oldBitmap = bm;
+            bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f),
+                    (int) (bm.getHeight() * scale + 0.5f), true);
+            oldBitmap.recycle();
+
+            if (isNinePatch) {
+                np = nativeScaleNinePatch(np, scale, outPadding);
+                bm.setNinePatchChunk(np);
+            }
+            bm.setDensity(targetDensity);
+        }
+
+        return bm;
+    }
+
+
     // ------ Native Delegates ------
 
     /*package*/ static void nativeSetDefaultConfig(int nativeConfig) {
@@ -107,7 +147,8 @@
     }
 
     /*package*/ static byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad) {
-        // don't scale for now.
+        // don't scale for now. This should not be called anyway since we re-implement
+        // BitmapFactory.finishDecode();
         return chunk;
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index 7a6da95..61ed71e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -91,6 +91,50 @@
         return array;
     }
 
+    /**
+     * Returns a {@link NinePatchChunk} object for the given serialized representation.
+     *
+     * If the chunk is present in the cache then the object from the cache is returned, otherwise
+     * the array is deserialized into a {@link NinePatchChunk} object.
+     *
+     * @param array the serialized representation of the chunk.
+     * @return the NinePatchChunk or null if deserialization failed.
+     */
+    public static NinePatchChunk getChunk(byte[] array) {
+        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
+        NinePatchChunk chunk = chunkRef.get();
+        if (chunk == null) {
+            ByteArrayInputStream bais = new ByteArrayInputStream(array);
+            ObjectInputStream ois = null;
+            try {
+                ois = new ObjectInputStream(bais);
+                chunk = (NinePatchChunk) ois.readObject();
+
+                // put back the chunk in the cache
+                if (chunk != null) {
+                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
+                }
+            } catch (IOException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
+                return null;
+            } catch (ClassNotFoundException e) {
+                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
+                return null;
+            } finally {
+                if (ois != null) {
+                    try {
+                        ois.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+
+        return chunk;
+    }
+
     // ---- native methods ----
 
     /*package*/ static boolean isNinePatchChunk(byte[] chunk) {
@@ -173,47 +217,5 @@
 
     // ---- Private Helper methods ----
 
-    /**
-     * Returns a {@link NinePatchChunk} object for the given serialized representation.
-     *
-     * If the chunk is present in the cache then the object from the cache is returned, otherwise
-     * the array is deserialized into a {@link NinePatchChunk} object.
-     *
-     * @param array the serialized representation of the chunk.
-     * @return the NinePatchChunk or null if deserialization failed.
-     */
-    private static NinePatchChunk getChunk(byte[] array) {
-        SoftReference<NinePatchChunk> chunkRef = sChunkCache.get(array);
-        NinePatchChunk chunk = chunkRef.get();
-        if (chunk == null) {
-            ByteArrayInputStream bais = new ByteArrayInputStream(array);
-            ObjectInputStream ois = null;
-            try {
-                ois = new ObjectInputStream(bais);
-                chunk = (NinePatchChunk) ois.readObject();
 
-                // put back the chunk in the cache
-                if (chunk != null) {
-                    sChunkCache.put(array, new SoftReference<NinePatchChunk>(chunk));
-                }
-            } catch (IOException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk content.", e, null /*data*/);
-                return null;
-            } catch (ClassNotFoundException e) {
-                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
-                        "Failed to deserialize NinePatchChunk class.", e, null /*data*/);
-                return null;
-            } finally {
-                if (ois != null) {
-                    try {
-                        ois.close();
-                    } catch (IOException e) {
-                    }
-                }
-            }
-        }
-
-        return chunk;
-    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index dff7ff1..c01962d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -20,12 +20,14 @@
 import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
 
 import com.android.ide.common.rendering.api.Capability;
+import com.android.ide.common.rendering.api.DrawableParams;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.ide.common.rendering.api.RenderSession;
 import com.android.ide.common.rendering.api.Result;
 import com.android.ide.common.rendering.api.SessionParams;
 import com.android.layoutlib.bridge.android.BridgeAssetManager;
 import com.android.layoutlib.bridge.impl.FontLoader;
+import com.android.layoutlib.bridge.impl.RenderDrawable;
 import com.android.layoutlib.bridge.impl.RenderSessionImpl;
 import com.android.ninepatch.NinePatchChunk;
 import com.android.resources.ResourceType;
@@ -332,6 +334,33 @@
     }
 
     @Override
+    public Result renderDrawable(DrawableParams params) {
+        try {
+            Result lastResult = SUCCESS.createResult();
+            RenderDrawable action = new RenderDrawable(params);
+            try {
+                prepareThread();
+                lastResult = action.init(params.getTimeout());
+                if (lastResult.isSuccess()) {
+                    lastResult = action.render();
+                }
+            } finally {
+                action.release();
+                cleanupThread();
+            }
+
+            return lastResult;
+        } catch (Throwable t) {
+            // get the real cause of the exception.
+            Throwable t2 = t;
+            while (t2.getCause() != null) {
+                t2 = t.getCause();
+            }
+            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
+        }
+    }
+
+    @Override
     public void clearCaches(Object projectKey) {
         if (projectKey != null) {
             sProjectBitmapCache.remove(projectKey);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index f039994..70c507c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -24,6 +24,7 @@
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.resources.Density;
+import com.android.resources.ResourceType;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
@@ -36,6 +37,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.TypedValue;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.ImageView;
@@ -62,6 +64,7 @@
             throws XmlPullParserException {
         super(context);
         setOrientation(LinearLayout.HORIZONTAL);
+        setGravity(Gravity.CENTER_VERTICAL);
         setBackgroundColor(0xFF000000);
 
         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
@@ -79,33 +82,58 @@
         inflater.inflate(bridgeParser, this, true);
     }
 
+    private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut,
+            boolean tryOtherDensities) {
+        // current density
+        Density density = densityInOut[0];
+
+        // bitmap url relative to this class
+        pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
+
+        InputStream stream = getClass().getResourceAsStream(pathOut[0]);
+        if (stream == null && tryOtherDensities) {
+            for (Density d : Density.values()) {
+                if (d != density) {
+                    densityInOut[0] = d;
+                    stream = getIcon(iconName, densityInOut, pathOut, false /*tryOtherDensities*/);
+                    if (stream != null) {
+                        return stream;
+                    }
+                }
+            }
+        }
+
+        return stream;
+    }
+
     protected void loadIcon(int index, String iconName, Density density) {
         View child = getChildAt(index);
         if (child instanceof ImageView) {
             ImageView imageView = (ImageView) child;
 
-            // bitmap url relative to this class
-            String path = "/bars/" + density.getResourceValue() + "/" + iconName;
+            String[] pathOut = new String[1];
+            Density[] densityInOut = new Density[] { density };
+            InputStream stream = getIcon(iconName, densityInOut, pathOut,
+                    true /*tryOtherDensities*/);
+            density = densityInOut[0];
 
-            // create a bitmap
-            Bitmap bitmap = Bridge.getCachedBitmap(path, true /*isFramework*/);
-
-            if (bitmap == null) {
-                InputStream stream = getClass().getResourceAsStream(path);
-
-                if (stream != null) {
+            if (stream != null) {
+                // look for a cached bitmap
+                Bitmap bitmap = Bridge.getCachedBitmap(pathOut[0], true /*isFramework*/);
+                if (bitmap == null) {
                     try {
                         bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
-                        Bridge.setCachedBitmap(path, bitmap, true /*isFramework*/);
+                        Bridge.setCachedBitmap(pathOut[0], bitmap, true /*isFramework*/);
                     } catch (IOException e) {
                         return;
                     }
                 }
-            }
 
-            if (bitmap != null) {
-                BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), bitmap);
-                imageView.setBackgroundDrawable(drawable);
+                if (bitmap != null) {
+                    BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(),
+                            bitmap);
+                    imageView.setBackgroundDrawable(drawable);
+                }
             }
         }
     }
@@ -113,19 +141,39 @@
     protected void loadIcon(int index, String iconReference) {
         ResourceValue value = getResourceValue(iconReference);
         if (value != null) {
-            View child = getChildAt(index);
-            if (child instanceof ImageView) {
-                ImageView imageView = (ImageView) child;
-
-                Drawable drawable = ResourceHelper.getDrawable(
-                        value, (BridgeContext) mContext);
-                if (drawable != null) {
-                    imageView.setBackgroundDrawable(drawable);
-                }
-            }
+            loadIcon(index, value);
         }
     }
 
+    protected Drawable loadIcon(int index, ResourceType type, String name) {
+        BridgeContext bridgeContext = (BridgeContext) mContext;
+        RenderResources res = bridgeContext.getRenderResources();
+
+        // find the resource
+        ResourceValue value = res.getFrameworkResource(type, name);
+
+        // resolve it if needed
+        value = res.resolveResValue(value);
+        return loadIcon(index, value);
+    }
+
+    private Drawable loadIcon(int index, ResourceValue value) {
+        View child = getChildAt(index);
+        if (child instanceof ImageView) {
+            ImageView imageView = (ImageView) child;
+
+            Drawable drawable = ResourceHelper.getDrawable(
+                    value, (BridgeContext) mContext);
+            if (drawable != null) {
+                imageView.setBackgroundDrawable(drawable);
+            }
+
+            return drawable;
+        }
+
+        return null;
+    }
+
     protected TextView setText(int index, String stringReference) {
         View child = getChildAt(index);
         if (child instanceof TextView) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
index 92615dc..e3022b4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
@@ -17,10 +17,14 @@
 package com.android.layoutlib.bridge.bars;
 
 import com.android.resources.Density;
+import com.android.resources.ResourceType;
 
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LevelListDrawable;
+import android.view.Gravity;
 import android.widget.TextView;
 
 public class PhoneSystemBar extends CustomBar {
@@ -28,11 +32,17 @@
     public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
         super(context, density, "/bars/tablet_system_bar.xml");
 
+        setGravity(mGravity | Gravity.RIGHT);
+
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
         // We do know the order though.
         // 0 is the spacer
         loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
+        Drawable drawable = loadIcon(2, ResourceType.DRAWABLE, "stat_sys_battery_charge");
+        if (drawable instanceof LevelListDrawable) {
+            ((LevelListDrawable) drawable).setLevel(100);
+        }
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
index bc61799..db1efdb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
@@ -17,10 +17,13 @@
 package com.android.layoutlib.bridge.bars;
 
 import com.android.resources.Density;
+import com.android.resources.ResourceType;
 
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LevelListDrawable;
 import android.widget.TextView;
 
 public class TabletSystemBar extends CustomBar {
@@ -36,6 +39,10 @@
         loadIcon(2, "ic_sysbar_recent_default.png", density);
         // 3 is the spacer
         loadIcon(4, "stat_sys_wifi_signal_4_fully.png", density);
+        Drawable drawable = loadIcon(5, ResourceType.DRAWABLE, "stat_sys_battery_charge");
+        if (drawable instanceof LevelListDrawable) {
+            ((LevelListDrawable) drawable).setLevel(100);
+        }
     }
 
     @Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index 82ac176..8e80c21 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -35,16 +35,18 @@
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
- * Class implementing the render session.
+ * Base class for rendering action.
  *
- * A session is a stateful representation of a layout file. It is initialized with data coming
- * through the {@link Bridge} API to inflate the layout. Further actions and rendering can then
- * be done on the layout.
+ * It provides life-cycle methods to init and stop the rendering.
+ * The most important methods are:
+ * {@link #init(long)} and {@link #acquire(long)} to start a rendering and {@link #release()}
+ * after the rendering.
+ *
  *
  * @param <T> the {@link RenderParams} implementation
  *
  */
-public class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
+public abstract class RenderAction<T extends RenderParams> extends FrameworkResourceIdProvider {
 
     /**
      * The current context being rendered. This is set through {@link #acquire(long)} and
@@ -65,7 +67,7 @@
      * @param params the RenderParams. This must be a copy that the action can keep
      *
      */
-    public RenderAction(T params) {
+    protected RenderAction(T params) {
         mParams = params;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
new file mode 100644
index 0000000..953d8cf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.bridge.impl;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+
+import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.ResourceValue;
+import com.android.ide.common.rendering.api.Result;
+import com.android.ide.common.rendering.api.Result.Status;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeWindow;
+import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import com.android.resources.ResourceType;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.view.View;
+import android.view.View.AttachInfo;
+import android.view.View.MeasureSpec;
+import android.widget.FrameLayout;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+/**
+ * Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
+ *
+ * The class only provides a simple {@link #render()} method, but the full life-cycle of the
+ * action must be respected.
+ *
+ * @see RenderAction
+ *
+ */
+public class RenderDrawable extends RenderAction<DrawableParams> {
+
+    public RenderDrawable(DrawableParams params) {
+        super(new DrawableParams(params));
+    }
+
+    public Result render() {
+        checkLock();
+        try {
+            // get the drawable resource value
+            DrawableParams params = getParams();
+            ResourceValue drawableResource = params.getDrawable();
+
+            // resolve it
+            BridgeContext context = getContext();
+            drawableResource = context.getRenderResources().resolveResValue(drawableResource);
+
+            if (drawableResource == null ||
+                    drawableResource.getResourceType() != ResourceType.DRAWABLE) {
+                return Status.ERROR_NOT_A_DRAWABLE.createResult();
+            }
+
+            // create a simple FrameLayout
+            FrameLayout content = new FrameLayout(context);
+
+            // get the actual Drawable object to draw
+            Drawable d = ResourceHelper.getDrawable(drawableResource, context);
+            content.setBackgroundDrawable(d);
+
+            // set the AttachInfo on the root view.
+            AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
+                    new Handler(), null);
+            info.mHasWindowFocus = true;
+            info.mWindowVisibility = View.VISIBLE;
+            info.mInTouchMode = false; // this is so that we can display selections.
+            info.mHardwareAccelerated = false;
+            content.dispatchAttachedToWindow(info, 0);
+
+
+            // measure
+            int w = params.getScreenWidth();
+            int h = params.getScreenHeight();
+            int w_spec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
+            int h_spec = MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY);
+            content.measure(w_spec, h_spec);
+
+            // now do the layout.
+            content.layout(0, 0, w, h);
+
+            // preDraw setup
+            content.mAttachInfo.mTreeObserver.dispatchOnPreDraw();
+
+            // draw into a new image
+            BufferedImage image = getImage(w, h);
+
+            // create an Android bitmap around the BufferedImage
+            Bitmap bitmap = Bitmap_Delegate.createBitmap(image,
+                    true /*isMutable*/, params.getDensity());
+
+            // create a Canvas around the Android bitmap
+            Canvas canvas = new Canvas(bitmap);
+            canvas.setDensity(params.getDensity().getDpiValue());
+
+            // and draw
+            content.draw(canvas);
+
+            return Status.SUCCESS.createResult(image);
+        } catch (IOException e) {
+            return ERROR_UNKNOWN.createResult(e.getMessage(), e);
+        }
+    }
+
+    protected BufferedImage getImage(int w, int h) {
+        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D gc = image.createGraphics();
+        gc.setComposite(AlphaComposite.Src);
+
+        gc.setColor(new Color(0x00000000, true));
+        gc.fillRect(0, 0, w, h);
+
+        // done
+        gc.dispose();
+
+        return image;
+    }
+
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index cea7cf3..19392a7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -43,8 +43,10 @@
 import android.util.TypedValue;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -171,59 +173,24 @@
 
         String lowerCaseValue = stringValue.toLowerCase();
 
+        Density density = Density.MEDIUM;
+        if (value instanceof DensityBasedResourceValue) {
+            density =
+                ((DensityBasedResourceValue)value).getResourceDensity();
+        }
+
+
         if (lowerCaseValue.endsWith(NinePatch.EXTENSION_9PATCH)) {
             File file = new File(stringValue);
             if (file.isFile()) {
-                // see if we still have both the chunk and the bitmap in the caches
-                NinePatchChunk chunk = Bridge.getCached9Patch(stringValue,
-                        value.isFramework() ? null : context.getProjectKey());
-                Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
-                        value.isFramework() ? null : context.getProjectKey());
-
-                // if either chunk or bitmap is null, then we reload the 9-patch file.
-                if (chunk == null || bitmap == null) {
-                    try {
-                        NinePatch ninePatch = NinePatch.load(file.toURI().toURL(),
-                                false /* convert */);
-                        if (ninePatch != null) {
-                            if (chunk == null) {
-                                chunk = ninePatch.getChunk();
-
-                                Bridge.setCached9Patch(stringValue, chunk,
-                                        value.isFramework() ? null : context.getProjectKey());
-                            }
-
-                            if (bitmap == null) {
-                                Density density = Density.MEDIUM;
-                                if (value instanceof DensityBasedResourceValue) {
-                                    density =
-                                        ((DensityBasedResourceValue)value).getResourceDensity();
-                                }
-
-                                bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
-                                        false /*isMutable*/,
-                                        density);
-
-                                Bridge.setCachedBitmap(stringValue, bitmap,
-                                        value.isFramework() ? null : context.getProjectKey());
-                            }
-                        }
-                    } catch (MalformedURLException e) {
-                        // URL is wrong, we'll return null below
-                    } catch (IOException e) {
-                        // failed to read the file, we'll return null below.
-                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
-                                "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
-                    }
-                }
-
-                if (chunk != null && bitmap != null) {
-                    int[] padding = chunk.getPadding();
-                    Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
-
-                    return new NinePatchDrawable(context.getResources(), bitmap,
-                            NinePatch_Delegate.serialize(chunk),
-                            paddingRect, null);
+                try {
+                    return getNinePatchDrawable(
+                            new FileInputStream(file), density, value.isFramework(),
+                            stringValue, context);
+                } catch (IOException e) {
+                    // failed to read the file, we'll return null below.
+                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+                            "Failed lot load " + file.getAbsolutePath(), e, null /*data*/);
                 }
             }
 
@@ -262,11 +229,6 @@
                             value.isFramework() ? null : context.getProjectKey());
 
                     if (bitmap == null) {
-                        Density density = Density.MEDIUM;
-                        if (value instanceof DensityBasedResourceValue) {
-                            density = ((DensityBasedResourceValue)value).getResourceDensity();
-                        }
-
                         bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
                                 density);
                         Bridge.setCachedBitmap(stringValue, bitmap,
@@ -296,6 +258,52 @@
         return null;
     }
 
+    private static Drawable getNinePatchDrawable(InputStream inputStream, Density density,
+            boolean isFramework, String cacheKey, BridgeContext context) throws IOException {
+        // see if we still have both the chunk and the bitmap in the caches
+        NinePatchChunk chunk = Bridge.getCached9Patch(cacheKey,
+                isFramework ? null : context.getProjectKey());
+        Bitmap bitmap = Bridge.getCachedBitmap(cacheKey,
+                isFramework ? null : context.getProjectKey());
+
+        // if either chunk or bitmap is null, then we reload the 9-patch file.
+        if (chunk == null || bitmap == null) {
+            try {
+                NinePatch ninePatch = NinePatch.load(inputStream, true /*is9Patch*/,
+                        false /* convert */);
+                if (ninePatch != null) {
+                    if (chunk == null) {
+                        chunk = ninePatch.getChunk();
+
+                        Bridge.setCached9Patch(cacheKey, chunk,
+                                isFramework ? null : context.getProjectKey());
+                    }
+
+                    if (bitmap == null) {
+                        bitmap = Bitmap_Delegate.createBitmap(ninePatch.getImage(),
+                                false /*isMutable*/,
+                                density);
+
+                        Bridge.setCachedBitmap(cacheKey, bitmap,
+                                isFramework ? null : context.getProjectKey());
+                    }
+                }
+            } catch (MalformedURLException e) {
+                // URL is wrong, we'll return null below
+            }
+        }
+
+        if (chunk != null && bitmap != null) {
+            int[] padding = chunk.getPadding();
+            Rect paddingRect = new Rect(padding[0], padding[1], padding[2], padding[3]);
+
+            return new NinePatchDrawable(context.getResources(), bitmap,
+                    NinePatch_Delegate.serialize(chunk),
+                    paddingRect, null);
+        }
+
+        return null;
+    }
 
     // ------- TypedValue stuff
     // This is taken from //device/libs/utils/ResourceTypes.cpp
@@ -458,3 +466,4 @@
         return false;
     }
 }
+
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index fb215ab..eff6bbc 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -97,6 +97,7 @@
         "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
         "android.content.res.Resources$Theme#obtainStyledAttributes",
         "android.content.res.Resources$Theme#resolveAttribute",
+        "android.graphics.BitmapFactory#finishDecode",
         "android.os.Handler#sendMessageAtTime",
         "android.os.Build#getString",
         "android.view.LayoutInflater#rInflate",