Merge "Fix emulator trackball." into honeycomb
diff --git a/api/11.xml b/api/11.xml
index 6ed9d22..d17325f 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -199955,6 +199955,25 @@
 >
 </field>
 </class>
+<class name="Base64DataException"
+ extends="java.io.IOException"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64DataException"
+ type="android.util.Base64DataException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detailMessage" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
 <class name="Base64InputStream"
  extends="java.io.FilterInputStream"
  abstract="false"
@@ -214823,6 +214842,19 @@
 <parameter name="selected" type="boolean">
 </parameter>
 </method>
+<method name="dispatchSystemUiVisibilityChanged"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="visibility" type="int">
+</parameter>
+</method>
 <method name="dispatchTouchEvent"
  return="boolean"
  abstract="false"
@@ -215876,6 +215908,17 @@
  visibility="protected"
 >
 </method>
+<method name="getSystemUiVisibility"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getTag"
  return="java.lang.Object"
  abstract="false"
@@ -218126,6 +218169,19 @@
 <parameter name="l" type="android.view.View.OnLongClickListener">
 </parameter>
 </method>
+<method name="setOnSystemUiVisibilityChangeListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="l" type="android.view.View.OnSystemUiVisibilityChangeListener">
+</parameter>
+</method>
 <method name="setOnTouchListener"
  return="void"
  abstract="false"
@@ -218379,6 +218435,19 @@
 <parameter name="soundEffectsEnabled" type="boolean">
 </parameter>
 </method>
+<method name="setSystemUiVisibility"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="visibility" type="int">
+</parameter>
+</method>
 <method name="setTag"
  return="void"
  abstract="false"
@@ -219386,6 +219455,28 @@
  visibility="public"
 >
 </field>
+<field name="STATUS_BAR_HIDDEN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_BAR_VISIBLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="VIEW_LOG_TAG"
  type="java.lang.String"
  transient="false"
@@ -219804,6 +219895,27 @@
 </parameter>
 </method>
 </interface>
+<interface name="View.OnSystemUiVisibilityChangeListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onSystemUiVisibilityChange"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="visibility" type="int">
+</parameter>
+</method>
+</interface>
 <interface name="View.OnTouchListener"
  abstract="true"
  static="true"
diff --git a/api/current.xml b/api/current.xml
index 3bcac93..b7d7b3a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -29889,6 +29889,17 @@
  visibility="public"
 >
 </method>
+<method name="isRemoving"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isResumed"
  return="boolean"
  abstract="false"
@@ -199955,6 +199966,25 @@
 >
 </field>
 </class>
+<class name="Base64DataException"
+ extends="java.io.IOException"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64DataException"
+ type="android.util.Base64DataException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detailMessage" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
 <class name="Base64InputStream"
  extends="java.io.FilterInputStream"
  abstract="false"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 511ddc1..960b943 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2385,7 +2385,9 @@
             performPauseActivity(token, finished, r.isPreHoneycomb());
 
             // Make sure any pending writes are now committed.
-            QueuedWork.waitToFinish();
+            if (r.isPreHoneycomb()) {
+                QueuedWork.waitToFinish();
+            }
             
             // Tell the activity manager we have paused.
             try {
@@ -2583,6 +2585,11 @@
 
         updateVisibility(r, show);
 
+        // Make sure any pending writes are now committed.
+        if (!r.isPreHoneycomb()) {
+            QueuedWork.waitToFinish();
+        }
+
         // Tell activity manager we have been stopped.
         try {
             ActivityManagerNative.getDefault().activityStopped(
@@ -2647,6 +2654,12 @@
                 }
                 r.stopped = true;
             }
+
+            // Make sure any pending writes are now committed.
+            if (!r.isPreHoneycomb()) {
+                QueuedWork.waitToFinish();
+            }
+
             // Tell activity manager we slept.
             try {
                 ActivityManagerNative.getDefault().activitySlept(r.token);
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 3280b22..b3d111a 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -357,6 +357,9 @@
     // True if the fragment is in the list of added fragments.
     boolean mAdded;
     
+    // If set this fragment is being removed from its activity.
+    boolean mRemoving;
+
     // True if the fragment is in the resumed state.
     boolean mResumed;
     
@@ -638,6 +641,9 @@
      * Return <code>getActivity().getResources()</code>.
      */
     final public Resources getResources() {
+        if (mActivity == null) {
+            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+        }
         return mActivity.getResources();
     }
     
@@ -689,7 +695,16 @@
      * Return true if the fragment is currently added to its activity.
      */
     final public boolean isAdded() {
-        return mActivity != null && mActivity.mFragments.mAdded.contains(this);
+        return mActivity != null && mAdded;
+    }
+
+    /**
+     * Return true if this fragment is currently being removed from its
+     * activity.  This is  <em>not</em> whether its activity is finishing, but
+     * rather whether it is in the process of being removed from its activity.
+     */
+    final public boolean isRemoving() {
+        return mRemoving;
     }
     
     /**
@@ -787,6 +802,9 @@
         if (mLoaderManager != null) {
             return mLoaderManager;
         }
+        if (mActivity == null) {
+            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+        }
         mCheckedForLoaderManager = true;
         mLoaderManager = mActivity.getLoaderManager(mIndex, mLoadersStarted, true);
         return mLoaderManager;
@@ -797,6 +815,9 @@
      * containing Activity.
      */
     public void startActivity(Intent intent) {
+        if (mActivity == null) {
+            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+        }
         mActivity.startActivityFromFragment(this, intent, -1);
     }
     
@@ -805,6 +826,9 @@
      * containing Activity.
      */
     public void startActivityForResult(Intent intent, int requestCode) {
+        if (mActivity == null) {
+            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
+        }
         mActivity.startActivityFromFragment(this, intent, requestCode);
     }
     
@@ -1217,6 +1241,7 @@
                 writer.print(" mWho="); writer.print(mWho);
                 writer.print(" mBackStackNesting="); writer.println(mBackStackNesting);
         writer.print(prefix); writer.print("mAdded="); writer.print(mAdded);
+                writer.print(" mRemoving="); writer.print(mRemoving);
                 writer.print(" mResumed="); writer.print(mResumed);
                 writer.print(" mFromLayout="); writer.print(mFromLayout);
                 writer.print(" mInLayout="); writer.println(mInLayout);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index e729805..2c9c85b 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -28,6 +28,8 @@
 import android.os.Parcelable;
 import android.util.DebugUtils;
 import android.util.Log;
+import android.util.LogWriter;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -968,6 +970,7 @@
         makeActive(fragment);
         if (DEBUG) Log.v(TAG, "add: " + fragment);
         fragment.mAdded = true;
+        fragment.mRemoving = false;
         if (fragment.mHasMenu) {
             mNeedMenuInvalidate = true;
         }
@@ -984,6 +987,7 @@
             mNeedMenuInvalidate = true;
         }
         fragment.mAdded = false;
+        fragment.mRemoving = true;
         moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
                 transition, transitionStyle);
         if (inactive) {
@@ -1376,6 +1380,14 @@
                     }
 
                     if (f.mTarget != null) {
+                        if (f.mTarget.mIndex < 0) {
+                            String msg = "Failure saving state: " + f
+                                + " has target not in fragment manager: " + f.mTarget;
+                            Slog.e(TAG, msg);
+                            dump("  ", null, new PrintWriter(new LogWriter(
+                                    Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
+                            throw new IllegalStateException(msg);
+                        }
                         if (fs.mSavedFragmentState == null) {
                             fs.mSavedFragmentState = new Bundle();
                         }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 60213f8..c406524 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -567,6 +567,7 @@
             } else {
                 rd.validate(context, handler);
             }
+            rd.mForgotten = false;
             return rd.getIIntentReceiver();
         }
     }
@@ -596,6 +597,7 @@
                         rd.setUnregisterLocation(ex);
                         holder.put(r, rd);
                     }
+                    rd.mForgotten = true;
                     return rd.getIIntentReceiver();
                 }
             }
@@ -666,6 +668,7 @@
         final boolean mRegistered;
         final IntentReceiverLeaked mLocation;
         RuntimeException mUnregisterLocation;
+        boolean mForgotten;
 
         final class Args extends BroadcastReceiver.PendingResult implements Runnable {
             private Intent mCurIntent;
@@ -696,7 +699,7 @@
                 final Intent intent = mCurIntent;
                 mCurIntent = null;
                 
-                if (receiver == null || !mRegistered) {
+                if (receiver == null || mForgotten) {
                     if (mRegistered && ordered) {
                         if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                 "Finishing null broadcast to " + mReceiver);
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index 3d6182b..a7dd5fb 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -195,7 +195,7 @@
                 }
             }
             if (DEBUG) Slog.v(TAG, "Executing: " + mTask);
-            mTask.execute((Void[]) null);
+            mTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
         }
     }
 
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 5467a30..1764e11 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -899,7 +899,7 @@
                     return null;
                 }
             };
-            task.execute((Object[])null);
+            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null);
 
             return fds[0];
         } catch (IOException e) {
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 01fc010..df8cf9a 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -76,6 +76,8 @@
     }
 
     public void executeMessage(Message msg) {
+        if (mInputMethodSession == null) return;
+
         switch (msg.what) {
             case DO_FINISH_INPUT:
                 mInputMethodSession.finishInput();
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index 6a54846..343242e 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -19,11 +19,16 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.graphics.Rect;
 import android.os.IBinder;
 import android.view.Gravity;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowManager;
 
+import java.lang.Math;
+
 /**
  * A SoftInputWindow is a Dialog that is intended to be used for a top-level input
  * method window.  It will be displayed along the edge of the screen, moving
@@ -32,6 +37,7 @@
  */
 class SoftInputWindow extends Dialog {
     final KeyEvent.DispatcherState mDispatcherState;
+    private final Rect mBounds = new Rect();
     
     public void setToken(IBinder token) {
         WindowManager.LayoutParams lp = getWindow().getAttributes();
@@ -64,6 +70,13 @@
         mDispatcherState.reset();
     }
 
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        getWindow().getDecorView().getHitRect(mBounds);
+        final MotionEvent event = clipMotionEvent(ev, mBounds);
+        return super.dispatchTouchEvent(event);
+    }
+
     /**
      * Get the size of the DockWindow.
      * 
@@ -150,4 +163,48 @@
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                 WindowManager.LayoutParams.FLAG_DIM_BEHIND);
     }
+
+    private static MotionEvent clipMotionEvent(MotionEvent me, Rect bounds) {
+        final int pointerCount = me.getPointerCount();
+        boolean shouldClip = false;
+        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
+            final int x = (int)me.getX(pointerIndex);
+            final int y = (int)me.getY(pointerIndex);
+            if (!bounds.contains(x, y)) {
+                shouldClip = true;
+                break;
+            }
+        }
+        if (!shouldClip)
+            return me;
+
+        if (pointerCount == 1) {
+            final int x = (int)me.getX();
+            final int y = (int)me.getY();
+            me.setLocation(
+                    Math.max(bounds.left, Math.min(x, bounds.right - 1)),
+                    Math.max(bounds.top, Math.min(y, bounds.bottom - 1)));
+            return me;
+        }
+
+        final int[] pointerIds = new int[pointerCount];
+        final MotionEvent.PointerCoords[] pointerCoords =
+            new MotionEvent.PointerCoords[pointerCount];
+        for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
+            pointerIds[pointerIndex] = me.getPointerId(pointerIndex);
+            final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
+            me.getPointerCoords(pointerIndex, coords);
+            pointerCoords[pointerIndex] = coords;
+            final int x = (int)coords.x;
+            final int y = (int)coords.y;
+            if (!bounds.contains(x, y)) {
+                coords.x = Math.max(bounds.left, Math.min(x, bounds.right - 1));
+                coords.y = Math.max(bounds.top, Math.min(y, bounds.bottom - 1));
+            }
+        }
+        return MotionEvent.obtain(
+                me.getDownTime(), me.getEventTime(), me.getAction(), pointerCount, pointerIds,
+                pointerCoords, me.getMetaState(), me.getXPrecision(), me.getYPrecision(),
+                me.getDeviceId(), me.getEdgeFlags(), me.getSource(), me.getFlags());
+    }
 }
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index 30f25a2..bba11b0 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -25,8 +25,8 @@
 
 import java.security.cert.X509Certificate;
 
-import org.bouncycastle.asn1.DERObjectIdentifier;
-import org.bouncycastle.asn1.x509.X509Name;
+import com.android.org.bouncycastle.asn1.DERObjectIdentifier;
+import com.android.org.bouncycastle.asn1.x509.X509Name;
 
 /**
  * SSL certificate info (certificate details) class
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index b6aa03a..403f20e 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -341,55 +341,47 @@
         }
     }
 
-    private void dump(boolean show) {
-        int n = getLineCount();
-
-        for (int i = 0; i < n; i++) {
-            System.out.print("line " + i + ": " + getLineStart(i) + " to " + getLineEnd(i) + " ");
-
-            if (show) {
-                System.out.print(getText().subSequence(getLineStart(i),
-                                                       getLineEnd(i)));
-            }
-
-            System.out.println("");
-        }
-
-        System.out.println("");
-    }
-
+    @Override
     public int getLineCount() {
         return mInts.size() - 1;
     }
 
+    @Override
     public int getLineTop(int line) {
         return mInts.getValue(line, TOP);
     }
 
+    @Override
     public int getLineDescent(int line) {
         return mInts.getValue(line, DESCENT);
     }
 
+    @Override
     public int getLineStart(int line) {
         return mInts.getValue(line, START) & START_MASK;
     }
 
+    @Override
     public boolean getLineContainsTab(int line) {
         return (mInts.getValue(line, TAB) & TAB_MASK) != 0;
     }
 
+    @Override
     public int getParagraphDirection(int line) {
         return mInts.getValue(line, DIR) >> DIR_SHIFT;
     }
 
+    @Override
     public final Directions getLineDirections(int line) {
         return mObjects.getValue(line, 0);
     }
 
+    @Override
     public int getTopPadding() {
         return mTopPadding;
     }
 
+    @Override
     public int getBottomPadding() {
         return mBottomPadding;
     }
@@ -403,11 +395,11 @@
     implements TextWatcher, SpanWatcher
     {
         public ChangeWatcher(DynamicLayout layout) {
-            mLayout = new WeakReference(layout);
+            mLayout = new WeakReference<DynamicLayout>(layout);
         }
 
         private void reflow(CharSequence s, int where, int before, int after) {
-            DynamicLayout ml = (DynamicLayout) mLayout.get();
+            DynamicLayout ml = mLayout.get();
 
             if (ml != null)
                 ml.reflow(s, where, before, after);
@@ -417,7 +409,6 @@
 
         public void beforeTextChanged(CharSequence s,
                                       int where, int before, int after) {
-            ;
         }
 
         public void onTextChanged(CharSequence s,
@@ -426,7 +417,6 @@
         }
 
         public void afterTextChanged(Editable s) {
-            ;
         }
 
         public void onSpanAdded(Spannable s, Object o, int start, int end) {
@@ -447,9 +437,10 @@
             }
         }
 
-        private WeakReference mLayout;
+        private WeakReference<DynamicLayout> mLayout;
     }
 
+    @Override
     public int getEllipsisStart(int line) {
         if (mEllipsizeAt == null) {
             return 0;
@@ -458,6 +449,7 @@
         return mInts.getValue(line, ELLIPSIS_START);
     }
 
+    @Override
     public int getEllipsisCount(int line) {
         if (mEllipsizeAt == null) {
             return 0;
@@ -494,7 +486,6 @@
     private static final int COLUMNS_ELLIPSIZE = 5;
 
     private static final int START_MASK = 0x1FFFFFFF;
-    private static final int DIR_MASK   = 0xC0000000;
     private static final int DIR_SHIFT  = 30;
     private static final int TAB_MASK   = 0x20000000;
 
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index a6fd2f1..90279d1 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -90,13 +90,11 @@
         tl.mText = null;
         tl.mPaint = null;
         tl.mDirections = null;
-        if (tl.mLen < 250) {
-            synchronized(cached) {
-                for (int i = 0; i < cached.length; ++i) {
-                    if (cached[i] == null) {
-                        cached[i] = tl;
-                        break;
-                    }
+        synchronized(cached) {
+            for (int i = 0; i < cached.length; ++i) {
+                if (cached[i] == null) {
+                    cached[i] = tl;
+                    break;
                 }
             }
         }
diff --git a/core/java/android/util/Base64DataException.java b/core/java/android/util/Base64DataException.java
new file mode 100644
index 0000000..de12ee1
--- /dev/null
+++ b/core/java/android/util/Base64DataException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import java.io.IOException;
+
+/**
+ * This exception is thrown by {@link Base64InputStream} or {@link Base64OutputStream}
+ * when an error is detected in the data being decoded.  This allows problems with the base64 data
+ * to be disambiguated from errors in the underlying streams (e.g. actual connection errors.)
+ */
+public class Base64DataException extends IOException {
+    public Base64DataException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/core/java/android/util/Base64InputStream.java b/core/java/android/util/Base64InputStream.java
index e9dac24..9eba5b5 100644
--- a/core/java/android/util/Base64InputStream.java
+++ b/core/java/android/util/Base64InputStream.java
@@ -145,7 +145,7 @@
             success = coder.process(inputBuffer, 0, bytesRead, false);
         }
         if (!success) {
-            throw new IOException("bad base-64");
+            throw new Base64DataException("bad base-64");
         }
         outputEnd = coder.op;
         outputStart = 0;
diff --git a/core/java/android/util/Base64OutputStream.java b/core/java/android/util/Base64OutputStream.java
index 30d632d..4535d1c 100644
--- a/core/java/android/util/Base64OutputStream.java
+++ b/core/java/android/util/Base64OutputStream.java
@@ -136,7 +136,7 @@
     private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
         coder.output = embiggen(coder.output, coder.maxOutputSize(len));
         if (!coder.process(b, off, len, finish)) {
-            throw new IOException("bad base-64");
+            throw new Base64DataException("bad base-64");
         }
         out.write(coder.output, 0, coder.op);
     }
diff --git a/core/java/android/util/LogWriter.java b/core/java/android/util/LogWriter.java
new file mode 100644
index 0000000..ce30631
--- /dev/null
+++ b/core/java/android/util/LogWriter.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import java.io.Writer;
+
+/** @hide */
+public class LogWriter extends Writer {
+    private final int mPriority;
+    private final String mTag;
+    private final int mBuffer;
+    private StringBuilder mBuilder = new StringBuilder(128);
+
+    /**
+     * Create a new Writer that sends to the log with the given priority
+     * and tag.
+     *
+     * @param priority The desired log priority:
+     * {@link android.util.Log#VERBOSE Log.VERBOSE},
+     * {@link android.util.Log#DEBUG Log.DEBUG},
+     * {@link android.util.Log#INFO Log.INFO},
+     * {@link android.util.Log#WARN Log.WARN}, or
+     * {@link android.util.Log#ERROR Log.ERROR}.
+     * @param tag A string tag to associate with each printed log statement.
+     */
+    public LogWriter(int priority, String tag) {
+        mPriority = priority;
+        mTag = tag;
+        mBuffer = Log.LOG_ID_MAIN;
+    }
+
+    /**
+     * @hide
+     * Same as above, but buffer is one of the LOG_ID_ constants from android.util.Log.
+     */
+    public LogWriter(int priority, String tag, int buffer) {
+        mPriority = priority;
+        mTag = tag;
+        mBuffer = buffer;
+    }
+
+    @Override public void close() {
+        flushBuilder();
+    }
+
+    @Override public void flush() {
+        flushBuilder();
+    }
+
+    @Override public void write(char[] buf, int offset, int count) {
+        for(int i = 0; i < count; i++) {
+            char c = buf[offset + i];
+            if ( c == '\n') {
+                flushBuilder();
+            }
+            else {
+                mBuilder.append(c);
+            }
+        }
+    }
+
+    private void flushBuilder() {
+        if (mBuilder.length() > 0) {
+            Log.println_native(mBuffer, mPriority, mTag, mBuilder.toString());
+            mBuilder.delete(0, mBuilder.length());
+        }
+    }
+}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index dce1a6c..dac3135 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -192,21 +192,36 @@
         nSetViewport(mRenderer, width, height);
     }
     
