Merge "Make sure the prefetcher is actively fetching data if we pause playback due to cache underrun."
diff --git a/api/current.xml b/api/current.xml
index 88d7b6a..504dab4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -39747,7 +39747,18 @@
  type="int"
  transient="false"
  volatile="false"
- value="10"
+ value="12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATE_AUDIO_CONNECTING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="11"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -39758,7 +39769,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="11"
+ value="10"
  static="true"
  final="true"
  deprecated="not deprecated"
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index f63a5c5..d5b0042 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -184,29 +184,29 @@
             "android.bluetooth.headset.intent.category.companyid";
 
     /**
-     * Headset state when SCO audio is connected
+     * Headset state when SCO audio is not connected
      * This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
      */
-    public static final int STATE_AUDIO_CONNECTED = 10;
+    public static final int STATE_AUDIO_DISCONNECTED = 10;
 
     /**
      * Headset state when SCO audio is connecting
      * This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
-     * @hide
      */
-    public static final int STATE_AUDIO_CONNECTING = 12;
+    public static final int STATE_AUDIO_CONNECTING = 11;
 
     /**
-     * Headset state when SCO audio is not connected
+     * Headset state when SCO audio is connected
      * This state can be one of
      * {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
      * {@link #ACTION_AUDIO_STATE_CHANGED} intent.
      */
-    public static final int STATE_AUDIO_DISCONNECTED = 11;
+    public static final int STATE_AUDIO_CONNECTED = 12;
+
 
     private Context mContext;
     private ServiceListener mServiceListener;
@@ -377,11 +377,15 @@
      * audio connection.
      *
      * <p> Users can listen to {@link #ACTION_AUDIO_STATE_CHANGED}.
-     * {@link #EXTRA_STATE} will be set to {@link #STATE_AUDIO_CONNECTED}
-     * when the audio connection is established,
-     * and to {@link #STATE_AUDIO_DISCONNECTED} in case of failure.
+     * If this function returns true, this intent will be broadcasted with
+     * {@link #EXTRA_STATE} set to {@link #STATE_AUDIO_CONNECTING}.
      *
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+     * <p> {@link #EXTRA_STATE} will transition from
+     * {@link #STATE_AUDIO_CONNECTING} to {@link #STATE_AUDIO_CONNECTED} when
+     * audio connection is established and to {@link #STATE_AUDIO_DISCONNECTED}
+     * in case of failure to establish the audio connection.
+     *
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
      *
      * @param device Bluetooth headset
      * @return false if there is no headset connected of if the
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 25d868f..22876c0 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -112,6 +112,9 @@
     // Only show an annoying dialog at most every 30 seconds
     private static final long MIN_DIALOG_INTERVAL_MS = 30000;
 
+    // How many Span tags (e.g. animations) to report.
+    private static final int MAX_SPAN_TAGS = 20;
+
     // How many offending stacks to keep track of (and time) per loop
     // of the Looper.
     private static final int MAX_OFFENSES_PER_LOOP = 10;
@@ -1217,6 +1220,140 @@
     }
 
     /**
+     * A tracked, critical time span.  (e.g. during an animation.)
+     *
+     * The object itself is a linked list node, to avoid any allocations
+     * during rapid span entries and exits.
+     *
+     * @hide
+     */
+    public static class Span {
+        private String mName;
+        private long mCreateMillis;
+        private Span mNext;
+        private Span mPrev;  // not used when in freeList, only active
+        private final ThreadSpanState mContainerState;
+
+        Span(ThreadSpanState threadState) {
+            mContainerState = threadState;
+        }
+
+        /**
+         * To be called when the critical span is complete (i.e. the
+         * animation is done animating).  This can be called on any
+         * thread (even a different one from where the animation was
+         * taking place), but that's only a defensive implementation
+         * measure.  It really makes no sense for you to call this on
+         * thread other than that where you created it.
+         *
+         * @hide
+         */
+        public void finish() {
+            ThreadSpanState state = mContainerState;
+            synchronized (state) {
+                if (mName == null) {
+                    // Duplicate finish call.  Ignore.
+                    return;
+                }
+
+                // Remove ourselves from the active list.
+                if (mPrev != null) {
+                    mPrev.mNext = mNext;
+                }
+                if (mNext != null) {
+                    mNext.mPrev = mPrev;
+                }
+                if (state.mActiveHead == this) {
+                    state.mActiveHead = mNext;
+                }
+
+                this.mCreateMillis = -1;
+                this.mName = null;
+                this.mPrev = null;
+                this.mNext = null;
+                state.mActiveSize--;
+
+                // Add ourselves to the freeList, if it's not already
+                // too big.
+                if (state.mFreeListSize < 5) {
+                    this.mNext = state.mFreeListHead;
+                    state.mFreeListHead = this;
+                    state.mFreeListSize++;
+                }
+            }
+        }
+    }
+
+    /**
+     * Linked lists of active spans and a freelist.
+     *
+     * Locking notes: there's one of these structures per thread and
+     * all members of this structure (as well as the Span nodes under
+     * it) are guarded by the ThreadSpanState object instance.  While
+     * in theory there'd be no locking required because it's all local
+     * per-thread, the finish() method above is defensive against
+     * people calling it on a different thread from where they created
+     * the Span, hence the locking.
+     */
+    private static class ThreadSpanState {
+        public Span mActiveHead;    // doubly-linked list.
+        public int mActiveSize;
+        public Span mFreeListHead;  // singly-linked list.  only changes at head.
+        public int mFreeListSize;
+    }
+
+    private static final ThreadLocal<ThreadSpanState> sThisThreadSpanState =
+            new ThreadLocal<ThreadSpanState>() {
+        @Override protected ThreadSpanState initialValue() {
+            return new ThreadSpanState();
+        }
+    };
+
+    /**
+     * Enter a named critical span (e.g. an animation)
+     *
+     * <p>The name is an arbitary label (or tag) that will be applied
+     * to any strictmode violation that happens while this span is
+     * active.  You must call finish() on the span when done.
+     *
+     * <p>This will never return null, but on devices without debugging
+     * enabled, this may return a dummy object on which the finish()
+     * method is a no-op.
+     *
+     * <p>TODO: add CloseGuard to this, verifying callers call finish.
+     *
+     * @hide
+     */
+    public static Span enterCriticalSpan(String name) {
+        if (name == null || name.isEmpty()) {
+            throw new IllegalArgumentException("name must be non-null and non-empty");
+        }
+        ThreadSpanState state = sThisThreadSpanState.get();
+        Span span = null;
+        synchronized (state) {
+            if (state.mFreeListHead != null) {
+                span = state.mFreeListHead;
+                state.mFreeListHead = span.mNext;
+                state.mFreeListSize--;
+            } else {
+                // Shouldn't have to do this often.
+                span = new Span(state);
+            }
+            span.mName = name;
+            span.mCreateMillis = SystemClock.uptimeMillis();
+            span.mNext = state.mActiveHead;
+            span.mPrev = null;
+            state.mActiveHead = span;
+            state.mActiveSize++;
+            if (span.mNext != null) {
+                span.mNext.mPrev = span;
+            }
+        }
+        return span;
+    }
+
+
+    /**
      * Parcelable that gets sent in Binder call headers back to callers
      * to report violations that happened during a cross-process call.
      *
@@ -1245,6 +1382,12 @@
         public int numAnimationsRunning = 0;
 
         /**
+         * List of tags from active Span instances during this
+         * violation, or null for none.
+         */
+        public String[] tags;
+
+        /**
          * Which violation number this was (1-based) since the last Looper loop,
          * from the perspective of the root caller (if it crossed any processes
          * via Binder calls).  The value is 0 if the root caller wasn't on a Looper
@@ -1284,6 +1427,23 @@
             if (broadcastIntent != null) {
                 broadcastIntentAction = broadcastIntent.getAction();
             }
+            ThreadSpanState state = sThisThreadSpanState.get();
+            synchronized (state) {
+                int spanActiveCount = state.mActiveSize;
+                if (spanActiveCount > MAX_SPAN_TAGS) {
+                    spanActiveCount = MAX_SPAN_TAGS;
+                }
+                if (spanActiveCount != 0) {
+                    this.tags = new String[spanActiveCount];
+                    Span iter = state.mActiveHead;
+                    int index = 0;
+                    while (iter != null && index < spanActiveCount) {
+                        this.tags[index] = iter.mName;
+                        index++;
+                        iter = iter.mNext;
+                    }
+                }
+            }
         }
 
         /**
@@ -1312,6 +1472,7 @@
             numAnimationsRunning = in.readInt();
             violationUptimeMillis = in.readLong();
             broadcastIntentAction = in.readString();
+            tags = in.readStringArray();
         }
 
         /**
@@ -1325,6 +1486,7 @@
             dest.writeInt(numAnimationsRunning);
             dest.writeLong(violationUptimeMillis);
             dest.writeString(broadcastIntentAction);
+            dest.writeStringArray(tags);
         }
 
 
@@ -1347,6 +1509,12 @@
             if (broadcastIntentAction != null) {
                 pw.println(prefix + "broadcastIntentAction: " + broadcastIntentAction);
             }
+            if (tags != null) {
+                int index = 0;
+                for (String tag : tags) {
+                    pw.println(prefix + "tag[" + (index++) + "]: " + tag);
+                }
+            }
         }
 
     }
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index bbad2b6..45c8174 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -322,7 +322,7 @@
     private void requestInputMethod(Dialog dialog) {
         Window window = dialog.getWindow();
         window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE |
-                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+                WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
     }
 
     /**
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index ec8f031..01a6b94 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2508,44 +2508,42 @@
         // dump
         pw.println("\n--Headset Service--");
         if (mBluetoothHeadset != null) {
-           List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
-           if (deviceList.size() == 0) {
-              pw.println("\n--No headsets connected--");
-           }
-           BluetoothDevice device = deviceList.get(0);
+            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
+            if (deviceList.size() == 0) {
+                pw.println("\n--No headsets connected--");
+            } else {
+                BluetoothDevice device = deviceList.get(0);
+                pw.println("\ngetConnectedDevices[0] = " + device);
 
-            switch (mBluetoothHeadset.getConnectionState(device)) {
-                case BluetoothHeadset.STATE_DISCONNECTED:
-                    pw.println("getConnectionState() = STATE_DISCONNECTED");
-                    break;
-                case BluetoothHeadset.STATE_CONNECTING:
-                    pw.println("getConnectionState() = STATE_CONNECTING");
-                    break;
-                case BluetoothHeadset.STATE_CONNECTED:
-                    pw.println("getConnectionState() = STATE_CONNECTED");
-                    break;
-                case BluetoothHeadset.STATE_DISCONNECTING:
-                    pw.println("getConnectionState() = STATE_DISCONNECTING");
-                    break;
-                case BluetoothHeadset.STATE_AUDIO_CONNECTED:
-                    pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
-                    break;
+                switch (mBluetoothHeadset.getConnectionState(device)) {
+                    case BluetoothHeadset.STATE_CONNECTING:
+                        pw.println("getConnectionState() = STATE_CONNECTING");
+                        break;
+                    case BluetoothHeadset.STATE_CONNECTED:
+                        pw.println("getConnectionState() = STATE_CONNECTED");
+                        break;
+                    case BluetoothHeadset.STATE_DISCONNECTING:
+                        pw.println("getConnectionState() = STATE_DISCONNECTING");
+                        break;
+                    case BluetoothHeadset.STATE_AUDIO_CONNECTED:
+                        pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
+                        break;
+                }
+                pw.println("getBatteryUsageHint() = " +
+                             mBluetoothHeadset.getBatteryUsageHint(device));
             }
 
             deviceList.clear();
             deviceList = mBluetoothHeadset.getDevicesMatchingConnectionStates(new int[] {
                      BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
             pw.println("\n--Connected and Disconnected Headsets");
-            for (BluetoothDevice dev: deviceList) {
+            for (BluetoothDevice device: deviceList) {
                 pw.println(device);
                 if (mBluetoothHeadset.isAudioConnected(device)) {
                     pw.println("SCO audio connected to device:" + device);
                 }
             }
 
-            pw.println("\ngetCurrentHeadset() = " + device);
-            pw.println("getBatteryUsageHint() = " +
-                       mBluetoothHeadset.getBatteryUsageHint(device));
             mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
         }
 
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 454ef4d..026f1a0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8637,7 +8637,6 @@
     public void setBackgroundColor(int color) {
         if (mBGDrawable instanceof ColorDrawable) {
             ((ColorDrawable) mBGDrawable).setColor(color);
-            invalidate();
         } else {
             setBackgroundDrawable(new ColorDrawable(color));
         }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index fb760ac7..f3f9a6d 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -6529,8 +6529,11 @@
                         // If the text entry has created more events, ignore
                         // this one.
                         } else if (msg.arg2 == mTextGeneration) {
-                            mWebTextView.setTextAndKeepSelection(
-                                    (String) msg.obj);
+                            String text = (String) msg.obj;
+                            if (null == text) {
+                                text = "";
+                            }
+                            mWebTextView.setTextAndKeepSelection(text);
                         }
                     }
                     break;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3838a02..fdd75d5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -23,6 +23,7 @@
 
 import android.R;
 import android.content.ClipData;
+import android.content.ClipData.Item;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -88,6 +89,7 @@
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.ContextMenu;
+import android.view.DragEvent;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
@@ -759,6 +761,13 @@
 
         BufferType bufferType = BufferType.EDITABLE;
 
+        final int variation =
+                inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION);
+        final boolean passwordInputType = variation
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
+        final boolean webPasswordInputType = variation
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD);
+
         if (inputMethod != null) {
             Class<?> c;
 
@@ -854,19 +863,18 @@
             }
         }
 
-        if (password) {
-            // Caller used the deprecated xml attribute "password".  Ensure that
-            // the inputType is correct.
-            boolean normalText = (mInputType & EditorInfo.TYPE_MASK_CLASS)
-                    == EditorInfo.TYPE_CLASS_TEXT;
-            if (normalText && !isPasswordInputType(mInputType)) {
+        // mInputType has been set from inputType, possibly modified by mInputMethod.
+        // Specialize mInputType to [web]password if we have a text class and the original input
+        // type was a password.
+        if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
+            if (password || passwordInputType) {
                 mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
-                    | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+                        | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
             }
-        } else if (isPasswordInputType(mInputType)) {
-            // Caller did not use the deprecated xml attribute "password", but
-            // did set the input properly.  Set password to true.
-            password = true;
+            if (webPasswordInputType) {
+                mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
+                        | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
+            }
         }
 
         if (selectallonfocus) {
@@ -880,7 +888,10 @@
             drawableLeft, drawableTop, drawableRight, drawableBottom);
         setCompoundDrawablePadding(drawablePadding);
 
-        setSingleLine(singleLine);
+        // Same as setSingleLine, but make sure the transformation method is unchanged.
+        setInputTypeSingleLine(singleLine);
+        applySingleLine(singleLine, false);
+
         if (singleLine && mInput == null && ellipsize < 0) {
                 ellipsize = 3; // END
         }
@@ -909,13 +920,11 @@
         }
         setRawTextSize(textSize);
 
-        if (password) {
+        if (password || passwordInputType || webPasswordInputType) {
             setTransformationMethod(PasswordTransformationMethod.getInstance());
             typefaceIndex = MONOSPACE;
-        } else if ((mInputType&(EditorInfo.TYPE_MASK_CLASS
-                |EditorInfo.TYPE_MASK_VARIATION))
-                == (EditorInfo.TYPE_CLASS_TEXT
-                        |EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
+        } else if ((mInputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
             typefaceIndex = MONOSPACE;
         }
 
@@ -1146,7 +1155,9 @@
             } catch (IncompatibleClassChangeError e) {
                 mInputType = EditorInfo.TYPE_CLASS_TEXT;
             }
-            setSingleLine(mSingleLine);
+            // Change inputType, without affecting transformation.
+            // No need to applySingleLine since mSingleLine is unchanged.
+            setInputTypeSingleLine(mSingleLine);
         } else {
             mInputType = EditorInfo.TYPE_NULL;
         }
@@ -3049,21 +3060,19 @@
     }
 
     private boolean isPasswordInputType(int inputType) {
-        final int variation = inputType & (EditorInfo.TYPE_MASK_CLASS
-                | EditorInfo.TYPE_MASK_VARIATION);
+        final int variation =
+                inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION);
         return variation
-                == (EditorInfo.TYPE_CLASS_TEXT
-                        | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)
-                        || variation == (EditorInfo.TYPE_CLASS_TEXT
-                        | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD);
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)
+                || variation
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD);
     }
 
     private boolean isVisiblePasswordInputType(int inputType) {
-        final int variation = inputType & (EditorInfo.TYPE_MASK_CLASS
-                | EditorInfo.TYPE_MASK_VARIATION);
+        final int variation =
+                inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION);
         return variation
-                == (EditorInfo.TYPE_CLASS_TEXT
-                        | EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
+                == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
     }
 
     /**
@@ -6073,6 +6082,15 @@
      */
     @android.view.RemotableViewMethod
     public void setSingleLine(boolean singleLine) {
+        setInputTypeSingleLine(singleLine);
+        applySingleLine(singleLine, true);
+    }
+
+    /**
+     * Adds or remove the EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE on the mInputType.
+     * @param singleLine
+     */
+    private void setInputTypeSingleLine(boolean singleLine) {
         if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
             if (singleLine) {
                 mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
@@ -6080,7 +6098,6 @@
                 mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
             }
         }
-        applySingleLine(singleLine, true);
     }
 
     private void applySingleLine(boolean singleLine, boolean applyTransformation) {
@@ -6731,10 +6748,6 @@
                     mMovement.onTakeFocus(this, (Spannable) mText, direction);
                 }
 
-                if (mSelectAllOnFocus) {
-                    Selection.setSelection((Spannable) mText, 0, mText.length());
-                }
-
                 // The DecorView does not have focus when the 'Done' ExtractEditText button is
                 // pressed. Since it is the ViewRoot's mView, it requests focus before
                 // ExtractEditText clears focus, which gives focus to the ExtractEditText.
@@ -6753,6 +6766,11 @@
                      */
                     Selection.setSelection((Spannable) mText, selStart, selEnd);
                 }
+
+                if (mSelectAllOnFocus) {
+                    Selection.setSelection((Spannable) mText, 0, mText.length());
+                }
+
                 mTouchFocusSelected = true;
             }
 
@@ -7029,12 +7047,12 @@
                     || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
         }
 
-        // TODO Add an extra android:cursorController flag to disable the controller?
-        if (windowSupportsHandles && mCursorVisible && mLayout != null) {
+        if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null) {
             if (mInsertionPointCursorController == null) {
                 mInsertionPointCursorController = new InsertionPointCursorController();
             }
         } else {
+            hideInsertionPointCursorController();
             mInsertionPointCursorController = null;
         }
 
@@ -7044,7 +7062,9 @@
             }
         } else {
             // Stop selection mode if the controller becomes unavailable.
-            stopSelectionActionMode();
+            if (mSelectionModifierCursorController != null) {
+                stopSelectionActionMode();
+            }
             mSelectionModifierCursorController = null;
         }
     }