-    private native void nSetViewport(int renderer, int width, int height);
+    private static native void nSetViewport(int renderer, int width, int height);
 
-    @Override
-    void onPreDraw() {
-        nPrepare(mRenderer, mOpaque);
+    /**
+     * @hide
+     */
+    public static boolean preserveBackBuffer() {
+        return nPreserveBackBuffer();
     }
 
-    private native void nPrepare(int renderer, boolean opaque);
+    private static native boolean nPreserveBackBuffer();    
+    
+    @Override
+    void onPreDraw(Rect dirty) {
+        if (dirty != null) {
+            nPrepareDirty(mRenderer, dirty.left, dirty.top, dirty.right, dirty.bottom, mOpaque);
+        } else {
+            nPrepare(mRenderer, mOpaque);
+        }
+    }
+
+    private static native void nPrepare(int renderer, boolean opaque);
+    private static native void nPrepareDirty(int renderer, int left, int top, int right, int bottom,
+            boolean opaque);
 
     @Override
     void onPostDraw() {
         nFinish(mRenderer);
     }
     
-    private native void nFinish(int renderer);
+    private static native void nFinish(int renderer);
 
     @Override
     public boolean acquireContext() {
@@ -217,14 +232,14 @@
         return mContextLocked;
     }
 
-    private native void nAcquireContext(int renderer);
+    private static native void nAcquireContext(int renderer);
 
     @Override
     public boolean callDrawGLFunction(int drawGLFunction) {
         return nCallDrawGLFunction(mRenderer, drawGLFunction);
     }
 
-    private native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
+    private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
 
     @Override
     public void releaseContext() {
@@ -234,7 +249,7 @@
         }
     }
 
-    private native void nReleaseContext(int renderer);
+    private static native void nReleaseContext(int renderer);
     
     ///////////////////////////////////////////////////////////////////////////
     // Display list
@@ -244,7 +259,7 @@
         return nGetDisplayList(mRenderer);
     }
 
-    private native int nGetDisplayList(int renderer);
+    private static native int nGetDisplayList(int renderer);
     
     static void destroyDisplayList(int displayList) {
         nDestroyDisplayList(displayList);
@@ -257,7 +272,7 @@
         return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).mNativeDisplayList);
     }
 
-    private native boolean nDrawDisplayList(int renderer, int displayList);
+    private static native boolean nDrawDisplayList(int renderer, int displayList);
 
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layer
@@ -271,7 +286,7 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
+    private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
     
     void interrupt() {
         nInterrupt(mRenderer);
@@ -281,8 +296,8 @@
         nResume(mRenderer);
     }
 
-    private native void nInterrupt(int renderer);
-    private native void nResume(int renderer);
+    private static native void nInterrupt(int renderer);
+    private static native void nResume(int renderer);
 
     ///////////////////////////////////////////////////////////////////////////
     // Clipping
@@ -303,7 +318,7 @@
         return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
     }
     
-    private native boolean nClipRect(int renderer, float left, float top,
+    private static native boolean nClipRect(int renderer, float left, float top,
             float right, float bottom, int op);
 
     @Override
@@ -316,7 +331,8 @@
         return nClipRect(mRenderer, left, top, right, bottom, Region.Op.INTERSECT.nativeInt);
     }
     
-    private native boolean nClipRect(int renderer, int left, int top, int right, int bottom, int op);
+    private static native boolean nClipRect(int renderer, int left, int top, int right, int bottom,
+            int op);
 
     @Override
     public boolean clipRect(Rect rect) {
@@ -355,14 +371,14 @@
         return nGetClipBounds(mRenderer, bounds);
     }
 
-    private native boolean nGetClipBounds(int renderer, Rect bounds);
+    private static native boolean nGetClipBounds(int renderer, Rect bounds);
 
     @Override
     public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
         return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt);
     }
     
-    private native boolean nQuickReject(int renderer, float left, float top,
+    private static native boolean nQuickReject(int renderer, float left, float top,
             float right, float bottom, int edge);
 
     @Override
@@ -384,56 +400,56 @@
         if (dx != 0.0f || dy != 0.0f) nTranslate(mRenderer, dx, dy);
     }
     
-    private native void nTranslate(int renderer, float dx, float dy);
+    private static native void nTranslate(int renderer, float dx, float dy);
 
     @Override
     public void skew(float sx, float sy) {
         nSkew(mRenderer, sx, sy);
     }
 
-    private native void nSkew(int renderer, float sx, float sy);
+    private static native void nSkew(int renderer, float sx, float sy);
 
     @Override
     public void rotate(float degrees) {
         nRotate(mRenderer, degrees);
     }
     
-    private native void nRotate(int renderer, float degrees);
+    private static native void nRotate(int renderer, float degrees);
 
     @Override
     public void scale(float sx, float sy) {
         nScale(mRenderer, sx, sy);
     }
     
-    private native void nScale(int renderer, float sx, float sy);
+    private static native void nScale(int renderer, float sx, float sy);
 
     @Override
     public void setMatrix(Matrix matrix) {
         nSetMatrix(mRenderer, matrix.native_instance);
     }
     
-    private native void nSetMatrix(int renderer, int matrix);
+    private static native void nSetMatrix(int renderer, int matrix);
 
     @Override
     public int getNativeMatrix() {
         return nGetMatrix(mRenderer);
     }
 
-    private native int nGetMatrix(int renderer);    
+    private static native int nGetMatrix(int renderer);    
 
     @Override
     public void getMatrix(Matrix matrix) {
         nGetMatrix(mRenderer, matrix.native_instance);
     }
     
-    private native void nGetMatrix(int renderer, int matrix);
+    private static native void nGetMatrix(int renderer, int matrix);
 
     @Override
     public void concat(Matrix matrix) {
         nConcatMatrix(mRenderer, matrix.native_instance);
     }
     
-    private native void nConcatMatrix(int renderer, int matrix);
+    private static native void nConcatMatrix(int renderer, int matrix);
     
     ///////////////////////////////////////////////////////////////////////////
     // State management
@@ -449,7 +465,7 @@
         return nSave(mRenderer, saveFlags);
     }
 
-    private native int nSave(int renderer, int flags);
+    private static native int nSave(int renderer, int flags);
     
     @Override
     public int saveLayer(RectF bounds, Paint paint, int saveFlags) {
@@ -469,8 +485,8 @@
         return save(saveFlags);
     }
 
-    private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
-            int paint, int saveFlags);
+    private static native int nSaveLayer(int renderer, float left, float top,
+            float right, float bottom, int paint, int saveFlags);
 
     @Override
     public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) {
@@ -487,7 +503,7 @@
         return save(saveFlags);
     }
 
-    private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
+    private static native int nSaveLayerAlpha(int renderer, float left, float top, float right,
             float bottom, int alpha, int saveFlags);
     
     @Override
@@ -495,21 +511,21 @@
         nRestore(mRenderer);
     }
     
-    private native void nRestore(int renderer);
+    private static native void nRestore(int renderer);
 
     @Override
     public void restoreToCount(int saveCount) {
         nRestoreToCount(mRenderer, saveCount);
     }
 
-    private native void nRestoreToCount(int renderer, int saveCount);
+    private static native void nRestoreToCount(int renderer, int saveCount);
     
     @Override
     public int getSaveCount() {
         return nGetSaveCount(mRenderer);
     }
     
-    private native int nGetSaveCount(int renderer);
+    private static native int nGetSaveCount(int renderer);
 
     ///////////////////////////////////////////////////////////////////////////
     // Filtering
@@ -538,8 +554,9 @@
         if (hasModifier) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawArc(int renderer, float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, boolean useCenter, int paint);
+    private static native void nDrawArc(int renderer, float left, float top,
+            float right, float bottom, float startAngle, float sweepAngle,
+            boolean useCenter, int paint);
 
     @Override
     public void drawARGB(int a, int r, int g, int b) {
@@ -556,7 +573,7 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
+    private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
             float left, float top, float right, float bottom, int paint);
 
     @Override
@@ -568,7 +585,7 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawBitmap(
+    private static native void nDrawBitmap(
             int renderer, int bitmap, byte[] buffer, float left, float top, int paint);
 
     @Override
@@ -581,7 +598,8 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawBitmap(int renderer, int bitmap, byte[] buff, int matrix, int paint);
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
+            int matrix, int paint);
 
     @Override
     public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) {
@@ -616,7 +634,7 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
+    private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
             float srcLeft, float srcTop, float srcRight, float srcBottom,
             float left, float top, float right, float bottom, int paint);
 
@@ -665,7 +683,7 @@
         if (hasColorFilter) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
+    private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
             int meshWidth, int meshHeight, float[] verts, int vertOffset,
             int[] colors, int colorOffset, int paint);
 
@@ -676,7 +694,8 @@
         if (hasModifier) nResetModifiers(mRenderer);        
     }
 
-    private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
+    private static native void nDrawCircle(int renderer, float cx, float cy,
+            float radius, int paint);
 
     @Override
     public void drawColor(int color) {
@@ -688,7 +707,7 @@
         nDrawColor(mRenderer, color, mode.nativeInt);
     }
     
-    private native void nDrawColor(int renderer, int color, int mode);
+    private static native void nDrawColor(int renderer, int color, int mode);
 
     @Override
     public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) {
@@ -709,7 +728,8 @@
         if (hasModifier) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawLines(int renderer, float[] points, int offset, int count, int paint);
+    private static native void nDrawLines(int renderer, float[] points,
+            int offset, int count, int paint);
 
     @Override
     public void drawLines(float[] pts, Paint paint) {
@@ -723,8 +743,8 @@
         if (hasModifier) nResetModifiers(mRenderer); 
     }
 
-    private native void nDrawOval(int renderer, float left, float top, float right, float bottom,
-            int paint);
+    private static native void nDrawOval(int renderer, float left, float top,
+            float right, float bottom, int paint);
 
     @Override
     public void drawPaint(Paint paint) {
@@ -746,8 +766,8 @@
         if (hasModifier) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawPath(int renderer, int path, int paint);
-    private native void nDrawRects(int renderer, int region, int paint);
+    private static native void nDrawPath(int renderer, int path, int paint);
+    private static native void nDrawRects(int renderer, int region, int paint);
 
     @Override
     public void drawPicture(Picture picture) {
@@ -798,8 +818,8 @@
         if (hasModifier) nResetModifiers(mRenderer);
     }
 
-    private native void nDrawRect(int renderer, float left, float top, float right, float bottom,
-            int paint);
+    private static native void nDrawRect(int renderer, float left, float top,
+            float right, float bottom, int paint);
 
     @Override
     public void drawRect(Rect r, Paint paint) {
@@ -824,7 +844,7 @@
         if (hasModifier) nResetModifiers(mRenderer);        
     }
 
-    private native void nDrawRoundRect(int renderer, float left, float top,
+    private static native void nDrawRoundRect(int renderer, float left, float top,
             float right, float bottom, float rx, float y, int paint);
 
     @Override
@@ -841,8 +861,8 @@
         }
     }
     
-    private native void nDrawText(int renderer, char[] text, int index, int count, float x, float y,
-            int bidiFlags, int paint);
+    private static native void nDrawText(int renderer, char[] text, int index, int count,
+            float x, float y, int bidiFlags, int paint);
 
     @Override
     public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
@@ -858,7 +878,8 @@
             } else {
                 char[] buf = TemporaryBuffer.obtain(end - start);
                 TextUtils.getChars(text, start, end, buf, 0);
-                nDrawText(mRenderer, buf, 0, end - start, x, y, paint.mBidiFlags, paint.mNativePaint);
+                nDrawText(mRenderer, buf, 0, end - start, x, y,
+                        paint.mBidiFlags, paint.mNativePaint);
                 TemporaryBuffer.recycle(buf);
             }
         } finally {
@@ -880,8 +901,8 @@
         }
     }
 
-    private native void nDrawText(int renderer, String text, int start, int end, float x, float y,
-            int bidiFlags, int paint);
+    private static native void nDrawText(int renderer, String text, int start, int end,
+            float x, float y, int bidiFlags, int paint);
 
     @Override
     public void drawText(String text, float x, float y, Paint paint) {
@@ -924,7 +945,7 @@
         }
     }
 
-    private native void nDrawTextRun(int renderer, char[] text, int index, int count,
+    private static native void nDrawTextRun(int renderer, char[] text, int index, int count,
             int contextIndex, int contextCount, float x, float y, int dir, int nativePaint);
 
     @Override
@@ -958,7 +979,7 @@
         }
     }
 
-    private native void nDrawTextRun(int renderer, String text, int start, int end,
+    private static native void nDrawTextRun(int renderer, String text, int start, int end,
             int contextStart, int contextEnd, float x, float y, int flags, int nativePaint);
 
     @Override
@@ -1001,9 +1022,10 @@
         return false;        
     }
     
-    private native void nSetupShader(int renderer, int shader);
-    private native void nSetupColorFilter(int renderer, int colorFilter);
-    private native void nSetupShadow(int renderer, float radius, float dx, float dy, int color);
+    private static native void nSetupShader(int renderer, int shader);
+    private static native void nSetupColorFilter(int renderer, int colorFilter);
+    private static native void nSetupShadow(int renderer, float radius,
+            float dx, float dy, int color);
 
-    private native void nResetModifiers(int renderer);
+    private static native void nResetModifiers(int renderer);
 }
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index a4d36b7..e6fecc8 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -19,6 +19,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Rect;
 
 /**
  * Hardware accelerated canvas.
@@ -38,8 +39,10 @@
     
     /**
      * Invoked before any drawing operation is performed in this canvas.
+     * 
+     * @param dirty The dirty rectangle to update, can be null.
      */
-    abstract void onPreDraw();
+    abstract void onPreDraw(Rect dirty);
 
     /**
      * Invoked after all drawing operation have been performed.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index c82184a..48f40c3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -18,6 +18,8 @@
 package android.view;
 
 import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
 import android.os.SystemClock;
 import android.util.EventLog;
 import android.util.Log;
@@ -39,6 +41,16 @@
     static final String LOG_TAG = "HardwareRenderer";
 
     /**
+     * Turn on to only refresh the parts of the screen that need updating.
+     */
+    public static final boolean RENDER_DIRTY_REGIONS = true;
+
+    /**
+     * Turn on to draw dirty regions every other frame.
+     */
+    private static final boolean DEBUG_DIRTY_REGION = false;
+    
+    /**
      * A process can set this flag to false to prevent the use of hardware
      * rendering.
      * 
@@ -108,11 +120,14 @@
 
     /**
      * Draws the specified view.
-     * 
+     *
      * @param view The view to draw.
      * @param attachInfo AttachInfo tied to the specified view.
+     * @param callbacks Callbacks invoked when drawing happens.
+     * @param dirty The dirty rectangle to update, can be null.
      */
-    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
+    abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+            Rect dirty);
 
     /**
      * Creates a new display list that can be used to record batches of
@@ -214,7 +229,13 @@
     @SuppressWarnings({"deprecation"})
     static abstract class GlRenderer extends HardwareRenderer {
         private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        private static final int EGL_SURFACE_TYPE = 0x3033;
+        private static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
 
+        private static final int SURFACE_STATE_ERROR = 0;
+        private static final int SURFACE_STATE_SUCCESS = 1;
+        private static final int SURFACE_STATE_UPDATED = 2;
+        
         static EGLContext sEglContext;
         static EGL10 sEgl;
         static EGLDisplay sEglDisplay;
@@ -226,6 +247,9 @@
         
         GL mGl;
         HardwareCanvas mCanvas;
+        int mFrameCount;
+        Paint mDebugPaint;
+
 
         final int mGlVersion;
         final boolean mTranslucent;
@@ -412,7 +436,7 @@
             if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                 int error = sEgl.eglGetError();
                 if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
-                    Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
                     return null;
                 }
                 throw new RuntimeException("createWindowSurface failed "
@@ -427,6 +451,12 @@
                 throw new RuntimeException("eglMakeCurrent failed "
                         + getEGLErrorString(sEgl.eglGetError()));
             }
+            
+            if (RENDER_DIRTY_REGIONS) {
+                if (!GLES20Canvas.preserveBackBuffer()) {
+                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
+                }
+            }
 
             return sEglContext.getGL();
         }
@@ -471,12 +501,12 @@
         void setup(int width, int height) {
             mCanvas.setViewport(width, height);
         }
-        
+
         boolean canDraw() {
             return mGl != null && mCanvas != null;
         }        
         
-        void onPreDraw() {
+        void onPreDraw(Rect dirty) {
         }
 
         void onPostDraw() {
@@ -492,8 +522,14 @@
         }
 
         @Override
-        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
+        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+                Rect dirty) {
             if (canDraw()) {
+                //noinspection PointlessBooleanExpression,ConstantConditions
+                if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+                    dirty = null;
+                }
+
                 attachInfo.mDrawingTime = SystemClock.uptimeMillis();
                 attachInfo.mIgnoreDirtyState = true;
                 view.mPrivateFlags |= View.DRAWN;
@@ -503,11 +539,18 @@
                     startTime = SystemClock.elapsedRealtime();
                 }
 
-                if (checkCurrent()) {
-                    onPreDraw();
+                final int surfaceState = checkCurrent();
+                if (surfaceState != SURFACE_STATE_ERROR) {
+                    // We had to change the current surface and/or context, redraw everything
+                    if (surfaceState == SURFACE_STATE_UPDATED) {
+                        dirty = null;
+                    }
+
+                    onPreDraw(dirty);
     
                     HardwareCanvas canvas = mCanvas;
                     attachInfo.mHardwareCanvas = canvas;
+
                     int saveCount = canvas.save();
                     callbacks.onHardwarePreDraw(canvas);
 
@@ -515,6 +558,7 @@
                         view.mRecreateDisplayList =
                                 (view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED;
                         view.mPrivateFlags &= ~View.INVALIDATED;
+
                         DisplayList displayList = view.getDisplayList();
                         if (displayList != null) {
                             if (canvas.drawDisplayList(displayList)) {
@@ -524,6 +568,16 @@
                             // Shouldn't reach here
                             view.draw(canvas);
                         }
+
+                        if (DEBUG_DIRTY_REGION) {
+                            if (mDebugPaint == null) {
+                                mDebugPaint = new Paint();
+                                mDebugPaint.setColor(0x7fff0000);
+                            }
+                            if (dirty != null && (mFrameCount++ & 1) == 0) {
+                                canvas.drawRect(dirty, mDebugPaint);
+                            }
+                        }
                     } finally {
                         callbacks.onHardwarePostDraw(canvas);
                         canvas.restoreToCount(saveCount);
@@ -543,8 +597,8 @@
                 }
             }
         }
-
-        private boolean checkCurrent() {
+        
+        private int checkCurrent() {
             // TODO: Don't check the current context when we have one per UI thread
             // TODO: Use a threadlocal flag to know whether the surface has changed
             if (sEgl.eglGetCurrentContext() != sEglContext ||
@@ -553,10 +607,12 @@
                     fallback(true);
                     Log.e(LOG_TAG, "eglMakeCurrent failed " +
                             getEGLErrorString(sEgl.eglGetError()));
-                    return false;
+                    return SURFACE_STATE_ERROR;
+                } else {
+                    return SURFACE_STATE_UPDATED;
                 }
             }
-            return true;
+            return SURFACE_STATE_SUCCESS;
         }
 
         static abstract class EglConfigChooser {
@@ -629,6 +685,7 @@
 
             ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize,
                     int alphaSize, int depthSize, int stencilSize) {
+                //noinspection PointlessBitwiseExpression
                 super(glVersion, new int[] {
                         EGL10.EGL_RED_SIZE, redSize,
                         EGL10.EGL_GREEN_SIZE, greenSize,
@@ -636,6 +693,8 @@
                         EGL10.EGL_ALPHA_SIZE, alphaSize,
                         EGL10.EGL_DEPTH_SIZE, depthSize,
                         EGL10.EGL_STENCIL_SIZE, stencilSize,
+                        EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT |
+                                (RENDER_DIRTY_REGIONS ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
                         EGL10.EGL_NONE });
                 mValue = new int[1];
                 mRedSize = redSize;
@@ -656,7 +715,16 @@
                         int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, 0);
                         int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
                         int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
-                        if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize) {
+                        boolean backBuffer;
+                        if (RENDER_DIRTY_REGIONS) {
+                            int surfaceType = findConfigAttrib(egl, display, config,
+                                    EGL_SURFACE_TYPE, 0);
+                            backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0;
+                        } else {
+                            backBuffer = true;
+                        }
+                        if (r >= mRedSize && g >= mGreenSize && b >= mBlueSize && a >= mAlphaSize
+                                && backBuffer) {
                             return config;
                         }
                     }
@@ -696,8 +764,8 @@
         }                
 
         @Override
-        void onPreDraw() {
-            mGlCanvas.onPreDraw();
+        void onPreDraw(Rect dirty) {
+            mGlCanvas.onPreDraw(dirty);
         }
 
         @Override
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8af2549..65d2e11 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6730,11 +6730,14 @@
             mPrivateFlags |= INVALIDATED;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
-            if (p != null && ai != null && ai.mHardwareAccelerated) {
-                // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                // with a null dirty rect, which tells the ViewRoot to redraw everything
-                p.invalidateChild(this, null);
-                return;
+            //noinspection PointlessBooleanExpression,ConstantConditions
+            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+                if (p != null && ai != null && ai.mHardwareAccelerated) {
+                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+                    // with a null dirty rect, which tells the ViewRoot to redraw everything
+                    p.invalidateChild(this, null);
+                    return;
+                }
             }
             if (p != null && ai != null) {
                 final int scrollX = mScrollX;
@@ -6770,11 +6773,14 @@
             mPrivateFlags |= INVALIDATED;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
-            if (p != null && ai != null && ai.mHardwareAccelerated) {
-                // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                // with a null dirty rect, which tells the ViewRoot to redraw everything
-                p.invalidateChild(this, null);
-                return;
+            //noinspection PointlessBooleanExpression,ConstantConditions
+            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+                if (p != null && ai != null && ai.mHardwareAccelerated) {
+                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+                    // with a null dirty rect, which tells the ViewRoot to redraw everything
+                    p.invalidateChild(this, null);
+                    return;
+                }
             }
             if (p != null && ai != null && l < r && t < b) {
                 final int scrollX = mScrollX;
@@ -6823,11 +6829,14 @@
             }
             final AttachInfo ai = mAttachInfo;
             final ViewParent p = mParent;
-            if (p != null && ai != null && ai.mHardwareAccelerated) {
-                // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                // with a null dirty rect, which tells the ViewRoot to redraw everything
-                p.invalidateChild(this, null);
-                return;
+            //noinspection PointlessBooleanExpression,ConstantConditions
+            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+                if (p != null && ai != null && ai.mHardwareAccelerated) {
+                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
+                    // with a null dirty rect, which tells the ViewRoot to redraw everything
+                    p.invalidateChild(this, null);
+                    return;
+                }
             }
 
             if (p != null && ai != null) {
@@ -8078,7 +8087,7 @@
      *
      * @return A HardwareLayer ready to render, or null if an error occurred.
      */
-    HardwareLayer getHardwareLayer(Canvas currentCanvas) {
+    HardwareLayer getHardwareLayer() {
         if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
             return null;
         }
@@ -8098,10 +8107,13 @@
                 mHardwareLayer.resize(width, height);
             }
 
-            final HardwareCanvas canvas = mHardwareLayer.start(mAttachInfo.mHardwareCanvas);
+            Canvas currentCanvas = mAttachInfo.mHardwareCanvas;
+            final HardwareCanvas canvas = mHardwareLayer.start(currentCanvas);
+            mAttachInfo.mHardwareCanvas = canvas;
             try {
                 canvas.setViewport(width, height);
-                canvas.onPreDraw();
+                // TODO: We should pass the dirty rect
+                canvas.onPreDraw(null);
 
                 computeScroll();
                 canvas.translate(-mScrollX, -mScrollY);
@@ -8121,7 +8133,8 @@
                 canvas.restoreToCount(restoreCount);
             } finally {
                 canvas.onPostDraw();
-                mHardwareLayer.end(mAttachInfo.mHardwareCanvas);
+                mHardwareLayer.end(currentCanvas);
+                mAttachInfo.mHardwareCanvas = currentCanvas;
             }
         }
 
@@ -8190,7 +8203,7 @@
             ViewGroup parent = (ViewGroup) this;
             final int count = parent.getChildCount();
             for (int i = 0; i < count; i++) {
-                final View child = (View) parent.getChildAt(i);
+                final View child = parent.getChildAt(i);
                 child.outputDirtyFlags(indent + "  ", clear, clearMask);
             }
         }
@@ -8251,7 +8264,8 @@
                 int height = mBottom - mTop;
 
                 canvas.setViewport(width, height);
-                canvas.onPreDraw();
+                // The dirty rect should always be null for a display list
+                canvas.onPreDraw(null);
 
                 final int restoreCount = canvas.save();
 
@@ -10288,6 +10302,7 @@
         }
 
         mPrivateFlags |= FORCE_LAYOUT;