@@ -7053,7 +7073,7 @@
      * @return True iff this TextView contains a text that can be edited.
      */
     private boolean isTextEditable() {
-        return mText instanceof Editable && onCheckIsTextEditor();
+        return mText instanceof Editable && onCheckIsTextEditor() && isEnabled();
     }
 
     /**
@@ -7684,13 +7704,53 @@
         return packRangeInLong(min, max);
     }
 
+    private DragThumbnailBuilder getTextThumbnailBuilder(CharSequence text) {
+        TextView thumbnail = (TextView) inflate(mContext,
+                com.android.internal.R.layout.text_drag_thumbnail, null);
+
+        if (thumbnail == null) {
+            throw new IllegalArgumentException("Unable to inflate text drag thumbnail");
+        }
+
+        if (text.length() > DRAG_THUMBNAIL_MAX_TEXT_LENGTH) {
+            text = text.subSequence(0, DRAG_THUMBNAIL_MAX_TEXT_LENGTH);
+        }
+        thumbnail.setText(text);
+        thumbnail.setTextColor(getTextColors());
+
+        thumbnail.setTextAppearance(mContext, R.styleable.Theme_textAppearanceLarge);
+        thumbnail.setGravity(Gravity.CENTER);
+
+        thumbnail.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT));
+
+        final int size = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+        thumbnail.measure(size, size);
+
+        thumbnail.layout(0, 0, thumbnail.getMeasuredWidth(), thumbnail.getMeasuredHeight());
+        thumbnail.invalidate();
+        return new DragThumbnailBuilder(thumbnail);
+    }
+
     @Override
     public boolean performLongClick() {
         if (super.performLongClick()) {
             mEatTouchRelease = true;
             return true;
         }
-        
+
+        if (mSelectionActionMode != null && touchPositionIsInSelection()) {
+            final int start = getSelectionStart();
+            final int end = getSelectionEnd();
+            CharSequence selectedText = mTransformed.subSequence(start, end);
+            ClipData data = ClipData.newPlainText(null, null, selectedText);
+            startDrag(data, getTextThumbnailBuilder(selectedText), false);
+            stopSelectionActionMode();
+            performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+            mEatTouchRelease = true;
+            return true;
+        }
+
         if (startSelectionActionMode()) {
             performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
             mEatTouchRelease = true;
@@ -7830,6 +7890,8 @@
                 if (hasPasswordTransformationMethod()) {
                     // selectCurrentWord is not available on a password field and would return an
                     // arbitrary 10-charater selection around pressed position. Select all instead.
+                    // Note that cut/copy menu entries are not available for passwords.
+                    // This is however useful to delete or paste to replace the entire content.
                     Selection.setSelection((Spannable) mText, 0, mText.length());
                 } else {
                     selectCurrentWord();
@@ -8728,6 +8790,46 @@
         return getOffsetForHorizontal(line, x);
     }
 
+    @Override
+    public boolean onDragEvent(DragEvent event) {
+        switch (event.getAction()) {
+            case DragEvent.ACTION_DRAG_STARTED:
+                return mInsertionPointCursorController != null;
+
+            case DragEvent.ACTION_DRAG_ENTERED:
+                TextView.this.requestFocus();
+                return true;
+
+            case DragEvent.ACTION_DRAG_LOCATION: {
+                final int offset = getOffset((int)event.getX(), (int)event.getY());
+                Selection.setSelection((Spannable)mText, offset);
+                return true;
+            }
+
+            case DragEvent.ACTION_DROP: {
+                StringBuilder content = new StringBuilder("");
+                ClipData clipData = event.getClipData();
+                final int itemCount = clipData.getItemCount();
+                for (int i=0; i < itemCount; i++) {
+                    Item item = clipData.getItem(i);
+                    content.append(item.coerceToText(TextView.this.mContext));
+                }
+                final int offset = getOffset((int) event.getX(), (int) event.getY());
+                long minMax = prepareSpacesAroundPaste(offset, offset, content);
+                int min = extractRangeStartFromLong(minMax);
+                int max = extractRangeEndFromLong(minMax);
+                Selection.setSelection((Spannable) mText, max);
+                ((Editable) mText).replace(min, max, content);
+                return true;
+            }
+
+            case DragEvent.ACTION_DRAG_EXITED:
+            case DragEvent.ACTION_DRAG_ENDED:
+            default:
+                return true;
+        }
+    }
+
 
     @ViewDebug.ExportedProperty(category = "text")
     private CharSequence            mText;
@@ -8822,4 +8924,5 @@
     private static final InputFilter[] NO_FILTERS = new InputFilter[0];
     private InputFilter[] mFilters = NO_FILTERS;
     private static final Spanned EMPTY_SPANNED = new SpannedString("");
+    private static int DRAG_THUMBNAIL_MAX_TEXT_LENGTH = 20;
 }
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index abe33f4..90c4dd4 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -36,7 +36,7 @@
     static void finalizer(JNIEnv* env, jobject clazz, SkPath* obj) {
 #ifdef USE_OPENGL_RENDERER
         if (android::uirenderer::Caches::hasInstance()) {
-            android::uirenderer::Caches::getInstance().pathCache.remove(obj);
+            android::uirenderer::Caches::getInstance().pathCache.removeDeferred(obj);
         }
 #endif
         delete obj;
diff --git a/core/res/res/layout/text_drag_thumbnail.xml b/core/res/res/layout/text_drag_thumbnail.xml
new file mode 100644
index 0000000..63d2c05
--- /dev/null
+++ b/core/res/res/layout/text_drag_thumbnail.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2010, 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.
+*/
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textAppearance="@android:style/TextAppearance.Large"
+    android:gravity="center"
+    />
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7e892a4..0aa4247 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Umožňuje aplikaci zobrazit konfiguraci místního telefonu s rozhraním Bluetooth, vytvářet připojení ke spárovaným zařízením a přijímat tato připojení."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"ovládat technologii NFC"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Umožňuje aplikaci komunikovat se štítky, kartami a čtečkami s podporou technologie NFC."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"vypnutí zámku kláves"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Umožňuje aplikaci vypnout zámek kláves a související zabezpečení heslem. Příkladem oprávněného použití této funkce je vypnutí zámku klávesnice při příchozím hovoru a jeho opětovné zapnutí po skončení hovoru."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Umožňuje aplikaci načíst nastavení synchronizace, např. zda má být povolena synchronizace kontaktů."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0dbf3b7..e0be775 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Tillader, at et program viser konfigurationen af den lokale Bluetooth-telefon samt opretter og accepterer forbindelse med parrede enheder."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kontrollere Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Tillader, at et program kommunikerer med tags, kort og læsere i Near Field Communication (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"deaktiver tastaturlås"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Tillader, at et program deaktiverer tastaturlåsen og al associeret adgangskodesikkerhed. Et legitimt eksempel på dette er, at telefonen deaktiverer tastaturlåsen, når der modtages et indgående telefonopkald, og genaktiverer tastaturlåsen, når opkaldet er afsluttet."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"læs indstillinger for synkronisering"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Tillader, at et program læser synkroniseringsindstillingerne, f.eks. om kontakter skal synkroniseres."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0db7b0a..1566b1b 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Ermöglicht einer Anwendung, die Konfiguration des lokalen Bluetooth-Telefons einzusehen und Verbindungen mit Partnergeräten herzustellen und zu akzeptieren."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Nahfeldkommunikation steuern"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Ermöglicht einer Anwendung die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"Tastensperre deaktivieren"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Ermöglicht einer Anwendung, die Tastensperre sowie den damit verbundenen Passwortschutz zu deaktivieren. So wird die Tastensperre vom Telefon deaktiviert, wenn ein Anruf eingeht, und nach Beendigung des Anrufs wieder aktiviert."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"Synchronisierungseinstellungen lesen"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Ermöglicht einer Anwendung, die Synchronisierungseinstellungen zu lesen, etwa ob die Synchronisierung für Kontakte aktiviert ist oder nicht."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index dc3d747..bd86221 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Επιτρέπει σε μια εφαρμογή να προβάλει τη διαμόρφωση του τοπικού τηλεφώνου Bluetooth και επίσης να πραγματοποιεί και να αποδέχεται συνδέσεις με συζευγμένες συσκευές."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"έλεγχος Επικοινωνίας κοντινού πεδίου (Near Field Communication)"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Επιτρέπει σε μια εφαρμογή την επικοινωνία με ετικέτες, τις κάρτες και τους αναγνώστες της Επικοινωνίας κοντινού πεδίου (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"απενεργοποίηση κλειδώματος πληκτρολογίου"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Επιτρέπει σε μια εφαρμογή την απενεργοποίηση του κλειδώματος πληκτρολογίου και άλλης σχετικής ασφάλειας με κωδικό πρόσβασης. Για παράδειγμα, η απενεργοποίηση του κλειδώματος πληκτρολογίου όταν λαμβάνεται εισερχόμενη τηλεφωνική κλήση και η επανενεργοποίηση του κλειδώματος πληκτρολογίου όταν η κλήση τερματιστεί."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ανάγνωση ρυθμίσεων συγχρονισμού"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Επιτρέπει σε μια εφαρμογή την ανάγνωση των ρυθμίσεων συγχρονισμού, όπως π.χ. εάν ο συγχρονισμός είναι ενεργοποιημένος για τις Επαφές."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b518c46..e303707 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -439,6 +439,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Admite una aplicación que ve la configuración del teléfono Bluetooth local, y realiza y acepta conexiones con dispositivos vinculados."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar la Transmisión de datos en proximidad"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Permite que una aplicación se comunique con etiquetas, tarjetas y lectores de Transmisión de datos en proximidad (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"desactivar el bloqueo"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Admite una aplicación que desactiva el bloqueo y cualquier seguridad con contraseña relacionada. Un ejemplo legítimo de esto es el bloqueo desactivado por el teléfono cuando recibe una llamada telefónica entrante, y luego la reactivación del bloqueo cuando finaliza la llamada."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Admite una aplicación que lee la configuración de sincronización, como si está activada la sincronización para los Contactos."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 75e5dc1..452eefd 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Permite que una aplicación vea la configuración del teléfono Bluetooth local, y cree y acepte conexiones con los dispositivos sincronizados."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar Comunicación de campo cercano (NFC)"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Permite que la aplicación se comunique con lectores, tarjetas y etiquetas de Comunicación de campo cercano (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"inhabilitar bloqueo del teclado"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Permite que una aplicación inhabilite el bloqueo del teclado y cualquier protección con contraseña asociada. Un ejemplo legítimo de este permiso es la inhabilitación por parte del teléfono del bloqueo del teclado cuando recibe una llamada telefónica entrante y su posterior habilitación cuando finaliza la llamada."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Permite que una aplicación lea la configuración de sincronización como, por ejemplo, si la sincronización está habilitada para el menú \"Contactos\"."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 0a944b9..a802350 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Permet à une application d\'obtenir la configuration du téléphone Bluetooth local et de créer et accepter des connexions à des appareils associés."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"contrôler la communication en champ proche"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Autorise une application à communiquer avec des tags, cartes et lecteurs prenant en charge la communication en champ proche (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"Désactivation du verrouillage des touches"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Permet à une application de désactiver le verrouillage des touches et toute sécurité par mot de passe. Exemple : Votre téléphone désactive le verrouillage du clavier lorsque vous recevez un appel, puis le réactive lorsque vous raccrochez."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"Lecture des paramètres de synchronisation"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Permet à une application de lire les paramètres de synchronisation (par ex. savoir si la synchronisation est activée pour les Contacts)."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ba71e53..6e5987e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Consente a un\'applicazione di visualizzare la configurazione del telefono Bluetooth locale e di stabilire e accettare connessioni con dispositivi associati."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controllo Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Consente a un\'applicazione di comunicare con tag, schede e lettori NFC (Near Field Communication)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"disattivazione blocco tastiera"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Consente la disattivazione da parte di un\'applicazione del blocco tastiera e di eventuali protezioni tramite password associate. Un valido esempio è la disattivazione da parte del telefono del blocco tastiera quando riceve una telefonata in entrata, e la successiva riattivazione del blocco al termine della chiamata."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lettura impostazioni di sincronizz."</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Consente a un\'applicazione di leggere le impostazioni di sincronizzazione, come l\'attivazione o meno della sincronizzazione per Contatti."</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 748f8a7..12cb290 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"このBluetooth端末の設定表示、および別の端末をペアとして設定し接続を承認することをアプリケーションに許可します。"</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"NFCの管理"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"NFCタグ、カード、リーダーとの通信をアプリケーションに許可します。"</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"キーロックを無効にする"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"キーロックや関連するパスワードセキュリティを無効にすることをアプリケーションに許可します。正当な利用の例では、かかってきた電話を受信する際にキーロックを無効にし、通話の終了時にキーロックを有効にし直します。"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"同期設定の読み取り"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"連絡先の同期の有効/無効など、同期設定の読み取りをアプリケーションに許可します。"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 5951045..36e5134 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"애플리케이션이 로컬 Bluetooth 전화의 구성을 보고 페어링된 장치에 연결하며 연결을 수락할 수 있도록 합니다."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"NFC(Near Field Communication) 제어"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"애플리케이션에서 NFC(Near Field Communication) 태그, 카드 및 리더와 통신할 수 있습니다."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"키 잠금 사용 중지"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"애플리케이션이 키 잠금 및 관련 비밀번호 보안을 사용 중지할 수 있도록 합니다. 예를 들어, 휴대전화가 수신전화를 받을 때 키 잠금을 사용 중지했다가 통화가 끝나면 키 잠금을 다시 사용할 수 있습니다."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"동기화 설정 읽기"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"애플리케이션이 주소록에 동기화를 사용할지 여부와 같은 동기화 설정을 읽을 수 있도록 합니다."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index d97e803..e43aabd 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Lar applikasjonen se konfigurasjonen til den lokale Bluetooth-telefonen, og å opprette og godta tilkoblinger med parede enheter."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kontroller overføring av data med NFC-teknologi"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Tillater programmet å kommunisere data via koder, kort og lesere for NFC-teknologi."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"slå av tastaturlås"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Lar applikasjonen slå av tastaturlåsen og enhver tilknyttet passordsikkerhet. Et legitimt eksempel på dette er at telefonen slår av tastaturlåsen når den mottar et innkommende anrop, og så slår den på igjen når samtalen er over."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Lar applikasjonen lese synkroniseringsinnstillingene, som for eksempel om kontakter blir synkronisert."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 483b236..d66b694 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Hiermee kan een toepassing de configuratie van een lokale Bluetooth-telefoon bekijken en verbindingen met gekoppelde apparaten maken en accepteren."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Near Field Communication regelen"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Hiermee kan een toepassing communiceren met NFC-tags (Near Field Communication), kaarten en lezers."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"toetsvergrendeling uitschakelen"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Hiermee kan een toepassing de toetsvergrendeling en bijbehorende wachtwoordbeveiliging uitschakelen. Een voorbeeld: de telefoon schakelt de toetsvergrendeling uit als er een oproep binnenkomt en schakelt de toetsvergrendeling weer in als de oproep is beëindigd."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Hiermee kan een toepassing de synchronisatie-instellingen lezen, bijvoorbeeld of de synchronisatie van contacten is ingeschakeld."</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d2f345e..66a7160 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Pozwala aplikacji na wyświetlanie konfiguracji lokalnego telefonu Bluetooth oraz na tworzenie i akceptowanie połączeń ze sparowanymi urządzeniami."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kontrolowanie łączności Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Zezwala aplikacji na komunikowanie się z użyciem tagów, kart i czytników Near Field Communication (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"wyłączanie blokady klawiatury"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Pozwala aplikacji na wyłączenie blokady klawiatury i wszystkich związanych z tym haseł zabezpieczających. Typowym przykładem takiego działania jest wyłączanie blokady klawiatury, gdy pojawia się połączenie przychodzące, a następnie ponowne jej włączanie po zakończeniu połączenia."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"czytanie ustawień synchronizowania"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Pozwala aplikacji na czytanie ustawień synchronizacji, takich jak informacje, czy synchronizacja kontaktów jest włączona."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 3252911..990d630 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Permite a uma aplicação ver a configuração do telefone Bluetooth local, bem como efectuar e aceitar ligações com dispositivos emparelhados."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controlo Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Permite que uma aplicação comunique com etiquetas, cartões e leitores Near Field Communication (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"desactivar bloqueio de teclas"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Permite a uma aplicação desactivar o bloqueio de teclas e qualquer segurança por palavra-passe associada. Um exemplo legítimo é a desactivação do bloqueio de teclas pelo telefone ao receber uma chamada, reactivando, em seguida, o bloqueio de teclas ao terminar a chamada."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler definições de sincronização"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Permite a uma aplicação ler as definições de sincronização como, por exemplo, se a sincronização está activada para Contactos."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 28d7bf6..ce106db 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Permite que um aplicativo veja a configuração do telefone Bluetooth local e que possa fazer e aceitar conexões com dispositivos pareados."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"controlar a comunicação a curta distância"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Permite que um aplicativo se comunique com tags, cartões e leitores de comunicação a curta distância (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"desativar o bloqueio de teclas"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Permite que um aplicativo desative o bloqueio de teclas e qualquer segurança por senha associada. Um exemplo legítimo disso é a desativação do bloqueio de teclas pelo telefone ao receber uma chamada e a reativação do bloqueio quando a chamada é finalizada."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler as configurações de sincronização"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Permite que um aplicativo leia as configurações de sincronização, como se a sincronização está ativada para Contatos."</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 3feba6a..bbd61bd 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -444,6 +444,7 @@
     <skip />
     <!-- no translation found for permdesc_nfc (9171401851954407226) -->
     <skip />
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"deactivar la bloccaziun da la tastatura"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Permetta ad ina applicaziun da deactivar la bloccaziun da la tastatura e la protecziun cun il pled-clav associada. In exempel dad ina utilisaziun legitima: La bloccaziun da la tastatura vegn deactivada sche Vus retschavais in clom ed ella vegn reactivada sche Vus finis il telefon."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"leger ils parameters da sincronisaziun"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Permetta ad ina applicaziun da leger ils parameters da sincronisaziun (per exempel per savair sche la sincronisaziun da contacts è activà u betg)."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 38ae2aa..4babb3bd 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Позволяет приложению просматривать конфигурацию локального телефона Bluetooth, создавать подключения с сопряженными устройствами."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"управлять радиосвязью ближнего действия"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Позволяет приложению обмениваться данными с метками, картами и считывателями через радиосвязь ближнего действия (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"отключать блокировку клавиатуры"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Позволяет приложению отключить блокировку клавиатуры и другие функции защиты паролем. Примером допустимого использования этой функции является отключение блокировки клавиатуры при получении входящего вызова и включение блокировки после завершения разговора."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"считывать настройки синхронизации"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Позволяет приложению считывать настройки синхронизации, такие как включение синхронизации Контактов."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index dd05ecb..102a08d16 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Tillåter att ett program ser den lokala Bluetooth-telefonens konfiguration, och skapar och accepterar anslutningar med parkopplade enheter."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"kontrollera närfältskommunikationen"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Tillåter att en app kommunicerar med taggar, kort och läsare för närfältskommunikation (NFC)."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"inaktivera tangentlås"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Tillåter att ett program inaktiverar tangentlåset och tillhörande lösenordsskydd. Ett exempel på detta är att telefonen inaktiverar tangentlåset vid inkommande samtal och sedan aktiverar det igen när samtalet är avslutat."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"läsa synkroniseringsinställningar"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Tillåter att ett program läser synkroniseringsinställningarna, till exempel om synkronisering har aktiverats för kontakter."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 1545d7a..a6bfbf6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"Uygulamaların yerel Bluetooth telefonunun yapılandırmasını görüntülemesine ve eşleşilmiş cihazlar ile bağlantı kurup kabul etmesine izin verir."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Yakın Alan İletişimini denetle"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"Bir uyg\'nın Yakın Alan İletişimi etiketleri, kartları ve okuyclr ile iletşm kurmasına izin verir."</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"tuş kilidini devre dışı bırak"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"Uygulamaların tuş kilidini ve ilgili şifreli güvenlik önlemini devre dışı bırakmasına izin verir. Bunun geçerli bir örneği gelen bir çağrı alındığında tuş kilidinin devre dışı bırakılması, sonra çağrı bittiğinde kilidin yeniden devreye sokulmasıdır."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"senk. ayarlarını oku"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"Uygulamanın, senkronizasyon işlevinin Kişiler için devrede olup olmadığı gibi senkronizasyon ayarlarını okumasına izin verir."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 76690dd..4fd5161 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"允许应用程序查看本地蓝牙手机的配置,以及建立或接受与配对设备的连接。"</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"控制近距离通信"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"允许应用程序与近距离通信 (NFC) 标签、卡和读卡器进行通信。"</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"停用键锁"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"允许应用程序停用键锁和任何关联的密码安全设置。例如,在手机上接听电话时停用键锁,在通话结束后重新启用键锁。"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"允许应用程序读取同步设置,例如是否为“联系人”启用同步。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5fb0998..6d5c4d4 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -440,6 +440,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="762515380679392945">"允許應用程式檢視本機藍牙電話設定,並與其他配對裝置連線。"</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"控制近距離無線通訊"</string>
     <string name="permdesc_nfc" msgid="9171401851954407226">"允許應用程式使用近距離無線通訊 (NFC) 標記、卡片及讀取程式進行通訊。"</string>
+    <string name="permlab_disableKeyguard" msgid="4977406164311535092">"停用按鍵鎖定"</string>
     <string name="permdesc_disableKeyguard" msgid="3189763479326302017">"允許應用程式停用按鍵鎖定以及其他相關的密碼安全性。例如:收到來電時解除按鍵鎖定,通話結束後重新啟動按鍵鎖定。"</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
     <string name="permdesc_readSyncSettings" msgid="5315925706353341823">"允許應用程式讀取同步處理設定,例如:是否同步處理 [聯絡人]。"</string>
diff --git a/docs/html/sdk/adding-components.jd b/docs/html/sdk/adding-components.jd
index 05be0d6..1f9cb31 100644
--- a/docs/html/sdk/adding-components.jd
+++ b/docs/html/sdk/adding-components.jd
@@ -150,14 +150,19 @@
 
 <p>For example, there may be a dependency between the ADT Plugin for Eclipse and
 the SDK Tools component. When you install the SDK Tools
-component, you would then need to upgrade to the required version of ADT (if you
-are developing in Eclipse). In this case, you would find dependencies listed in
-"Revisions" section of the <a href="{@docRoot}sdk/eclipse-adt.html#notes">ADT
-Plugin Notes</a> and <a href="{@docRoot}sdk/tools-notes.html#notes">SDK Tools
-Notes</a> documents. </p>
+component, you should also upgrade to the required version of ADT (if you
+are developing in Eclipse). In this case,  the major version number for your ADT plugin should
+always match the revision number of your SDK Tools (for example, ADT 8.x requires SDK Tools r8).
+</p>
 
-<p>Additionally, the development tools will notify you with debug warnings
-if there is dependency that you need to address. </p>
+<p>Also make sure that, each time you install a new version of the Android platform, you have
+the latest version of the SDK Platform-tools component. The SDK Platform-tools contain
+tools that are backward compatible with all versions of the Android platform and are
+often updated to support new features in the latest version of the Android platform.</p>
+
+<p>The development tools will notify you with debug warnings if there is dependency that you need to
+address. The SDK and AVD Manager also enforces dependencies by requiring that you download any
+components that are needed by those you have selected.</p>
 
 
 <h2 id="AddingSites">Adding New Sites</h2>
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 32111e8..032244f 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -174,11 +174,14 @@
     }
     
     private void setBitmap(Bitmap bitmap) {
-        mBitmap = bitmap;
-        if (bitmap != null) {
-            computeBitmapSize();
-        } else {
-            mBitmapWidth = mBitmapHeight = -1;
+        if (bitmap != mBitmap) {
+            mBitmap = bitmap;
+            if (bitmap != null) {
+                computeBitmapSize();
+            } else {
+                mBitmapWidth = mBitmapHeight = -1;
+            }
+            invalidateSelf();
         }
     }
 
@@ -205,10 +208,7 @@
      * @see android.graphics.Bitmap#getDensity()
      */
     public void setTargetDensity(DisplayMetrics metrics) {
-        mTargetDensity = metrics.densityDpi;
-        if (mBitmap != null) {
-            computeBitmapSize();
-        }
+        setTargetDensity(metrics.densityDpi);
     }
 
     /**
@@ -220,9 +220,12 @@
      * @see android.graphics.Bitmap#getDensity()
      */
     public void setTargetDensity(int density) {
-        mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
-        if (mBitmap != null) {
-            computeBitmapSize();
+        if (mTargetDensity != density) {
+            mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+            if (mBitmap != null) {
+                computeBitmapSize();
+            }
+            invalidateSelf();
         }
     }
 
@@ -239,22 +242,28 @@
      * @param gravity the gravity
      */
     public void setGravity(int gravity) {
-        mBitmapState.mGravity = gravity;
-        mApplyGravity = true;
+        if (mBitmapState.mGravity != gravity) {
+            mBitmapState.mGravity = gravity;
+            mApplyGravity = true;
+            invalidateSelf();
+        }
     }
 
     public void setAntiAlias(boolean aa) {
         mBitmapState.mPaint.setAntiAlias(aa);
+        invalidateSelf();
     }
     
     @Override
     public void setFilterBitmap(boolean filter) {
         mBitmapState.mPaint.setFilterBitmap(filter);
+        invalidateSelf();
     }
 
     @Override
     public void setDither(boolean dither) {
         mBitmapState.mPaint.setDither(dither);
+        invalidateSelf();
     }
 
     public Shader.TileMode getTileModeX() {
@@ -280,6 +289,7 @@
             state.mTileModeX = xmode;
             state.mTileModeY = ymode;
             mRebuildShader = true;
+            invalidateSelf();
         }
     }
 
@@ -336,11 +346,13 @@
     @Override
     public void setAlpha(int alpha) {
         mBitmapState.mPaint.setAlpha(alpha);
+        invalidateSelf();
     }
 
     @Override
     public void setColorFilter(ColorFilter cf) {
         mBitmapState.mPaint.setColorFilter(cf);
+        invalidateSelf();
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 289348a..4d560be 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -87,7 +87,10 @@
      * @param color The color to draw.
      */
     public void setColor(int color) {
-        mState.mBaseColor = mState.mUseColor = color;
+        if (mState.mBaseColor != color || mState.mUseColor != color) {
+            invalidateSelf();
+            mState.mBaseColor = mState.mUseColor = color;
+        }
     }
 
     /**
@@ -109,6 +112,7 @@
         int baseAlpha = mState.mBaseColor >>> 24;
         int useAlpha = baseAlpha * alpha >> 8;
         mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24);
+        invalidateSelf();
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index baa9d62..2f13bef 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -488,7 +488,10 @@
      */
     public boolean setVisible(boolean visible, boolean restart) {
         boolean changed = mVisible != visible;
-        mVisible = visible;
+        if (changed) {
+            mVisible = visible;
+            invalidateSelf();
+        }
         return changed;
     }
 
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index c558632..da8bb1b 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -180,6 +180,7 @@
     public void setCornerRadii(float[] radii) {
         mGradientState.setCornerRadii(radii);
         mPathIsDirty = true;
+        invalidateSelf();
     }
     
     /**
@@ -189,6 +190,7 @@
     public void setCornerRadius(float radius) {
         mGradientState.setCornerRadius(radius);
         mPathIsDirty = true;
+        invalidateSelf();
     }
     
     /**
@@ -214,34 +216,41 @@
             e = new DashPathEffect(new float[] { dashWidth, dashGap }, 0);
         }
         mStrokePaint.setPathEffect(e);
+        invalidateSelf();
     }
     
     public void setSize(int width, int height) {
         mGradientState.setSize(width, height);
         mPathIsDirty = true;
+        invalidateSelf();
     }
     
     public void setShape(int shape) {
         mRingPath = null;
         mPathIsDirty = true;
         mGradientState.setShape(shape);
+        invalidateSelf();
     }
 
     public void setGradientType(int gradient) {
         mGradientState.setGradientType(gradient);
         mRectIsDirty = true;
+        invalidateSelf();
     }
 
     public void setGradientCenter(float x, float y) {
         mGradientState.setGradientCenter(x, y);
+        invalidateSelf();
     }
 
     public void setGradientRadius(float gradientRadius) {
         mGradientState.setGradientRadius(gradientRadius);
+        invalidateSelf();
     }
 
     public void setUseLevel(boolean useLevel) {
         mGradientState.mUseLevel = useLevel;
+        invalidateSelf();
     }
     
     private int modulateAlpha(int alpha) {
@@ -433,6 +442,7 @@
     public void setColor(int argb) {
         mGradientState.setSolidColor(argb);
         mFillPaint.setColor(argb);
+        invalidateSelf();
     }
 
     @Override
@@ -443,17 +453,26 @@
     
     @Override
     public void setAlpha(int alpha) {
-        mAlpha = alpha;
+        if (alpha != mAlpha) {
+            mAlpha = alpha;
+            invalidateSelf();
+        }
     }
 
     @Override
     public void setDither(boolean dither) {
-        mDither = dither;
+        if (dither != mDither) {
+            mDither = dither;
+            invalidateSelf();
+        }
     }
 
     @Override
     public void setColorFilter(ColorFilter cf) {
-        mColorFilter = cf;
+        if (cf != mColorFilter) {
+            mColorFilter = cf;
+            invalidateSelf();
+        }
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 50b4b75..35b8319 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -132,10 +132,7 @@
      * @see android.graphics.Bitmap#getDensity()
      */
     public void setTargetDensity(DisplayMetrics metrics) {
-        mTargetDensity = metrics.densityDpi;
-        if (mNinePatch != null) {
-            computeBitmapSize();
-        }
+        setTargetDensity(metrics.densityDpi);
     }
 
     /**
@@ -147,9 +144,12 @@
      * @see android.graphics.Bitmap#getDensity()
      */
     public void setTargetDensity(int density) {
-        mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
-        if (mNinePatch != null) {
-            computeBitmapSize();
+        if (density != mTargetDensity) {
+            mTargetDensity = density == 0 ? DisplayMetrics.DENSITY_DEFAULT : density;
+            if (mNinePatch != null) {
+                computeBitmapSize();
+            }
+            invalidateSelf();
         }
     }
 
@@ -197,16 +197,19 @@
     @Override
     public void setAlpha(int alpha) {
         getPaint().setAlpha(alpha);
+        invalidateSelf();
     }
     
     @Override
     public void setColorFilter(ColorFilter cf) {
         getPaint().setColorFilter(cf);
+        invalidateSelf();
     }
 
     @Override
     public void setDither(boolean dither) {
         getPaint().setDither(dither);
+        invalidateSelf();
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/PaintDrawable.java b/graphics/java/android/graphics/drawable/PaintDrawable.java
index c86fc46..c71cda1 100644
--- a/graphics/java/android/graphics/drawable/PaintDrawable.java
+++ b/graphics/java/android/graphics/drawable/PaintDrawable.java
@@ -66,6 +66,7 @@
         } else {
             setShape(new RoundRectShape(radii, null, null));
         }
+        invalidateSelf();
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index be1892e..92252fc 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -129,6 +129,7 @@
             }
             mShapeState.mPadding.set(left, top, right, bottom);
         }
+        invalidateSelf();
     }
     
     /**
@@ -144,6 +145,7 @@
             }
             mShapeState.mPadding.set(padding);
         }
+        invalidateSelf();
     }
     
     /**
@@ -153,6 +155,7 @@
      */
     public void setIntrinsicWidth(int width) {
         mShapeState.mIntrinsicWidth = width;
+        invalidateSelf();
     }
     
     /**
@@ -162,6 +165,7 @@
      */
     public void setIntrinsicHeight(int height) {
         mShapeState.mIntrinsicHeight = height;
+        invalidateSelf();
     }
     
     @Override