+        mPrivateFlags |= INVALIDATED;
 
         if (mParent != null && !mParent.isLayoutRequested()) {
             mParent.requestLayout();
@@ -10301,6 +10316,7 @@
      */
     public void forceLayout() {
         mPrivateFlags |= FORCE_LAYOUT;
+        mPrivateFlags |= INVALIDATED;
     }
 
     /**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c73cbe6..f198c46 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2395,8 +2395,6 @@
                 canvas.scale(scale, scale);
             }
         }
-        
-        boolean layerSaved = false;
 
         if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
             if (transformToApply != null || !childHasIdentityMatrix) {
@@ -2477,7 +2475,7 @@
         if (hasNoCache) {
             boolean layerRendered = false;
             if (layerType == LAYER_TYPE_HARDWARE) {
-                final HardwareLayer layer = child.getHardwareLayer(canvas);
+                final HardwareLayer layer = child.getHardwareLayer();
                 if (layer != null && layer.isValid()) {
                     ((HardwareCanvas) canvas).drawHardwareLayer(layer, 0, 0, child.mLayerPaint);
                     layerRendered = true;
@@ -3357,7 +3355,9 @@
         addInArray(child, index);
 
         child.mParent = this;
-        child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) | DRAWN;
+        child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) |
+                DRAWN | INVALIDATED;
+        this.mPrivateFlags |= INVALIDATED;
 
         if (child.hasFocus()) {
             requestChildFocus(child, child.findFocus());
@@ -3527,10 +3527,20 @@
                             (int) (boundingRect.bottom + 0.5f));
                 }
 
+                if (child.mLayerType != LAYER_TYPE_NONE) {
+                    mPrivateFlags |= INVALIDATED;
+                    mPrivateFlags &= ~DRAWING_CACHE_VALID;
+                }                
                 do {
                     View view = null;
                     if (parent instanceof View) {
                         view = (View) parent;
+                        if (view.mLayerType != LAYER_TYPE_NONE &&
+                                view.getParent() instanceof View) {
+                            final View grandParent = (View) view.getParent();
+                            grandParent.mPrivateFlags |= INVALIDATED;
+                            grandParent.mPrivateFlags &= ~DRAWING_CACHE_VALID;
+                        }
                     }
 
                     if (drawAnimation) {
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index ba671c0..19d7811 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -160,7 +160,9 @@
 
     int mWidth;
     int mHeight;
-    Rect mDirty; // will be a graphics.Region soon
+    Rect mDirty;
+    final Rect mCurrentDirty = new Rect();
+    final Rect mPreviousDirty = new Rect();
     boolean mIsAnimating;
 
     CompatibilityInfo.Translator mTranslator;
@@ -1055,6 +1057,7 @@
                     disposeResizeBitmap();
                 } else if (surfaceGenerationId != mSurface.getGenerationId() &&
                         mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
+                    fullRedrawNeeded = true;
                     mAttachInfo.mHardwareRenderer.updateSurface(mHolder);
                 }
             } catch (RemoteException e) {
@@ -1488,10 +1491,15 @@
         if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
             if (!dirty.isEmpty() || mIsAnimating) {
                 mIsAnimating = false;
-                dirty.setEmpty();
                 mHardwareYOffset = yoff;
                 mResizeAlpha = resizeAlpha;
-                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
+
+                mCurrentDirty.set(dirty);
+                mCurrentDirty.union(mPreviousDirty);
+                mPreviousDirty.set(dirty);
+                dirty.setEmpty();
+
+                mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this, mCurrentDirty);
             }
 
             if (animating) {
@@ -1986,6 +1994,7 @@
 
                     if (mAttachInfo.mHardwareRenderer != null &&
                             mSurface != null && mSurface.isValid()) {
+                        mFullRedrawNeeded = true;
                         mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                                 mAttachInfo, mHolder);
                     }
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index a553a459..e440eb9 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -33,8 +33,8 @@
 import java.util.Map;
 
 
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA1Digest;
+import com.android.org.bouncycastle.crypto.Digest;
+import com.android.org.bouncycastle.crypto.digests.SHA1Digest;
 
 /**
  * The class CacheManager provides the persistent cache of content that is
diff --git a/core/java/android/webkit/CertTool.java b/core/java/android/webkit/CertTool.java
index 99757d2..d25d970 100644
--- a/core/java/android/webkit/CertTool.java
+++ b/core/java/android/webkit/CertTool.java
@@ -16,10 +16,10 @@
 
 package android.webkit;
 
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.jce.netscape.NetscapeCertRequest;
-import org.bouncycastle.util.encoders.Base64;
+import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import com.android.org.bouncycastle.jce.netscape.NetscapeCertRequest;
+import com.android.org.bouncycastle.util.encoders.Base64;
 
 import android.content.ActivityNotFoundException;
 import android.content.Context;
diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java
index 257ed2a..8eb1524 100644
--- a/core/java/android/webkit/WebStorage.java
+++ b/core/java/android/webkit/WebStorage.java
@@ -75,6 +75,9 @@
     private Handler mHandler = null;
     private Handler mUIHandler = null;
 
+    /**
+     * Class containing the HTML5 database quota and usage for an origin.
+     */
     public static class Origin {
         private String mOrigin = null;
         private long mQuota = 0;
@@ -95,14 +98,30 @@
             mOrigin = origin;
         }
 
+        /**
+         * An origin string is created using WebCore::SecurityOrigin::toString().
+         * Note that WebCore::SecurityOrigin uses 0 (which is not printed) for
+         * the port if the port is the default for the protocol. Eg
+         * http://www.google.com and http://www.google.com:80 both record a port
+         * of 0 and hence toString() == 'http://www.google.com' for both.
+         * @return The origin string.
+         */
         public String getOrigin() {
             return mOrigin;
         }
 
+        /**
+         * Returns the quota for this origin's HTML5 database.
+         * @return The quota in bytes.
+         */
         public long getQuota() {
             return mQuota;
         }
 
+        /**
+         * Returns the usage for this origin's HTML5 database.
+         * @return The usage in bytes.
+         */
         public long getUsage() {
             return mUsage;
         }
@@ -229,7 +248,8 @@
      */
 
     /**
-     * Returns a list of origins having a database
+     * Returns a list of origins having a database. The Map is of type
+     * Map<String, Origin>.
      */
     public void getOrigins(ValueCallback<Map> callback) {
         if (callback != null) {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index bb4441f..0992079 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -130,6 +130,7 @@
 
     private int mLowMemoryUsageThresholdMb;
     private int mHighMemoryUsageThresholdMb;
+    private int mHighUsageDeltaMb;
 
     // The thread name used to identify the WebCore thread and for use in
     // debugging other classes that require operation within the WebCore thread.
@@ -186,12 +187,15 @@
 
         // Allow us to use up to our memory class value before V8's GC kicks in.
         // These values have been determined by experimentation.
-        mLowMemoryUsageThresholdMb = manager.getMemoryClass();
+        mLowMemoryUsageThresholdMb = manager.getLargeMemoryClass();
         // If things get crazy, allow V8 to use up to 3 times our memory class, or a third of the
-        // device's total available memory, whichever is smaller. At that point V8 will start
-        // attempting more aggressive garbage collection.
-        mHighMemoryUsageThresholdMb = Math.min(mLowMemoryUsageThresholdMb * 3,
-                (int) (memInfo.availMem / 3) >> 20);
+        // device's total available memory, whichever is smaller.  This value must be no less
+        // than the low memory threshold.
+        // At that point V8 will start attempting more aggressive garbage collection.
+        mHighMemoryUsageThresholdMb = Math.max(Math.min(mLowMemoryUsageThresholdMb * 3,
+                (int) (memInfo.availMem / 3) >> 20), mLowMemoryUsageThresholdMb);
+        // Avoid constant V8 GC when memory usage equals to working set estimate.
+        mHighUsageDeltaMb = 1;
 
         // Send a message to initialize the WebViewCore.
         Message init = sWebCoreHandler.obtainMessage(
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 796af55..a107c60 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2706,7 +2706,7 @@
             int startPos = (mSelectedPosition != INVALID_POSITION) ?
                     mSelectedPosition - 1 :
                     firstPosition + getChildCount() - 1;
-            if (startPos < 0) {
+            if (startPos < 0 || startPos >= mAdapter.getCount()) {
                 return INVALID_POSITION;
             }
             if (startPos > last) {
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 45f8599..e7c3948 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -29,7 +29,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
-import org.bouncycastle.util.encoders.Base64;
+import com.android.org.bouncycastle.util.encoders.Base64;
 
 import java.io.File;
 import java.io.FileFilter;
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index ff59950..14d0ac5 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -215,6 +215,11 @@
 
     private ViewGroup mMeasureActionButtonParent;
 
+    private final WeakReference<MenuAdapter>[] mAdapterCache =
+            new WeakReference[NUM_TYPES];
+    private final WeakReference<OverflowMenuAdapter>[] mOverflowAdapterCache =
+            new WeakReference[NUM_TYPES];
+
     // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
     private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
 
@@ -1004,6 +1009,12 @@
                     MenuView menuView = menuTypes[i].mMenuView.get();
                     menuView.updateChildren(cleared);
                 }
+
+                MenuAdapter adapter = mAdapterCache[i] == null ? null : mAdapterCache[i].get();
+                if (adapter != null) adapter.notifyDataSetChanged();
+
+                adapter = mOverflowAdapterCache[i] == null ? null : mOverflowAdapterCache[i].get();
+                if (adapter != null) adapter.notifyDataSetChanged();
             }
         }
     }
@@ -1358,7 +1369,13 @@
      * @return A {@link MenuAdapter} for this menu with the given menu type.
      */
     public MenuAdapter getMenuAdapter(int menuType) {
-        return new MenuAdapter(menuType);
+        MenuAdapter adapter = mAdapterCache[menuType] == null ?
+                null : mAdapterCache[menuType].get();
+        if (adapter != null) return adapter;
+
+        adapter = new MenuAdapter(menuType);
+        mAdapterCache[menuType] = new WeakReference<MenuAdapter>(adapter);
+        return adapter;
     }
 
     /**
@@ -1368,7 +1385,13 @@
      * @return A {@link MenuAdapter} for this menu with the given menu type.
      */
     public MenuAdapter getOverflowMenuAdapter(int menuType) {
-        return new OverflowMenuAdapter(menuType);
+        OverflowMenuAdapter adapter = mOverflowAdapterCache[menuType] == null ?
+                null : mOverflowAdapterCache[menuType].get();
+        if (adapter != null) return adapter;
+
+        adapter = new OverflowMenuAdapter(menuType);
+        mOverflowAdapterCache[menuType] = new WeakReference<OverflowMenuAdapter>(adapter);
+        return adapter;
     }
 
     void setOptionalIconsVisible(boolean visible) {
@@ -1469,21 +1492,18 @@
      * source for overflow menu items that do not fit in the list of action items.
      */
     private class OverflowMenuAdapter extends MenuAdapter {
-        private ArrayList<MenuItemImpl> mOverflowItems;
-
         public OverflowMenuAdapter(int menuType) {
             super(menuType);
-            mOverflowItems = getNonActionItems(true);
         }
 
         @Override
         public MenuItemImpl getItem(int position) {
-            return mOverflowItems.get(position);
+            return getNonActionItems(true).get(position);
         }
 
         @Override
         public int getCount() {
-            return mOverflowItems.size();
+            return getNonActionItems(true).size();
         }
     }
 }
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index a1a28ac..65973b6 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -128,7 +128,8 @@
                 final boolean visiblePassword = Settings.System.getInt(
                         mContext.getContentResolver(),
                         Settings.System.TEXT_SHOW_PASSWORD, 1) != 0;
-                mKeyboardView.setPreviewEnabled(visiblePassword);
+                final boolean enablePreview = false; // TODO: grab from configuration
+                mKeyboardView.setPreviewEnabled(visiblePassword && enablePreview);
                 break;
             case KEYBOARD_MODE_NUMERIC:
                 mKeyboardView.setKeyboard(mNumericKeyboard);
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e4a89d7..9de270d 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "OpenGLRenderer"
 
+#include <EGL/egl.h>
+
 #include "jni.h"
 #include "GraphicsJNI.h"
 #include <nativehelper/JNIHelp.h>
@@ -75,6 +77,23 @@
 } gRectClassInfo;
 
 // ----------------------------------------------------------------------------
+// Misc
+// ----------------------------------------------------------------------------
+
+static jboolean android_view_GLES20Canvas_preserveBackBuffer(JNIEnv* env, jobject clazz) {
+    EGLDisplay display = eglGetCurrentDisplay();
+    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
+
+    eglGetError();
+    eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+    EGLint error = eglGetError();
+    RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
+
+    return error == EGL_SUCCESS;
+}
+
+// ----------------------------------------------------------------------------
 // Constructors
 // ----------------------------------------------------------------------------
 
@@ -97,32 +116,38 @@
 // Setup
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jint width, jint height) {
     renderer->setViewport(width, height);
 }
 
-static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jboolean opaque) {
     renderer->prepare(opaque);
 }
 
-static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
+        OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom,
+        jboolean opaque) {
+    renderer->prepareDirty(left, top, right, bottom, opaque);
+}
+
+static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->finish();
 }
 
-static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_acquireContext(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->acquireContext();
 }
 
-static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Functor *functor) {
     return renderer->callDrawGLFunction(functor);
 }
 
-static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_releaseContext(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->releaseContext();
 }
@@ -131,22 +156,22 @@
 // State
 // ----------------------------------------------------------------------------
 
-static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer,
+static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer,
         jint flags) {
     return renderer->save(flags);
 }
 
-static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     return renderer->getSaveCount();
 }
 
-static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->restore();
 }
 
-static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jint saveCount) {
     renderer->restoreToCount(saveCount);
 }
@@ -155,13 +180,13 @@
 // Layers
 // ----------------------------------------------------------------------------
 
-static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         SkPaint* paint, jint saveFlags) {
     return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
 }
 
-static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject canvas,
+static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jint alpha, jint saveFlags) {
     return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
@@ -171,25 +196,25 @@
 // Clipping
 // ----------------------------------------------------------------------------
 
-static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         SkCanvas::EdgeType edge) {
     return renderer->quickReject(left, top, right, bottom);
 }
 
-static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         SkRegion::Op op) {
     return renderer->clipRect(left, top, right, bottom, op);
 }
 
-static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jint left, jint top, jint right, jint bottom,
         SkRegion::Op op) {
     return renderer->clipRect(float(left), float(top), float(right), float(bottom), op);
 }
 
-static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject canvas,
+static bool android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jobject rect) {
     const android::uirenderer::Rect& bounds(renderer->getClipBounds());
 
@@ -203,42 +228,42 @@
 // Transforms
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat dx, jfloat dy) {
     renderer->translate(dx, dy);
 }
 
-static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat degrees) {
     renderer->rotate(degrees);
 }
 
-static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
     renderer->scale(sx, sy);
 }
 
-static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat sx, jfloat sy) {
     renderer->skew(sx, sy);
 }
 
-static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkMatrix* matrix) {
     renderer->setMatrix(matrix);
 }
 
 static const float* android_view_GLES20Canvas_getNativeMatrix(JNIEnv* env,
-        jobject canvas, OpenGLRenderer* renderer) {
+        jobject clazz, OpenGLRenderer* renderer) {
     return renderer->getMatrix();
 }
 
-static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkMatrix* matrix) {
     renderer->getMatrix(matrix);
 }
 
-static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkMatrix* matrix) {
     renderer->concatMatrix(matrix);
 }
@@ -247,7 +272,7 @@
 // Drawing
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, float left,
         float top, SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -256,7 +281,7 @@
     renderer->drawBitmap(bitmap, left, top, paint);
 }
 
-static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
         float srcLeft, float srcTop, float srcRight, float srcBottom,
         float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) {
@@ -267,7 +292,7 @@
             dstLeft, dstTop, dstRight, dstBottom, paint);
 }
 
-static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, SkMatrix* matrix,
         SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -276,7 +301,7 @@
     renderer->drawBitmap(bitmap, matrix, paint);
 }
 
-static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
         jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset,
         jintArray colors, jint colorOffset, SkPaint* paint) {
@@ -292,7 +317,7 @@
     if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
 }
 
-static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks,
         float left, float top, float right, float bottom, SkPaint* paint) {
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
@@ -309,41 +334,41 @@
     env->ReleaseByteArrayElements(chunks, storage, 0);
 }
 
-static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jint color, SkXfermode::Mode mode) {
     renderer->drawColor(color, mode);
 }
 
-static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         SkPaint* paint) {
     renderer->drawRect(left, top, right, bottom, paint);
 }
 
-static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jfloat rx, jfloat ry, SkPaint* paint) {
     renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
 }
 
-static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
     renderer->drawCircle(x, y, radius, paint);
 }
 
-static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         SkPaint* paint) {
     renderer->drawOval(left, top, right, bottom, paint);
 }
 
-static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jfloat startAngle, jfloat sweepAngle, jboolean useCenter, SkPaint* paint) {
     renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
 }
 
-static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
     SkRegion::Iterator it(*region);
     while (!it.done()) {
@@ -353,12 +378,12 @@
     }
 }
 
-static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkPath* path, SkPaint* paint) {
     renderer->drawPath(path, paint);
 }
 
-static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloatArray points, jint offset, jint count, SkPaint* paint) {
     jfloat* storage = env->GetFloatArrayElements(points, NULL);
 
@@ -371,24 +396,24 @@
 // Shaders and color filters
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->resetShader();
     renderer->resetColorFilter();
     renderer->resetShadow();
 }
 
-static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkiaShader* shader) {
     renderer->setupShader(shader);
 }
 
-static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, SkiaColorFilter* filter) {
     renderer->setupColorFilter(filter);
 }
 
-static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jfloat radius, jfloat dx, jfloat dy, jint color) {
     renderer->setupShadow(radius, dx, dy, color);
 }
@@ -425,7 +450,7 @@
     }
 }
 
-static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
         jfloat x, jfloat y, jint flags, SkPaint* paint) {
     jchar* textArray = env->GetCharArrayElements(text, NULL);
@@ -433,7 +458,7 @@
     env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
 }
 
-static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jstring text, jint start, jint end,
         jfloat x, jfloat y, jint flags, SkPaint* paint) {
     const jchar* textArray = env->GetStringChars(text, NULL);
@@ -441,7 +466,7 @@
     env->ReleaseStringChars(text, textArray);
 }
 
-static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
         jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
         SkPaint* paint) {
@@ -451,7 +476,7 @@
     env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
  }
 
-static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, jstring text, jint start, jint end,
         jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
         SkPaint* paint) {
@@ -468,7 +493,7 @@
 // ----------------------------------------------------------------------------
 
 static DisplayList* android_view_GLES20Canvas_getDisplayList(JNIEnv* env,
-        jobject canvas, DisplayListRenderer* renderer) {
+        jobject clazz, DisplayListRenderer* renderer) {
     return renderer->getDisplayList();
 }
 
@@ -488,7 +513,7 @@
 }
 
 static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
-        jobject canvas, OpenGLRenderer* renderer, DisplayList* displayList) {
+        jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList) {
     return renderer->drawDisplayList(displayList);
 }
 
@@ -496,12 +521,12 @@
 // Layers
 // ----------------------------------------------------------------------------
 
-static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->interrupt();
 }
 
-static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer) {
     renderer->resume();
 }
@@ -547,7 +572,7 @@
     LayerRenderer::destroyLayerDeferred(layer);
 }
 
-static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject canvas,
+static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
         OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
     renderer->drawLayer(layer, x, y, paint);
 }
@@ -576,16 +601,20 @@
     { "nIsAvailable",       "()Z",             (void*) android_view_GLES20Canvas_isAvailable },
 
 #ifdef USE_OPENGL_RENDERER