@@ -236,11 +240,13 @@
      */
     @Override public void setAlpha(int alpha) {
         mShapeState.mAlpha = alpha;
+        invalidateSelf();
     }
     
     @Override
     public void setColorFilter(ColorFilter cf) {
         mShapeState.mPaint.setColorFilter(cf);
+        invalidateSelf();
     }
     
     @Override
@@ -264,6 +270,7 @@
     @Override
     public void setDither(boolean dither) {
         mShapeState.mPaint.setDither(dither);
+        invalidateSelf();
     }
 
     @Override
@@ -344,6 +351,7 @@
                 mShapeState.mPaint.setShader(mShapeState.mShaderFactory.resize(w, h));
             }
         }
+        invalidateSelf();
     }
     
     @Override
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 517868c..0aba347 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -293,6 +293,8 @@
             uint32_t flags,
             Vector<String8> *matchingCodecs);
 
+    void restorePatchedDataPointer(BufferInfo *info);
+
     OMXCodec(const OMXCodec &);
     OMXCodec &operator=(const OMXCodec &);
 };
@@ -305,6 +307,7 @@
 struct CodecCapabilities {
     String8 mComponentName;
     Vector<CodecProfileLevel> mProfileLevels;
+    Vector<OMX_U32> mColorFormats;
 };
 
 // Return a vector of componentNames with supported profile/level pairs
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index d6ae5e9..9d589cf 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -285,6 +285,8 @@
     uint32_t getTransform(int buffer) const;
 
     status_t resize(int newNumBuffers);
+    status_t grow(int newNumBuffers);
+    status_t shrink(int newNumBuffers);
 
     SharedBufferStack::Statistics getStats() const;
     
@@ -346,6 +348,14 @@
     int mNumBuffers;
     BufferList mBufferList;
 
+    struct BuffersAvailableCondition : public ConditionBase {
+        int mNumBuffers;
+        inline BuffersAvailableCondition(SharedBufferServer* sbs,
+                int numBuffers);
+        inline bool operator()() const;
+        inline const char* name() const { return "BuffersAvailableCondition"; }
+    };
+
     struct UnlockUpdate : public UpdateBase {
         const int lockedBuffer;
         inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 2b498c6..40dd117 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -95,6 +95,16 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// Memory management
+///////////////////////////////////////////////////////////////////////////////
+
+void Caches::clearGarbage() {
+    textureCache.clearGarbage();
+    gradientCache.clearGarbage();
+    pathCache.clearGarbage();
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // VBO
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 2779dfd..e8ced9c 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -101,6 +101,12 @@
     }
 
     /**
+     * Call this on each frame to ensure that garbage is deleted from
+     * GPU memory.
+     */
+    void clearGarbage();
+
+    /**
      * Binds the VBO used to render simple textured quads.
      */
     void bindMeshBuffer();
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index d08df44..77d628a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -153,13 +153,13 @@
     mPaints.clear();
 
     for (size_t i = 0; i < mMatrices.size(); i++) {
-        delete  mMatrices.itemAt(i);
+        delete mMatrices.itemAt(i);
     }
     mMatrices.clear();
 
     if (mPathHeap) {
         for (int i = 0; i < mPathHeap->count(); i++) {
-            caches.pathCache.remove(&(*mPathHeap)[i]);
+            caches.pathCache.removeDeferred(&(*mPathHeap)[i]);
         }
         mPathHeap->safeUnref();
     }
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 97f4cb4..a37964e 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -54,7 +54,6 @@
 }
 
 GradientCache::~GradientCache() {
-    Mutex::Autolock _l(mLock);
     mCache.clear();
 }
 
@@ -63,17 +62,14 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 uint32_t GradientCache::getSize() {
-    Mutex::Autolock _l(mLock);
     return mSize;
 }
 
 uint32_t GradientCache::getMaxSize() {
-    Mutex::Autolock _l(mLock);
     return mMaxSize;
 }
 
 void GradientCache::setMaxSize(uint32_t maxSize) {
-    Mutex::Autolock _l(mLock);
     mMaxSize = maxSize;
     while (mSize > mMaxSize) {
         mCache.removeOldest();
@@ -102,17 +98,28 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* GradientCache::get(SkShader* shader) {
-    Mutex::Autolock _l(mLock);
     return mCache.get(shader);
 }
 
 void GradientCache::remove(SkShader* shader) {
-    Mutex::Autolock _l(mLock);
     mCache.remove(shader);
 }
 
-void GradientCache::clear() {
+void GradientCache::removeDeferred(SkShader* shader) {
     Mutex::Autolock _l(mLock);
+    mGarbage.push(shader);
+}
+
+void GradientCache::clearGarbage() {
+    Mutex::Autolock _l(mLock);
+    size_t count = mGarbage.size();
+    for (size_t i = 0; i < count; i++) {
+        mCache.remove(mGarbage.itemAt(i));
+    }
+    mGarbage.clear();
+}
+
+void GradientCache::clear() {
     mCache.clear();
 }
 
@@ -138,21 +145,17 @@
 
     canvas.drawRectCoords(0.0f, 0.0f, bitmap.width(), 1.0f, p);
 
-    mLock.lock();
     // Asume the cache is always big enough
     const uint32_t size = bitmap.rowBytes() * bitmap.height();
     while (mSize + size > mMaxSize) {
         mCache.removeOldest();
     }
-    mLock.unlock();
 
     Texture* texture = new Texture;
     generateTexture(&bitmap, texture);
 
-    mLock.lock();
     mSize += size;
     mCache.put(shader, texture);
-    mLock.unlock();
 
     return texture;
 }
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index c9553f4..30da462 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -19,6 +19,8 @@
 
 #include <SkShader.h>
 
+#include <utils/Vector.h>
+
 #include "Texture.h"
 #include "utils/GenerationCache.h"
 
@@ -53,11 +55,20 @@
      */
     Texture* get(SkShader* shader);
     /**
-     * Removes the texture associated with the specified shader. Returns NULL
-     * if the texture cannot be found. Upon remove the texture is freed.
+     * Removes the texture associated with the specified shader.
+     * Upon remove the texture is freed.
      */
     void remove(SkShader* shader);
     /**
+     * Removes the texture associated with the specified shader. This is meant
+     * to be called from threads that are not the EGL context thread.
+     */
+    void removeDeferred(SkShader* shader);
+    /**
+     * Process deferred removals.
+     */
+    void clearGarbage();
+    /**
      * Clears the cache. This causes all textures to be deleted.
      */
     void clear();
@@ -83,10 +94,7 @@
     uint32_t mSize;
     uint32_t mMaxSize;
 
-    /**
-     * Used to access mCache and mSize. All methods are accessed from a single
-     * thread except for remove().
-     */
+    Vector<SkShader*> mGarbage;
     mutable Mutex mLock;
 }; // class GradientCache
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 540f115..ad72584 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -135,6 +135,8 @@
 }
 
 void OpenGLRenderer::prepare(bool opaque) {
+    mCaches.clearGarbage();
+
     mSnapshot = new Snapshot(mFirstSnapshot,
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
@@ -1463,7 +1465,9 @@
             dirtyLayer(left, top, right, bottom);
         }
     }
-    mCaches.currentProgram->setColor(r, g, b, a);
+    if (!mShader || (mShader && setColor)) {
+        mCaches.currentProgram->setColor(r, g, b, a);
+    }
 
     // Setup attributes and uniforms required by the shaders
     if (mShader) {
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 7ff26dc..8740a64 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -53,7 +53,6 @@
 }
 
 PathCache::~PathCache() {
-    Mutex::Autolock _l(mLock);
     mCache.clear();
 }
 
@@ -72,17 +71,14 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 uint32_t PathCache::getSize() {
-    Mutex::Autolock _l(mLock);
     return mSize;
 }
 
 uint32_t PathCache::getMaxSize() {
-    Mutex::Autolock _l(mLock);
     return mMaxSize;
 }
 
 void PathCache::setMaxSize(uint32_t maxSize) {
-    Mutex::Autolock _l(mLock);
     mMaxSize = maxSize;
     while (mSize > mMaxSize) {
         mCache.removeOldest();
@@ -94,6 +90,14 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) {
+    removeTexture(texture);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+void PathCache::removeTexture(PathTexture* texture) {
     if (texture) {
         const uint32_t size = texture->width * texture->height;
         mSize -= size;
@@ -109,39 +113,46 @@
     }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
 void PathCache::remove(SkPath* path) {
-    Mutex::Autolock _l(mLock);
-
     // TODO: Linear search...
     Vector<uint32_t> pathsToRemove;
     for (uint32_t i = 0; i < mCache.size(); i++) {
         if (mCache.getKeyAt(i).path == path) {
             pathsToRemove.push(i);
+            removeTexture(mCache.getValueAt(i));
         }
     }
 
+    mCache.setOnEntryRemovedListener(NULL);
     for (size_t i = 0; i < pathsToRemove.size(); i++) {
         mCache.removeAt(pathsToRemove.itemAt(i));
     }
+    mCache.setOnEntryRemovedListener(this);
+}
+
+void PathCache::removeDeferred(SkPath* path) {
+    Mutex::Autolock _l(mLock);
+    mGarbage.push(path);
+}
+
+void PathCache::clearGarbage() {
+    Mutex::Autolock _l(mLock);
+    size_t count = mGarbage.size();
+    for (size_t i = 0; i < count; i++) {
+        remove(mGarbage.itemAt(i));
+    }
+    mGarbage.clear();
 }
 
 PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
     PathCacheEntry entry(path, paint);
 
-    mLock.lock();
     PathTexture* texture = mCache.get(entry);
-    mLock.unlock();
 
     if (!texture) {
         texture = addTexture(entry, path, paint);
     } else if (path->getGenerationID() != texture->generation) {
-        mLock.lock();
         mCache.remove(entry);
-        mLock.unlock();
         texture = addTexture(entry, path, paint);
     }
 
@@ -167,11 +178,9 @@
     const uint32_t size = width * height;
     // Don't even try to cache a bitmap that's bigger than the cache
     if (size < mMaxSize) {
-        mLock.lock();
         while (mSize + size > mMaxSize) {
             mCache.removeOldest();
         }
-        mLock.unlock();
     }
 
     PathTexture* texture = new PathTexture;
@@ -200,7 +209,6 @@
     generateTexture(bitmap, texture);
 
     if (size < mMaxSize) {
-        mLock.lock();
         mSize += size;
         PATH_LOGD("PathCache::get: create path: name, size, mSize = %d, %d, %d",
                 texture->id, size, mSize);
@@ -208,7 +216,6 @@
             LOGD("Path created, size = %d", size);
         }
         mCache.put(entry, texture);
-        mLock.unlock();
     } else {
         texture->cleanup = true;
     }
@@ -217,7 +224,6 @@
 }
 
 void PathCache::clear() {
-    Mutex::Autolock _l(mLock);
     mCache.clear();
 }
 
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 0193f43..ae2e55d 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -21,6 +21,8 @@
 #include <SkPaint.h>
 #include <SkPath.h>
 
+#include <utils/Vector.h>
+
 #include "Debug.h"
 #include "Texture.h"
 #include "utils/Compare.h"
@@ -146,6 +148,15 @@
      * Removes an entry.
      */
     void remove(SkPath* path);
+    /**
+     * Removes the specified path. This is meant to be called from threads
+     * that are not the EGL context thread.
+     */
+    void removeDeferred(SkPath* path);
+    /**
+     * Process deferred removals.
+     */
+    void clearGarbage();
 
     /**
      * Sets the maximum size of the cache in bytes.
@@ -166,6 +177,8 @@
      */
     void generateTexture(SkBitmap& bitmap, Texture* texture);
 
+    void removeTexture(PathTexture* texture);
+
     PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint);
 
     void init();