+    { "nPreserveBackBuffer", "()Z",            (void*) android_view_GLES20Canvas_preserveBackBuffer },
+
     { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
     { "nSetViewport",       "(III)V",          (void*) android_view_GLES20Canvas_setViewport },
     { "nPrepare",           "(IZ)V",           (void*) android_view_GLES20Canvas_prepare },
+    { "nPrepareDirty",      "(IIIIIZ)V",       (void*) android_view_GLES20Canvas_prepareDirty },
     { "nFinish",            "(I)V",            (void*) android_view_GLES20Canvas_finish },
     { "nAcquireContext",    "(I)V",            (void*) android_view_GLES20Canvas_acquireContext },
-    { "nCallDrawGLFunction",    "(II)Z",
-            (void*) android_view_GLES20Canvas_callDrawGLFunction },
     { "nReleaseContext",    "(I)V",            (void*) android_view_GLES20Canvas_releaseContext },
 
+    { "nCallDrawGLFunction", "(II)Z",
+            (void*) android_view_GLES20Canvas_callDrawGLFunction },
+
     { "nSave",              "(II)I",           (void*) android_view_GLES20Canvas_save },
     { "nRestore",           "(I)V",            (void*) android_view_GLES20Canvas_restore },
     { "nRestoreToCount",    "(II)V",           (void*) android_view_GLES20Canvas_restoreToCount },
diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png
index bd353ae..00e8f06 100644
--- a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png
index d127b3c..997ccb2 100644
--- a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png
deleted file mode 100644
index b86c65a..0000000
--- a/core/res/res/drawable-hdpi/btn_group_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_group_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_holo_light.9.png
deleted file mode 100644
index 1248e88..0000000
--- a/core/res/res/drawable-hdpi/btn_group_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png
new file mode 100644
index 0000000..b2120f4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_group_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png
new file mode 100644
index 0000000..782d36b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_group_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_background_opaque_holo_dark.9.png b/core/res/res/drawable-hdpi/cab_background_dark.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/cab_background_opaque_holo_dark.9.png
rename to core/res/res/drawable-hdpi/cab_background_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/cab_background_opaque_holo_light.9.png b/core/res/res/drawable-hdpi/cab_background_light.9.png
similarity index 100%
rename from core/res/res/drawable-hdpi/cab_background_opaque_holo_light.9.png
rename to core/res/res/drawable-hdpi/cab_background_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/overscroll_edge.png b/core/res/res/drawable-hdpi/overscroll_edge.png
index 6d3c26d..7eb615b 100644
--- a/core/res/res/drawable-hdpi/overscroll_edge.png
+++ b/core/res/res/drawable-hdpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/overscroll_glow.png b/core/res/res/drawable-hdpi/overscroll_glow.png
index 0b0b936..a800d8e 100644
--- a/core/res/res/drawable-hdpi/overscroll_glow.png
+++ b/core/res/res/drawable-hdpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png
index aa04cc9..5894afe 100644
--- a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png
index 25aefd2..1dfc7d3 100644
--- a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png
deleted file mode 100644
index 9541252..0000000
--- a/core/res/res/drawable-mdpi/btn_group_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_holo_light.9.png
deleted file mode 100644
index bf4f9b2..0000000
--- a/core/res/res/drawable-mdpi/btn_group_holo_light.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png
new file mode 100644
index 0000000..c6257bb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_group_normal_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png
new file mode 100644
index 0000000..7e25ad3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_group_normal_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_opaque_holo_dark.9.png b/core/res/res/drawable-mdpi/cab_background_dark.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/cab_background_opaque_holo_dark.9.png
rename to core/res/res/drawable-mdpi/cab_background_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/cab_background_opaque_holo_light.9.png b/core/res/res/drawable-mdpi/cab_background_light.9.png
similarity index 100%
rename from core/res/res/drawable-mdpi/cab_background_opaque_holo_light.9.png
rename to core/res/res/drawable-mdpi/cab_background_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/overscroll_edge.png b/core/res/res/drawable-mdpi/overscroll_edge.png
index 6d3c26d..86d9454 100644
--- a/core/res/res/drawable-mdpi/overscroll_edge.png
+++ b/core/res/res/drawable-mdpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/overscroll_glow.png b/core/res/res/drawable-mdpi/overscroll_glow.png
index 0b0b936..d96b9be 100644
--- a/core/res/res/drawable-mdpi/overscroll_glow.png
+++ b/core/res/res/drawable-mdpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
deleted file mode 100644
index 137923b..0000000
--- a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
deleted file mode 100644
index 62b1deb..0000000
--- a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
deleted file mode 100644
index ab30a77..0000000
--- a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
deleted file mode 100644
index 9274bc7..0000000
--- a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
deleted file mode 100644
index e46155e..0000000
--- a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png
new file mode 100644
index 0000000..a233b0d
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png
new file mode 100644
index 0000000..403f502
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..0ded801
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..27237b8
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..0e451f1
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/textfield_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/action_bar_context_background.xml b/core/res/res/drawable/btn_group_holo_dark.xml
similarity index 65%
rename from core/res/res/drawable/action_bar_context_background.xml
rename to core/res/res/drawable/btn_group_holo_dark.xml
index 8789898..553f023 100644
--- a/core/res/res/drawable/action_bar_context_background.xml
+++ b/core/res/res/drawable/btn_group_holo_dark.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,9 @@
      limitations under the License.
 -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient
-        android:startColor="#ff000000"
-        android:centerColor="#ffd1d2d4"
-        android:endColor="#ff85878a"
-        android:angle="270" />
-</shape>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_group_normal_holo_dark" />
+    <item
+        android:drawable="@drawable/btn_group_disabled_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/action_bar_context_background.xml b/core/res/res/drawable/btn_group_holo_light.xml
similarity index 65%
copy from core/res/res/drawable/action_bar_context_background.xml
copy to core/res/res/drawable/btn_group_holo_light.xml
index 8789898..9c89eef 100644
--- a/core/res/res/drawable/action_bar_context_background.xml
+++ b/core/res/res/drawable/btn_group_holo_light.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,10 +14,9 @@
      limitations under the License.
 -->
 
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient
-        android:startColor="#ff000000"
-        android:centerColor="#ffd1d2d4"
-        android:endColor="#ff85878a"
-        android:angle="270" />
-</shape>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+        android:drawable="@drawable/btn_group_normal_holo_light" />
+    <item
+        android:drawable="@drawable/btn_group_disabled_holo_light" />
+</selector>
diff --git a/core/res/res/drawable/group_button_background_holo_dark.xml b/core/res/res/drawable/group_button_background_holo_dark.xml
deleted file mode 100644
index fa00785..0000000
--- a/core/res/res/drawable/group_button_background_holo_dark.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_window_focused="false" android:drawable="@color/transparent" />
-
-    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
-    <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_dark" />
-    <item android:state_focused="true"  android:state_enabled="false"                              android:drawable="@drawable/btn_group_disabled_holo_dark" />
-    <item android:state_focused="true"                                android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" />
-    <item android:state_focused="false"                               android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" />
-    <item android:state_focused="true"                                                             android:drawable="@drawable/btn_group_focused_holo_dark" />
-    <item                                                                                          android:drawable="@color/transparent" />
-</selector>
diff --git a/core/res/res/drawable/group_button_background_holo_light.xml b/core/res/res/drawable/group_button_background_holo_light.xml
deleted file mode 100644
index 1e74ec7..0000000
--- a/core/res/res/drawable/group_button_background_holo_light.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-
-    <item android:state_window_focused="false" android:drawable="@color/transparent" />
-
-    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
-    <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_light" />
-    <item android:state_focused="true"  android:state_enabled="false"                              android:drawable="@drawable/btn_group_disabled_holo_light" />
-    <item android:state_focused="true"                                android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" />
-    <item android:state_focused="false"                               android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" />
-    <item android:state_focused="true"                                                             android:drawable="@drawable/btn_group_focused_holo_light" />
-    <item                                                                                          android:drawable="@color/transparent" />
-</selector>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
index fab69d8..e4a1b81 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -74,6 +74,7 @@
             android:layout_height="230dip"
             android:background="#00000000"
             android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+            android:visibility="gone"
         />
 
         <!-- emergency call button -->
diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml
index e001894..4477df7 100644
--- a/core/res/res/layout/action_menu_item_layout.xml
+++ b/core/res/res/layout/action_menu_item_layout.xml
@@ -42,6 +42,7 @@
             android:visibility="gone"
             android:textAppearance="?attr/textAppearanceMedium"
             style="?attr/buttonStyleSmall"
+            android:textColor="?attr/textColorPrimary"
             android:background="@null"
             android:paddingLeft="4dip"
             android:paddingRight="4dip" />
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index d22f74a..fef017d 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -16,7 +16,7 @@
 
 <com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="48dip"
+    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
     android:minWidth="196dip"
     android:paddingLeft="16dip"
     android:paddingRight="16dip">
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index ccc6326..9cf08ea 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -25,7 +25,7 @@
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:focusable="true"
-    android:background="@drawable/cab_background_opaque_holo_light"
+    android:background="@drawable/cab_background_light"
     android:descendantFocusability="afterDescendants">
 
     <RelativeLayout
diff --git a/core/res/res/layout/simple_spinner_dropdown_item.xml b/core/res/res/layout/simple_spinner_dropdown_item.xml
index 5fd7a09..cb999b6 100644
--- a/core/res/res/layout/simple_spinner_dropdown_item.xml
+++ b/core/res/res/layout/simple_spinner_dropdown_item.xml
@@ -22,5 +22,5 @@
     style="?android:attr/spinnerDropDownItemStyle"
     android:singleLine="true"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:layout_height="?android:attr/dropdownListPreferredItemHeight"
     android:ellipsize="marquee" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c808a07..a404fba 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -223,6 +223,9 @@
         <!-- The preferred right bound for an expandable list child's indicator. -->
         <attr name="expandableListPreferredChildIndicatorRight" format="dimension" />
 
+        <!-- The preferred item height for dropdown lists. -->
+        <attr name="dropdownListPreferredItemHeight" format="dimension" />
+
         <!-- ============= -->
         <!-- Window styles -->
         <!-- ============= -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 1a6f404..ff9ef59 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -56,8 +56,8 @@
     <color name="hint_foreground_light">#808080</color>
     <color name="highlight_background">#cc475925</color>
     <color name="highlight_background_inverse">#ccd2e461</color>
-    <color name="highlighted_text_dark">#cc475925</color>
-    <color name="highlighted_text_light">#ccd2e461</color>
+    <color name="highlighted_text_dark">#9983CC39</color>
+    <color name="highlighted_text_light">#9983CC39</color>
     <color name="link_text_dark">#5c5cff</color>
     <color name="link_text_light">#0000ee</color>
 
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 36dec8e..25a43e0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1065,19 +1065,20 @@
     </style>
 
     <style name="TextAppearance.Widget.ActionBar.Title"
-           parent="@android:style/TextAppearance.Medium.Inverse">
+           parent="@android:style/TextAppearance.Medium">
     </style>
 
     <style name="TextAppearance.Widget.ActionBar.Subtitle"
-           parent="@android:style/TextAppearance.Small.Inverse">
+           parent="@android:style/TextAppearance.Small">
     </style>
 
     <style name="TextAppearance.Widget.ActionMode.Title"
-           parent="@android:style/TextAppearance.Medium.Inverse">
+           parent="@android:style/TextAppearance.Medium">
     </style>
 
     <style name="TextAppearance.Widget.ActionMode.Subtitle"
-           parent="@android:style/TextAppearance.Small.Inverse">
+           parent="@android:style/TextAppearance.Small">
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="Widget.ActionButton">
@@ -1266,11 +1267,9 @@
     </style>
 
     <style name="TextAppearance.Holo.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Holo.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle">
-        <item name="android:textColor">?android:attr/textColorSecondary</item>
     </style>
 
     <style name="TextAppearance.Holo.Widget.Switch" parent="TextAppearance.Holo.Small">
@@ -1369,11 +1368,9 @@
     </style>
 
     <style name="TextAppearance.Holo.Light.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Holo.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
     </style>
 
     <style name="TextAppearance.Holo.Light.WindowTitle">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 08542bf..03eca1c 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -95,6 +95,8 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
+        <item name="dropdownListPreferredItemHeight">64dip</item>
+
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
         <item name="listDivider">@drawable/divider_horizontal_dark</item>
@@ -253,7 +255,7 @@
         <item name="actionDropDownStyle">@android:style/Widget.Spinner.DropDown</item>
         <item name="actionButtonStyle">@android:style/Widget.ActionButton</item>
         <item name="actionOverflowButtonStyle">@android:style/Widget.ActionButton.Overflow</item>
-        <item name="actionModeBackground">@android:drawable/action_bar_context_background</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_dark</item>
         <item name="actionModeCloseDrawable">@android:drawable/ic_menu_close_clear_cancel</item>
         <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_dark</item>
         <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_dark</item>
@@ -376,6 +378,8 @@
         <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_light</item>
         <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_light</item>
         <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_light</item>
+        <item name="actionModeBackground">@android:drawable/cab_background_light</item>
+
         <!-- SearchView attributes -->
         <item name="searchDropdownBackground">@android:drawable/search_dropdown_light</item>
         <item name="searchViewCloseIcon">@android:drawable/ic_clear_holo_light</item>
@@ -813,6 +817,8 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
+        <item name="dropdownListPreferredItemHeight">48dip</item>
+
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
         <item name="listDivider">@drawable/list_divider_holo_dark</item>
@@ -1084,6 +1090,8 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
+        <item name="dropdownListPreferredItemHeight">48dip</item>
+
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
         <item name="listDivider">@drawable/list_divider_holo_light</item>
diff --git a/data/fonts/AndroidClock-Solid.ttf b/data/fonts/AndroidClock-Solid.ttf
new file mode 100644
index 0000000..108839e
--- /dev/null
+++ b/data/fonts/AndroidClock-Solid.ttf
Binary files differ
diff --git a/data/fonts/AndroidClock.ttf b/data/fonts/AndroidClock.ttf
index 03e36cb..7b550ee 100644
--- a/data/fonts/AndroidClock.ttf
+++ b/data/fonts/AndroidClock.ttf
Binary files differ
diff --git a/data/fonts/AndroidClock_Highlight.ttf b/data/fonts/AndroidClock_Highlight.ttf
index 8fb31ba..a95d548 100644
--- a/data/fonts/AndroidClock_Highlight.ttf
+++ b/data/fonts/AndroidClock_Highlight.ttf
Binary files differ
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index a768efe..c2106d4 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -629,7 +629,8 @@
     mHeight = height;
 }
 
-void DisplayListRenderer::prepare(bool opaque) {
+void DisplayListRenderer::prepareDirty(float left, float top,
+        float right, float bottom, bool opaque) {
     mSnapshot = new Snapshot(mFirstSnapshot,
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     mSaveCount = 1;
@@ -848,7 +849,7 @@
 
 void DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
         float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
-    addOp(DisplayList::DrawOval);
+    addOp(DisplayList::DrawArc);
     addBounds(left, top, right, bottom);
     addPoint(startAngle, sweepAngle);
     addInt(useCenter ? 1 : 0);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6c8e8f5..bab5149 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -28,7 +28,7 @@
 #include <SkTSearch.h>
 
 #include "OpenGLRenderer.h"
-#include "Functor.h"
+#include "utils/Functor.h"
 
 namespace android {
 namespace uirenderer {
@@ -241,7 +241,7 @@
     DisplayList* getDisplayList();
 
     void setViewport(int width, int height);
-    void prepare(bool opaque);
+    void prepareDirty(float left, float top, float right, float bottom, bool opaque);
     void finish();
 
     bool callDrawGLFunction(Functor *functor);
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 1c89577..36709dc 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -26,7 +26,7 @@
 // Rendering
 ///////////////////////////////////////////////////////////////////////////////
 
-void LayerRenderer::prepare(bool opaque) {
+void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
     LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
 
 #if RENDER_LAYERS_AS_REGIONS
@@ -35,7 +35,7 @@
 
     glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
 
-    OpenGLRenderer::prepare(opaque);
+    OpenGLRenderer::prepareDirty(0.0f, 0.0f, mLayer->width, mLayer->height, opaque);
 }
 
 void LayerRenderer::finish() {
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 1e39847..d2f565e 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -46,7 +46,7 @@
     ~LayerRenderer() {
     }
 
-    void prepare(bool opaque);
+    void prepareDirty(float left, float top, float right, float bottom, bool opaque);
     void finish();
 
     bool hasLayer();
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 98f8fc5..9f491b3 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -136,6 +136,10 @@
 }
 
 void OpenGLRenderer::prepare(bool opaque) {
+    prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
+}
+
+void OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
     mCaches.clearGarbage();
 
     mSnapshot = new Snapshot(mFirstSnapshot,
@@ -146,15 +150,14 @@
 
     glDisable(GL_DITHER);
 
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
+    mSnapshot->setClip(left, top, right, bottom);
+
     if (!opaque) {
-        glDisable(GL_SCISSOR_TEST);
         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
         glClear(GL_COLOR_BUFFER_BIT);
     }
-
-    glEnable(GL_SCISSOR_TEST);
-    glScissor(0, 0, mWidth, mHeight);
-    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
 }
 
 void OpenGLRenderer::finish() {
@@ -1210,8 +1213,7 @@
         const bool pureTranslate = mSnapshot->transform->isPureTranslate();
 #if RENDER_LAYERS_AS_REGIONS
         // Mark the current layer dirty where we are going to draw the patch
-        if ((mSnapshot->flags & Snapshot::kFlagFboTarget) &&
-                mSnapshot->region && mesh->hasEmptyQuads) {
+        if (hasLayer() && mesh->hasEmptyQuads) {
             const size_t count = mesh->quads.size();
             for (size_t i = 0; i < count; i++) {
                 const Rect& bounds = mesh->quads.itemAt(i);
@@ -1607,18 +1609,18 @@
     layer->alpha = alpha;
     layer->mode = mode;
 
-
 #if RENDER_LAYERS_AS_REGIONS
     if (!layer->region.isEmpty()) {
         if (layer->region.isRect()) {
             const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
             composeLayerRect(layer, r);
         } else if (layer->mesh) {
+            const float a = alpha / 255.0f;
             const Rect& rect = layer->layer;
 
             setupDraw();
             setupDrawWithTexture();
-            setupDrawColor(alpha, alpha, alpha, alpha);
+            setupDrawColor(a, a, a, a);
             setupDrawColorFilter();
             setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
             setupDrawProgram();
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index bd29609..77de1d2 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -62,7 +62,8 @@
 
     virtual void setViewport(int width, int height);
 
-    virtual void prepare(bool opaque);
+    void prepare(bool opaque);
+    virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
     virtual void finish();
 
     // These two calls must not be recorded in display lists
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
index 02993fe..8cad82b 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -12,6 +12,31 @@
 volatile int3 i3;
 volatile int4 i4;
 
+volatile uint ui1;
+volatile uint2 ui2;
+volatile uint3 ui3;
+volatile uint4 ui4;
+
+volatile short s1;
+volatile short2 s2;
+volatile short3 s3;
+volatile short4 s4;
+
+volatile ushort us1;
+volatile ushort2 us2;
+volatile ushort3 us3;
+volatile ushort4 us4;
+
+volatile char c1;
+volatile char2 c2;
+volatile char3 c3;
+volatile char4 c4;
+
+volatile uchar uc1;
+volatile uchar2 uc2;
+volatile uchar3 uc3;
+volatile uchar4 uc4;
+
 #define TEST_FN_FUNC_FN(fnc)        \
     rsDebug("Testing " #fnc, 0);    \
     f1 = fnc(f1);                   \
@@ -168,9 +193,124 @@
     return failed;
 }
 
+#define DECL_INT(prefix)            \
+volatile char prefix##_c_1 = 1;     \
+volatile char2 prefix##_c_2 = 1;    \
+volatile char3 prefix##_c_3 = 1;    \
+volatile char4 prefix##_c_4 = 1;    \
+volatile uchar prefix##_uc_1 = 1;   \
+volatile uchar2 prefix##_uc_2 = 1;  \
+volatile uchar3 prefix##_uc_3 = 1;  \
+volatile uchar4 prefix##_uc_4 = 1;  \
+volatile short prefix##_s_1 = 1;    \
+volatile short2 prefix##_s_2 = 1;   \
+volatile short3 prefix##_s_3 = 1;   \
+volatile short4 prefix##_s_4 = 1;   \
+volatile ushort prefix##_us_1 = 1;  \
+volatile ushort2 prefix##_us_2 = 1; \
+volatile ushort3 prefix##_us_3 = 1; \
+volatile ushort4 prefix##_us_4 = 1; \
+volatile int prefix##_i_1 = 1;      \
+volatile int2 prefix##_i_2 = 1;     \
+volatile int3 prefix##_i_3 = 1;     \
+volatile int4 prefix##_i_4 = 1;     \
+volatile uint prefix##_ui_1 = 1;    \
+volatile uint2 prefix##_ui_2 = 1;   \
+volatile uint3 prefix##_ui_3 = 1;   \
+volatile uint4 prefix##_ui_4 = 1;   \
+volatile long prefix##_l_1 = 1;     \
+volatile ulong prefix##_ul_1 = 1;
+
+#define TEST_INT_OP_TYPE(op, type)                      \
+rsDebug("Testing " #op " for " #type "1", i++);         \
+res_##type##_1 = src1_##type##_1 op src2_##type##_1;    \
+rsDebug("Testing " #op " for " #type "2", i++);         \
+res_##type##_2 = src1_##type##_2 op src2_##type##_2;    \
+rsDebug("Testing " #op " for " #type "3", i++);         \
+res_##type##_3 = src1_##type##_3 op src2_##type##_3;    \
+rsDebug("Testing " #op " for " #type "4", i++);         \
+res_##type##_4 = src1_##type##_4 op src2_##type##_4;
+
+#define TEST_INT_OP(op)                     \
+TEST_INT_OP_TYPE(op, c)                     \
+TEST_INT_OP_TYPE(op, uc)                    \
+TEST_INT_OP_TYPE(op, s)                     \
+TEST_INT_OP_TYPE(op, us)                    \
+TEST_INT_OP_TYPE(op, i)                     \
+TEST_INT_OP_TYPE(op, ui)                    \
+rsDebug("Testing " #op " for l1", i++);     \
+res_l_1 = src1_l_1 op src2_l_1;             \
+rsDebug("Testing " #op " for ul1", i++);    \
+res_ul_1 = src1_ul_1 op src2_ul_1;
+
+DECL_INT(res)
+DECL_INT(src1)
+DECL_INT(src2)
+
+static bool test_basic_operators() {
+    bool failed = false;
+    int i = 0;
+
+    TEST_INT_OP(+);
+    TEST_INT_OP(-);
+    TEST_INT_OP(*);
+    TEST_INT_OP(/);
+    TEST_INT_OP(%);
+    TEST_INT_OP(<<);
+    TEST_INT_OP(>>);
+
+    if (failed) {
+        rsDebug("test_basic_operators FAILED", 0);
+    }
+    else {
+        rsDebug("test_basic_operators PASSED", 0);
+    }
+
+    return failed;
+}
+
+#define TEST_CVT(to, from, type)                        \
+rsDebug("Testing convert from " #from " to " #to, 0);   \
+to##1 = from##1;                                        \
+to##2 = convert_##type##2(from##2);                     \
+to##3 = convert_##type##3(from##3);                     \
+to##4 = convert_##type##4(from##4);
+
+#define TEST_CVT_MATRIX(to, type)   \
+TEST_CVT(to, c, type);              \
+TEST_CVT(to, uc, type);             \
+TEST_CVT(to, s, type);              \
+TEST_CVT(to, us, type);             \
+TEST_CVT(to, i, type);              \
+TEST_CVT(to, ui, type);             \
+TEST_CVT(to, f, type);              \
+
+static bool test_convert() {
+    bool failed = false;
+
+    TEST_CVT_MATRIX(c, char);
+    TEST_CVT_MATRIX(uc, uchar);
+    TEST_CVT_MATRIX(s, short);
+    TEST_CVT_MATRIX(us, ushort);
+    TEST_CVT_MATRIX(i, int);
+    TEST_CVT_MATRIX(ui, uint);
+    TEST_CVT_MATRIX(f, float);
+
+    if (failed) {
+        rsDebug("test_convert FAILED", 0);
+    }
+    else {
+        rsDebug("test_convert PASSED", 0);
+    }
+
+    return failed;
+}
+
 void math_test(uint32_t index, int test_num) {
     bool failed = false;
+    failed |= test_convert();
     failed |= test_fp_math(index);
+    failed |= test_basic_operators();
 
     if (failed) {
         rsSendToClientBlocking(RS_MSG_TEST_FAILED);
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 3acb624..40cb5c7 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -201,9 +201,9 @@
     mGL.mExtensions = glGetString(GL_EXTENSIONS);
 
     //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
-    LOGV("GL Version %s", mGL.mVersion);
+    //LOGV("GL Version %s", mGL.mVersion);
     //LOGV("GL Vendor %s", mGL.mVendor);
-    LOGV("GL Renderer %s", mGL.mRenderer);
+    //LOGV("GL Renderer %s", mGL.mRenderer);
     //LOGV("GL Extensions %s", mGL.mExtensions);
 
     const char *verptr = NULL;
@@ -468,7 +468,6 @@
          return NULL;
      }
 
-     rsc->mScriptC.init(rsc);
      if (rsc->mIsGraphicsContext) {
          rsc->mStateRaster.init(rsc);
          rsc->setProgramRaster(NULL);
@@ -528,7 +527,7 @@
 }
 
 void Context::destroyWorkerThreadResources() {
-    LOGV("destroyWorkerThreadResources 1");
+    //LOGV("destroyWorkerThreadResources 1");
     if (mIsGraphicsContext) {
          mRaster.clear();
          mFragment.clear();
@@ -544,7 +543,7 @@
          mShaderCache.cleanupAll();
     }
     ObjectBase::zeroAllUserRef(this);
-    LOGV("destroyWorkerThreadResources 2");
+    //LOGV("destroyWorkerThreadResources 2");
     mExit = true;
 }
 
@@ -552,7 +551,7 @@
      Context *rsc = static_cast<Context *>(vrsc);
      uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount);
 
-     LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+     //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
 
      rsc->mWorkers.mLaunchSignals[idx].init();
      rsc->mWorkers.mNativeThreadId[idx] = gettid();
@@ -573,7 +572,7 @@
          LOGE("pthread_setspecific %i", status);
      }
 
-     while (rsc->mRunning) {
+     while (!rsc->mExit) {
          rsc->mWorkers.mLaunchSignals[idx].wait();
          if (rsc->mWorkers.mLaunchCallback) {
             rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx);
@@ -582,7 +581,7 @@
          rsc->mWorkers.mCompleteSignal.set();
      }
 
-     LOGV("RS helperThread exiting %p idx=%i", rsc, idx);
+     //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
      return NULL;
 }
 
@@ -730,6 +729,18 @@
     mIO.shutdown();
     int status = pthread_join(mThreadId, &res);
 
+    // Cleanup compute threads.
+    mWorkers.mLaunchData = NULL;
+    mWorkers.mLaunchCallback = NULL;
+    mWorkers.mRunningCount = (int)mWorkers.mCount;
+    for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
+        mWorkers.mLaunchSignals[ct].set();
+    }
+    for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
+        int status = pthread_join(mWorkers.mThreadId[ct], &res);
+    }
+    rsAssert(!mWorkers.mRunningCount);
+
     // Global structure cleanup.
     pthread_mutex_lock(&gInitMutex);
     if (mDev) {
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index eb2af1c..3f88543 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -76,7 +76,8 @@
 }
 
 bool LocklessCommandFifo::isEmpty() const {
-    return mPut == mGet;
+    uint32_t p = android_atomic_acquire_load((int32_t *)&mPut);
+    return ((uint8_t *)p) == mGet;
 }
 
 
@@ -155,7 +156,9 @@
 
 void LocklessCommandFifo::next() {
     uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1];
-    mGet += ((bytes + 3) & ~3) + 4;
+
+    android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet);
+    //mGet += ((bytes + 3) & ~3) + 4;
     if (isEmpty()) {
         mSignalToControl.set();
     }
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index eecfa16..3858e1c 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -421,21 +421,9 @@
 }
 
 ScriptCState::ScriptCState() {
-    mScript.clear();
 }
 
 ScriptCState::~ScriptCState() {
-    mScript.clear();
-}
-
-void ScriptCState::init(Context *rsc) {
-    clear(rsc);
-}
-
-void ScriptCState::clear(Context *rsc) {
-    rsAssert(rsc);
-    mScript.clear();
-    mScript.set(new ScriptC(rsc));
 }
 
 static void* symbolLookup(void* pContext, char const* name) {
@@ -608,8 +596,6 @@
 namespace renderscript {
 
 void rsi_ScriptCBegin(Context * rsc) {
-    ScriptCState *ss = &rsc->mScriptC;
-    ss->clear(rsc);
 }
 
 void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) {
@@ -618,8 +604,8 @@
     char *t = (char *)malloc(len + 1);
     memcpy(t, text, len);
     t[len] = 0;
-    ss->mScript->mEnviroment.mScriptText = t;
-    ss->mScript->mEnviroment.mScriptTextLength = len;
+    ss->mScriptText = t;
+    ss->mScriptLen = len;
 }
 
 
@@ -630,17 +616,19 @@
 {
     ScriptCState *ss = &rsc->mScriptC;
 
-    ObjectBaseRef<ScriptC> s(ss->mScript);
-    ss->mScript.clear();
+    ScriptC *s = new ScriptC(rsc);
+    s->mEnviroment.mScriptText = ss->mScriptText;
+    s->mEnviroment.mScriptTextLength = ss->mScriptLen;
+    ss->mScriptText = NULL;
+    ss->mScriptLen = 0;
     s->incUserRef();
 
-    if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) {
+    if (!ss->runCompiler(rsc, s, resName, cacheDir)) {
         // Error during compile, destroy s and return null.
-        s->zeroUserRef();
+        delete s;
         return NULL;
     }
-    ss->clear(rsc);
-    return s.get();
+    return s;
 }
 
 }
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 612e38a..7143c67 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -76,11 +76,9 @@
     ScriptCState();
     ~ScriptCState();
 
-    ObjectBaseRef<ScriptC> mScript;
+    char * mScriptText;
+    size_t mScriptLen;
 
-    void init(Context *rsc);
-
-    void clear(Context *rsc);
     bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
 
     struct SymbolTable_t {
@@ -88,7 +86,6 @@
         void * mPtr;
         bool threadable;
     };
-    //static SymbolTable_t gSyms[];
     static const SymbolTable_t * lookupSymbol(const char *);
     static const SymbolTable_t * lookupSymbolCL(const char *);
     static const SymbolTable_t * lookupSymbolGL(const char *);
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index f550d98..beb4d72 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -305,6 +305,14 @@
     return a % b;
 }
 
+unsigned int SC_udivsi3(unsigned int a, unsigned int b) {
+    return a / b;
+}
+
+unsigned int SC_umodsi3(unsigned int a, unsigned int b) {
+    return a % b;
+}
+
 int SC_getAllocation(const void *ptr) {
     GET_TLS();
     const Allocation *alloc = sc->ptrToAllocation(ptr);
@@ -363,6 +371,8 @@
 static ScriptCState::SymbolTable_t gSyms[] = {
     { "__divsi3", (void *)&SC_divsi3, true },
     { "__modsi3", (void *)&SC_modsi3, true },
+    { "__udivsi3", (void *)&SC_udivsi3, true },
+    { "__umodsi3", (void *)&SC_umodsi3, true },
 
     // allocation
     { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index f3e0ab0..21c0f7b 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -683,7 +683,7 @@
 rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
     q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
     q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
-    q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->z + q->w*rhs->y;
+    q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
     q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
 }
 
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 11e27a9..925f965 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -299,12 +299,16 @@
         String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF);
 
         if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
-            output[0] = convertRationalLatLonToFloat(latValue, latRef);
-            output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
-            return true;
-        } else {
-            return false;
+            try {
+                output[0] = convertRationalLatLonToFloat(latValue, latRef);
+                output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+                return true;
+            } catch (IllegalArgumentException e) {
+                // if values are not parseable
+            }
         }
+
+        return false;
     }
 
     /**
@@ -373,12 +377,12 @@
 
             String [] pair;
             pair = parts[0].split("/");
-            int degrees = (int) (Float.parseFloat(pair[0].trim())
-                    / Float.parseFloat(pair[1].trim()));
+            double degrees = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
 
             pair = parts[1].split("/");
-            int minutes = (int) ((Float.parseFloat(pair[0].trim())
-                    / Float.parseFloat(pair[1].trim())));
+            double minutes = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
 
             pair = parts[2].split("/");
             double seconds = Double.parseDouble(pair[0].trim())
@@ -389,10 +393,12 @@
                 return (float) -result;
             }
             return (float) result;
-        } catch (RuntimeException ex) {
-            // if for whatever reason we can't parse the lat long then return
-            // null
-            return 0f;
+        } catch (NumberFormatException e) {
+            // Some of the nubmers are not valid
+            throw new IllegalArgumentException();
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // Some of the rational does not follow the correct format
+            throw new IllegalArgumentException();
         }
     }
 
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 54db8cd..8156439 100755
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -30,6 +30,9 @@
 import android.util.Log;
 import android.util.Pair;
 import android.view.Surface;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
 
 /**
  *This class provide Native methods to be used by MediaArtist {@hide}
@@ -67,7 +70,10 @@
     private boolean mExportDone = false;
 
     private int mProgressToApp;
-
+    /**
+     *  The resize paint
+     */
+    private static final Paint sResizePaint = new Paint(Paint.FILTER_BITMAP_FLAG);
 
     public static final int TASK_LOADING_SETTINGS = 1;
 
@@ -3838,11 +3844,39 @@
             throw new IllegalArgumentException();
         }
 
-        IntBuffer rgb888 = IntBuffer.allocate(width * height * 4);
-        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        nativeGetPixels(inputFile, rgb888.array(), width, height, timeMS);
-        bitmap.copyPixelsFromBuffer(rgb888);
+        int newWidth = 0;
+        int newHeight = 0;
+        Bitmap tempBitmap = null;
 
+        /* Make width and height as even */
+        newWidth = (width + 1) & 0xFFFFFFFE;
+        newHeight = (height + 1) & 0xFFFFFFFE;
+
+        /* Create a temp bitmap for resized thumbnails */
+        if ((newWidth != width) || (newHeight != height)) {
+             tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
+        }
+
+        IntBuffer rgb888 = IntBuffer.allocate(newWidth * newHeight * 4);
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        nativeGetPixels(inputFile, rgb888.array(), newWidth, newHeight, timeMS);
+
+        if ((newWidth == width) && (newHeight == height)) {
+            bitmap.copyPixelsFromBuffer(rgb888);
+        } else {
+            /* Create a temp bitmap to be used for resize */
+            tempBitmap.copyPixelsFromBuffer(rgb888);
+
+            /* Create a canvas to resize */
+            final Canvas canvas = new Canvas(bitmap);
+            canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
+                                          new Rect(0, 0, width, height),
+                                          sResizePaint);
+        }
+
+        if (tempBitmap != null) {
+            tempBitmap.recycle();
+        }
         return bitmap;
     }
 
@@ -3863,11 +3897,24 @@
     public Bitmap[] getPixelsList(String filename, int width, int height, long startMs, long endMs,
             int thumbnailCount) {
         int[] rgb888 = null;
-        int thumbnailSize = width * height * 4;
+        int thumbnailSize = 0;
+        int newWidth = 0;
+        int newHeight = 0;
+        Bitmap tempBitmap = null;
 
+        /* Make width and height as even */
+        newWidth = (width + 1) & 0xFFFFFFFE;
+        newHeight = (height + 1) & 0xFFFFFFFE;
+        thumbnailSize = newWidth * newHeight * 4;
+
+        /* Create a temp bitmap for resized thumbnails */
+        if ((newWidth != width) || (newHeight != height)) {
+            tempBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
+        }
         int i = 0;
         int deltaTime = (int)(endMs - startMs) / thumbnailCount;
         Bitmap[] bitmap = null;
+
         try {
             // This may result in out of Memory Error
             rgb888 = new int[thumbnailSize * thumbnailCount];
@@ -3880,19 +3927,35 @@
                 bitmap = new Bitmap[MAX_THUMBNAIL_PERMITTED];
                 thumbnailCount = MAX_THUMBNAIL_PERMITTED;
             } catch (Throwable ex) {
-                throw new RuntimeException("Memory allocation fails,reduce nos of thumbanail count");
+                throw new RuntimeException("Memory allocation fails, thumbnail count too large: "+thumbnailCount);
             }
         }
         IntBuffer tmpBuffer = IntBuffer.allocate(thumbnailSize);
-        nativeGetPixelsList(filename, rgb888, width, height, deltaTime, thumbnailCount, startMs,
+        nativeGetPixelsList(filename, rgb888, newWidth, newHeight, deltaTime, thumbnailCount, startMs,
                 endMs);
+
         for (; i < thumbnailCount; i++) {
             bitmap[i] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
             tmpBuffer.put(rgb888, (i * thumbnailSize), thumbnailSize);
             tmpBuffer.rewind();
-            bitmap[i].copyPixelsFromBuffer(tmpBuffer);
+
+            if ((newWidth == width) && (newHeight == height)) {
+                bitmap[i].copyPixelsFromBuffer(tmpBuffer);
+            } else {
+                /* Copy the out rgb buffer to temp bitmap */
+                tempBitmap.copyPixelsFromBuffer(tmpBuffer);
+
+                /* Create a canvas to resize */
+                final Canvas canvas = new Canvas(bitmap[i]);
+                canvas.drawBitmap(tempBitmap, new Rect(0, 0, newWidth, newHeight),
+                                              new Rect(0, 0, width, height),
+                                              sResizePaint);
+            }
         }
 
+        if (tempBitmap != null) {
+            tempBitmap.recycle();
+        }
         return bitmap;
     }
 
@@ -3942,12 +4005,11 @@
         }
     }
 
-    public void clearPreviewSurface(Surface surface, int width, int height) {
-       nativeClearSurface(surface,width,height);
+    public void clearPreviewSurface(Surface surface) {
+       nativeClearSurface(surface);
     }
     /**     Native Methods        */
-
-    public native Properties getMediaProperties(String file) throws IllegalArgumentException,
+    native Properties getMediaProperties(String file) throws IllegalArgumentException,
     IllegalStateException, RuntimeException, Exception;
 
     /**
@@ -3957,7 +4019,7 @@
      * @throws RuntimeException if an error occurred
      * @see Version
      */
-    public static native Version getVersion() throws RuntimeException;
+    private static native Version getVersion() throws RuntimeException;
 
     /**
      * Returns the video thumbnail in an array of integers. Output format is
@@ -3974,10 +4036,10 @@
      *             negative
      * @throws RuntimeException on runtime errors in native code
      */
-    public native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height,
+    private native int nativeGetPixels(String fileName, int[] pixelArray, int width, int height,
             long timeMS);
 
-    public native int nativeGetPixelsList(String fileName, int[] pixelArray, int width, int height,
+    private native int nativeGetPixelsList(String fileName, int[] pixelArray, int width, int height,
             int timeMS, int nosofTN, long startTimeMs, long endTimeMs);
 
     /**
@@ -3986,12 +4048,12 @@
      *
      * @throws IllegalStateException if the method could not be called
      */
-    public native void release() throws IllegalStateException, RuntimeException;
+    private native void release() throws IllegalStateException, RuntimeException;
 
     /*
      * Clear the preview surface
      */
-    public native void nativeClearSurface(Surface surface, int width, int height);
+    private native void nativeClearSurface(Surface surface);
 
 
     /**
@@ -4000,7 +4062,7 @@
      *
      * @throws IllegalStateException if the method could not be called
      */
-    public native void stopEncoding() throws IllegalStateException, RuntimeException;
+    private native void stopEncoding() throws IllegalStateException, RuntimeException;
 
 
 
@@ -4026,12 +4088,12 @@
 
     private native void nativeStopPreview();
 
-    public native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
+    private native int nativeGenerateAudioGraph(String pcmFilePath, String outGraphPath,
             int frameDuration, int channels, int sampleCount);
 
-    public native int nativeGenerateRawAudio(String InFileName, String PCMFileName);
+    private native int nativeGenerateRawAudio(String InFileName, String PCMFileName);
 
-    public native int nativeGenerateClip(EditSettings editSettings)
+    private native int nativeGenerateClip(EditSettings editSettings)
     throws IllegalArgumentException, IllegalStateException, RuntimeException;
 
 }
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index 1c02878..a977b8e 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -1013,9 +1013,20 @@
 
             if (dx > dy) {
                 bitmapWidth = width;
-                bitmapHeight = Math.round(nativeHeight / dx);
+
+                if (((float)nativeHeight / dx) < (float)height) {
+                    bitmapHeight = (float)Math.ceil(nativeHeight / dx);
+                } else { // value equals the requested height
+                    bitmapHeight = (float)Math.floor(nativeHeight / dx);
+                }
+
             } else {
-                bitmapWidth = Math.round(nativeWidth / dy);
+                if (((float)nativeWidth / dy) > (float)width) {
+                    bitmapWidth = (float)Math.floor(nativeWidth / dy);
+                } else { // value equals the requested width
+                    bitmapWidth = (float)Math.ceil(nativeWidth / dy);
+                }
+
                 bitmapHeight = height;
             }
 
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 5b87d16..c19725c 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -1828,9 +1828,6 @@
       if (surfaceHolder == null) {
          throw new IllegalArgumentException();
        }
-      Rect frame;
-      int surfaceWidth;
-      int surfaceHeight;
       Surface surface = surfaceHolder.getSurface();
 
       if (surface == null) {
@@ -1838,10 +1835,7 @@
         "Surface could not be retrieved from surface holder");
         throw new RuntimeException();
       }
-      frame = surfaceHolder.getSurfaceFrame();
-      surfaceWidth = frame.width();
-      surfaceHeight = frame.height();
-      mMANativeHelper.clearPreviewSurface(surface,surfaceWidth,surfaceHeight);
+      mMANativeHelper.clearPreviewSurface(surface);
     }
 
 }
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 1751396..8ce788b 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -261,9 +261,7 @@
 
 static void videoEditor_clearSurface(JNIEnv* pEnv,
                                     jobject thiz,
-                                    jobject surface,
-                                    jint width,
-                                    jint height);
+                                    jobject surface);
 
 static JNINativeMethod gManualEditMethods[] = {
     {"getVersion",               "()L"VERSION_CLASS_NAME";",
@@ -300,7 +298,7 @@
                                 (int *)videoEditor_generateAudioRawFile      },
     {"nativeGenerateClip",      "(L"EDIT_SETTINGS_CLASS_NAME";)I",
                                 (void *)videoEditor_generateClip  },
-    {"nativeClearSurface",       "(Landroid/view/Surface;II)V",
+    {"nativeClearSurface",       "(Landroid/view/Surface;)V",
                                 (void *)videoEditor_clearSurface  },
 };
 
@@ -428,16 +426,15 @@
 
 static void videoEditor_clearSurface(JNIEnv* pEnv,
                                     jobject thiz,
-                                    jobject surface,
-                                    jint width,
-                                    jint height)
+                                    jobject surface)
 {
     bool needToBeLoaded = true;
-    M4OSA_UInt32 framesizeYuv =0;
     M4OSA_ERR result = M4NO_ERROR;
     VideoEditor_renderPreviewFrameStr frameStr;
     const char* pMessage = NULL;
-    M4VIFI_ImagePlane *yuvPlane;
+    // Let the size be QVGA
+    int width = 320;
+    int height = 240;
     ManualEditContext* pContext = M4OSA_NULL;
 
     // Get the context.
@@ -474,62 +471,7 @@
     Surface* const p = (Surface*)pEnv->GetIntField(surface, surface_native);
     sp<Surface> previewSurface = sp<Surface>(p);
 
-    /**
-    * Allocate output YUV planes
-    */
-    yuvPlane = (M4VIFI_ImagePlane*)M4OSA_malloc(3*sizeof(M4VIFI_ImagePlane), M4VS,
-        (M4OSA_Char*)"videoEditor_clearSurface Output plane YUV");
-    if (yuvPlane == M4OSA_NULL) {
-        VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "videoEditor_clearSurface() malloc error for yuv plane");
-        pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
-        jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-        return ;
-    }
-
-    framesizeYuv = width * height * 1.5;
-    yuvPlane[0].u_width = width;
-    yuvPlane[0].u_height = height;
-    yuvPlane[0].u_topleft = 0;
-    yuvPlane[0].u_stride = width;
-    yuvPlane[0].pac_data = (M4VIFI_UInt8 *)M4OSA_malloc(framesizeYuv, M4VS,
-            (M4OSA_Char*)"videoEditor pixelArray");
-    if (yuvPlane[0].pac_data == M4OSA_NULL) {
-       VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-       "videoEditor_renderPreviewFrame() malloc error");
-       pMessage = videoEditJava_getErrorName(M4ERR_ALLOC);
-       jniThrowException(pEnv, "java/lang/RuntimeException", pMessage);
-       return;
-    }
-
-    /* memset yuvPlane[0].pac_data with 0 for black frame */
-    M4OSA_memset((M4OSA_MemAddr8)yuvPlane[0].pac_data,framesizeYuv,0x00);
-    FILE *p1 = fopen("/mnt/sdcard/black.raw","wb");
-    fwrite(yuvPlane[0].pac_data,1,framesizeYuv,p1);
-    fclose(p1);
-
-    yuvPlane[1].u_width = width>>1;
-    yuvPlane[1].u_height = height>>1;
-    yuvPlane[1].u_topleft = 0;
-    yuvPlane[1].u_stride = width>>1;
-    yuvPlane[1].pac_data = yuvPlane[0].pac_data
-                + yuvPlane[0].u_width * yuvPlane[0].u_height;
-
-    M4OSA_memset((M4OSA_MemAddr8)yuvPlane[1].pac_data,yuvPlane[1].u_width *
-                                yuvPlane[1].u_height,128);
-    yuvPlane[2].u_width = (width)>>1;
-    yuvPlane[2].u_height = (height)>>1;
-    yuvPlane[2].u_topleft = 0;
-    yuvPlane[2].u_stride = (width)>>1;
-    yuvPlane[2].pac_data = yuvPlane[1].pac_data
-                + yuvPlane[1].u_width * yuvPlane[1].u_height;
-
-    M4OSA_memset((M4OSA_MemAddr8)yuvPlane[2].pac_data,yuvPlane[2].u_width *
-                                 yuvPlane[2].u_height,128);
-
-    /* Fill up the render structure*/
-    frameStr.pBuffer = (M4OSA_Void*)yuvPlane[0].pac_data;
-
+    frameStr.pBuffer = M4OSA_NULL;
     frameStr.timeMs = 0;
     frameStr.uiSurfaceWidth = width;
     frameStr.uiSurfaceHeight = height;
@@ -539,19 +481,11 @@
     frameStr.clipBeginCutTime = 0;
     frameStr.clipEndCutTime = 0;
 
-    /*pContext->mPreviewController->setPreviewFrameRenderingMode(
-        pContext->pEditSettings->\
-        pClipList[iCurrentClipIndex]->xVSS.MediaRendering,
-        pContext->pEditSettings->xVSS.outputVideoSize);
-     */
-
-    result = pContext->mPreviewController->renderPreviewFrame(previewSurface,
+    result = pContext->mPreviewController->clearSurface(previewSurface,
                                                               &frameStr);
     videoEditJava_checkAndThrowRuntimeException(&needToBeLoaded, pEnv,
             (M4NO_ERROR != result), result);
 
-    M4OSA_free((M4OSA_MemAddr32)yuvPlane[0].pac_data);
-    M4OSA_free((M4OSA_MemAddr32)yuvPlane);
   }
 
 static int videoEditor_renderPreviewFrame(JNIEnv* pEnv,
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml
index 3028a42..3fef7e0 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_input_methods_item.xml
@@ -47,12 +47,11 @@
                 android:id="@+id/item_radio"
                 android:layout_width="30dip"
                 android:layout_height="wrap_content"
-                android:layout_marginRight="11dip"
                 android:focusable="false"
                 android:clickable="false" />
             <ImageView
                 android:id="@+id/item_icon"
-                android:layout_width="wrap_content"
+                android:layout_width="@android:dimen/app_icon_size"
                 android:layout_height="wrap_content"
                 android:scaleType="fitCenter" />
             <LinearLayout
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index a3ccef9..06c789c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -36,9 +36,12 @@
 import android.widget.RadioButton;
 import android.widget.TextView;
 
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import com.android.systemui.R;
 
@@ -47,9 +50,10 @@
     private static final String TAG = "InputMethodsPanel";
 
     private final InputMethodManager mImm;
-    private final HashMap<InputMethodInfo, List<InputMethodSubtype>>
+    private final TreeMap<InputMethodInfo, List<InputMethodSubtype>>
             mEnabledInputMethodAndSubtypesCache =
-                    new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
+                    new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+                            new InputMethodComparator());
     private final HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>> mRadioViewAndImiMap =
             new HashMap<View, Pair<InputMethodInfo, InputMethodSubtype>>();
 
@@ -61,6 +65,21 @@
     private String mEnabledInputMethodAndSubtypesCacheStr;
     private View mConfigureImeShortcut;
 
+    private class InputMethodComparator implements Comparator<InputMethodInfo> {
+        public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
+            if (imi2 == null) return 0;
+            if (imi1 == null) return 1;
+            if (mPackageManager != null) {
+                CharSequence imiId1 = imi1.loadLabel(mPackageManager);
+                CharSequence imiId2 = imi2.loadLabel(mPackageManager);
+                if (imiId1 != null && imiId2 != null) {
+                    return imiId1.toString().compareTo(imiId2.toString());
+                }
+            }
+            return imi1.getId().compareTo(imi2.getId());
+        }
+    }
+
     public InputMethodsPanel(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -190,8 +209,8 @@
         mRadioViewAndImiMap.clear();
         mPackageManager = mContext.getPackageManager();
 
-        HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs
-                = getEnabledInputMethodAndSubtypeList();
+        Map<InputMethodInfo, List<InputMethodSubtype>> enabledIMIs =
+                getEnabledInputMethodAndSubtypeList();
         // TODO: Sort by alphabet and mode.
         Set<InputMethodInfo> cachedImiSet = enabledIMIs.keySet();
         for (InputMethodInfo imi: cachedImiSet) {
@@ -278,7 +297,7 @@
         }
     }
 
-    private HashMap<InputMethodInfo, List<InputMethodSubtype>>
+    private TreeMap<InputMethodInfo, List<InputMethodSubtype>>
             getEnabledInputMethodAndSubtypeList() {
         String newEnabledIMIs = Settings.Secure.getString(
                 mContext.getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index e26b8ea..9549930 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -81,7 +81,7 @@
 
     public static final int MAX_NOTIFICATION_ICONS = 5;
     // IME switcher icon is big and occupy width of two icons
-    public static final int MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE = MAX_NOTIFICATION_ICONS - 2;
+    public static final int MAX_NOTIFICATION_ICONS_IME_BUTTON_VISIBLE = MAX_NOTIFICATION_ICONS - 1;
 
     public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000;
     public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001;
@@ -860,11 +860,8 @@
         if (DEBUG) {
             Slog.d(TAG, (visible?"showing":"hiding") + " the IME button");
         }
-        int oldVisibility = mInputMethodSwitchButton.getVisibility();
         mInputMethodSwitchButton.setIMEButtonVisible(token, visible);
-        if (oldVisibility != mInputMethodSwitchButton.getVisibility()) {
-            updateNotificationIcons();
-        }
+        updateNotificationIcons();
         mInputMethodsPanel.setImeToken(token);
         mBackButton.setImageResource(
                 visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back);
diff --git a/preloaded-classes b/preloaded-classes
index ca2e6ed..3780853 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1839,94 +1839,94 @@
 org.apache.http.util.ByteArrayBuffer
 org.apache.http.util.CharArrayBuffer
 org.apache.http.util.LangUtils
-org.bouncycastle.asn1.ASN1Choice
-org.bouncycastle.asn1.ASN1Collection
-org.bouncycastle.asn1.ASN1Collection$ASN1CollectionEnumeration
-org.bouncycastle.asn1.ASN1Encodable
-org.bouncycastle.asn1.ASN1EncodableVector
-org.bouncycastle.asn1.ASN1InputStream
-org.bouncycastle.asn1.ASN1Null
-org.bouncycastle.asn1.ASN1Object
-org.bouncycastle.asn1.ASN1OctetString
-org.bouncycastle.asn1.ASN1OctetStringParser
-org.bouncycastle.asn1.ASN1OutputStream
-org.bouncycastle.asn1.ASN1Sequence
-org.bouncycastle.asn1.ASN1SequenceParser
-org.bouncycastle.asn1.ASN1Set
-org.bouncycastle.asn1.ASN1StreamParser
-org.bouncycastle.asn1.ASN1TaggedObject
-org.bouncycastle.asn1.ASN1TaggedObjectParser
-org.bouncycastle.asn1.BERTaggedObjectParser
-org.bouncycastle.asn1.DERBitString
-org.bouncycastle.asn1.DERBoolean
-org.bouncycastle.asn1.DEREncodable
-org.bouncycastle.asn1.DEREncodableVector
-org.bouncycastle.asn1.DERFactory
-org.bouncycastle.asn1.DERIA5String
-org.bouncycastle.asn1.DERInteger
-org.bouncycastle.asn1.DERNull
-org.bouncycastle.asn1.DERObject
-org.bouncycastle.asn1.DERObjectIdentifier
-org.bouncycastle.asn1.DEROctetString
-org.bouncycastle.asn1.DEROctetStringParser
-org.bouncycastle.asn1.DEROutputStream
-org.bouncycastle.asn1.DERPrintableString
-org.bouncycastle.asn1.DERSequence
-org.bouncycastle.asn1.DERSequenceParser
-org.bouncycastle.asn1.DERSet
-org.bouncycastle.asn1.DERString
-org.bouncycastle.asn1.DERT61String
-org.bouncycastle.asn1.DERTaggedObject
-org.bouncycastle.asn1.DERTags
-org.bouncycastle.asn1.DERUTCTime
-org.bouncycastle.asn1.DERUTF8String
-org.bouncycastle.asn1.DERUniversalString
-org.bouncycastle.asn1.DefiniteLengthInputStream
-org.bouncycastle.asn1.IndefiniteLengthInputStream
-org.bouncycastle.asn1.LimitedInputStream
-org.bouncycastle.asn1.OIDTokenizer
-org.bouncycastle.asn1.OrderedTable
-org.bouncycastle.asn1.bc.BCObjectIdentifiers
-org.bouncycastle.asn1.iana.IANAObjectIdentifiers
-org.bouncycastle.asn1.nist.NISTObjectIdentifiers
-org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
-org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
-org.bouncycastle.asn1.x509.AlgorithmIdentifier
-org.bouncycastle.asn1.x509.BasicConstraints
-org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
-org.bouncycastle.asn1.x509.TBSCertificateStructure
-org.bouncycastle.asn1.x509.Time
-org.bouncycastle.asn1.x509.X509CertificateStructure
-org.bouncycastle.asn1.x509.X509Extension
-org.bouncycastle.asn1.x509.X509Extensions
-org.bouncycastle.asn1.x509.X509Name
-org.bouncycastle.asn1.x509.X509NameElementList
-org.bouncycastle.asn1.x509.X509ObjectIdentifiers
-org.bouncycastle.asn1.x9.X9ObjectIdentifiers
-org.bouncycastle.crypto.Digest
-org.bouncycastle.crypto.ExtendedDigest
-org.bouncycastle.crypto.Mac
-org.bouncycastle.crypto.digests.OpenSSLDigest
-org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
-org.bouncycastle.crypto.macs.HMac
-org.bouncycastle.jce.ProviderConfigurationPermission
-org.bouncycastle.jce.interfaces.BCKeyStore
-org.bouncycastle.jce.interfaces.ConfigurableProvider
-org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
-org.bouncycastle.jce.provider.BouncyCastleProvider
-org.bouncycastle.jce.provider.BouncyCastleProvider$1
-org.bouncycastle.jce.provider.JDKKeyStore
-org.bouncycastle.jce.provider.JDKKeyStore$StoreEntry
-org.bouncycastle.jce.provider.JDKX509CertificateFactory
-org.bouncycastle.jce.provider.PEMUtil
-org.bouncycastle.jce.provider.PKCS12BagAttributeCarrierImpl
-org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
-org.bouncycastle.jce.provider.ProviderUtil
-org.bouncycastle.jce.provider.X509CertificateObject
-org.bouncycastle.jce.provider.asymmetric.ECMappings
-org.bouncycastle.jce.provider.symmetric.AESMappings
-org.bouncycastle.util.Strings
-org.bouncycastle.util.io.Streams
+com.android.org.bouncycastle.asn1.ASN1Choice
+com.android.org.bouncycastle.asn1.ASN1Collection
+com.android.org.bouncycastle.asn1.ASN1Collection$ASN1CollectionEnumeration
+com.android.org.bouncycastle.asn1.ASN1Encodable
+com.android.org.bouncycastle.asn1.ASN1EncodableVector
+com.android.org.bouncycastle.asn1.ASN1InputStream
+com.android.org.bouncycastle.asn1.ASN1Null
+com.android.org.bouncycastle.asn1.ASN1Object
+com.android.org.bouncycastle.asn1.ASN1OctetString
+com.android.org.bouncycastle.asn1.ASN1OctetStringParser
+com.android.org.bouncycastle.asn1.ASN1OutputStream
+com.android.org.bouncycastle.asn1.ASN1Sequence
+com.android.org.bouncycastle.asn1.ASN1SequenceParser
+com.android.org.bouncycastle.asn1.ASN1Set
+com.android.org.bouncycastle.asn1.ASN1StreamParser
+com.android.org.bouncycastle.asn1.ASN1TaggedObject
+com.android.org.bouncycastle.asn1.ASN1TaggedObjectParser
+com.android.org.bouncycastle.asn1.BERTaggedObjectParser
+com.android.org.bouncycastle.asn1.DERBitString
+com.android.org.bouncycastle.asn1.DERBoolean
+com.android.org.bouncycastle.asn1.DEREncodable
+com.android.org.bouncycastle.asn1.DEREncodableVector
+com.android.org.bouncycastle.asn1.DERFactory
+com.android.org.bouncycastle.asn1.DERIA5String
+com.android.org.bouncycastle.asn1.DERInteger
+com.android.org.bouncycastle.asn1.DERNull
+com.android.org.bouncycastle.asn1.DERObject
+com.android.org.bouncycastle.asn1.DERObjectIdentifier
+com.android.org.bouncycastle.asn1.DEROctetString
+com.android.org.bouncycastle.asn1.DEROctetStringParser
+com.android.org.bouncycastle.asn1.DEROutputStream
+com.android.org.bouncycastle.asn1.DERPrintableString
+com.android.org.bouncycastle.asn1.DERSequence
+com.android.org.bouncycastle.asn1.DERSequenceParser
+com.android.org.bouncycastle.asn1.DERSet
+com.android.org.bouncycastle.asn1.DERString
+com.android.org.bouncycastle.asn1.DERT61String
+com.android.org.bouncycastle.asn1.DERTaggedObject
+com.android.org.bouncycastle.asn1.DERTags
+com.android.org.bouncycastle.asn1.DERUTCTime
+com.android.org.bouncycastle.asn1.DERUTF8String
+com.android.org.bouncycastle.asn1.DERUniversalString
+com.android.org.bouncycastle.asn1.DefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.IndefiniteLengthInputStream
+com.android.org.bouncycastle.asn1.LimitedInputStream
+com.android.org.bouncycastle.asn1.OIDTokenizer
+com.android.org.bouncycastle.asn1.OrderedTable
+com.android.org.bouncycastle.asn1.bc.BCObjectIdentifiers
+com.android.org.bouncycastle.asn1.iana.IANAObjectIdentifiers
+com.android.org.bouncycastle.asn1.nist.NISTObjectIdentifiers
+com.android.org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
+com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier
+com.android.org.bouncycastle.asn1.x509.BasicConstraints
+com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
+com.android.org.bouncycastle.asn1.x509.TBSCertificateStructure
+com.android.org.bouncycastle.asn1.x509.Time
+com.android.org.bouncycastle.asn1.x509.X509CertificateStructure
+com.android.org.bouncycastle.asn1.x509.X509Extension
+com.android.org.bouncycastle.asn1.x509.X509Extensions
+com.android.org.bouncycastle.asn1.x509.X509Name
+com.android.org.bouncycastle.asn1.x509.X509NameElementList
+com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
+com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
+com.android.org.bouncycastle.crypto.Digest
+com.android.org.bouncycastle.crypto.ExtendedDigest
+com.android.org.bouncycastle.crypto.Mac
+com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
+com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
+com.android.org.bouncycastle.crypto.macs.HMac
+com.android.org.bouncycastle.jce.ProviderConfigurationPermission
+com.android.org.bouncycastle.jce.interfaces.BCKeyStore
+com.android.org.bouncycastle.jce.interfaces.ConfigurableProvider
+com.android.org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
+com.android.org.bouncycastle.jce.provider.BouncyCastleProvider$1
+com.android.org.bouncycastle.jce.provider.JDKKeyStore
+com.android.org.bouncycastle.jce.provider.JDKKeyStore$StoreEntry
+com.android.org.bouncycastle.jce.provider.JDKX509CertificateFactory
+com.android.org.bouncycastle.jce.provider.PEMUtil
+com.android.org.bouncycastle.jce.provider.PKCS12BagAttributeCarrierImpl
+com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
+com.android.org.bouncycastle.jce.provider.ProviderUtil
+com.android.org.bouncycastle.jce.provider.X509CertificateObject
+com.android.org.bouncycastle.jce.provider.asymmetric.ECMappings
+com.android.org.bouncycastle.jce.provider.symmetric.AESMappings
+com.android.org.bouncycastle.util.Strings
+com.android.org.bouncycastle.util.io.Streams
 org.xml.sax.Attributes
 org.xml.sax.ContentHandler
 org.xml.sax.Locator
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 21c1e81..0147b1a 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1356,14 +1356,27 @@
 
     public boolean switchToLastInputMethod(IBinder token) {
         synchronized (mMethodMap) {
-            Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
-            if (lastIme != null) {
-                InputMethodInfo imi = mMethodMap.get(lastIme.first);
-                if (imi != null) {
-                    setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode(
-                            imi, Integer.valueOf(lastIme.second)));
-                    return true;
+            final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
+            if (lastIme == null) return false;
+            final InputMethodInfo lastImi = mMethodMap.get(lastIme.first);
+            if (lastImi == null) return false;
+
+            final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId);
+            final int lastSubtypeHash = Integer.valueOf(lastIme.second);
+            // If the last IME is the same as the current IME and the last subtype is not defined,
+            // there is no need to switch to the last IME.
+            if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false;
+
+            int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
+                    : mCurrentSubtype.hashCode();
+            if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: "
+                            + mCurMethodId + ", " + currentSubtypeHash);
                 }
+                setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode(
+                        lastImi, lastSubtypeHash));
+                return true;
             }
             return false;
         }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 059c0b8..5806de2 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -2087,7 +2087,7 @@
                 return (List<ResolveInfo>) mActivities.queryIntentForPackage(intent,
                         resolvedType, flags, pkg.activities);
             }