@@ -178,10 +191,7 @@
 
     bool mDebugEnabled;
 
-    /**
-     * Used to access mCache and mSize. All methods are accessed from a single
-     * thread except for remove().
-     */
+    Vector<SkPath*> mGarbage;
     mutable Mutex mLock;
 }; // class PathCache
 
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index 47c5d48..9f18948 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -126,7 +126,7 @@
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
-            Caches::getInstance().textureCache.remove(resource);
+            Caches::getInstance().textureCache.removeDeferred(resource);
         }
         delete resource;
         return;
@@ -143,7 +143,7 @@
     if (ref == NULL) {
         // If we're not tracking this resource, just delete it
         if (Caches::hasInstance()) {
-            Caches::getInstance().gradientCache.remove(resource->getSkShader());
+            Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader());
         }
         delete resource;
         return;
@@ -179,7 +179,7 @@
             {
                 SkBitmap* bitmap = (SkBitmap*)resource;
                 if (Caches::hasInstance()) {
-                    Caches::getInstance().textureCache.remove(bitmap);
+                    Caches::getInstance().textureCache.removeDeferred(bitmap);
                 }
                 delete bitmap;
             }
@@ -188,7 +188,7 @@
             {
                 SkiaShader* shader = (SkiaShader*)resource;
                 if (Caches::hasInstance()) {
-                    Caches::getInstance().gradientCache.remove(shader->getSkShader());
+                    Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader());
                 }
                 delete shader;
             }
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index e7e1187..590a9d7 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -63,8 +63,7 @@
         GLuint* textureUnit) {
 }
 
-void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) {
-    glActiveTexture(gTextureUnitsMap[textureUnit]);
+void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT) {
     glBindTexture(GL_TEXTURE_2D, texture->id);
     if (wrapS != texture->wrapS) {
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
@@ -132,7 +131,7 @@
     computeScreenSpaceMatrix(textureTransform, modelView);
 
     // Uniforms
-    bindTexture(texture, mWrapS, mWrapT, textureSlot);
+    bindTexture(texture, mWrapS, mWrapT);
     glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
             GL_FALSE, &textureTransform.data[0]);
@@ -204,7 +203,7 @@
     computeScreenSpaceMatrix(screenSpace, modelView);
 
     // Uniforms
-    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
+    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
     glUniform1i(program->getUniform("gradientSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
 }
@@ -297,7 +296,7 @@
     computeScreenSpaceMatrix(screenSpace, modelView);
 
     // Uniforms
-    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot);
+    bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY]);
     glUniform1i(program->getUniform("gradientSampler"), textureSlot);
     glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
 }
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 1d884ab..6702129 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -97,7 +97,11 @@
     void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
 
 protected:
-    inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
+    /**
+     * The appropriate texture unit must have been activated prior to invoking
+     * this method.
+     */
+    inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
 
     Type mType;
     SkShader* mKey;
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 1be6868..ebecebe 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -53,7 +53,6 @@
 }
 
 TextureCache::~TextureCache() {
-    Mutex::Autolock _l(mLock);
     mCache.clear();
 }
 
@@ -71,17 +70,14 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 uint32_t TextureCache::getSize() {
-    Mutex::Autolock _l(mLock);
     return mSize;
 }
 
 uint32_t TextureCache::getMaxSize() {
-    Mutex::Autolock _l(mLock);
     return mMaxSize;
 }
 
 void TextureCache::setMaxSize(uint32_t maxSize) {
-    Mutex::Autolock _l(mLock);
     mMaxSize = maxSize;
     while (mSize > mMaxSize) {
         mCache.removeOldest();
@@ -111,9 +107,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Texture* TextureCache::get(SkBitmap* bitmap) {
-    mLock.lock();
     Texture* texture = mCache.get(bitmap);
-    mLock.unlock();
 
     if (!texture) {
         if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
@@ -124,11 +118,9 @@
         const uint32_t size = bitmap->rowBytes() * bitmap->height();
         // Don't even try to cache a bitmap that's bigger than the cache
         if (size < mMaxSize) {
-            mLock.lock();
             while (mSize + size > mMaxSize) {
                 mCache.removeOldest();
             }
-            mLock.unlock();
         }
 
         texture = new Texture;
@@ -136,7 +128,6 @@
         generateTexture(bitmap, texture, false);
 
         if (size < mMaxSize) {
-            mLock.lock();
             mSize += size;
             TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
                      bitmap, texture->id, size, mSize);
@@ -144,7 +135,6 @@
                 LOGD("Texture created, size = %d", size);
             }
             mCache.put(bitmap, texture);
-            mLock.unlock();
         } else {
             texture->cleanup = true;
         }
@@ -156,12 +146,24 @@
 }
 
 void TextureCache::remove(SkBitmap* bitmap) {
-    Mutex::Autolock _l(mLock);
     mCache.remove(bitmap);
 }
 
-void TextureCache::clear() {
+void TextureCache::removeDeferred(SkBitmap* bitmap) {
     Mutex::Autolock _l(mLock);
+    mGarbage.push(bitmap);
+}
+
+void TextureCache::clearGarbage() {
+    Mutex::Autolock _l(mLock);
+    size_t count = mGarbage.size();
+    for (size_t i = 0; i < count; i++) {
+        mCache.remove(mGarbage.itemAt(i));
+    }
+    mGarbage.clear();
+}
+
+void TextureCache::clear() {
     mCache.clear();
     TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize);
 }
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 27693df..f7707f7 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -19,6 +19,8 @@
 
 #include <SkBitmap.h>
 
+#include <utils/Vector.h>
+
 #include "Debug.h"
 #include "Texture.h"
 #include "utils/GenerationCache.h"
@@ -64,11 +66,21 @@
      */
     Texture* get(SkBitmap* bitmap);
     /**
-     * Removes the texture associated with the specified bitmap. Returns NULL
-     * if the texture cannot be found. Upon remove the texture is freed.
+     * Removes the texture associated with the specified bitmap.
+     * Upon remove the texture is freed.
      */
     void remove(SkBitmap* bitmap);
     /**
+     * Removes the texture associated with the specified bitmap. This is meant
+     * to be called from threads that are not the EGL context thread.
+     */
+    void removeDeferred(SkBitmap* bitmap);
+    /**
+     * Process deferred removals.
+     */
+    void clearGarbage();
+
+    /**
      * Clears the cache. This causes all textures to be deleted.
      */
     void clear();
@@ -109,10 +121,7 @@
 
     bool mDebugEnabled;
 
-    /**
-     * Used to access mCache and mSize. All methods are accessed from a single
-     * thread except for remove().
-     */
+    Vector<SkBitmap*> mGarbage;
     mutable Mutex mLock;
 }; // class TextureCache
 
diff --git a/libs/hwui/utils/GenerationCache.h b/libs/hwui/utils/GenerationCache.h
index 2e76236..42e6d9b 100644
--- a/libs/hwui/utils/GenerationCache.h
+++ b/libs/hwui/utils/GenerationCache.h
@@ -130,7 +130,7 @@
 
 template<typename K, typename V>
 V GenerationCache<K, V>::getValueAt(uint32_t index) const {
-    return mCache.valueAt(index);
+    return mCache.valueAt(index)->value;
 }
 
 template<typename K, typename V>
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 8f583f06..3b2ef84 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -265,6 +265,14 @@
             (stack.queued > 0 && stack.inUse != buf));
 }
 
+SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition(
+        SharedBufferServer* sbs, int numBuffers) : ConditionBase(sbs),
+        mNumBuffers(numBuffers) {
+}
+bool SharedBufferServer::BuffersAvailableCondition::operator()() const {
+    return stack.available == mNumBuffers;
+}
+
 // ----------------------------------------------------------------------------
 
 SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
@@ -448,6 +456,7 @@
 
     const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
     stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
+
     return err;
 }
 
@@ -492,6 +501,7 @@
     if (err == NO_ERROR) {
         mNumBuffers = bufferCount;
         queued_head = (stack.head + stack.queued) % mNumBuffers;
+        tail = computeTail();
     }
     return err;
 }
@@ -606,17 +616,24 @@
  */
 status_t SharedBufferServer::resize(int newNumBuffers)
 {
-    if (uint32_t(newNumBuffers) >= SharedBufferStack::NUM_BUFFER_MAX)
+    if ((unsigned int)(newNumBuffers) < SharedBufferStack::NUM_BUFFER_MIN ||
+        (unsigned int)(newNumBuffers) > SharedBufferStack::NUM_BUFFER_MAX) {
         return BAD_VALUE;
+    }
 
     RWLock::AutoWLock _l(mLock);
 
-    // for now we're not supporting shrinking
-    const int numBuffers = mNumBuffers;
-    if (newNumBuffers < numBuffers)
-        return BAD_VALUE;
+    if (newNumBuffers < mNumBuffers) {
+        return shrink(newNumBuffers);
+    } else {
+        return grow(newNumBuffers);
+    }
+}
 
+status_t SharedBufferServer::grow(int newNumBuffers)
+{
     SharedBufferStack& stack( *mSharedStack );
+    const int numBuffers = mNumBuffers;
     const int extra = newNumBuffers - numBuffers;
 
     // read the head, make sure it's valid
@@ -650,6 +667,54 @@
     return NO_ERROR;
 }
 
+status_t SharedBufferServer::shrink(int newNumBuffers)
+{
+    SharedBufferStack& stack( *mSharedStack );
+
+    // Shrinking is only supported if there are no buffers currently dequeued.
+    int32_t avail = stack.available;
+    int32_t queued = stack.queued;
+    if (avail + queued != mNumBuffers) {
+        return INVALID_OPERATION;
+    }
+
+    // Wait for any queued buffers to be displayed.
+    BuffersAvailableCondition condition(this, mNumBuffers);
+    status_t err = waitForCondition(condition);
+    if (err < 0) {
+        return err;
+    }
+
+    // Reset head to index 0 and make it refer to buffer 0.  The same renaming
+    // (head -> 0) is done in the BufferManager.
+    int32_t head = stack.head;
+    int8_t* index = const_cast<int8_t*>(stack.index);
+    for (int8_t i = 0; i < newNumBuffers; i++) {
+        index[i] = i;
+    }
+    stack.head = 0;
+    stack.headBuf = 0;
+
+    // If one of the buffers is in use it must be the head buffer, which we are
+    // renaming to buffer 0.
+    if (stack.inUse > 0) {
+        stack.inUse = 0;
+    }
+
+    // Free the buffers from the end of the list that are no longer needed.
+    for (int i = newNumBuffers; i < mNumBuffers; i++) {
+        mBufferList.remove(i);
+    }
+
+    // Tell the client to reallocate all the buffers.
+    reallocateAll();
+
+    mNumBuffers = newNumBuffers;
+    stack.available = newNumBuffers;
+
+    return NO_ERROR;
+}
+
 SharedBufferStack::Statistics SharedBufferServer::getStats() const
 {
     SharedBufferStack& stack( *mSharedStack );
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 7af6ce8..9467a4c 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -855,6 +855,12 @@
     status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
     LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
             bufferCount, strerror(-err));
+
+    if (err == NO_ERROR) {
+        // Clear out any references to the old buffers.
+        mBuffers.clear();
+    }
+
     return err;
 }
 
@@ -1029,7 +1035,7 @@
         // one of the buffers for which we do know the index.  This can happen
         // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that
         // was dequeued from an ANativeWindow.
-        for (int i = 0; i < mBuffers.size(); i++) {
+        for (size_t i = 0; i < mBuffers.size(); i++) {
             if (buffer->handle == mBuffers[i]->handle) {
                 idx = mBuffers[i]->getIndex();
                 break;
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
index f409f48..7ef5926 100644
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
+++ b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
@@ -32,7 +32,8 @@
 int main(int argc, char** argv)
 {
     SharedClient client;
-    SharedBufferServer s(&client, 0, 4, 0);
+    sp<SharedBufferServer> ps(new SharedBufferServer(&client, 0, 4, 0));
+    SharedBufferServer& s(*ps);
     SharedBufferClient c(&client, 0, 4, 0);
 
     printf("basic test 0\n");
@@ -67,6 +68,10 @@
     int list3[6] = {3, 2, 1, 4, 5, 0};
     test0(s, c, 6, list3);
 
+    c.setBufferCount(4, resize);
+    int list4[4] = {1, 2, 3, 0};
+    test0(s, c, 4, list4);
+
     return 0;
 }
 
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 532a2df..80c97a0 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -170,6 +170,7 @@
         addFileType("OTA", FILE_TYPE_MID, "audio/midi");
         
         addFileType("MPEG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
+        addFileType("MPG", FILE_TYPE_MP4, "video/mpeg", MtpConstants.FORMAT_MPEG);
         addFileType("MP4", FILE_TYPE_MP4, "video/mp4", MtpConstants.FORMAT_MPEG);
         addFileType("M4V", FILE_TYPE_M4V, "video/mp4", MtpConstants.FORMAT_MPEG);
         addFileType("3GP", FILE_TYPE_3GPP, "video/3gpp",  MtpConstants.FORMAT_3GP_CONTAINER);
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 9f9c83a..3d490c9 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1913,6 +1913,13 @@
 
             // Buffer could not be released until empty buffer done is called.
             if (info->mMediaBuffer != NULL) {
+                if (mIsEncoder &&
+                    (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
+                    // If zero-copy mode is enabled this will send the
+                    // input buffer back to the upstream source.
+                    restorePatchedDataPointer(info);
+                }
+
                 info->mMediaBuffer->release();
                 info->mMediaBuffer = NULL;
             }
@@ -2462,6 +2469,7 @@
     status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
 
     if (err == OK && info->mMediaBuffer != NULL) {
+        CHECK_EQ(portIndex, kPortIndexOutput);
         info->mMediaBuffer->setObserver(NULL);
 
         // Make sure nobody but us owns this buffer at this point.
@@ -2474,6 +2482,7 @@
         }
 
         info->mMediaBuffer->release();
+        info->mMediaBuffer = NULL;
     }
 
     if (err == OK) {
@@ -2714,10 +2723,10 @@
         if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
             CHECK(mOMXLivesLocally && offset == 0);
             OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *) info->mBuffer;
+            CHECK(header->pBuffer == info->mData);
             header->pBuffer = (OMX_U8 *) srcBuffer->data() + srcBuffer->range_offset();
             releaseBuffer = false;
             info->mMediaBuffer = srcBuffer;
-            // FIXME: we are leaking memory
         } else {
             if (mIsMetaDataStoredInVideoBuffers) {
                 releaseBuffer = false;
@@ -3997,8 +4006,30 @@
             caps->mProfileLevels.push(profileLevel);
         }
 
+        // Color format query
+        OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat;
+        InitOMXParams(&portFormat);
+        portFormat.nPortIndex = queryDecoders ? 1 : 0;
+        for (portFormat.nIndex = 0;; ++portFormat.nIndex)  {
+            err = omx->getParameter(
+                    node, OMX_IndexParamVideoPortFormat,
+                    &portFormat, sizeof(portFormat));
+            if (err != OK) {
+                break;
+            }
+            caps->mColorFormats.push(portFormat.eColorFormat);
+        }
+
         CHECK_EQ(omx->freeNode(node), OK);
     }
 }
 
+void OMXCodec::restorePatchedDataPointer(BufferInfo *info) {
+    CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames));
+    CHECK(mOMXLivesLocally);
+
+    OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer;
+    header->pBuffer = (OMX_U8 *)info->mData;
+}
+
 }  // namespace android
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index 23bbb87..64ffa4e 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -344,10 +344,8 @@
     
     @LargeTest
     public void testWAVSeekToEnd() throws Exception {
-        if (isWMVEnable) {
-            boolean isEnd = CodecTest.seekToEnd(MediaNames.WAV);
-            assertTrue("WAV seekToEnd", isEnd);
-        }
+        boolean isEnd = CodecTest.seekToEnd(MediaNames.WAV);
+        assertTrue("WAV seekToEnd", isEnd);
     }  
     
     @MediumTest
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index fee7263..828fae8 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b6ca93b..74def1c 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Seneste"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index d3fb06e..e033982 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Zuletzt verwendet"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f50395b..ddcfc2c 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Πρόσφατα"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index a6ce25a..aff9f4ca 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index fc75775..0b6af34 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Reciente"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 22b8d5e..0e2a765 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8af1d9a..c45bb4c 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recenti"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 807ecd6..f6a8e5f 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"新着"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 0c13821..1189194 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"최근 사용한 앱"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 380e751..b5f4676 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Nylig"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7159b06..ec8fcfb 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recent"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 3b03b52..7034a6d 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Najnowsze"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f59ce9b..80028a2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 950f196..006379c 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Recente"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index 8a8d8ae..646d7f5 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Utilisà sco ultim"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index bb8b375..d598ff3 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Недавние"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 1bcd55f..6ecdfa8 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 96b88de..059a4f1 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"En Son Görevler"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0dcb31c..9c1f71f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"近期任务"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 16c3427..11051be 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -40,6 +40,8 @@
     <string name="recent_tasks_title" msgid="3691764623638127888">"最新的"</string>
     <!-- no translation found for recent_tasks_empty (1905484479067697884) -->
     <skip />
+    <!-- no translation found for recent_tasks_app_label (3796483981246752469) -->
+    <skip />
     <!-- no translation found for toast_rotation_free (2700542202836832631) -->
     <skip />
     <!-- no translation found for toast_rotation_locked (7484691306949652450) -->
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ba8d7d2..1ec8a22 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6702,9 +6702,14 @@
             if (info.broadcastIntentAction != null) {
                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
             }
-            if (info != null && info.durationMillis != -1) {
+            if (info.durationMillis != -1) {
                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
             }
+            if (info.tags != null) {
+                for (String tag : info.tags) {
+                    sb.append("Span-Tag: ").append(tag).append("\n");
+                }
+            }
             sb.append("\n");
             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
                 sb.append(info.crashInfo.stackTrace);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index c9ab992..b5e73ac 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -218,25 +218,13 @@
             break;
         }
 