-            return null;
+            return new ArrayList<ResolveInfo>();
         }
     }
 
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index dd9db9a..26c7e71 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -31,6 +31,7 @@
 import android.net.InterfaceConfiguration;
 import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
+import android.net.LinkProperties;
 import android.net.NetworkInfo;
 import android.os.Binder;
 import android.os.Environment;
@@ -1219,7 +1220,20 @@
             }
             protected String findActiveUpstreamIface() {
                 // check for what iface we can use - if none found switch to error.
-                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+                IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
+
+                try {
+                    LinkProperties defaultProp = cm.getActiveLinkProperties();
+                    if (defaultProp != null) {
+                        String iface = defaultProp.getInterfaceName();
+                        for(String regex : mUpstreamIfaceRegexs) {
+                            if (iface.matches(regex)) return iface;
+                        }
+                    }
+                } catch (RemoteException e) { }
+
+                b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
                 INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
 
                 String[] ifaces = new String[0];
@@ -1390,7 +1404,8 @@
                         }
                         break;
                     case CMD_UPSTREAM_CHANGED:
-                        mTryCell = WAIT_FOR_NETWORK_TO_SETTLE;
+                        // need to try DUN immediately if Wifi goes down
+                        mTryCell = !WAIT_FOR_NETWORK_TO_SETTLE;
                         chooseUpstreamType(mTryCell);
                         mTryCell = !mTryCell;
                         break;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 694af70..291ebc5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2170,8 +2170,6 @@
 
     GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
 
-    LOGD("screenshot: FBO created, status=0x%x", status);
-
     if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
 
         // invert everything, b/c glReadPixel() below will invert the FB
@@ -2187,8 +2185,6 @@
         glClearColor(0,0,0,1);
         glClear(GL_COLOR_BUFFER_BIT);
 
-        LOGD("screenshot: glClear() issued");
-
         const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
         const size_t count = layers.size();
         for (size_t i=0 ; i<count ; ++i) {
@@ -2199,8 +2195,6 @@
             }
         }
 
-        LOGD("screenshot: All layers rendered");
-
         // XXX: this is needed on tegra
         glScissor(0, 0, sw, sh);
 
@@ -2215,10 +2209,6 @@
                     new MemoryHeapBase(size, 0, "screen-capture") );
             void* const ptr = base->getBase();
             if (ptr) {
-
-                LOGD("screenshot: about to call glReadPixels(0,0,%d,%d,...,%p)",
-                        sw, sh, ptr);
-
                 // capture the screen with glReadPixels()
                 glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
                 if (glGetError() == GL_NO_ERROR) {
@@ -2231,9 +2221,6 @@
             } else {
                 result = NO_MEMORY;
             }
-
-            LOGD("screenshot: glReadPixels() returned %s", strerror(result));
-
         }
         glEnable(GL_SCISSOR_TEST);
         glViewport(0, 0, hw_w, hw_h);
@@ -2244,18 +2231,14 @@
         result = BAD_VALUE;
     }
 
-    LOGD("screenshot: about to release FBO resources");
-
     // release FBO resources
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
     glDeleteRenderbuffersOES(1, &tname);
     glDeleteFramebuffersOES(1, &name);
 
-    LOGD("screenshot: about to call compositionComplete()");
-
     hw.compositionComplete();
 
-    LOGD("screenshot: result = %s", strerror(result));
+    LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK");
 
     return result;
 }
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 719e5b4..43fae69 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -774,13 +774,23 @@
         boolean allLinesTaken = hasActiveCall && hasHoldingCall;
         Call.State fgCallState = getActiveFgCallState();
 
-        return (serviceState != ServiceState.STATE_POWER_OFF
+        boolean result = (serviceState != ServiceState.STATE_POWER_OFF
                 && !hasRingingCall
                 && !allLinesTaken
                 && ((fgCallState == Call.State.ACTIVE)
                     || (fgCallState == Call.State.IDLE)
                     || (fgCallState == Call.State.DISCONNECTED)));
-            }
+
+        if (result == false) {
+            Log.d(LOG_TAG, "canDial serviceState=" + serviceState
+                            + " hasRingingCall=" + hasRingingCall
+                            + " hasActiveCall=" + hasActiveCall
+                            + " hasHoldingCall=" + hasHoldingCall
+                            + " allLinesTaken=" + allLinesTaken
+                            + " fgCallState=" + fgCallState);
+        }
+        return result;
+    }
 
     /**
      * Whether or not the phone can do explicit call transfer in the current
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 61f8e1a..2895b69 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
     package="com.android.test.hwui">
 
     <uses-permission android:name="android.permission.INTERNET" />
-    <uses-sdk android:minSdkVersion="Honeycomb" />
+    <uses-sdk android:minSdkVersion="11" />
     
     <application
         android:label="HwUi"
diff --git a/tests/HwAccelerationTest/default.properties b/tests/HwAccelerationTest/default.properties
index 5a8ea50..da2dcdd 100644
--- a/tests/HwAccelerationTest/default.properties
+++ b/tests/HwAccelerationTest/default.properties
@@ -8,4 +8,4 @@
 # project structure.
 
 # Project target.
-target=android-Froyo
+target=android-Honeycomb