+        recordLastValue(buffer, count);
+
         const SortedVector< wp<SensorEventConnection> > activeConnections(
                 getActiveConnections());
 
         size_t numConnections = activeConnections.size();
         if (numConnections) {
-            Mutex::Autolock _l(mLock);
-
-            // record the last event for each sensor
-            int32_t prev = buffer[0].sensor;
-            for (ssize_t i=1 ; i<count ; i++) {
-                // record the last event of each sensor type in this buffer
-                int32_t curr = buffer[i].sensor;
-                if (curr != prev) {
-                    mLastEventSeen.editValueFor(prev) = buffer[i-1];
-                    prev = curr;
-                }
-            }
-            mLastEventSeen.editValueFor(prev) = buffer[count-1];
-
             for (size_t i=0 ; i<numConnections ; i++) {
                 sp<SensorEventConnection> connection(activeConnections[i].promote());
                 if (connection != 0) {
@@ -251,6 +239,24 @@
     return false;
 }
 
+void SensorService::recordLastValue(
+        sensors_event_t const * buffer, size_t count)
+{
+    Mutex::Autolock _l(mLock);
+
+    // record the last event for each sensor
+    int32_t prev = buffer[0].sensor;
+    for (size_t i=1 ; i<count ; i++) {
+        // record the last event of each sensor type in this buffer
+        int32_t curr = buffer[i].sensor;
+        if (curr != prev) {
+            mLastEventSeen.editValueFor(prev) = buffer[i-1];
+            prev = curr;
+        }
+    }
+    mLastEventSeen.editValueFor(prev) = buffer[count-1];
+}
+
 SortedVector< wp<SensorService::SensorEventConnection> >
 SensorService::getActiveConnections() const
 {
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index dfb1c0e..b442779 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -111,6 +111,8 @@
     String8 getSensorName(int handle) const;
     status_t recomputeEventsPeriodLocked(int32_t handle);
 
+    void recordLastValue(sensors_event_t const * buffer, size_t count);
+
     // constants
     Vector<Sensor> mSensorList;
     struct sensors_poll_device_t* mSensorDevice;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1b06843..7be58c6 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -340,8 +340,10 @@
 
     // NOTE: lcblk->resize() is protected by an internal lock
     status_t err = lcblk->resize(bufferCount);
-    if (err == NO_ERROR)
-        mBufferManager.resize(bufferCount);
+    if (err == NO_ERROR) {
+        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+        mBufferManager.resize(bufferCount, mFlinger, dpy);
+    }
 
     return err;
 }
@@ -774,9 +776,52 @@
 {
 }
 
-status_t Layer::BufferManager::resize(size_t size)
+status_t Layer::BufferManager::resize(size_t size,
+        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
 {
     Mutex::Autolock _l(mLock);
+
+    if (size < mNumBuffers) {
+        // Move the active texture into slot 0
+        BufferData activeBufferData = mBufferData[mActiveBuffer];
+        mBufferData[mActiveBuffer] = mBufferData[0];
+        mBufferData[0] = activeBufferData;
+        mActiveBuffer = 0;
+
+        // Free the buffers that are no longer needed.
+        for (size_t i = size; i < mNumBuffers; i++) {
+            mBufferData[i].buffer = 0;
+
+            // Create a message to destroy the textures on SurfaceFlinger's GL
+            // thread.
+            class MessageDestroyTexture : public MessageBase {
+                Image mTexture;
+                EGLDisplay mDpy;
+             public:
+                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
+                    : mTexture(texture), mDpy(dpy) { }
+                virtual bool handler() {
+                    status_t err = Layer::BufferManager::destroyTexture(
+                            &mTexture, mDpy);
+                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
+                            mTexture.name, strerror(-err));
+                    return true; // XXX: err == 0;  ????
+                }
+            };
+
+            MessageDestroyTexture *msg = new MessageDestroyTexture(
+                    mBufferData[i].texture, dpy);
+
+            // Don't allow this texture to be cleaned up by
+            // BufferManager::destroy.
+            mBufferData[i].texture.name = -1U;
+            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
+
+            // Post the message to the SurfaceFlinger object.
+            flinger->postMessageAsync(msg);
+        }
+    }
+
     mNumBuffers = size;
     return NO_ERROR;
 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index caa6d17..07434cf 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -177,7 +177,8 @@
         sp<GraphicBuffer> detachBuffer(size_t index);
         status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
         // resize the number of active buffers
-        status_t resize(size_t size);
+        status_t resize(size_t size, const sp<SurfaceFlinger>& flinger,
+                EGLDisplay dpy);
 
         // ----------------------------------------------
         // must be called from GL thread
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c59f2fd..2e785aa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -786,10 +786,6 @@
 {
     // compute the invalid region
     mInvalidRegion.orSelf(mDirtyRegion);
-    if (mInvalidRegion.isEmpty()) {
-        // nothing to do
-        return;
-    }
 
     if (UNLIKELY(mDebugRegion)) {
         debugFlashRegions();
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
index 68bcf11..d425734 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
@@ -56,21 +56,38 @@
     private static final int MSG_SET_TOUCH_MODIFIER = 16;
     private static final int MSG_CANCEL_TOUCH_POINT = 17;
 
-    public static class TouchPoint {
-        WebView mWebView;
-        private int mId;
+    private static class Point {
         private int mX;
         private int mY;
+
+        public Point(int x, int y) {
+            mX = x;
+            mY = y;
+        }
+        public int x() {
+            return mX;
+        }
+        public int y() {
+            return mY;
+        }
+    }
+
+    private Point createViewPointFromContentCoordinates(int x, int y) {
+        return new Point((int)(x * mWebView.getScale()) - mWebView.getScrollX(),
+                         (int)(y * mWebView.getScale()) - mWebView.getScrollY());
+    }
+
+    public static class TouchPoint {
+        private int mId;
+        private Point mPoint;
         private long mDownTime;
         private boolean mReleased = false;
         private boolean mMoved = false;
         private boolean mCancelled = false;
 
-        public TouchPoint(WebView webView, int id, int x, int y) {
-            mWebView = webView;
+        public TouchPoint(int id, Point point) {
             mId = id;
-            mX = scaleX(x);
-            mY = scaleY(y);
+            mPoint = point;
         }
 
         public int getId() {
@@ -78,20 +95,19 @@
         }
 
         public int getX() {
-            return mX;
+            return mPoint.x();
         }
 
         public int getY() {
-            return mY;
+            return mPoint.y();
         }
 
         public boolean hasMoved() {
             return mMoved;
         }
 
-        public void move(int newX, int newY) {
-            mX = scaleX(newX);
-            mY = scaleY(newY);
+        public void move(Point point) {
+            mPoint = point;
             mMoved = true;
         }
 
@@ -122,20 +138,11 @@
         public void cancel() {
             mCancelled = true;
         }
-
-        private int scaleX(int x) {
-            return (int)(x * mWebView.getScale()) - mWebView.getScrollX();
-        }
-
-        private int scaleY(int y) {
-            return (int)(y * mWebView.getScale()) - mWebView.getScrollY();
-        }
     }
 
     private List<TouchPoint> mTouchPoints;
     private int mTouchMetaState;
-    private int mMouseX;
-    private int mMouseY;
+    private Point mMousePoint;
 
     private WebView mWebView;
 
@@ -177,15 +184,19 @@
                 /** MOUSE */
 
                 case MSG_MOUSE_DOWN:
-                    ts = SystemClock.uptimeMillis();
-                    event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mMouseX, mMouseY, 0);
-                    mWebView.onTouchEvent(event);
+                    if (mMousePoint != null) {
+                        ts = SystemClock.uptimeMillis();
+                        event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_DOWN, mMousePoint.x(), mMousePoint.y(), 0);
+                        mWebView.onTouchEvent(event);
+                    }
                     break;
 
                 case MSG_MOUSE_UP:
-                    ts = SystemClock.uptimeMillis();
-                    event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mMouseX, mMouseY, 0);
-                    mWebView.onTouchEvent(event);
+                    if (mMousePoint != null) {
+                        ts = SystemClock.uptimeMillis();
+                        event = MotionEvent.obtain(ts, ts, MotionEvent.ACTION_UP, mMousePoint.x(), mMousePoint.y(), 0);
+                        mWebView.onTouchEvent(event);
+                    }
                     break;
 
                 case MSG_MOUSE_CLICK:
@@ -194,8 +205,7 @@
                     break;
 
                 case MSG_MOUSE_MOVE_TO:
-                    mMouseX = msg.arg1;
-                    mMouseY = msg.arg2;
+                    mMousePoint = createViewPointFromContentCoordinates(msg.arg1, msg.arg2);
                     break;
 
                 /** TOUCH */
@@ -208,8 +218,8 @@
                     } else {
                         id = getTouchPoints().get(numPoints - 1).getId() + 1;
                     }
-                    getTouchPoints().add(new TouchPoint(mWebView, id,
-                            msg.arg1, msg.arg2));
+                    getTouchPoints().add(
+                            new TouchPoint(id, createViewPointFromContentCoordinates(msg.arg1, msg.arg2)));
                     break;
 
                 case MSG_TOUCH_START:
@@ -232,7 +242,8 @@
                         break;
                     }
 
-                    getTouchPoints().get(index).move(bundle.getInt("x"), bundle.getInt("y"));
+                    getTouchPoints().get(index).move(
+                            createViewPointFromContentCoordinates(bundle.getInt("x"), bundle.getInt("y")));
                     break;
 
                 case MSG_TOUCH_MOVE:
@@ -333,8 +344,7 @@
         mWebView = webView;
         mTouchPoints = null;
         mTouchMetaState = 0;
-        mMouseX = 0;
-        mMouseY = 0;
+        mMousePoint = null;
     }
 
     public void enableDOMUIEventLogging(int domNode) {
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index aeeffa6..7204ace 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -4,9 +4,9 @@
 	<classpathentry kind="src" path="tests"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
-	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_SRC/dalvik/libcore/xml/src/main/java"/>
-	<classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_SRC/development/tools/ninepatch/src"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilt/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_OUT_FRAMEWORK/ninepatch.jar" sourcepath="/ANDROID_PLAT_SRC/development/tools/ninepatch/src"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index e97b1e6..392462f 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Bitmap.Config;
 import android.os.Parcel;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index ce8e960..374bbb4 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Paint_Delegate.FontInfo;
 import android.text.TextUtils;
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
index 59b6a91..7ee72d8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.graphics.DashPathEffect
diff --git a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
index 405e537..7573dc1 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LinearGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Shader.TileMode;
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
index 0966f39..77de32d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java
@@ -17,7 +17,7 @@
 package android.graphics;
 
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Matrix.ScaleToFit;
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 6e90bdd..d83a33b 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Paint.FontMetrics;
 import android.graphics.Paint.FontMetricsInt;
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
index 6827ae7..ce7eef0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.graphics.PathEffect
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
index c242e80..a5885ea 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.graphics.PorterDuffXfermode
diff --git a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
index c4e764c..c36ce53 100644
--- a/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/RadialGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import android.graphics.Shader.TileMode;
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 4dcf144..646ac80 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.graphics.Shader
diff --git a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
index 0492e4f..358c3c7 100644
--- a/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/SweepGradient_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 import java.awt.Paint;
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 7e90e7d..0b54a0e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -16,8 +16,8 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
-import com.android.layoutlib.bridge.FontLoader;
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
 
 import android.content.res.AssetManager;
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
index d4408cf..0c1170d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.graphics;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.graphics.Xfermode
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
index ed24e16..9ca1338 100644
--- a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
@@ -16,7 +16,7 @@
 
 package android.util;
 
-import com.android.layoutlib.bridge.DelegateManager;
+import com.android.layoutlib.bridge.impl.DelegateManager;
 
 /**
  * Delegate implementing the native methods of android.util.FloatMath
diff --git a/tools/layoutlib/bridge/src/android/view/SurfaceView.java b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
index ce32da9..f7db98a 100644
--- a/tools/layoutlib/bridge/src/android/view/SurfaceView.java
+++ b/tools/layoutlib/bridge/src/android/view/SurfaceView.java
@@ -16,7 +16,7 @@
 
 package android.view;
 
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
 
 import android.content.Context;
 import android.graphics.Canvas;
diff --git a/tools/layoutlib/bridge/src/android/webkit/WebView.java b/tools/layoutlib/bridge/src/android/webkit/WebView.java
index 3b66188..a20a9d1 100644
--- a/tools/layoutlib/bridge/src/android/webkit/WebView.java
+++ b/tools/layoutlib/bridge/src/android/webkit/WebView.java
@@ -16,7 +16,7 @@
 
 package android.webkit;
 
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
 
 import android.content.Context;
 import android.graphics.Bitmap;
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 996a942..d2092d1 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,63 +16,26 @@
 
 package com.android.layoutlib.bridge;
 
-import com.android.internal.util.XmlUtils;
-import com.android.layoutlib.api.ILayoutBridge;
 import com.android.layoutlib.api.ILayoutLog;
-import com.android.layoutlib.api.ILayoutResult;
 import com.android.layoutlib.api.IProjectCallback;
 import com.android.layoutlib.api.IResourceValue;
-import com.android.layoutlib.api.IStyleResourceValue;
 import com.android.layoutlib.api.IXmlPullParser;
-import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
-import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
-import com.android.layoutlib.bridge.LayoutResult.LayoutViewInfo;
+import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.SceneParams;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.bridge.android.BridgeAssetManager;
+import com.android.layoutlib.bridge.impl.FontLoader;
+import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
 import com.android.ninepatch.NinePatch;
 import com.android.tools.layoutlib.create.MethodAdapter;
 import com.android.tools.layoutlib.create.OverrideMethod;
 
-import android.app.Fragment_Delegate;
-import android.content.ClipData;
-import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap_Delegate;
-import android.graphics.Canvas;
-import android.graphics.Canvas_Delegate;
-import android.graphics.Rect;
-import android.graphics.Region;
 import android.graphics.Typeface_Delegate;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.util.DisplayMetrics;
-import android.util.TypedValue;
-import android.view.BridgeInflater;
-import android.view.DragEvent;
-import android.view.IWindow;
-import android.view.IWindowSession;
-import android.view.InputChannel;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.AttachInfo;
-import android.view.View.MeasureSpec;
-import android.view.WindowManager.LayoutParams;
-import android.widget.FrameLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
 
-import java.awt.image.BufferedImage;
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -81,10 +44,7 @@
  * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
  * {@link #computeLayout(IXmlPullParser, Object, int, int, String, boolean, Map, Map, IProjectCallback, ILayoutLog)}.
  */
-public final class Bridge implements ILayoutBridge {
-
-    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
-    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+public final class Bridge extends LayoutBridge {
 
     public static class StaticMethodNotImplementedException extends RuntimeException {
         private static final long serialVersionUID = 1L;
@@ -143,34 +103,28 @@
         }
     };
 
-    /**
-     * Logger defined during a compute layout operation.
-     * <p/>
-     * This logger is generally set to {@link #sDefaultLogger} except during rendering
-     * operations when it might be set to a specific provided logger.
-     * <p/>
-     * To change this value, use a block synchronized on {@link #sDefaultLogger}.
-     */
-    private static ILayoutLog sLogger = sDefaultLogger;
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#getApiLevel()
-     */
+    @Override
     public int getApiLevel() {
-        return API_CURRENT;
+        return LayoutBridge.API_CURRENT;
     }
 
     /*
      * (non-Javadoc)
      * @see com.android.layoutlib.api.ILayoutLibBridge#init(java.lang.String, java.util.Map)
      */
-    public boolean init(
-            String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+    @Override
+    public boolean init(String fontOsLocation, Map<String, Map<String, Integer>> enumValueMap) {
+        BridgeAssetManager.initSystem();
 
         return sinit(fontOsLocation, enumValueMap);
     }
 
+    @Override
+    public boolean dispose() {
+        BridgeAssetManager.clearSystem();
+        return true;
+    }
+
     private static synchronized boolean sinit(String fontOsLocation,
             Map<String, Map<String, Integer>> enumValueMap) {
 
@@ -189,12 +143,8 @@
             OverrideMethod.setDefaultListener(new MethodAdapter() {
                 @Override
                 public void onInvokeV(String signature, boolean isNative, Object caller) {
-                    if (sLogger != null) {
-                        synchronized (sDefaultLogger) {
-                            sLogger.error("Missing Stub: " + signature +
-                                    (isNative ? " (native)" : ""));
-                        }
-                    }
+                    sDefaultLogger.error("Missing Stub: " + signature +
+                            (isNative ? " (native)" : ""));
 
                     if (debug.equalsIgnoreCase("throw")) {
                         // Throwing this exception doesn't seem that useful. It breaks
@@ -278,236 +228,82 @@
         return true;
     }
 
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+    /**
+     * Sets a 9 patch in a project cache or in the framework cache.
+     * @param value the path of the 9 patch
+     * @param ninePatch the 9 patch object
+     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
      */
-    @Deprecated
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription,
-            Object projectKey,
-            int screenWidth, int screenHeight, String themeName,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        boolean isProjectTheme = false;
-        if (themeName.charAt(0) == '*') {
-            themeName = themeName.substring(1);
-            isProjectTheme = true;
-        }
+    public static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
+        if (projectKey != null) {
+            Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
 
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
-                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
-                themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
+            if (map == null) {
+                map = new HashMap<String, SoftReference<NinePatch>>();
+                sProject9PatchCache.put(projectKey, map);
+            }
+
+            map.put(value, new SoftReference<NinePatch>(ninePatch));
+        } else {
+            sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
+        }
     }
 
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+    /**
+     * Starts a layout session by inflating and rendering it. The method returns a
+     * {@link ILayoutScene} on which further actions can be taken.
+     *
+     * @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the
+     * layout file.
+     * @param projectKey An Object identifying the project. This is used for the cache mechanism.
+     * @param screenWidth the screen width
+     * @param screenHeight the screen height
+     * @param renderFullSize if true, the rendering will render the full size needed by the
+     * layout. This size is never smaller than <var>screenWidth</var> x <var>screenHeight</var>.
+     * @param density the density factor for the screen.
+     * @param xdpi the screen actual dpi in X
+     * @param ydpi the screen actual dpi in Y
+     * @param themeName The name of the theme to use.
+     * @param isProjectTheme true if the theme is a project theme, false if it is a framework theme.
+     * @param projectResources the resources of the project. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the
+     * map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
+     * and the value is the resource value.
+     * @param frameworkResources the framework resources. The map contains (String, map) pairs
+     * where the string is the type of the resource reference used in the layout file, and the map
+     * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
+     * value is the resource value.
+     * @param projectCallback The {@link IProjectCallback} object to get information from
+     * the project.
+     * @param logger the object responsible for displaying warning/errors to the user.
+     * @return a new {@link ILayoutScene} object that contains the result of the layout.
+     * @since 5
      */
-    @Deprecated
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, DisplayMetrics.DENSITY_DEFAULT,
-                DisplayMetrics.DENSITY_DEFAULT, DisplayMetrics.DENSITY_DEFAULT,
-                themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
-    }
-
-    /*
-     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
-     */
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        return computeLayout(layoutDescription, projectKey,
-                screenWidth, screenHeight, false /* renderFullSize */,
-                density, xdpi, ydpi, themeName, isProjectTheme,
-                projectResources, frameworkResources, customViewLoader, logger);
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
-     */
-    public ILayoutResult computeLayout(IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, boolean renderFullSize,
-            int density, float xdpi, float ydpi,
-            String themeName, boolean isProjectTheme,
-            Map<String, Map<String, IResourceValue>> projectResources,
-            Map<String, Map<String, IResourceValue>> frameworkResources,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
-        if (logger == null) {
-            logger = sDefaultLogger;
-        }
-
-        synchronized (sDefaultLogger) {
-            sLogger = logger;
-        }
-
-        // find the current theme and compute the style inheritance map
-        Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
-            new HashMap<IStyleResourceValue, IStyleResourceValue>();
-
-        IStyleResourceValue currentTheme = computeStyleMaps(themeName, isProjectTheme,
-                projectResources.get(BridgeConstants.RES_STYLE),
-                frameworkResources.get(BridgeConstants.RES_STYLE), styleParentMap);
-
-        BridgeContext context = null;
+    @Override
+    public BridgeLayoutScene createScene(SceneParams params) {
         try {
-            // we need to make sure the Looper has been initialized for this thread.
-            // this is required for View that creates Handler objects.
-            if (Looper.myLooper() == null) {
-                Looper.prepare();
-            }
+            SceneResult lastResult = SceneResult.SUCCESS;
+            LayoutSceneImpl scene = null;
+            synchronized (this) {
+                try {
+                    scene = new LayoutSceneImpl(params);
 
-            // setup the display Metrics.
-            DisplayMetrics metrics = new DisplayMetrics();
-            metrics.densityDpi = density;
-            metrics.density = density / (float) DisplayMetrics.DENSITY_DEFAULT;
-            metrics.scaledDensity = metrics.density;
-            metrics.widthPixels = screenWidth;
-            metrics.heightPixels = screenHeight;
-            metrics.xdpi = xdpi;
-            metrics.ydpi = ydpi;
-
-            context = new BridgeContext(projectKey, metrics, currentTheme, projectResources,
-                    frameworkResources, styleParentMap, customViewLoader, logger);
-            BridgeInflater inflater = new BridgeInflater(context, customViewLoader);
-            context.setBridgeInflater(inflater);
-            inflater.setFactory2(context);
-
-            IResourceValue windowBackground = null;
-            int screenOffset = 0;
-            if (currentTheme != null) {
-                windowBackground = context.findItemInStyle(currentTheme, "windowBackground");
-                windowBackground = context.resolveResValue(windowBackground);
-
-                screenOffset = getScreenOffset(frameworkResources, currentTheme, context);
-            }
-
-            BridgeXmlBlockParser parser = new BridgeXmlBlockParser(layoutDescription,
-                    context, false /* platformResourceFlag */);
-
-            ViewGroup root = new FrameLayout(context);
-
-            // Sets the project callback (custom view loader) to the fragment delegate so that
-            // it can instantiate the custom Fragment.
-            Fragment_Delegate.setProjectCallback(customViewLoader);
-
-            View view = inflater.inflate(parser, root);
-
-            // post-inflate process. For now this supports TabHost/TabWidget
-            postInflateProcess(view, customViewLoader);
-
-            Fragment_Delegate.setProjectCallback(null);
-
-            // set the AttachInfo on the root view.
-            AttachInfo info = new AttachInfo(new WindowSession(), new Window(),
-                    new Handler(), null);
-            info.mHasWindowFocus = true;
-            info.mWindowVisibility = View.VISIBLE;
-            info.mInTouchMode = false; // this is so that we can display selections.
-            root.dispatchAttachedToWindow(info, 0);
-
-            // get the background drawable
-            if (windowBackground != null) {
-                Drawable d = ResourceHelper.getDrawable(windowBackground,
-                        context, true /* isFramework */);
-                root.setBackgroundDrawable(d);
-            }
-
-            // measure the views
-            int w_spec, h_spec;
-
-            if (renderFullSize) {
-                // measure the full size needed by the layout.
-                w_spec = MeasureSpec.makeMeasureSpec(screenWidth,
-                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
-                h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
-                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
-                root.measure(w_spec, h_spec);
-
-                int neededWidth = root.getChildAt(0).getMeasuredWidth();
-                if (neededWidth > screenWidth) {
-                    screenWidth = neededWidth;
-                }
-
-                int neededHeight = root.getChildAt(0).getMeasuredHeight();
-                if (neededHeight > screenHeight - screenOffset) {
-                    screenHeight = neededHeight + screenOffset;
+                    scene.prepare();
+                    lastResult = scene.inflate();
+                    if (lastResult == SceneResult.SUCCESS) {
+                        lastResult = scene.render();
+                    }
+                } finally {
+                    if (scene != null) {
+                        scene.cleanup();
+                    }
                 }
             }
 
-            // remeasure with only the size we need
-            // This must always be done before the call to layout
-            w_spec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY);
-            h_spec = MeasureSpec.makeMeasureSpec(screenHeight - screenOffset,
-                    MeasureSpec.EXACTLY);
-            root.measure(w_spec, h_spec);
-
-            // now do the layout.
-            root.layout(0, screenOffset, screenWidth, screenHeight);
-
-            // draw the views
-            // create the BufferedImage into which the layout will be rendered.
-            BufferedImage image = new BufferedImage(screenWidth, screenHeight - screenOffset,
-                    BufferedImage.TYPE_INT_ARGB);
-
-            // create an Android bitmap around the BufferedImage
-            Bitmap bitmap = Bitmap_Delegate.createBitmap(image, Density.getEnum(density));
-
-            // create a Canvas around the Android bitmap
-            Canvas canvas = new Canvas(bitmap);
-
-            // to set the logger, get the native delegate
-            Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
-            canvasDelegate.setLogger(logger);
-
-            root.draw(canvas);
-            canvasDelegate.dispose();
-
-            return new LayoutResult(
-                    visit(((ViewGroup)view).getChildAt(0), context),
-                    image);
-
-        } catch (PostInflateException e) {
-            return new LayoutResult(ILayoutResult.ERROR, "Error during post inflation process:\n"
-                    + e.getMessage());
-        } catch (Throwable e) {
-            // get the real cause of the exception.
-            Throwable t = e;
-            while (t.getCause() != null) {
-                t = t.getCause();
-            }
-
-            // log it
-            logger.error(t);
-
-            // then return with an ERROR status and the message from the real exception
-            return new LayoutResult(ILayoutResult.ERROR,
-                    t.getClass().getSimpleName() + ": " + t.getMessage());
-        } finally {
-            // Make sure to remove static references, otherwise we could not unload the lib
-            BridgeResources.clearSystem();
-            BridgeAssetManager.clearSystem();
-
-            // Remove the global logger
-            synchronized (sDefaultLogger) {
-                sLogger = sDefaultLogger;
-            }
+            return new BridgeLayoutScene(this, scene, lastResult);
+        } catch (Throwable t) {
+            t.printStackTrace();
+            return new BridgeLayoutScene(this, null, new SceneResult("error!", t));
         }
     }
 
@@ -515,6 +311,7 @@
      * (non-Javadoc)
      * @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
      */
+    @Override
     public void clearCaches(Object projectKey) {
         if (projectKey != null) {
             sProjectBitmapCache.remove(projectKey);
@@ -556,7 +353,10 @@
         return null;
     }
 
-    static Map<String, Integer> getEnumValues(String attributeName) {
+    /**
+     * Returns the list of possible enums for a given attribute name.
+     */
+    public static Map<String, Integer> getEnumValues(String attributeName) {
         if (sEnumValueMap != null) {
             return sEnumValueMap.get(attributeName);
         }
@@ -565,358 +365,13 @@
     }
 
     /**
-     * Visits a View and its children and generate a {@link ILayoutViewInfo} containing the
-     * bounds of all the views.
-     * @param view the root View
-     * @param context the context.
-     */
-    private ILayoutViewInfo visit(View view, BridgeContext context) {
-        if (view == null) {
-            return null;
-        }
-
-        LayoutViewInfo result = new LayoutViewInfo(view.getClass().getName(),
-                context.getViewKey(view),
-                view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
-
-        if (view instanceof ViewGroup) {
-            ViewGroup group = ((ViewGroup) view);
-            int n = group.getChildCount();
-            ILayoutViewInfo[] children = new ILayoutViewInfo[n];
-            for (int i = 0; i < group.getChildCount(); i++) {
-                children[i] = visit(group.getChildAt(i), context);
-            }
-            result.setChildren(children);
-        }
-
-        return result;
-    }
-
-    /**
-     * Compute style information from the given list of style for the project and framework.
-     * @param themeName the name of the current theme.  In order to differentiate project and
-     * platform themes sharing the same name, all project themes must be prepended with
-     * a '*' character.
-     * @param isProjectTheme Is this a project theme
-     * @param inProjectStyleMap the project style map
-     * @param inFrameworkStyleMap the framework style map
-     * @param outInheritanceMap the map of style inheritance. This is filled by the method
-     * @return the {@link IStyleResourceValue} matching <var>themeName</var>
-     */
-    private IStyleResourceValue computeStyleMaps(
-            String themeName, boolean isProjectTheme, Map<String,
-            IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
-            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
-
-        if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
-            // first, get the theme
-            IResourceValue theme = null;
-
-            // project theme names have been prepended with a *
-            if (isProjectTheme) {
-                theme = inProjectStyleMap.get(themeName);
-            } else {
-                theme = inFrameworkStyleMap.get(themeName);
-            }
-
-            if (theme instanceof IStyleResourceValue) {
-                // compute the inheritance map for both the project and framework styles
-                computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
-                        inFrameworkStyleMap, outInheritanceMap);
-
-                // Compute the style inheritance for the framework styles/themes.
-                // Since, for those, the style parent values do not contain 'android:'
-                // we want to force looking in the framework style only to avoid using
-                // similarly named styles from the project.
-                // To do this, we pass null in lieu of the project style map.
-                computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
-                        inFrameworkStyleMap, outInheritanceMap);
-
-                return (IStyleResourceValue)theme;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Compute the parent style for all the styles in a given list.
-     * @param styles the styles for which we compute the parent.
-     * @param inProjectStyleMap the map of project styles.
-     * @param inFrameworkStyleMap the map of framework styles.
-     * @param outInheritanceMap the map of style inheritance. This is filled by the method.
-     */
-    private void computeStyleInheritance(Collection<IResourceValue> styles,
-            Map<String, IResourceValue> inProjectStyleMap,
-            Map<String, IResourceValue> inFrameworkStyleMap,
-            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
-        for (IResourceValue value : styles) {
-            if (value instanceof IStyleResourceValue) {
-                IStyleResourceValue style = (IStyleResourceValue)value;
-                IStyleResourceValue parentStyle = null;
-
-                // first look for a specified parent.
-                String parentName = style.getParentStyle();
-
-                // no specified parent? try to infer it from the name of the style.
-                if (parentName == null) {
-                    parentName = getParentName(value.getName());
-                }
-
-                if (parentName != null) {
-                    parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
-
-                    if (parentStyle != null) {
-                        outInheritanceMap.put(style, parentStyle);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Searches for and returns the {@link IStyleResourceValue} from a given name.
-     * <p/>The format of the name can be:
-     * <ul>
-     * <li>[android:]&lt;name&gt;</li>
-     * <li>[android:]style/&lt;name&gt;</li>
-     * <li>@[android:]style/&lt;name&gt;</li>
-     * </ul>
-     * @param parentName the name of the style.
-     * @param inProjectStyleMap the project style map. Can be <code>null</code>
-     * @param inFrameworkStyleMap the framework style map.
-     * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
-     */
-    private IStyleResourceValue getStyle(String parentName,
-            Map<String, IResourceValue> inProjectStyleMap,
-            Map<String, IResourceValue> inFrameworkStyleMap) {
-        boolean frameworkOnly = false;
-
-        String name = parentName;
-
-        // remove the useless @ if it's there
-        if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
-            name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
-        }
-
-        // check for framework identifier.
-        if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
-            frameworkOnly = true;
-            name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
-        }
-
-        // at this point we could have the format <type>/<name>. we want only the name as long as
-        // the type is style.
-        if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
-            name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
-        } else if (name.indexOf('/') != -1) {
-            return null;
-        }
-
-        IResourceValue parent = null;
-
-        // if allowed, search in the project resources.
-        if (frameworkOnly == false && inProjectStyleMap != null) {
-            parent = inProjectStyleMap.get(name);
-        }
-
-        // if not found, then look in the framework resources.
-        if (parent == null) {
-            parent = inFrameworkStyleMap.get(name);
-        }
-
-        // make sure the result is the proper class type and return it.
-        if (parent instanceof IStyleResourceValue) {
-            return (IStyleResourceValue)parent;
-        }
-
-        sLogger.error(String.format("Unable to resolve parent style name: %s", parentName));
-
-        return null;
-    }
-
-    /**
-     * Computes the name of the parent style, or <code>null</code> if the style is a root style.
-     */
-    private String getParentName(String styleName) {
-        int index = styleName.lastIndexOf('.');
-        if (index != -1) {
-            return styleName.substring(0, index);
-        }
-
-        return null;
-    }
-
-    /**
-     * Returns the top screen offset. This depends on whether the current theme defines the user
-     * of the title and status bars.
-     * @param frameworkResources The framework resources
-     * @param currentTheme The current theme
-     * @param context The context
-     * @return the pixel height offset
-     */
-    private int getScreenOffset(Map<String, Map<String, IResourceValue>> frameworkResources,
-            IStyleResourceValue currentTheme, BridgeContext context) {
-        int offset = 0;
-
-        // get the title bar flag from the current theme.
-        IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
-
-        // because it may reference something else, we resolve it.
-        value = context.resolveResValue(value);
-
-        // if there's a value and it's true (default is false)
-        if (value == null || value.getValue() == null ||
-                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
-            // default size of the window title bar
-            int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT;
-
-            // get value from the theme.
-            value = context.findItemInStyle(currentTheme, "windowTitleSize");
-
-            // resolve it
-            value = context.resolveResValue(value);
-
-            if (value != null) {
-                // get the numerical value, if available
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
-                }
-            }
-
-            offset += defaultOffset;
-        }
-
-        // get the fullscreen flag from the current theme.
-        value = context.findItemInStyle(currentTheme, "windowFullscreen");
-
-        // because it may reference something else, we resolve it.
-        value = context.resolveResValue(value);
-
-        if (value == null || value.getValue() == null ||
-                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
-
-            // default value
-            int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT;
-
-            // get the real value, first the list of Dimensions from the framework map
-            Map<String, IResourceValue> dimens = frameworkResources.get(BridgeConstants.RES_DIMEN);
-
-            // now get the value
-            value = dimens.get("status_bar_height");
-            if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
-                if (typedValue != null) {
-                    // compute the pixel value based on the display metrics
-                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
-                }
-            }
-
-            // add the computed offset.
-            offset += defaultOffset;
-        }
-
-        return offset;
-    }
-
-    /**
-     * Post process on a view hierachy that was just inflated.
-     * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
-     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
-     * based on the content of the {@link FrameLayout}.
-     * @param view the root view to process.
-     * @param projectCallback callback to the project.
-     */
-    private void postInflateProcess(View view, IProjectCallback projectCallback)
-            throws PostInflateException {
-        if (view instanceof TabHost) {
-            setupTabHost((TabHost)view, projectCallback);
-        } else if (view instanceof ViewGroup) {
-            ViewGroup group = (ViewGroup)view;
-            final int count = group.getChildCount();
-            for (int c = 0 ; c < count ; c++) {
-                View child = group.getChildAt(c);
-                postInflateProcess(child, projectCallback);
-            }
-        }
-    }
-
-    /**
-     * Sets up a {@link TabHost} object.
-     * @param tabHost the TabHost to setup.
-     * @param projectCallback The project callback object to access the project R class.
-     * @throws PostInflateException
-     */
-    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
-            throws PostInflateException {
-        // look for the TabWidget, and the FrameLayout. They have their own specific names
-        View v = tabHost.findViewById(android.R.id.tabs);
-
-        if (v == null) {
-            throw new PostInflateException(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
-        }
-
-        if ((v instanceof TabWidget) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
-                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        v = tabHost.findViewById(android.R.id.tabcontent);
-
-        if (v == null) {
-            // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
-            throw new PostInflateException(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
-        }
-
-        if ((v instanceof FrameLayout) == false) {
-            throw new PostInflateException(String.format(
-                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
-                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
-        }
-
-        FrameLayout content = (FrameLayout)v;
-
-        // now process the content of the framelayout and dynamically create tabs for it.
-        final int count = content.getChildCount();
-
-        if (count == 0) {
-            throw new PostInflateException(
-                    "The FrameLayout for the TabHost has no content. Rendering failed.\n");
-        }
-
-        // this must be called before addTab() so that the TabHost searches its TabWidget
-        // and FrameLayout.
-        tabHost.setup();
-
-        // for each child of the framelayout, add a new TabSpec
-        for (int i = 0 ; i < count ; i++) {
-            View child = content.getChildAt(i);
-            String tabSpec = String.format("tab_spec%d", i+1);
-            int id = child.getId();
-            String[] resource = projectCallback.resolveResourceValue(id);
-            String name;
-            if (resource != null) {
-                name = resource[0]; // 0 is resource name, 1 is resource type.
-            } else {
-                name = String.format("Tab %d", i+1); // default name if id is unresolved.
-            }
-            tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
-        }
-    }
-
-    /**
      * Returns the bitmap for a specific path, from a specific project cache, or from the
      * framework cache.
      * @param value the path of the bitmap
      * @param projectKey the key of the project, or null to query the framework cache.
      * @return the cached Bitmap or null if not found.
      */
-    static Bitmap getCachedBitmap(String value, Object projectKey) {
+    public static Bitmap getCachedBitmap(String value, Object projectKey) {
         if (projectKey != null) {
             Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
             if (map != null) {
@@ -941,7 +396,7 @@
      * @param bmp the Bitmap object
      * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
      */
-    static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
+    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
         if (projectKey != null) {
             Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
 
@@ -963,7 +418,7 @@
      * @param projectKey the key of the project, or null to query the framework cache.
      * @return the cached 9 patch or null if not found.
      */
-    static NinePatch getCached9Patch(String value, Object projectKey) {
+    public static NinePatch getCached9Patch(String value, Object projectKey) {
         if (projectKey != null) {
             Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
 
@@ -983,262 +438,69 @@
         return null;
     }
 
-    /**
-     * Sets a 9 patch in a project cache or in the framework cache.
-     * @param value the path of the 9 patch
-     * @param ninePatch the 9 patch object
-     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
+
+    // ---------- OBSOLETE API METHODS ----------
+
+    /*
+     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+     * (non-Javadoc)
+     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
      */
-    static void setCached9Patch(String value, NinePatch ninePatch, Object projectKey) {
-        if (projectKey != null) {
-            Map<String, SoftReference<NinePatch>> map = sProject9PatchCache.get(projectKey);
-
-            if (map == null) {
-                map = new HashMap<String, SoftReference<NinePatch>>();
-                sProject9PatchCache.put(projectKey, map);
-            }
-
-            map.put(value, new SoftReference<NinePatch>(ninePatch));
-        } else {
-            sFramework9PatchCache.put(value, new SoftReference<NinePatch>(ninePatch));
-        }
+    @Deprecated
+    public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+            Object projectKey,
+            int screenWidth, int screenHeight, String themeName,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback customViewLoader, ILayoutLog logger) {
+        throw new UnsupportedOperationException();
     }
 
-    private static final class PostInflateException extends Exception {
-        private static final long serialVersionUID = 1L;
-
-        public PostInflateException(String message) {
-            super(message);
-        }
+    /*
+     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+     * (non-Javadoc)
+     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
+     */
+    @Deprecated
+    public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+            Object projectKey,
+            int screenWidth, int screenHeight, String themeName, boolean isProjectTheme,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback customViewLoader, ILayoutLog logger) {
+        throw new UnsupportedOperationException();
     }
 
-    /**
-     * Implementation of {@link IWindowSession} so that mSession is not null in
-     * the {@link SurfaceView}.
+    /*
+     * For compatilibty purposes, we implement the old deprecated version of computeLayout.
+     * (non-Javadoc)
+     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
      */
-    private static final class WindowSession implements IWindowSession {
-
-        @SuppressWarnings("unused")
-        public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
-                InputChannel outInputchannel)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-
-        @SuppressWarnings("unused")
-        public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-
-        @SuppressWarnings("unused")
-        public void finishDrawing(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void finishKey(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public boolean getInTouchMode() throws RemoteException {
-            // pass for now.
-            return false;
-        }
-
-        @SuppressWarnings("unused")
-        public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
-            // pass for now.
-            return false;
-        }
-
-        @SuppressWarnings("unused")
-        public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
-                boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
-                throws RemoteException {
-            // pass for now.
-            return 0;
-        }
-
-        public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void remove(IWindow arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setInTouchMode(boolean arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void setInsets(IWindow window, int touchable, Rect contentInsets,
-                Rect visibleInsets) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public IBinder prepareDrag(IWindow window, boolean localOnly,
-                int thumbnailWidth, int thumbnailHeight, Surface outSurface)
-                throws RemoteException {
-            // pass for now
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public boolean performDrag(IWindow window, IBinder dragToken,
-                float touchX, float touchY, float thumbCenterX, float thumbCenterY,
-                ClipData data)
-                throws RemoteException {
-            // pass for now
-            return false;
-        }
-
-        @SuppressWarnings("unused")
-        public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
-            // pass for now
-        }
-
-        @SuppressWarnings("unused")
-        public void dragRecipientEntered(IWindow window) throws RemoteException {
-            // pass for now
-        }
-
-        @SuppressWarnings("unused")
-        public void dragRecipientExited(IWindow window) throws RemoteException {
-            // pass for now
-        }
-
-        @SuppressWarnings("unused")
-        public void setWallpaperPosition(IBinder window, float x, float y,
-            float xStep, float yStep) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void wallpaperOffsetsComplete(IBinder window) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
-                int z, Bundle extras, boolean sync) {
-            // pass for now.
-            return null;
-        }
-
-        @SuppressWarnings("unused")
-        public void wallpaperCommandComplete(IBinder window, Bundle result) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void closeSystemDialogs(String reason) {
-            // pass for now.
-        }
-
-        public IBinder asBinder() {
-            // pass for now.
-            return null;
-        }
+    @Deprecated
+    public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+            Object projectKey,
+            int screenWidth, int screenHeight, int density, float xdpi, float ydpi,
+            String themeName, boolean isProjectTheme,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback customViewLoader, ILayoutLog logger) {
+        throw new UnsupportedOperationException();
     }
 
-    /**
-     * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+    /*
+     * (non-Javadoc)
+     * @see com.android.layoutlib.api.ILayoutBridge#computeLayout(com.android.layoutlib.api.IXmlPullParser, java.lang.Object, int, int, boolean, int, float, float, java.lang.String, boolean, java.util.Map, java.util.Map, com.android.layoutlib.api.IProjectCallback, com.android.layoutlib.api.ILayoutLog)
      */
-    private static final class Window implements IWindow {
-
-        @SuppressWarnings("unused")
-        public void dispatchAppVisibility(boolean arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchGetNewSurface() throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchKey(KeyEvent arg0) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
-                throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
-                throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
-                boolean sync) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchWallpaperCommand(String action, int x, int y,
-                int z, Bundle extras, boolean sync) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void closeSystemDialogs(String reason) {
-            // pass for now.
-        }
-
-        @SuppressWarnings("unused")
-        public void dispatchDragEvent(DragEvent event) {
-            // pass for now.
-        }
-
-        public IBinder asBinder() {
-            // pass for now.
-            return null;
-        }
+    @Deprecated
+    public com.android.layoutlib.api.ILayoutResult computeLayout(IXmlPullParser layoutDescription,
+            Object projectKey,
+            int screenWidth, int screenHeight, boolean renderFullSize,
+            int density, float xdpi, float ydpi,
+            String themeName, boolean isProjectTheme,
+            Map<String, Map<String, IResourceValue>> projectResources,
+            Map<String, Map<String, IResourceValue>> frameworkResources,
+            IProjectCallback customViewLoader, ILayoutLog logger) {
+        throw new UnsupportedOperationException();
     }
 
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
new file mode 100644
index 0000000..5fcb9ff
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 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;
+
+import com.android.layoutlib.api.LayoutScene;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
+
+import java.awt.image.BufferedImage;
+
+/**
+ * An implementation of {@link LayoutScene}.
+ *
+ * This is a pretty basic class that does almost nothing. All of the work is done in
+ * {@link LayoutSceneImpl}.
+ *
+ */
+public class BridgeLayoutScene extends LayoutScene {
+
+    private final Bridge mBridge;
+    private final LayoutSceneImpl mScene;
+    private SceneResult mLastResult;
+
+    @Override
+    public SceneResult getResult() {
+        return mLastResult;
+    }
+
+    @Override
+    public BufferedImage getImage() {
+        return mScene.getImage();
+    }
+
+    @Override
+    public ViewInfo getRootView() {
+        return mScene.getViewInfo();
+    }
+
+    @Override
+    public SceneResult render() {
+
+        synchronized (mBridge) {
+            try {
+                mScene.prepare();
+                mLastResult = mScene.render();
+            } finally {
+                mScene.cleanup();
+            }
+        }
+
+        return mLastResult;
+    }
+
+    @Override
+    public void dispose() {
+        // TODO Auto-generated method stub
+
+    }
+
+    /*package*/ BridgeLayoutScene(Bridge bridge, LayoutSceneImpl scene, SceneResult lastResult) {
+        mBridge = bridge;
+        mScene = scene;
+        mLastResult = lastResult;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
deleted file mode 100644
index c4c5225..0000000
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/LayoutResult.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import com.android.layoutlib.api.ILayoutResult;
-
-import java.awt.image.BufferedImage;
-
-/**
- * Implementation of {@link ILayoutResult}
- */
-public final class LayoutResult implements ILayoutResult {
-
-    private final ILayoutViewInfo mRootView;
-    private final BufferedImage mImage;
-    private final int mSuccess;
-    private final String mErrorMessage;
-
-    /**
-     * Creates a {@link #SUCCESS} {@link ILayoutResult} with the specified params
-     * @param rootView
-     * @param image
-     */
-    public LayoutResult(ILayoutViewInfo rootView, BufferedImage image) {
-        mSuccess = SUCCESS;
-        mErrorMessage = null;
-        mRootView = rootView;
-        mImage = image;
-    }
-    
-    /**
-     * Creates a LayoutResult with a specific success code and associated message
-     * @param code
-     * @param message
-     */
-    public LayoutResult(int code, String message) {
-        mSuccess = code;
-        mErrorMessage = message;
-        mRootView = null;
-        mImage = null;
-    }
-
-    public int getSuccess() {
-        return mSuccess;
-    }
-
-    public String getErrorMessage() {
-        return mErrorMessage;
-    }
-
-    public BufferedImage getImage() {
-        return mImage;
-    }
-
-    public ILayoutViewInfo getRootView() {
-        return mRootView;
-    }
-    
-    /**
-     * Implementation of {@link ILayoutResult.ILayoutViewInfo}
-     */
-    public static final class LayoutViewInfo implements ILayoutViewInfo {
-        private final Object mKey;
-        private final String mName;
-        private final int mLeft;
-        private final int mRight;
-        private final int mTop;
-        private final int mBottom;
-        private ILayoutViewInfo[] mChildren;
-
-        public LayoutViewInfo(String name, Object key, int left, int top, int right, int bottom) {
-            mName = name;
-            mKey = key;
-            mLeft = left;
-            mRight = right;
-            mTop = top;
-            mBottom = bottom;
-        }
-        
-        public void setChildren(ILayoutViewInfo[] children) {
-            mChildren = children;
-        }
-
-        public ILayoutViewInfo[] getChildren() {
-            return mChildren;
-        }
-
-        public Object getViewKey() {
-            return mKey;
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public int getLeft() {
-            return mLeft;
-        }
-
-        public int getTop() {
-            return mTop;
-        }
-
-        public int getRight() {
-            return mRight;
-        }
-
-        public int getBottom() {
-            return mBottom;
-        }
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
similarity index 89%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
index 71803fc..a825060 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeAssetManager.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.Bridge;
 
 import android.content.res.AssetManager;
 
@@ -28,7 +30,7 @@
      * <p/>
      * {@link Bridge} calls this method after setting up a new bridge.
      */
-    /*package*/ static AssetManager initSystem() {
+    /*package*/ public static AssetManager initSystem() {
         if (!(AssetManager.sSystem instanceof BridgeAssetManager)) {
             // Note that AssetManager() creates a system AssetManager and we override it
             // with our BridgeAssetManager.
@@ -42,7 +44,7 @@
      * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
      * around that would prevent us from unloading the library.
      */
-    /*package*/ static void clearSystem() {
+    public static void clearSystem() {
         AssetManager.sSystem = null;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
similarity index 98%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index 9d6dd27..3835378 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
similarity index 98%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
index e15cb69..0257686 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import android.content.ContentResolver;
 import android.content.Context;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
similarity index 93%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index b9899b2..2fa97a3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -14,12 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.layoutlib.api.ILayoutLog;
 import com.android.layoutlib.api.IProjectCallback;
 import com.android.layoutlib.api.IResourceValue;
 import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.TempResourceValue;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -50,7 +53,6 @@
 import android.os.Looper;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.view.BridgeInflater;
 import android.view.LayoutInflater;
 import android.view.View;
 
@@ -66,15 +68,16 @@
 import java.util.Map.Entry;
 
 /**
- * Custom implementation of Context to handle non compiled resources.
+ * Custom implementation of Context/Activity to handle non compiled resources.
  */
 public final class BridgeContext extends Activity {
 
-    private final Resources mResources;
-    private final Theme mTheme;
+    private Resources mResources;
+    private Theme mTheme;
     private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
     private final IStyleResourceValue mThemeValues;
     private final Object mProjectKey;
+    private final DisplayMetrics mMetrics;
     private final Map<String, Map<String, IResourceValue>> mProjectResources;
     private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
     private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
@@ -105,28 +108,18 @@
      * contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
      * value is the resource value.
      * @param styleInheritanceMap
-     * @param customViewLoader
+     * @param projectCallback
      */
     public BridgeContext(Object projectKey, DisplayMetrics metrics,
             IStyleResourceValue currentTheme,
             Map<String, Map<String, IResourceValue>> projectResources,
             Map<String, Map<String, IResourceValue>> frameworkResources,
             Map<IStyleResourceValue, IStyleResourceValue> styleInheritanceMap,
-            IProjectCallback customViewLoader, ILayoutLog logger) {
+            IProjectCallback projectCallback, ILayoutLog logger) {
         mProjectKey = projectKey;
-        mProjectCallback = customViewLoader;
+        mMetrics = metrics;
+        mProjectCallback = projectCallback;
         mLogger = logger;
-        Configuration config = new Configuration();
-
-        AssetManager assetManager = BridgeAssetManager.initSystem();
-        mResources = BridgeResources.initSystem(
-                this,
-                assetManager,
-                metrics,
-                config,
-                customViewLoader);
-
-        mTheme = mResources.newTheme();
 
         mThemeValues = currentTheme;
         mProjectResources = projectResources;
@@ -137,6 +130,32 @@
         mFragments.mActivity = this;
     }
 
+    /**
+     * Initializes the {@link Resources} singleton to be linked to this {@link Context}, its
+     * {@link DisplayMetrics}, {@link Configuration}, and {@link IProjectCallback}.
+     *
+     * @see #disposeResources()
+     */
+    public void initResources() {
+        AssetManager assetManager = AssetManager.getSystem();
+        Configuration config = new Configuration();
+
+        mResources = BridgeResources.initSystem(
+                this,
+                assetManager,
+                mMetrics,
+                config,
+                mProjectCallback);
+        mTheme = mResources.newTheme();
+    }
+
+    /**
+     * Disposes the {@link Resources} singleton.
+     */
+    public void disposeResources() {
+        BridgeResources.disposeSystem();
+    }
+
     public void setBridgeInflater(BridgeInflater inflater) {
         mInflater = inflater;
     }
@@ -266,6 +285,15 @@
             return null;
         }
 
+        Object key = null;
+        if (parser != null) {
+            key = parser.getViewKey();
+        }
+        if (key != null) {
+            String attrs_name = Bridge.resolveResourceValue(attrs);
+            System.out.println("KEY: " + key.toString() + "(" + attrs_name + ")");
+        }
+
         boolean[] frameworkAttributes = new boolean[1];
         TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes);
 
@@ -281,6 +309,9 @@
             customStyle = parser.getAttributeValue(null /* namespace*/, "style");
         }
         if (customStyle != null) {
+            if (key != null) {
+                print("style", customStyle, false);
+            }
             IResourceValue item = findResValue(customStyle, false /*forceFrameworkOnly*/);
 
             if (item instanceof IStyleResourceValue) {
@@ -292,6 +323,10 @@
             // get the name from the int.
             String defStyleName = searchAttr(defStyleAttr);
 
+            if (key != null) {
+                print("style", defStyleName, true);
+            }
+
             // look for the style in the current theme, and its parent:
             if (mThemeValues != null) {
                 IResourceValue item = findItemInStyle(mThemeValues, defStyleName);
@@ -350,11 +385,20 @@
                     // if we found a value, we make sure this doesn't reference another value.
                     // So we resolve it.
                     if (resValue != null) {
+                        if (key != null) {
+                            print(name, resValue.getValue(), true);
+                        }
+
                         resValue = resolveResValue(resValue);
+                    } else if (key != null) {
+                        print(name, "<unknown>", true);
                     }
 
                     ta.bridgeSetValue(index, name, resValue);
                 } else {
+                    if (key != null) {
+                        print(name, value, false);
+                    }
                     // there is a value in the XML, but we need to resolve it in case it's
                     // referencing another resource or a theme value.
                     ta.bridgeSetValue(index, name, resolveValue(null, name, value));
@@ -367,6 +411,15 @@
         return ta;
     }
 
+    private void print(String name, String value, boolean isDefault) {
+        System.out.print("\t" + name + " : " + value);
+        if (isDefault) {
+            System.out.println(" (default)");
+        } else {
+            System.out.println("");
+        }
+    }
+
     @Override
     public Looper getMainLooper() {
         return Looper.myLooper();
@@ -433,7 +486,7 @@
         // if resValue is null, but value is not null, this means it was not a reference.
         // we return the name/value wrapper in a IResourceValue
         if (resValue == null) {
-            return new ResourceValue(type, name, value);
+            return new TempResourceValue(type, name, value);
         }
 
         // we resolved a first reference, but we need to make sure this isn't a reference also.
@@ -453,7 +506,7 @@
      * @param value the value containing the reference to resolve.
      * @return a {@link IResourceValue} object or <code>null</code>
      */
-    IResourceValue resolveResValue(IResourceValue value) {
+    public IResourceValue resolveResValue(IResourceValue value) {
         if (value == null) {
             return null;
         }
@@ -661,7 +714,7 @@
      * @param itemName the name of the item to search for.
      * @return the {@link IResourceValue} object or <code>null</code>
      */
-    IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
+    public IResourceValue findItemInStyle(IStyleResourceValue style, String itemName) {
         IResourceValue item = style.findItem(itemName);
 
         // if we didn't find it, we look in the parent style (if applicable)
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
similarity index 97%
rename from tools/layoutlib/bridge/src/android/view/BridgeInflater.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index 4bc8855..b4a28a6 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -14,20 +14,22 @@
  * limitations under the License.
  */
 
-package android.view;
+package com.android.layoutlib.bridge.android;
 
 import com.android.layoutlib.api.IProjectCallback;
 import com.android.layoutlib.api.IResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
-import com.android.layoutlib.bridge.BridgeContext;
-import com.android.layoutlib.bridge.BridgeXmlBlockParser;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
 import java.io.File;
 import java.io.FileReader;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
similarity index 97%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index 6358abb..46eb776 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.layoutlib.api.IProjectCallback;
 import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
@@ -64,21 +67,18 @@
             DisplayMetrics metrics,
             Configuration config,
             IProjectCallback projectCallback) {
-        if (!(Resources.mSystem instanceof BridgeResources)) {
-            Resources.mSystem = new BridgeResources(context,
-                    assets,
-                    metrics,
-                    config,
-                    projectCallback);
-        }
-        return Resources.mSystem;
+        return Resources.mSystem = new BridgeResources(context,
+                assets,
+                metrics,
+                config,
+                projectCallback);
     }
 
     /**
-     * Clears the static {@link Resources#mSystem} to make sure we don't leave objects
+     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
      * around that would prevent us from unloading the library.
      */
-    /*package*/ static void clearSystem() {
+    /*package*/ static void disposeSystem() {
         if (Resources.mSystem instanceof BridgeResources) {
             ((BridgeResources)(Resources.mSystem)).mContext = null;
             ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
similarity index 98%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index 70c5bd7..c3ab461 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.internal.util.XmlUtils;
 import com.android.layoutlib.api.IResourceValue;
 import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ResourceHelper;
 
 import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
@@ -36,7 +39,7 @@
 import java.util.Map;
 
 /**
- * TODO: describe.
+ * Custom implementation of TypedArray to handle non compiled resources.
  */
 public final class BridgeTypedArray extends TypedArray {
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
new file mode 100644
index 0000000..c04c9e8
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 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.android;
+
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.view.DragEvent;
+import android.view.IWindow;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View.AttachInfo;
+
+/**
+ * Implementation of {@link IWindow} to pass to the {@link AttachInfo}.
+ */
+public final class BridgeWindow implements IWindow {
+
+    public void dispatchAppVisibility(boolean arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchGetNewSurface() throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchKey(KeyEvent arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchPointer(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchTrackball(MotionEvent arg0, long arg1, boolean arg2) throws RemoteException {
+        // pass for now.
+    }
+
+    public void executeCommand(String arg0, String arg1, ParcelFileDescriptor arg2)
+            throws RemoteException {
+        // pass for now.
+    }
+
+    public void resized(int arg0, int arg1, Rect arg2, Rect arg3, boolean arg4, Configuration arg5)
+            throws RemoteException {
+        // pass for now.
+    }
+
+    public void windowFocusChanged(boolean arg0, boolean arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
+            boolean sync) {
+        // pass for now.
+    }
+
+    public void dispatchWallpaperCommand(String action, int x, int y,
+            int z, Bundle extras, boolean sync) {
+        // pass for now.
+    }
+
+    public void closeSystemDialogs(String reason) {
+        // pass for now.
+    }
+
+    public void dispatchDragEvent(DragEvent event) {
+        // pass for now.
+    }
+
+    public IBinder asBinder() {
+        // pass for now.
+        return null;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
new file mode 100644
index 0000000..74e5a65
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010 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.android;
+
+import android.content.ClipData;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.view.IWindow;
+import android.view.IWindowSession;
+import android.view.InputChannel;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.WindowManager.LayoutParams;
+
+/**
+ * Implementation of {@link IWindowSession} so that mSession is not null in
+ * the {@link SurfaceView}.
+ */
+public final class BridgeWindowSession implements IWindowSession {
+
+    public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+            InputChannel outInputchannel)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public void finishDrawing(IWindow arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void finishKey(IWindow arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public boolean getInTouchMode() throws RemoteException {
+        // pass for now.
+        return false;
+    }
+
+    public boolean performHapticFeedback(IWindow window, int effectId, boolean always) {
+        // pass for now.
+        return false;
+    }
+
+    public MotionEvent getPendingPointerMove(IWindow arg0) throws RemoteException {
+        // pass for now.
+        return null;
+    }
+
+    public MotionEvent getPendingTrackballMove(IWindow arg0) throws RemoteException {
+        // pass for now.
+        return null;
+    }
+
+    public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
+            boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
+            throws RemoteException {
+        // pass for now.
+        return 0;
+    }
+
+    public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
+        // pass for now.
+    }
+
+    public void remove(IWindow arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setInTouchMode(boolean arg0) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setTransparentRegion(IWindow arg0, Region arg1) throws RemoteException {
+        // pass for now.
+    }
+
+    public void setInsets(IWindow window, int touchable, Rect contentInsets,
+            Rect visibleInsets) {
+        // pass for now.
+    }
+
+    public IBinder prepareDrag(IWindow window, boolean localOnly,
+            int thumbnailWidth, int thumbnailHeight, Surface outSurface)
+            throws RemoteException {
+        // pass for now
+        return null;
+    }
+
+    public boolean performDrag(IWindow window, IBinder dragToken,
+            float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+            ClipData data)
+            throws RemoteException {
+        // pass for now
+        return false;
+    }
+
+    public void reportDropResult(IWindow window, boolean consumed) throws RemoteException {
+        // pass for now
+    }
+
+    public void dragRecipientEntered(IWindow window) throws RemoteException {
+        // pass for now
+    }
+
+    public void dragRecipientExited(IWindow window) throws RemoteException {
+        // pass for now
+    }
+
+    public void setWallpaperPosition(IBinder window, float x, float y,
+        float xStep, float yStep) {
+        // pass for now.
+    }
+
+    public void wallpaperOffsetsComplete(IBinder window) {
+        // pass for now.
+    }
+
+    public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y,
+            int z, Bundle extras, boolean sync) {
+        // pass for now.
+        return null;
+    }
+
+    public void wallpaperCommandComplete(IBinder window, Bundle result) {
+        // pass for now.
+    }
+
+    public void closeSystemDialogs(String reason) {
+        // pass for now.
+    }
+
+    public IBinder asBinder() {
+        // pass for now.
+        return null;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
similarity index 99%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index d842a66..24f61c8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.layoutlib.api.IXmlPullParser;
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
similarity index 96%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
index d145ff6..c99b70b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeXmlPullAttributes.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlPullAttributes.java
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.BridgeConstants;
 
 import org.xmlpull.v1.XmlPullParser;
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java
similarity index 96%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java
index 1ca3182..e5bddcb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/MockView.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/MockView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import android.content.Context;
 import android.graphics.Canvas;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
similarity index 96%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
index 2c92567..4efa631 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/NinePatchDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/NinePatchDrawable.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
 
 import com.android.ninepatch.NinePatch;
 
@@ -28,7 +28,7 @@
 
     private NinePatch m9Patch;
 
-    NinePatchDrawable(NinePatch ninePatch) {
+    public NinePatchDrawable(NinePatch ninePatch) {
         m9Patch = ninePatch;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
similarity index 98%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 3d9f960..169d751 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
 
 import android.util.SparseArray;
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
similarity index 99%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index de89a81..5d56370 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
 
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
new file mode 100644
index 0000000..2012229
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 2010 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 com.android.internal.util.XmlUtils;
+import com.android.layoutlib.api.IProjectCallback;
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.api.LayoutBridge;
+import com.android.layoutlib.api.SceneParams;
+import com.android.layoutlib.api.SceneResult;
+import com.android.layoutlib.api.ViewInfo;
+import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
+import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeInflater;
+import com.android.layoutlib.bridge.android.BridgeWindow;
+import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+
+import android.app.Fragment_Delegate;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap_Delegate;
+import android.graphics.Canvas;
+import android.graphics.Canvas_Delegate;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.AttachInfo;
+import android.view.View.MeasureSpec;
+import android.widget.FrameLayout;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Class managing a layout "scene".
+ *
+ * A scene is a stateful representation of a layout file. It is initialized with data coming through
+ * the {@link LayoutBridge} API to inflate the layout. Further actions and rendering can then
+ * be done on the layout.
+ *
+ */
+public class LayoutSceneImpl {
+
+    private static final int DEFAULT_TITLE_BAR_HEIGHT = 25;
+    private static final int DEFAULT_STATUS_BAR_HEIGHT = 25;
+
+    private final SceneParams mParams;
+
+    // scene state
+    private BridgeContext mContext;
+    private BridgeXmlBlockParser mBlockParser;
+    private BridgeInflater mInflater;
+    private IStyleResourceValue mCurrentTheme;
+    private int mScreenOffset;
+    private IResourceValue mWindowBackground;
+    private FrameLayout mViewRoot;
+
+    // information being returned through the API
+    private BufferedImage mImage;
+    private ViewInfo mViewInfo;
+
+    private static final class PostInflateException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public PostInflateException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * Creates a layout scene with all the information coming from the layout bridge API.
+     *
+     * This also calls {@link LayoutSceneImpl#prepare()}.
+     * <p>
+     * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+     *
+     * @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
+     */
+    public LayoutSceneImpl(SceneParams params) {
+        // we need to make sure the Looper has been initialized for this thread.
+        // this is required for View that creates Handler objects.
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        // copy the params.
+        mParams = new SceneParams(params);
+
+        // setup the display Metrics.
+        DisplayMetrics metrics = new DisplayMetrics();
+        metrics.densityDpi = mParams.getDensity();
+        metrics.density = mParams.getDensity() / (float) DisplayMetrics.DENSITY_DEFAULT;
+        metrics.scaledDensity = metrics.density;
+        metrics.widthPixels = mParams.getScreenWidth();
+        metrics.heightPixels = mParams.getScreenHeight();
+        metrics.xdpi = mParams.getXdpi();
+        metrics.ydpi = mParams.getYdpi();
+
+        // find the current theme and compute the style inheritance map
+        Map<IStyleResourceValue, IStyleResourceValue> styleParentMap =
+            new HashMap<IStyleResourceValue, IStyleResourceValue>();
+
+        mCurrentTheme = computeStyleMaps(mParams.getThemeName(), mParams.getIsProjectTheme(),
+                mParams.getProjectResources().get(BridgeConstants.RES_STYLE),
+                mParams.getFrameworkResources().get(BridgeConstants.RES_STYLE), styleParentMap);
+
+        // build the context
+        mContext = new BridgeContext(mParams.getProjectKey(), metrics, mCurrentTheme,
+                mParams.getProjectResources(), mParams.getFrameworkResources(),
+                styleParentMap, mParams.getProjectCallback(), mParams.getLogger());
+
+        // make sure the Resources object references the context (and other objects) for this
+        // scene
+        mContext.initResources();
+
+        // get the screen offset and window-background resource
+        mWindowBackground = null;
+        mScreenOffset = 0;
+        if (mCurrentTheme != null && mParams.isCustomBackgroundEnabled() == false) {
+            mWindowBackground = mContext.findItemInStyle(mCurrentTheme, "windowBackground");
+            mWindowBackground = mContext.resolveResValue(mWindowBackground);
+
+            mScreenOffset = getScreenOffset(mParams.getFrameworkResources(), mCurrentTheme, mContext);
+        }
+
+        // build the inflater and parser.
+        mInflater = new BridgeInflater(mContext, mParams.getProjectCallback());
+        mContext.setBridgeInflater(mInflater);
+        mInflater.setFactory2(mContext);
+
+        mBlockParser = new BridgeXmlBlockParser(mParams.getLayoutDescription(),
+                mContext, false /* platformResourceFlag */);
+    }
+
+    /**
+     * Prepares the scene for action.
+     * <p>
+     * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+     */
+    public void prepare() {
+        // we need to make sure the Looper has been initialized for this thread.
+        // this is required for View that creates Handler objects.
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+
+        // make sure the Resources object references the context (and other objects) for this
+        // scene
+        mContext.initResources();
+    }
+
+    /**
+     * Cleans up the scene after an action.
+     * <p>
+     * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+     */
+    public void cleanup() {
+        // clean up the looper
+        Looper.sThreadLocal.remove();
+
+        // Make sure to remove static references, otherwise we could not unload the lib
+        mContext.disposeResources();
+    }
+
+    /**
+     * Inflates the layout.
+     * <p>
+     * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+     */
+    public SceneResult inflate() {
+        try {
+
+            mViewRoot = new FrameLayout(mContext);
+
+            // Sets the project callback (custom view loader) to the fragment delegate so that
+            // it can instantiate the custom Fragment.
+            Fragment_Delegate.setProjectCallback(mParams.getProjectCallback());
+
+            View view = mInflater.inflate(mBlockParser, mViewRoot);
+
+            // post-inflate process. For now this supports TabHost/TabWidget
+            postInflateProcess(view, mParams.getProjectCallback());
+
+            Fragment_Delegate.setProjectCallback(null);
+
+            // 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.
+            mViewRoot.dispatchAttachedToWindow(info, 0);
+
+            // get the background drawable
+            if (mWindowBackground != null) {
+                Drawable d = ResourceHelper.getDrawable(mWindowBackground,
+                        mContext, true /* isFramework */);
+                mViewRoot.setBackgroundDrawable(d);
+            }
+
+            return SceneResult.SUCCESS;
+        } catch (PostInflateException e) {
+            return new SceneResult("Error during post inflation process:\n" + e.getMessage());
+        } catch (Throwable e) {
+            // get the real cause of the exception.
+            Throwable t = e;
+            while (t.getCause() != null) {
+                t = t.getCause();
+            }
+
+            // log it
+            mParams.getLogger().error(t);
+
+            return new SceneResult("Unknown error during inflation.", t);
+        }
+    }
+
+    /**
+     * Renders the scene.
+     * <p>
+     * <b>THIS MUST BE INSIDE A SYNCHRONIZED BLOCK on the BRIDGE OBJECT.<b>
+     */
+    public SceneResult render() {
+        try {
+            if (mViewRoot == null) {
+                return new SceneResult("Layout has not been inflated!");
+            }
+            // measure the views
+            int w_spec, h_spec;
+
+            int renderScreenWidth = mParams.getScreenWidth();
+            int renderScreenHeight = mParams.getScreenHeight();
+
+            if (mParams.getRenderFullSize()) {
+                // measure the full size needed by the layout.
+                w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth,
+                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
+                h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset,
+                        MeasureSpec.UNSPECIFIED); // this lets us know the actual needed size
+                mViewRoot.measure(w_spec, h_spec);
+
+                int neededWidth = mViewRoot.getChildAt(0).getMeasuredWidth();
+                if (neededWidth > renderScreenWidth) {
+                    renderScreenWidth = neededWidth;
+                }
+
+                int neededHeight = mViewRoot.getChildAt(0).getMeasuredHeight();
+                if (neededHeight > renderScreenHeight - mScreenOffset) {
+                    renderScreenHeight = neededHeight + mScreenOffset;
+                }
+            }
+
+            // remeasure with the size we need
+            // This must always be done before the call to layout
+            w_spec = MeasureSpec.makeMeasureSpec(renderScreenWidth, MeasureSpec.EXACTLY);
+            h_spec = MeasureSpec.makeMeasureSpec(renderScreenHeight - mScreenOffset,
+                    MeasureSpec.EXACTLY);
+            mViewRoot.measure(w_spec, h_spec);
+
+            // now do the layout.
+            mViewRoot.layout(0, mScreenOffset, renderScreenWidth, renderScreenHeight);
+
+            // draw the views
+            // create the BufferedImage into which the layout will be rendered.
+            mImage = new BufferedImage(renderScreenWidth, renderScreenHeight - mScreenOffset,
+                    BufferedImage.TYPE_INT_ARGB);
+
+            if (mParams.isCustomBackgroundEnabled()) {
+                Graphics2D gc = mImage.createGraphics();
+                gc.setColor(new Color(mParams.getCustomBackgroundColor()));
+                gc.fillRect(0, 0, renderScreenWidth, renderScreenHeight - mScreenOffset);
+                gc.dispose();
+            }
+
+            // create an Android bitmap around the BufferedImage
+            Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
+                    Density.getEnum(mParams.getDensity()));
+
+            // create a Canvas around the Android bitmap
+            Canvas canvas = new Canvas(bitmap);
+
+            // to set the logger, get the native delegate
+            Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
+            canvasDelegate.setLogger(mParams.getLogger());
+
+            mViewRoot.draw(canvas);
+            canvasDelegate.dispose();
+
+            mViewInfo = visit(((ViewGroup)mViewRoot).getChildAt(0), mContext);
+
+            // success!
+            return SceneResult.SUCCESS;
+        } catch (Throwable e) {
+            // get the real cause of the exception.
+            Throwable t = e;
+            while (t.getCause() != null) {
+                t = t.getCause();
+            }
+
+            // log it
+            mParams.getLogger().error(t);
+
+            return new SceneResult("Unknown error during inflation.", t);
+        }
+    }
+
+    /**
+     * Compute style information from the given list of style for the project and framework.
+     * @param themeName the name of the current theme.  In order to differentiate project and
+     * platform themes sharing the same name, all project themes must be prepended with
+     * a '*' character.
+     * @param isProjectTheme Is this a project theme
+     * @param inProjectStyleMap the project style map
+     * @param inFrameworkStyleMap the framework style map
+     * @param outInheritanceMap the map of style inheritance. This is filled by the method
+     * @return the {@link IStyleResourceValue} matching <var>themeName</var>
+     */
+    private IStyleResourceValue computeStyleMaps(
+            String themeName, boolean isProjectTheme, Map<String,
+            IResourceValue> inProjectStyleMap, Map<String, IResourceValue> inFrameworkStyleMap,
+            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
+
+        if (inProjectStyleMap != null && inFrameworkStyleMap != null) {
+            // first, get the theme
+            IResourceValue theme = null;
+
+            // project theme names have been prepended with a *
+            if (isProjectTheme) {
+                theme = inProjectStyleMap.get(themeName);
+            } else {
+                theme = inFrameworkStyleMap.get(themeName);
+            }
+
+            if (theme instanceof IStyleResourceValue) {
+                // compute the inheritance map for both the project and framework styles
+                computeStyleInheritance(inProjectStyleMap.values(), inProjectStyleMap,
+                        inFrameworkStyleMap, outInheritanceMap);
+
+                // Compute the style inheritance for the framework styles/themes.
+                // Since, for those, the style parent values do not contain 'android:'
+                // we want to force looking in the framework style only to avoid using
+                // similarly named styles from the project.
+                // To do this, we pass null in lieu of the project style map.
+                computeStyleInheritance(inFrameworkStyleMap.values(), null /*inProjectStyleMap */,
+                        inFrameworkStyleMap, outInheritanceMap);
+
+                return (IStyleResourceValue)theme;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Compute the parent style for all the styles in a given list.
+     * @param styles the styles for which we compute the parent.
+     * @param inProjectStyleMap the map of project styles.
+     * @param inFrameworkStyleMap the map of framework styles.
+     * @param outInheritanceMap the map of style inheritance. This is filled by the method.
+     */
+    private void computeStyleInheritance(Collection<IResourceValue> styles,
+            Map<String, IResourceValue> inProjectStyleMap,
+            Map<String, IResourceValue> inFrameworkStyleMap,
+            Map<IStyleResourceValue, IStyleResourceValue> outInheritanceMap) {
+        for (IResourceValue value : styles) {
+            if (value instanceof IStyleResourceValue) {
+                IStyleResourceValue style = (IStyleResourceValue)value;
+                IStyleResourceValue parentStyle = null;
+
+                // first look for a specified parent.
+                String parentName = style.getParentStyle();
+
+                // no specified parent? try to infer it from the name of the style.
+                if (parentName == null) {
+                    parentName = getParentName(value.getName());
+                }
+
+                if (parentName != null) {
+                    parentStyle = getStyle(parentName, inProjectStyleMap, inFrameworkStyleMap);
+
+                    if (parentStyle != null) {
+                        outInheritanceMap.put(style, parentStyle);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Searches for and returns the {@link IStyleResourceValue} from a given name.
+     * <p/>The format of the name can be:
+     * <ul>
+     * <li>[android:]&lt;name&gt;</li>
+     * <li>[android:]style/&lt;name&gt;</li>
+     * <li>@[android:]style/&lt;name&gt;</li>
+     * </ul>
+     * @param parentName the name of the style.
+     * @param inProjectStyleMap the project style map. Can be <code>null</code>
+     * @param inFrameworkStyleMap the framework style map.
+     * @return The matching {@link IStyleResourceValue} object or <code>null</code> if not found.
+     */
+    private IStyleResourceValue getStyle(String parentName,
+            Map<String, IResourceValue> inProjectStyleMap,
+            Map<String, IResourceValue> inFrameworkStyleMap) {
+        boolean frameworkOnly = false;
+
+        String name = parentName;
+
+        // remove the useless @ if it's there
+        if (name.startsWith(BridgeConstants.PREFIX_RESOURCE_REF)) {
+            name = name.substring(BridgeConstants.PREFIX_RESOURCE_REF.length());
+        }
+
+        // check for framework identifier.
+        if (name.startsWith(BridgeConstants.PREFIX_ANDROID)) {
+            frameworkOnly = true;
+            name = name.substring(BridgeConstants.PREFIX_ANDROID.length());
+        }
+
+        // at this point we could have the format <type>/<name>. we want only the name as long as
+        // the type is style.
+        if (name.startsWith(BridgeConstants.REFERENCE_STYLE)) {
+            name = name.substring(BridgeConstants.REFERENCE_STYLE.length());
+        } else if (name.indexOf('/') != -1) {
+            return null;
+        }
+
+        IResourceValue parent = null;
+
+        // if allowed, search in the project resources.
+        if (frameworkOnly == false && inProjectStyleMap != null) {
+            parent = inProjectStyleMap.get(name);
+        }
+
+        // if not found, then look in the framework resources.
+        if (parent == null) {
+            parent = inFrameworkStyleMap.get(name);
+        }
+
+        // make sure the result is the proper class type and return it.
+        if (parent instanceof IStyleResourceValue) {
+            return (IStyleResourceValue)parent;
+        }
+
+        mParams.getLogger().error(
+                String.format("Unable to resolve parent style name: %s", parentName));
+
+        return null;
+    }
+
+    /**
+     * Computes the name of the parent style, or <code>null</code> if the style is a root style.
+     */
+    private String getParentName(String styleName) {
+        int index = styleName.lastIndexOf('.');
+        if (index != -1) {
+            return styleName.substring(0, index);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the top screen offset. This depends on whether the current theme defines the user
+     * of the title and status bars.
+     * @param frameworkResources The framework resources
+     * @param currentTheme The current theme
+     * @param context The context
+     * @return the pixel height offset
+     */
+    private int getScreenOffset(Map<String, Map<String, IResourceValue>> frameworkResources,
+            IStyleResourceValue currentTheme, BridgeContext context) {
+        int offset = 0;
+
+        // get the title bar flag from the current theme.
+        IResourceValue value = context.findItemInStyle(currentTheme, "windowNoTitle");
+
+        // because it may reference something else, we resolve it.
+        value = context.resolveResValue(value);
+
+        // if there's a value and it's true (default is false)
+        if (value == null || value.getValue() == null ||
+                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
+            // default size of the window title bar
+            int defaultOffset = DEFAULT_TITLE_BAR_HEIGHT;
+
+            // get value from the theme.
+            value = context.findItemInStyle(currentTheme, "windowTitleSize");
+
+            // resolve it
+            value = context.resolveResValue(value);
+
+            if (value != null) {
+                // get the numerical value, if available
+                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                if (typedValue != null) {
+                    // compute the pixel value based on the display metrics
+                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
+                }
+            }
+
+            offset += defaultOffset;
+        }
+
+        // get the fullscreen flag from the current theme.
+        value = context.findItemInStyle(currentTheme, "windowFullscreen");
+
+        // because it may reference something else, we resolve it.
+        value = context.resolveResValue(value);
+
+        if (value == null || value.getValue() == null ||
+                XmlUtils.convertValueToBoolean(value.getValue(), false /* defValue */) == false) {
+
+            // default value
+            int defaultOffset = DEFAULT_STATUS_BAR_HEIGHT;
+
+            // get the real value, first the list of Dimensions from the framework map
+            Map<String, IResourceValue> dimens = frameworkResources.get(BridgeConstants.RES_DIMEN);
+
+            // now get the value
+            value = dimens.get("status_bar_height");
+            if (value != null) {
+                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                if (typedValue != null) {
+                    // compute the pixel value based on the display metrics
+                    defaultOffset = (int)typedValue.getDimension(context.getResources().mMetrics);
+                }
+            }
+
+            // add the computed offset.
+            offset += defaultOffset;
+        }
+
+        return offset;
+
+    }
+
+    /**
+     * Post process on a view hierachy that was just inflated.
+     * <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
+     * {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
+     * based on the content of the {@link FrameLayout}.
+     * @param view the root view to process.
+     * @param projectCallback callback to the project.
+     */
+    private void postInflateProcess(View view, IProjectCallback projectCallback)
+            throws PostInflateException {
+        if (view instanceof TabHost) {
+            setupTabHost((TabHost)view, projectCallback);
+        } else if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup)view;
+            final int count = group.getChildCount();
+            for (int c = 0 ; c < count ; c++) {
+                View child = group.getChildAt(c);
+                postInflateProcess(child, projectCallback);
+            }
+        }
+    }
+
+    /**
+     * Sets up a {@link TabHost} object.
+     * @param tabHost the TabHost to setup.
+     * @param projectCallback The project callback object to access the project R class.
+     * @throws PostInflateException
+     */
+    private void setupTabHost(TabHost tabHost, IProjectCallback projectCallback)
+            throws PostInflateException {
+        // look for the TabWidget, and the FrameLayout. They have their own specific names
+        View v = tabHost.findViewById(android.R.id.tabs);
+
+        if (v == null) {
+            throw new PostInflateException(
+                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n");
+        }
+
+        if ((v instanceof TabWidget) == false) {
+            throw new PostInflateException(String.format(
+                    "TabHost requires a TabWidget with id \"android:id/tabs\".\n" +
+                    "View found with id 'tabs' is '%s'", v.getClass().getCanonicalName()));
+        }
+
+        v = tabHost.findViewById(android.R.id.tabcontent);
+
+        if (v == null) {
+            // TODO: see if we can fake tabs even without the FrameLayout (same below when the framelayout is empty)
+            throw new PostInflateException(
+                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".");
+        }
+
+        if ((v instanceof FrameLayout) == false) {
+            throw new PostInflateException(String.format(
+                    "TabHost requires a FrameLayout with id \"android:id/tabcontent\".\n" +
+                    "View found with id 'tabcontent' is '%s'", v.getClass().getCanonicalName()));
+        }
+
+        FrameLayout content = (FrameLayout)v;
+
+        // now process the content of the framelayout and dynamically create tabs for it.
+        final int count = content.getChildCount();
+
+        if (count == 0) {
+            throw new PostInflateException(
+                    "The FrameLayout for the TabHost has no content. Rendering failed.\n");
+        }
+
+        // this must be called before addTab() so that the TabHost searches its TabWidget
+        // and FrameLayout.
+        tabHost.setup();
+
+        // for each child of the framelayout, add a new TabSpec
+        for (int i = 0 ; i < count ; i++) {
+            View child = content.getChildAt(i);
+            String tabSpec = String.format("tab_spec%d", i+1);
+            int id = child.getId();
+            String[] resource = projectCallback.resolveResourceValue(id);
+            String name;
+            if (resource != null) {
+                name = resource[0]; // 0 is resource name, 1 is resource type.
+            } else {
+                name = String.format("Tab %d", i+1); // default name if id is unresolved.
+            }
+            tabHost.addTab(tabHost.newTabSpec(tabSpec).setIndicator(name).setContent(id));
+        }
+    }
+
+
+    /**
+     * Visits a View and its children and generate a {@link ViewInfo} containing the
+     * bounds of all the views.
+     * @param view the root View
+     * @param context the context.
+     */
+    private ViewInfo visit(View view, BridgeContext context) {
+        if (view == null) {
+            return null;
+        }
+
+        ViewInfo result = new ViewInfo(view.getClass().getName(),
+                context.getViewKey(view),
+                view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = ((ViewGroup) view);
+            List<ViewInfo> children = new ArrayList<ViewInfo>();
+            for (int i = 0; i < group.getChildCount(); i++) {
+                children.add(visit(group.getChildAt(i), context));
+            }
+            result.setChildren(children);
+        }
+
+        return result;
+    }
+
+    public BufferedImage getImage() {
+        return mImage;
+    }
+
+    public ViewInfo getViewInfo() {
+        return mViewInfo;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
similarity index 97%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index f13ecdc..3e506b8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -14,11 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
 
 import com.android.layoutlib.api.IDensityBasedResourceValue;
 import com.android.layoutlib.api.IDensityBasedResourceValue.Density;
 import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.android.NinePatchDrawable;
 import com.android.ninepatch.NinePatch;
 
 import org.kxml2.io.KXmlParser;
@@ -56,7 +60,7 @@
      * @return the color as an int
      * @throw NumberFormatException if the conversion failed.
      */
-    static int getColor(String value) {
+    public static int getColor(String value) {
         if (value != null) {
             if (value.startsWith("#") == false) {
                 throw new NumberFormatException();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java
similarity index 74%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java
rename to tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java
index 01a4871..4ab98ce 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/ResourceValue.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/TempResourceValue.java
@@ -14,24 +14,24 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.impl;
 
+import com.android.layoutlib.api.ILayoutBridge;
 import com.android.layoutlib.api.IResourceValue;
 
 /**
- * Basic implementation of IResourceValue.
+ * Basic implementation of IResourceValue for when it is needed to dynamically make a new
+ * {@link IResourceValue} object.
+ *
+ * Most of the time, implementations of IResourceValue come through the {@link ILayoutBridge}
+ * API.
  */
-class ResourceValue implements IResourceValue {
+public class TempResourceValue implements IResourceValue {
     private final String mType;
     private final String mName;
     private String mValue = null;
-    
-    ResourceValue(String name) {
-        mType = null;
-        mName = name;
-    }
 
-    public ResourceValue(String type, String name, String value) {
+    public TempResourceValue(String type, String name, String value) {
         mType = type;
         mName = name;
         mValue = value;
@@ -44,16 +44,16 @@
     public final String getName() {
         return mName;
     }
-    
+
     public final String getValue() {
         return mValue;
     }
-    
+
     public final void setValue(String value) {
         mValue = value;
     }
-    
-    public void replaceWith(ResourceValue value) {
+
+    public void replaceWith(TempResourceValue value) {
         mValue = value.mValue;
     }
 
diff --git a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
index 6d013bb..1ec6262 100644
--- a/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
+++ b/tools/layoutlib/bridge/src/com/google/android/maps/MapView.java
@@ -16,7 +16,7 @@
 
 package com.google.android.maps;
 
-import com.android.layoutlib.bridge.MockView;
+import com.android.layoutlib.bridge.android.MockView;
 
 import android.content.Context;
 import android.os.Bundle;
diff --git a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
similarity index 96%
rename from tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
rename to tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index db1262f..3252fb4 100644
--- a/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge;
+package com.android.layoutlib.bridge.android;
+
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
 
 import org.kxml2.io.KXmlParser;
 import org.w3c.dom.Node;