Merge "Import revised translations."
diff --git a/api/current.txt b/api/current.txt
index 52b28f5..f8b7bd9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4031,6 +4031,7 @@
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
     field public static final int PASSWORD_QUALITY_ALPHABETIC = 262144; // 0x40000
     field public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680; // 0x50000
+    field public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768; // 0x8000
     field public static final int PASSWORD_QUALITY_COMPLEX = 393216; // 0x60000
     field public static final int PASSWORD_QUALITY_NUMERIC = 131072; // 0x20000
     field public static final int PASSWORD_QUALITY_SOMETHING = 65536; // 0x10000
@@ -10683,7 +10684,6 @@
     method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
     method public void setScreenOnWhilePlaying(boolean);
     method public void setSurface(android.view.Surface);
-    method public void setTexture(android.graphics.SurfaceTexture);
     method public void setVolume(float, float);
     method public void setWakeMode(android.content.Context, int);
     method public void start() throws java.lang.IllegalStateException;
@@ -16775,7 +16775,7 @@
     field public static final android.net.Uri CONTENT_URI;
   }
 
-  public final class LiveFolders implements android.provider.BaseColumns {
+  public final deprecated class LiveFolders implements android.provider.BaseColumns {
     field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER";
     field public static final java.lang.String DESCRIPTION = "description";
     field public static final int DISPLAY_MODE_GRID = 1; // 0x1
@@ -19932,6 +19932,7 @@
     method public abstract int getTopPadding();
     method public final int getWidth();
     method public final void increaseWidthTo(int);
+    method public boolean isRtlCharAt(int);
     method protected final boolean isSpanned();
     field public static final int DIR_LEFT_TO_RIGHT = 1; // 0x1
     field public static final int DIR_RIGHT_TO_LEFT = -1; // 0xffffffff
@@ -23714,7 +23715,7 @@
     field public static final int FLAGS_CHANGED = 4; // 0x4
     field public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 1; // 0x1
     field public static final int FLAG_ALT_FOCUSABLE_IM = 131072; // 0x20000
-    field public static final int FLAG_BLUR_BEHIND = 4; // 0x4
+    field public static final deprecated int FLAG_BLUR_BEHIND = 4; // 0x4
     field public static final int FLAG_DIM_BEHIND = 2; // 0x2
     field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000
     field public static final int FLAG_DITHER = 4096; // 0x1000
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 31c5f8d..d2d66b6 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -351,7 +351,7 @@
     @Override
     public void start() {
         if (DBG) {
-            Log.d("ObjectAnimator", "Anim target, duration" + mTarget + ", " + getDuration());
+            Log.d("ObjectAnimator", "Anim target, duration: " + mTarget + ", " + getDuration());
             for (int i = 0; i < mValues.length; ++i) {
                 PropertyValuesHolder pvh = mValues[i];
                 ArrayList<Keyframe> keyframes = pvh.mKeyframeSet.mKeyframes;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8275cbd..2c2a493 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -372,6 +372,7 @@
         IInstrumentationWatcher instrumentationWatcher;
         int debugMode;
         boolean restrictedBackupMode;
+        boolean persistent;
         Configuration config;
         CompatibilityInfo compatInfo;
         boolean handlingProfiling;
@@ -644,9 +645,9 @@
                 ComponentName instrumentationName, String profileFile,
                 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
                 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
-                int debugMode, boolean isRestrictedBackupMode, Configuration config,
-                CompatibilityInfo compatInfo, Map<String, IBinder> services,
-                Bundle coreSettings) {
+                int debugMode, boolean isRestrictedBackupMode, boolean persistent,
+                Configuration config, CompatibilityInfo compatInfo,
+                Map<String, IBinder> services, Bundle coreSettings) {
 
             if (services != null) {
                 // Setup the service cache in the ServiceManager
@@ -666,6 +667,7 @@
             data.instrumentationWatcher = instrumentationWatcher;
             data.debugMode = debugMode;
             data.restrictedBackupMode = isRestrictedBackupMode;
+            data.persistent = persistent;
             data.config = config;
             data.compatInfo = compatInfo;
             queueOrSendMessage(H.BIND_APPLICATION, data);
@@ -3687,6 +3689,16 @@
         Process.setArgV0(data.processName);
         android.ddm.DdmHandleAppName.setAppName(data.processName);
 
+        if (data.persistent) {
+            // Persistent processes on low-memory devices do not get to
+            // use hardware accelerated drawing, since this can add too much
+            // overhead to the process.
+            Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
+            if (!ActivityManager.isHighEndGfx(display)) {
+                HardwareRenderer.disable(false);
+            }
+        }
+
         if (data.profileFd != null) {
             data.startProfiling();
         }
@@ -4242,7 +4254,7 @@
     }
 
     public static final ActivityThread systemMain() {
-        HardwareRenderer.disable();
+        HardwareRenderer.disable(true);
         ActivityThread thread = new ActivityThread();
         thread.attach(true);
         return thread;
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 0a6fdd4..cde06cd 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -267,13 +267,14 @@
             IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
             int testMode = data.readInt();
             boolean restrictedBackupMode = (data.readInt() != 0);
+            boolean persistent = (data.readInt() != 0);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
             CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
             HashMap<String, IBinder> services = data.readHashMap(null);
             Bundle coreSettings = data.readBundle();
             bindApplication(packageName, info,
                             providers, testName, profileName, profileFd, autoStopProfiler,
-                            testArgs, testWatcher, testMode, restrictedBackupMode,
+                            testArgs, testWatcher, testMode, restrictedBackupMode, persistent,
                             config, compatInfo, services, coreSettings);
             return true;
         }
@@ -811,8 +812,8 @@
     public final void bindApplication(String packageName, ApplicationInfo info,
             List<ProviderInfo> providers, ComponentName testName, String profileName,
             ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs,
-            IInstrumentationWatcher testWatcher, int debugMode,
-            boolean restrictedBackupMode, Configuration config, CompatibilityInfo compatInfo,
+            IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
+            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
             Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -837,6 +838,7 @@
         data.writeStrongInterface(testWatcher);
         data.writeInt(debugMode);
         data.writeInt(restrictedBackupMode ? 1 : 0);
+        data.writeInt(persistent ? 1 : 0);
         config.writeToParcel(data, 0);
         compatInfo.writeToParcel(data, 0);
         data.writeMap(services);
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 9ae5ab1..5d200b4 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -88,8 +88,8 @@
     static final int DEBUG_WAIT = 2;
     void bindApplication(String packageName, ApplicationInfo info, List<ProviderInfo> providers,
             ComponentName testName, String profileName, ParcelFileDescriptor profileFd,
-            boolean autoStopProfiler, Bundle testArguments,
-            IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
+            boolean autoStopProfiler, Bundle testArguments, IInstrumentationWatcher testWatcher,
+            int debugMode, boolean restrictedBackupMode, boolean persistent,
             Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
             Bundle coreSettings) throws RemoteException;
     void scheduleExit() throws RemoteException;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4147b0f..c89396b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -82,7 +82,7 @@
     /**
      * Activity action: send when any policy admin changes a policy.
      * This is generally used to find out when a new policy is in effect.
-     * 
+     *
      * @hide
      */
     public static final String ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
@@ -206,6 +206,14 @@
     public static final int PASSWORD_QUALITY_UNSPECIFIED = 0;
 
     /**
+     * Constant for {@link #setPasswordQuality}: the policy allows for low-security biometric
+     * recognition technology.  This implies technologies that can recognize the identity of
+     * an individual to about a 3 digit PIN (false detection is less than 1 in 1,000).
+     * Note that quality constants are ordered so that higher values are more restrictive.
+     */
+    public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 0x8000;
+
+    /**
      * Constant for {@link #setPasswordQuality}: the policy requires some kind
      * of password, but doesn't care what it is.  Note that quality constants
      * are ordered so that higher values are more restrictive.
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 316c474..48d0203 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -127,7 +127,7 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-            if (!device.equals(mDevice)) return;
+            if (device == null || !device.equals(mDevice)) return;
 
             if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
                 int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
index 98afdb8..b0c0a0b 100644
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ b/core/java/android/bluetooth/BluetoothProfileState.java
@@ -59,7 +59,9 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
+            if (device == null) {
+                return;
+            }
             if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
                 int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
                 if (mProfile == HFP && (newState == BluetoothProfile.STATE_CONNECTED ||
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 3cc6820..da878d4 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -20,7 +20,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 
-import java.util.HashMap;
+import java.util.WeakHashMap;
 
 /**
  * Manages NFC API's that are coupled to the life-cycle of an Activity.
@@ -38,7 +38,7 @@
     static final Boolean DBG = false;
 
     final NfcAdapter mAdapter;
-    final HashMap<Activity, NfcActivityState> mNfcState;  // contents protected by this
+    final WeakHashMap<Activity, NfcActivityState> mNfcState;  // contents protected by this
     final NfcEvent mDefaultEvent;  // can re-use one NfcEvent because it just contains adapter
 
     /**
@@ -60,7 +60,7 @@
 
     public NfcActivityManager(NfcAdapter adapter) {
         mAdapter = adapter;
-        mNfcState = new HashMap<Activity, NfcActivityState>();
+        mNfcState = new WeakHashMap<Activity, NfcActivityState>();
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
@@ -88,6 +88,13 @@
         }
     }
 
+    /**
+     * onDestroy hook from fragment attached to activity
+     */
+    public void onDestroy(Activity activity) {
+        mNfcState.remove(activity);
+    }
+
     public synchronized void setNdefPushMessage(Activity activity, NdefMessage message) {
         NfcActivityState state = getOrCreateState(activity, message != null);
         if (state == null || state.ndefMessage == message) {
@@ -214,4 +221,5 @@
             callback.onNdefPushComplete(mDefaultEvent);
         }
     }
+
 }
diff --git a/core/java/android/nfc/NfcFragment.java b/core/java/android/nfc/NfcFragment.java
index c48859b..17278dc 100644
--- a/core/java/android/nfc/NfcFragment.java
+++ b/core/java/android/nfc/NfcFragment.java
@@ -80,4 +80,14 @@
             sNfcActivityManager.onPause(getActivity());
         }
     }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (sNfcActivityManager != null) {
+            sNfcActivityManager.onDestroy(getActivity());
+        }
+    }
+
+
 }
diff --git a/core/java/android/provider/LiveFolders.java b/core/java/android/provider/LiveFolders.java
index 7856bab..cf8ad46 100644
--- a/core/java/android/provider/LiveFolders.java
+++ b/core/java/android/provider/LiveFolders.java
@@ -162,7 +162,17 @@
  *     </tr>
  *     </tbody>
  * </table>
+ * 
+ * @deprecated Live folders are no longer supported by Android.  These have been
+ * replaced by the new
+ * <a href="{@docRoot}guide/topics/appwidgets/index.html#collections">AppWidget Collection</a>
+ * APIs introduced in {@link android.os.Build.VERSION_CODES#HONEYCOMB}.  These provide
+ * all of the features of live folders plus many more.  The use of live folders is greatly
+ * discouraged because of security issues they introduce -- publishing a live folder requires
+ * making all data show for the live folder available to all applications with no
+ * permissions protecting it.
  */
+@Deprecated
 public final class LiveFolders implements BaseColumns {
     /**
      * <p>Content provider column.</p>
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index efdb79e..bc5994e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -42,6 +42,7 @@
 import android.text.TextUtils;
 import android.util.AndroidException;
 import android.util.Log;
+import android.view.WindowOrientationListener;
 
 import java.net.URISyntaxException;
 import java.util.HashMap;
@@ -59,7 +60,7 @@
      * <p>
      * Input: Nothing.
      * <p>
-     * Output: nothing.
+     * Output: Nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_SETTINGS = "android.settings.SETTINGS";
@@ -69,7 +70,7 @@
      * <p>
      * Input: Nothing.
      * <p>
-     * Output: nothing.
+     * Output: Nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_APN_SETTINGS = "android.settings.APN_SETTINGS";
@@ -328,6 +329,23 @@
             "android.settings.USER_DICTIONARY_SETTINGS";
 
     /**
+     * Activity Action: Adds a word to the user dictionary.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: An extra with key <code>word</code> that contains the word
+     * that should be added to the dictionary.
+     * <p>
+     * Output: Nothing.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_USER_DICTIONARY_INSERT =
+            "com.android.settings.USER_DICTIONARY_INSERT";
+
+    /**
      * Activity Action: Show settings to allow configuration of application-related settings.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -1462,6 +1480,7 @@
          * @hide
          * @deprecated
          */
+        @Deprecated
         public static final String NOTIFICATIONS_USE_RING_VOLUME =
             "notifications_use_ring_volume";
 
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 85a3bbb..ca7263c 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -499,11 +499,11 @@
             handleP(mSpannableStringBuilder);
         } else if (tag.equalsIgnoreCase("div")) {
             handleP(mSpannableStringBuilder);
-        } else if (tag.equalsIgnoreCase("em")) {
+        } else if (tag.equalsIgnoreCase("strong")) {
             end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD));
         } else if (tag.equalsIgnoreCase("b")) {
             end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD));
-        } else if (tag.equalsIgnoreCase("strong")) {
+        } else if (tag.equalsIgnoreCase("em")) {
             end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));
         } else if (tag.equalsIgnoreCase("cite")) {
             end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC));
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 768071f..bdfe940 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -673,6 +673,35 @@
         return false;
     }
 
+    /**
+     * Returns true if the character at offset is right to left (RTL).
+     * @param offset the offset
+     * @return true if the character is RTL, false if it is LTR
+     */
+    public boolean isRtlCharAt(int offset) {
+        int line = getLineForOffset(offset);
+        Directions dirs = getLineDirections(line);
+        if (dirs == DIRS_ALL_LEFT_TO_RIGHT) {
+            return false;
+        }
+        if (dirs == DIRS_ALL_RIGHT_TO_LEFT) {
+            return  true;
+        }
+        int[] runs = dirs.mDirections;
+        int lineStart = getLineStart(line);
+        for (int i = 0; i < runs.length; i += 2) {
+            int start = lineStart + (runs[i] & RUN_LENGTH_MASK);
+            // No need to test the end as an offset after the last run should return the value
+            // corresponding of the last run
+            if (offset >= start) {
+                int level = (runs[i+1] >>> RUN_LEVEL_SHIFT) & RUN_LEVEL_MASK;
+                return ((level & 1) != 0);
+            }
+        }
+        // Should happen only if the offset is "out of bounds"
+        return false;
+    }
+
     private boolean primaryIsTrailingPrevious(int offset) {
         int line = getLineForOffset(offset);
         int lineStart = getLineStart(line);
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 355d467..894afbd 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -750,7 +750,7 @@
                 case SUGGESTION_RANGE_SPAN:
                     readSpan(p, sp, new SuggestionRangeSpan(p));
                     break;
-                    
+
                 case EASY_EDIT_SPAN:
                     readSpan(p, sp, new EasyEditSpan());
                     break;
diff --git a/core/java/android/text/method/ArrowKeyMovementMethod.java b/core/java/android/text/method/ArrowKeyMovementMethod.java
index fe96565..b8728ee 100644
--- a/core/java/android/text/method/ArrowKeyMovementMethod.java
+++ b/core/java/android/text/method/ArrowKeyMovementMethod.java
@@ -232,8 +232,7 @@
 
         if (widget.isFocused() && !widget.didTouchFocusSelect()) {
             if (action == MotionEvent.ACTION_DOWN) {
-              boolean cap = isSelecting(buffer);
-              if (cap) {
+              if (isSelecting(buffer)) {
                   int offset = widget.getOffsetForPosition(event.getX(), event.getY());
 
                   buffer.setSpan(LAST_TAP_DOWN, offset, offset, Spannable.SPAN_POINT_POINT);
@@ -245,9 +244,7 @@
                   widget.getParent().requestDisallowInterceptTouchEvent(true);
               }
             } else if (action == MotionEvent.ACTION_MOVE) {
-                boolean cap = isSelecting(buffer);
-
-                if (cap && handled) {
+                if (isSelecting(buffer) && handled) {
                     // Before selecting, make sure we've moved out of the "slop".
                     // handled will be true, if we're in select mode AND we're
                     // OUT of the slop
@@ -279,7 +276,7 @@
                 if (isSelecting(buffer)) {
                     buffer.removeSpan(LAST_TAP_DOWN);
                     Selection.extendSelection(buffer, offset);
-                } else {
+                } else if (!widget.shouldIgnoreActionUpEvent()) {
                     Selection.setSelection(buffer, offset);
                 }
 
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index a528044..3f9b945 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -147,12 +147,10 @@
                     int nx = widget.getScrollX() + (int) dx;
                     int ny = widget.getScrollY() + (int) dy;
 
-                    int padding = widget.getTotalPaddingTop() +
-                                  widget.getTotalPaddingBottom();
+                    int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
                     Layout layout = widget.getLayout();
 
-                    ny = Math.min(ny, layout.getHeight() - (widget.getHeight() -
-                                                            padding));
+                    ny = Math.min(ny, layout.getHeight() - (widget.getHeight() - padding));
                     ny = Math.max(ny, 0);
         
                     int oldX = widget.getScrollX();
@@ -161,8 +159,7 @@
                     scrollTo(widget, layout, nx, ny);
 
                     // If we actually scrolled, then cancel the up action.
-                    if (oldX != widget.getScrollX()
-                            || oldY != widget.getScrollY()) {
+                    if (oldX != widget.getScrollX() || oldY != widget.getScrollY()) {
                         widget.cancelLongPress();
                     }
 
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 8625257..693a7a9 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -76,8 +76,11 @@
     private final String mNotificationTargetClassName;
     private final int mHashCode;
 
-    private float mUnderlineThickness;
-    private int mUnderlineColor;
+    private float mEasyCorrectUnderlineThickness;
+    private int mEasyCorrectUnderlineColor;
+
+    private float mMisspelledUnderlineThickness;
+    private int mMisspelledUnderlineColor;
 
     /*
      * TODO: If switching IME is required, needs to add parameters for ids of InputMethodInfo
@@ -132,25 +135,22 @@
     }
 
     private void initStyle(Context context) {
-        int defStyle = 0;
-        if ((getFlags() & FLAG_MISSPELLED) != 0) {
-            defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
-        } else if ((getFlags() & FLAG_EASY_CORRECT) != 0) {
-            defStyle = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
-        } else {
-            // No style is applied.
-            mUnderlineThickness = 0;
-            mUnderlineColor = 0;
-            return;
-        }
-
-        TypedArray typedArray = context.obtainStyledAttributes(null,
-                com.android.internal.R.styleable.SuggestionSpan,
-                defStyle, 0);
-
-        mUnderlineThickness = typedArray.getDimension(
+        int defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
+        TypedArray typedArray = context.obtainStyledAttributes(
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+        mMisspelledUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
-        mUnderlineColor = typedArray.getColor(
+        mMisspelledUnderlineColor = typedArray.getColor(
+                com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
+
+        defStyle = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
+
+        typedArray = context.obtainStyledAttributes(
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+
+        mEasyCorrectUnderlineThickness = typedArray.getDimension(
+                com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
+        mEasyCorrectUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
     }
 
@@ -160,8 +160,10 @@
         mLocaleString = src.readString();
         mNotificationTargetClassName = src.readString();
         mHashCode = src.readInt();
-        mUnderlineColor = src.readInt();
-        mUnderlineThickness = src.readFloat();
+        mEasyCorrectUnderlineColor = src.readInt();
+        mEasyCorrectUnderlineThickness = src.readFloat();
+        mMisspelledUnderlineColor = src.readInt();
+        mMisspelledUnderlineThickness = src.readFloat();
     }
 
     /**
@@ -211,8 +213,10 @@
         dest.writeString(mLocaleString);
         dest.writeString(mNotificationTargetClassName);
         dest.writeInt(mHashCode);
-        dest.writeInt(mUnderlineColor);
-        dest.writeFloat(mUnderlineThickness);
+        dest.writeInt(mEasyCorrectUnderlineColor);
+        dest.writeFloat(mEasyCorrectUnderlineThickness);
+        dest.writeInt(mMisspelledUnderlineColor);
+        dest.writeFloat(mMisspelledUnderlineThickness);
     }
 
     @Override
@@ -254,6 +258,10 @@
 
     @Override
     public void updateDrawState(TextPaint tp) {
-        tp.setUnderlineText(mUnderlineColor, mUnderlineThickness);
+        if ((mFlags & FLAG_MISSPELLED) != 0) {
+            tp.setUnderlineText(mMisspelledUnderlineColor, mMisspelledUnderlineThickness);
+        } else if ((mFlags & FLAG_EASY_CORRECT) != 0) {
+            tp.setUnderlineText(mEasyCorrectUnderlineColor, mEasyCorrectUnderlineThickness);
+        }
     }
 }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 1fcde3d..23d1b0f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -94,6 +94,13 @@
      */
     public static boolean sRendererDisabled = false;
 
+    /**
+     * Further hardware renderer disabling for the system process.
+     * 
+     * @hide
+     */
+    public static boolean sSystemRendererDisabled = false;
+
     private boolean mEnabled;
     private boolean mRequested = true;
 
@@ -102,8 +109,11 @@
      * 
      * @hide
      */
-    public static void disable() {
+    public static void disable(boolean system) {
         sRendererDisabled = true;
+        if (system) {
+            sSystemRendererDisabled = true;
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7db1b32..0d160a9 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -584,16 +584,25 @@
                 return;
             }
 
-            // Only enable hardware acceleration if we are not in the system process
-            // The window manager creates ViewAncestors to display animated preview windows
-            // of launching apps and we don't want those to be hardware accelerated
+            // Persistent processes (including the system) should not do
+            // accelerated rendering on low-end devices.  In that case,
+            // sRendererDisabled will be set.  In addition, the system process
+            // itself should never do accelerated rendering.  In that case, both
+            // sRendererDisabled and sSystemRendererDisabled are set.  When
+            // sSystemRendererDisabled is set, PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED
+            // can be used by code on the system process to escape that and enable
+            // HW accelerated drawing.  (This is basically for the lock screen.)
 
-            final boolean systemHwAccelerated =
-                (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM) != 0;
+            final boolean fakeHwAccelerated = (attrs.privateFlags &
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
+            final boolean forceHwAccelerated = (attrs.privateFlags &
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
 
-            if (!HardwareRenderer.sRendererDisabled || systemHwAccelerated) {
+            if (!HardwareRenderer.sRendererDisabled || (HardwareRenderer.sSystemRendererDisabled
+                    && forceHwAccelerated)) {
                 // Don't enable hardware acceleration when we're not on the main thread
-                if (!systemHwAccelerated && Looper.getMainLooper() != Looper.myLooper()) {
+                if (!HardwareRenderer.sSystemRendererDisabled
+                        && Looper.getMainLooper() != Looper.myLooper()) {
                     Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
                             + "acceleration outside of the main thread, aborting");
                     return;
@@ -606,12 +615,12 @@
                 mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
                 mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
                         = mAttachInfo.mHardwareRenderer != null;
-            } else {
-                // We would normally have enabled hardware acceleration, but
-                // haven't because we are in the system process.  We still want
-                // what is drawn on the screen to behave as if it is accelerated,
-                // so that our preview starting windows visually match what will
-                // actually be drawn by the app.
+            } else if (fakeHwAccelerated) {
+                // The window had wanted to use hardware acceleration, but this
+                // is not allowed in its process.  By setting this flag, it can
+                // still render as if it was accelerated.  This is basically for
+                // the preview windows the window manager shows for launching
+                // applications, so they will look more like the app being launched.
                 mAttachInfo.mHardwareAccelerationRequested = true;
             }
         }
@@ -1599,6 +1608,11 @@
                 }
             }
         } else {
+            // If we're not drawing, then we don't need to draw the transitions, either
+            if (mPendingTransitions != null) {
+                mPendingTransitions.clear();
+            }
+
             // We were supposed to report when we are done drawing. Since we canceled the
             // draw, remember it here.
             if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 52d25d9..fb31e7d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -412,12 +412,6 @@
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
-        
-        /**
-         * @deprecated this is ignored
-         */
-        @Deprecated
-        public int memoryType;
 
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
@@ -431,58 +425,12 @@
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
         public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;
-
+        
         /**
-         * Various behavioral options/flags.  Default is none.
-         * 
-         * @see #FLAG_BLUR_BEHIND
-         * @see #FLAG_DIM_BEHIND
-         * @see #FLAG_NOT_FOCUSABLE
-         * @see #FLAG_NOT_TOUCHABLE
-         * @see #FLAG_NOT_TOUCH_MODAL
-         * @see #FLAG_LAYOUT_IN_SCREEN
-         * @see #FLAG_DITHER
-         * @see #FLAG_KEEP_SCREEN_ON
-         * @see #FLAG_FULLSCREEN
-         * @see #FLAG_FORCE_NOT_FULLSCREEN
-         * @see #FLAG_IGNORE_CHEEK_PRESSES
-         * @see #FLAG_HARDWARE_ACCELERATED
+         * @deprecated this is ignored
          */
-        @ViewDebug.ExportedProperty(flagMapping = {
-            @ViewDebug.FlagToString(mask = FLAG_BLUR_BEHIND, equals = FLAG_BLUR_BEHIND,
-                    name = "FLAG_BLUR_BEHIND"),
-            @ViewDebug.FlagToString(mask = FLAG_DIM_BEHIND, equals = FLAG_DIM_BEHIND,
-                    name = "FLAG_DIM_BEHIND"),
-            @ViewDebug.FlagToString(mask = FLAG_NOT_FOCUSABLE, equals = FLAG_NOT_FOCUSABLE,
-                    name = "FLAG_NOT_FOCUSABLE"),
-            @ViewDebug.FlagToString(mask = FLAG_NOT_TOUCHABLE, equals = FLAG_NOT_TOUCHABLE,
-                    name = "FLAG_NOT_TOUCHABLE"),
-            @ViewDebug.FlagToString(mask = FLAG_NOT_TOUCH_MODAL, equals = FLAG_NOT_TOUCH_MODAL,
-                    name = "FLAG_NOT_TOUCH_MODAL"),
-            @ViewDebug.FlagToString(mask = FLAG_LAYOUT_IN_SCREEN, equals = FLAG_LAYOUT_IN_SCREEN,
-                    name = "FLAG_LAYOUT_IN_SCREEN"),
-            @ViewDebug.FlagToString(mask = FLAG_DITHER, equals = FLAG_DITHER,
-                    name = "FLAG_DITHER"),
-            @ViewDebug.FlagToString(mask = FLAG_TURN_SCREEN_ON, equals = FLAG_TURN_SCREEN_ON,
-                    name = "FLAG_TURN_SCREEN_ON"),
-            @ViewDebug.FlagToString(mask = FLAG_KEEP_SCREEN_ON, equals = FLAG_KEEP_SCREEN_ON,
-                    name = "FLAG_KEEP_SCREEN_ON"),
-            @ViewDebug.FlagToString(mask = FLAG_SHOW_WHEN_LOCKED, equals = FLAG_SHOW_WHEN_LOCKED,
-                    name = "FLAG_SHOW_WHEN_LOCKED"),
-            @ViewDebug.FlagToString(mask = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
-                    name = "FLAG_ALLOW_LOCK_WHILE_SCREEN_ON"),
-            @ViewDebug.FlagToString(mask = FLAG_DISMISS_KEYGUARD, equals = FLAG_DISMISS_KEYGUARD,
-                    name = "FLAG_DISMISS_KEYGUARD"),
-            @ViewDebug.FlagToString(mask = FLAG_FULLSCREEN, equals = FLAG_FULLSCREEN,
-                    name = "FLAG_FULLSCREEN"),
-            @ViewDebug.FlagToString(mask = FLAG_FORCE_NOT_FULLSCREEN,
-                    equals = FLAG_FORCE_NOT_FULLSCREEN, name = "FLAG_FORCE_NOT_FULLSCREEN"),
-            @ViewDebug.FlagToString(mask = FLAG_IGNORE_CHEEK_PRESSES,
-                    equals = FLAG_IGNORE_CHEEK_PRESSES, name = "FLAG_IGNORE_CHEEK_PRESSES"),
-            @ViewDebug.FlagToString(mask = FLAG_HARDWARE_ACCELERATED,
-                    equals = FLAG_HARDWARE_ACCELERATED, name = "FLAG_HARDWARE_ACCELERATED")
-        })
-        public int flags;
+        @Deprecated
+        public int memoryType;
         
         /** Window flag: as long as this window is visible to the user, allow
          *  the lock screen to activate while the screen is on. 
@@ -493,10 +441,12 @@
         /** Window flag: everything behind this window will be dimmed.
          *  Use {@link #dimAmount} to control the amount of dim. */
         public static final int FLAG_DIM_BEHIND        = 0x00000002;
-        
-        /** Window flag: blur everything behind this window. */
+
+        /** Window flag: blur everything behind this window.
+         * @deprecated Blurring is no longer supported. */
+        @Deprecated
         public static final int FLAG_BLUR_BEHIND        = 0x00000004;
-        
+
         /** Window flag: this window won't ever get key input focus, so the
          * user can not send key or other button events to it.  Those will
          * instead go to whatever focusable window is behind it.  This flag
@@ -686,17 +636,6 @@
          * XML attribute is set to true on an activity or on the application.</p>
          */
         public static final int FLAG_HARDWARE_ACCELERATED = 0x01000000;
-        
-        /**
-         * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
-         * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
-         * is generally disabled. This flag must be specified in addition to 
-         * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
-         * windows.
-         * 
-         * @hide
-         */
-        public static final int FLAG_HARDWARE_ACCELERATED_SYSTEM = 0x02000000;
 
         // ----- HIDDEN FLAGS.
         // These start at the high bit and go down.
@@ -747,6 +686,125 @@
         public static final int FLAG_SYSTEM_ERROR = 0x40000000;
 
         /**
+         * Various behavioral options/flags.  Default is none.
+         * 
+         * @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
+         * @see #FLAG_DIM_BEHIND
+         * @see #FLAG_NOT_FOCUSABLE
+         * @see #FLAG_NOT_TOUCHABLE
+         * @see #FLAG_NOT_TOUCH_MODAL
+         * @see #FLAG_TOUCHABLE_WHEN_WAKING
+         * @see #FLAG_KEEP_SCREEN_ON
+         * @see #FLAG_LAYOUT_IN_SCREEN
+         * @see #FLAG_LAYOUT_NO_LIMITS
+         * @see #FLAG_FULLSCREEN
+         * @see #FLAG_FORCE_NOT_FULLSCREEN
+         * @see #FLAG_DITHER
+         * @see #FLAG_SECURE
+         * @see #FLAG_SCALED
+         * @see #FLAG_IGNORE_CHEEK_PRESSES
+         * @see #FLAG_LAYOUT_INSET_DECOR
+         * @see #FLAG_ALT_FOCUSABLE_IM
+         * @see #FLAG_WATCH_OUTSIDE_TOUCH
+         * @see #FLAG_SHOW_WHEN_LOCKED
+         * @see #FLAG_SHOW_WALLPAPER
+         * @see #FLAG_TURN_SCREEN_ON
+         * @see #FLAG_DISMISS_KEYGUARD
+         * @see #FLAG_SPLIT_TOUCH
+         * @see #FLAG_HARDWARE_ACCELERATED
+         */
+        @ViewDebug.ExportedProperty(flagMapping = {
+            @ViewDebug.FlagToString(mask = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON, equals = FLAG_ALLOW_LOCK_WHILE_SCREEN_ON,
+                    name = "FLAG_ALLOW_LOCK_WHILE_SCREEN_ON"),
+            @ViewDebug.FlagToString(mask = FLAG_DIM_BEHIND, equals = FLAG_DIM_BEHIND,
+                    name = "FLAG_DIM_BEHIND"),
+            @ViewDebug.FlagToString(mask = FLAG_BLUR_BEHIND, equals = FLAG_BLUR_BEHIND,
+                    name = "FLAG_BLUR_BEHIND"),
+            @ViewDebug.FlagToString(mask = FLAG_NOT_FOCUSABLE, equals = FLAG_NOT_FOCUSABLE,
+                    name = "FLAG_NOT_FOCUSABLE"),
+            @ViewDebug.FlagToString(mask = FLAG_NOT_TOUCHABLE, equals = FLAG_NOT_TOUCHABLE,
+                    name = "FLAG_NOT_TOUCHABLE"),
+            @ViewDebug.FlagToString(mask = FLAG_NOT_TOUCH_MODAL, equals = FLAG_NOT_TOUCH_MODAL,
+                    name = "FLAG_NOT_TOUCH_MODAL"),
+            @ViewDebug.FlagToString(mask = FLAG_TOUCHABLE_WHEN_WAKING, equals = FLAG_TOUCHABLE_WHEN_WAKING,
+                    name = "FLAG_TOUCHABLE_WHEN_WAKING"),
+            @ViewDebug.FlagToString(mask = FLAG_KEEP_SCREEN_ON, equals = FLAG_KEEP_SCREEN_ON,
+                    name = "FLAG_KEEP_SCREEN_ON"),
+            @ViewDebug.FlagToString(mask = FLAG_LAYOUT_IN_SCREEN, equals = FLAG_LAYOUT_IN_SCREEN,
+                    name = "FLAG_LAYOUT_IN_SCREEN"),
+            @ViewDebug.FlagToString(mask = FLAG_LAYOUT_NO_LIMITS, equals = FLAG_LAYOUT_NO_LIMITS,
+                    name = "FLAG_LAYOUT_NO_LIMITS"),
+            @ViewDebug.FlagToString(mask = FLAG_FULLSCREEN, equals = FLAG_FULLSCREEN,
+                    name = "FLAG_FULLSCREEN"),
+            @ViewDebug.FlagToString(mask = FLAG_FORCE_NOT_FULLSCREEN, equals = FLAG_FORCE_NOT_FULLSCREEN,
+                    name = "FLAG_FORCE_NOT_FULLSCREEN"),
+            @ViewDebug.FlagToString(mask = FLAG_DITHER, equals = FLAG_DITHER,
+                    name = "FLAG_DITHER"),
+            @ViewDebug.FlagToString(mask = FLAG_SECURE, equals = FLAG_SECURE,
+                    name = "FLAG_SECURE"),
+            @ViewDebug.FlagToString(mask = FLAG_SCALED, equals = FLAG_SCALED,
+                    name = "FLAG_SCALED"),
+            @ViewDebug.FlagToString(mask = FLAG_IGNORE_CHEEK_PRESSES, equals = FLAG_IGNORE_CHEEK_PRESSES,
+                    name = "FLAG_IGNORE_CHEEK_PRESSES"),
+            @ViewDebug.FlagToString(mask = FLAG_LAYOUT_INSET_DECOR, equals = FLAG_LAYOUT_INSET_DECOR,
+                    name = "FLAG_LAYOUT_INSET_DECOR"),
+            @ViewDebug.FlagToString(mask = FLAG_ALT_FOCUSABLE_IM, equals = FLAG_ALT_FOCUSABLE_IM,
+                    name = "FLAG_ALT_FOCUSABLE_IM"),
+            @ViewDebug.FlagToString(mask = FLAG_WATCH_OUTSIDE_TOUCH, equals = FLAG_WATCH_OUTSIDE_TOUCH,
+                    name = "FLAG_WATCH_OUTSIDE_TOUCH"),
+            @ViewDebug.FlagToString(mask = FLAG_SHOW_WHEN_LOCKED, equals = FLAG_SHOW_WHEN_LOCKED,
+                    name = "FLAG_SHOW_WHEN_LOCKED"),
+            @ViewDebug.FlagToString(mask = FLAG_SHOW_WALLPAPER, equals = FLAG_SHOW_WALLPAPER,
+                    name = "FLAG_SHOW_WALLPAPER"),
+            @ViewDebug.FlagToString(mask = FLAG_TURN_SCREEN_ON, equals = FLAG_TURN_SCREEN_ON,
+                    name = "FLAG_TURN_SCREEN_ON"),
+            @ViewDebug.FlagToString(mask = FLAG_DISMISS_KEYGUARD, equals = FLAG_DISMISS_KEYGUARD,
+                    name = "FLAG_DISMISS_KEYGUARD"),
+            @ViewDebug.FlagToString(mask = FLAG_SPLIT_TOUCH, equals = FLAG_SPLIT_TOUCH,
+                    name = "FLAG_SPLIT_TOUCH"),
+            @ViewDebug.FlagToString(mask = FLAG_HARDWARE_ACCELERATED, equals = FLAG_HARDWARE_ACCELERATED,
+                    name = "FLAG_HARDWARE_ACCELERATED")
+        })
+        public int flags;
+
+        /**
+         * If the window has requested hardware acceleration, but this is not
+         * allowed in the process it is in, then still render it as if it is
+         * hardware accelerated.  This is used for the starting preview windows
+         * in the system process, which don't need to have the overhead of
+         * hardware acceleration (they are just a static rendering), but should
+         * be rendered as much to match the actual window of the app even if it
+         * is hardware accelerated.
+         * Even if the window isn't hardware accelerated, still do its rendering
+         * as if it is.
+         * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
+         * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
+         * is generally disabled. This flag must be specified in addition to 
+         * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
+         * windows.
+         * 
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
+
+        /**
+         * In the system process, we globally do not use hardware acceleration
+         * because there are many threads doing UI there and they an conflict.
+         * If certain parts of the UI that really do want to use hardware
+         * acceleration, this flag can be set to force it.  This is basically
+         * for the lock screen.  Anyone else using it, you are probably wrong.
+         * 
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
+
+        /**
+         * Control flags that are private to the platform.
+         * @hide
+         */
+        public int privateFlags;
+
+        /**
          * Given a particular set of window manager flags, determine whether
          * such a window may be a target for an input method when it has
          * focus.  In particular, this checks the
@@ -1110,6 +1168,7 @@
             out.writeInt(y);
             out.writeInt(type);
             out.writeInt(flags);
+            out.writeInt(privateFlags);
             out.writeInt(softInputMode);
             out.writeInt(gravity);
             out.writeFloat(horizontalMargin);
@@ -1149,6 +1208,7 @@
             y = in.readInt();
             type = in.readInt();
             flags = in.readInt();
+            privateFlags = in.readInt();
             softInputMode = in.readInt();
             gravity = in.readInt();
             horizontalMargin = in.readFloat();
@@ -1190,6 +1250,8 @@
         public static final int SYSTEM_UI_LISTENER_CHANGED = 1<<14;
         /** {@hide} */
         public static final int INPUT_FEATURES_CHANGED = 1<<15;
+        /** {@hide} */
+        public static final int PRIVATE_FLAGS_CHANGED = 1<<16;
     
         // internal buffer to backup/restore parameters under compatibility mode.
         private int[] mCompatibilityParamsBackup = null;
@@ -1237,6 +1299,10 @@
                 flags = o.flags;
                 changes |= FLAGS_CHANGED;
             }
+            if (privateFlags != o.privateFlags) {
+                privateFlags = o.privateFlags;
+                changes |= PRIVATE_FLAGS_CHANGED;
+            }
             if (softInputMode != o.softInputMode) {
                 softInputMode = o.softInputMode;
                 changes |= SOFT_INPUT_MODE_CHANGED;
@@ -1353,6 +1419,9 @@
             sb.append(type);
             sb.append(" fl=#");
             sb.append(Integer.toHexString(flags));
+            if (privateFlags != 0) {
+                sb.append(" pfl=0x").append(Integer.toHexString(privateFlags));
+            }
             if (format != PixelFormat.OPAQUE) {
                 sb.append(" fmt=");
                 sb.append(format);
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 0119d03..131f0ae 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -77,6 +77,8 @@
      */
     private final ArrayList<InputMethodSubtype> mSubtypes = new ArrayList<InputMethodSubtype>();
 
+    private boolean mIsAuxIme;
+
     /**
      * Constructor.
      *
@@ -104,6 +106,7 @@
         mService = service;
         ServiceInfo si = service.serviceInfo;
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
+        mIsAuxIme = true;
 
         PackageManager pm = context.getPackageManager();
         String settingsActivityComponent = null;
@@ -167,6 +170,9 @@
                                     .InputMethod_Subtype_isAuxiliary, false),
                             a.getBoolean(com.android.internal.R.styleable
                                     .InputMethod_Subtype_overridesImplicitlyEnabledSubtype, false));
+                    if (!subtype.isAuxiliary()) {
+                        mIsAuxIme = false;
+                    }
                     mSubtypes.add(subtype);
                 }
             }
@@ -177,6 +183,10 @@
             if (parser != null) parser.close();
         }
 
+        if (mSubtypes.size() == 0) {
+            mIsAuxIme = false;
+        }
+
         if (additionalSubtypesMap != null && additionalSubtypesMap.containsKey(mId)) {
             final List<InputMethodSubtype> additionalSubtypes = additionalSubtypesMap.get(mId);
             final int N = additionalSubtypes.size();
@@ -195,6 +205,7 @@
         mId = source.readString();
         mSettingsActivityName = source.readString();
         mIsDefaultResId = source.readInt();
+        mIsAuxIme = source.readInt() == 1;
         mService = ResolveInfo.CREATOR.createFromParcel(source);
         source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
     }
@@ -220,6 +231,7 @@
         mId = new ComponentName(si.packageName, si.name).flattenToShortString();
         mSettingsActivityName = settingsActivity;
         mIsDefaultResId = 0;
+        mIsAuxIme = false;
     }
 
     /**
@@ -361,15 +373,24 @@
     }
 
     /**
+     * @hide
+     */
+    public boolean isAuxiliaryIme() {
+        return mIsAuxIme;
+    }
+
+    /**
      * Used to package this object into a {@link Parcel}.
      * 
      * @param dest The {@link Parcel} to be written.
      * @param flags The flags used for parceling.
      */
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(mId);
         dest.writeString(mSettingsActivityName);
         dest.writeInt(mIsDefaultResId);
+        dest.writeInt(mIsAuxIme ? 1 : 0);
         mService.writeToParcel(dest, flags);
         dest.writeTypedList(mSubtypes);
     }
@@ -379,15 +400,18 @@
      */
     public static final Parcelable.Creator<InputMethodInfo> CREATOR
             = new Parcelable.Creator<InputMethodInfo>() {
+        @Override
         public InputMethodInfo createFromParcel(Parcel source) {
             return new InputMethodInfo(source);
         }
 
+        @Override
         public InputMethodInfo[] newArray(int size) {
             return new InputMethodInfo[size];
         }
     };
 
+    @Override
     public int describeContents() {
         return 0;
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 2e7f923..5bb0ef2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2346,6 +2346,14 @@
     }
 
     /**
+     * Return the reading level scale of the WebView
+     * @return The reading level scale.
+     */
+    /*package*/ float getReadingLevelScale() {
+        return mZoomManager.getReadingLevelScale();
+    }
+
+    /**
      * Set the initial scale for the WebView. 0 means default. If
      * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the
      * way. Otherwise it starts with 100%. If initial scale is greater than 0,
@@ -6538,6 +6546,13 @@
     }
 
     private void stopTouch() {
+        if (mScroller.isFinished() && !mSelectingText
+                && (mTouchMode == TOUCH_DRAG_MODE || mTouchMode == TOUCH_DRAG_LAYER_MODE)) {
+            WebViewCore.resumePriority();
+            WebViewCore.resumeUpdatePicture(mWebViewCore);
+            nativeSetIsScrolling(false);
+        }
+
         // we also use mVelocityTracker == null to tell us that we are
         // not "moving around", so we can take the slower/prettier
         // mode in the drawing code
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c895b84..c61bd48 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2460,7 +2460,7 @@
                     if (mSettings.isNarrowColumnLayout()) {
                         // In case of automatic text reflow in fixed view port mode.
                         mInitialViewState.mTextWrapScale =
-                                ZoomManager.computeReadingLevelScale(data.mScale);
+                                mWebView.getReadingLevelScale();
                     }
                 } else {
                     // Scale is given such as when page is restored, use it.
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 2bcb020..0bfb668 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -58,13 +58,6 @@
     private ZoomControlExternal mExternalZoomControl;
 
     /*
-     * For large screen devices, the defaultScale usually set to 1.0 and
-     * equal to the overview scale, to differentiate the zoom level for double tapping,
-     * a default reading level scale is used.
-     */
-    private static final float DEFAULT_READING_LEVEL_SCALE = 1.5f;
-
-    /*
      * The scale factors that determine the upper and lower bounds for the
      * default zoom scale.
      */
@@ -151,6 +144,19 @@
     private float mDefaultScale;
     private float mInvDefaultScale;
 
+    /*
+     * The scale factor that is used to determine the zoom level for reading text.
+     * The value is initially set to equal the display density.
+     * TODO: Support changing this in WebSettings
+     */
+    private float mReadingLevelScale;
+
+    /*
+     * The scale factor that is used as the minimum increment when going from
+     * overview to reading level on a double tap.
+     */
+    private static float MIN_DOUBLE_TAP_SCALE_INCREMENT = 0.5f;
+
     // the current computed zoom scale and its inverse.
     private float mActualScale;
     private float mInvActualScale;
@@ -230,6 +236,7 @@
         setDefaultZoomScale(density);
         mActualScale = density;
         mInvActualScale = 1 / density;
+        mReadingLevelScale = density;
         mTextWrapScale = density;
     }
 
@@ -304,13 +311,7 @@
     }
 
     public final float getReadingLevelScale() {
-        return computeScaleWithLimits(computeReadingLevelScale(getZoomOverviewScale()));
-    }
-
-    /* package */ final static float computeReadingLevelScale(float scale) {
-        // The reading scale is at least 0.5f apart from the input scale.
-        final float MIN_SCALE_DIFF = 0.5f;
-        return Math.max(scale + MIN_SCALE_DIFF, DEFAULT_READING_LEVEL_SCALE);
+        return mReadingLevelScale;
     }
 
     public final float getInvDefaultScale() {
@@ -652,7 +653,7 @@
         } else if (!mInZoomOverview && willScaleTriggerZoom(getZoomOverviewScale())) {
             zoomToOverview();
         } else {
-            zoomToReadingLevel();
+            zoomToReadingLevelOrMore();
         }
     }
 
@@ -683,8 +684,10 @@
             !mWebView.getSettings().getUseFixedViewport());
     }
 
-    private void zoomToReadingLevel() {
-        final float readingScale = getReadingLevelScale();
+    private void zoomToReadingLevelOrMore() {
+        final float zoomScale = Math.max(getReadingLevelScale(),
+                mActualScale + MIN_DOUBLE_TAP_SCALE_INCREMENT);
+
         int left = mWebView.nativeGetBlockLeftEdge(mAnchorX, mAnchorY, mActualScale);
         if (left != WebView.NO_LEFTEDGE) {
             // add a 5pt padding to the left edge.
@@ -693,13 +696,13 @@
             // Re-calculate the zoom center so that the new scroll x will be
             // on the left edge.
             if (viewLeft > 0) {
-                mZoomCenterX = viewLeft * readingScale / (readingScale - mActualScale);
+                mZoomCenterX = viewLeft * zoomScale / (zoomScale - mActualScale);
             } else {
                 mWebView.scrollBy(viewLeft, 0);
                 mZoomCenterX = 0;
             }
         }
-        startZoomAnimation(readingScale,
+        startZoomAnimation(zoomScale,
             !mWebView.getSettings().getUseFixedViewport());
     }
 
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 133f435..5a97317 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3384,11 +3384,11 @@
     protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
         super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
 
+        final ListAdapter adapter = mAdapter;
         int closetChildIndex = -1;
-        if (gainFocus && previouslyFocusedRect != null) {
+        if (adapter != null && gainFocus && previouslyFocusedRect != null) {
             previouslyFocusedRect.offset(mScrollX, mScrollY);
 
-            final ListAdapter adapter = mAdapter;
             // Don't cache the result of getChildCount or mFirstPosition here,
             // it could change in layoutChildren.
             if (adapter.getCount() < getChildCount() + mFirstPosition) {
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index b2c3051..e033d2d 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -933,9 +933,32 @@
         // onDraw will translate the canvas so we draw starting at 0,0
         int right = w - mPaddingRight - mPaddingLeft;
         int bottom = h - mPaddingBottom - mPaddingTop;
+        int top = 0;
+        int left = 0;
 
         if (mIndeterminateDrawable != null) {
-            mIndeterminateDrawable.setBounds(0, 0, right, bottom);
+            if (mOnlyIndeterminate) {
+                // Maintain aspect ratio. Certain kinds of animated drawables
+                // get very confused otherwise.
+                final int intrinsicWidth = mIndeterminateDrawable.getIntrinsicWidth();
+                final int intrinsicHeight = mIndeterminateDrawable.getIntrinsicHeight();
+                final float intrinsicAspect = (float) intrinsicWidth / intrinsicHeight;
+                final float boundAspect = (float) w / h;
+                if (intrinsicAspect != boundAspect) {
+                    if (boundAspect > intrinsicAspect) {
+                        // New width is larger. Make it smaller to match height.
+                        final int width = (int) (h * intrinsicAspect);
+                        left = (w - width) / 2;
+                        right = left + width;
+                    } else {
+                        // New height is larger. Make it smaller to match width.
+                        final int height = (int) (w * (1 / intrinsicAspect));
+                        top = (h - height) / 2;
+                        bottom = top + height;
+                    }
+                }
+            }
+            mIndeterminateDrawable.setBounds(left, top, right, bottom);
         }
         
         if (mProgressDrawable != null) {
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 4fcb358..02c9d03 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -161,6 +161,7 @@
         mMinFlingVelocity = config.getScaledMinimumFlingVelocity();
 
         // Refresh display with current params
+        refreshDrawableState();
         setChecked(isChecked());
     }
 
@@ -632,8 +633,9 @@
         int[] myDrawableState = getDrawableState();
 
         // Set the state of the Drawable
-        mThumbDrawable.setState(myDrawableState);
-        mTrackDrawable.setState(myDrawableState);
+        // Drawable may be null when checked state is set from XML, from super constructor
+        if (mThumbDrawable != null) mThumbDrawable.setState(myDrawableState);
+        if (mTrackDrawable != null) mTrackDrawable.setState(myDrawableState);
 
         invalidate();
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1aa009b..0f30734 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -21,6 +21,7 @@
 import android.content.ClipData.Item;
 import android.content.ClipboardManager;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -42,6 +43,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.text.BoringLayout;
 import android.text.DynamicLayout;
 import android.text.Editable;
@@ -8119,6 +8121,7 @@
                 Selection.setSelection((Spannable) mText, selStart, selEnd);
             } else {
                 hideControllers();
+                downgradeEasyCorrectionSpans();
             }
 
             // No need to create the controller
@@ -8243,10 +8246,10 @@
             return superResult;
         }
 
-        final boolean touchIsFinished = action == MotionEvent.ACTION_UP && !mIgnoreActionUpEvent &&
-                isFocused();
+        final boolean touchIsFinished = (action == MotionEvent.ACTION_UP) &&
+                !shouldIgnoreActionUpEvent() && isFocused();
 
-        if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
+         if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()
                 && mText instanceof Spannable && mLayout != null) {
             boolean handled = false;
 
@@ -8254,9 +8257,10 @@
                 handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);
             }
 
-            if (mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable && touchIsFinished) {
+            if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && mTextIsSelectable) {
                 // The LinkMovementMethod which should handle taps on links has not been installed
-                // to support text selection. We reproduce its behavior here to open links.
+                // on non editable text that support text selection.
+                // We reproduce its behavior here to open links for these.
                 ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),
                         getSelectionEnd(), ClickableSpan.class);
 
@@ -8266,7 +8270,7 @@
                 }
             }
 
-            if ((isTextEditable() || mTextIsSelectable) && touchIsFinished) {
+            if (touchIsFinished && (isTextEditable() || mTextIsSelectable)) {
                 // Show the IME, except when selecting in read-only text.
                 final InputMethodManager imm = InputMethodManager.peekInstance();
                 if (imm != null) {
@@ -8277,16 +8281,12 @@
                 }
 
                 boolean selectAllGotFocus = mSelectAllOnFocus && didTouchFocusSelect();
-                if (!selectAllGotFocus && hasSelection()) {
-                    startSelectionActionMode();
-                } else {
-                    hideControllers();
-                    if (!selectAllGotFocus && mText.length() > 0) {
-                        if (isCursorInsideEasyCorrectionSpan()) {
-                            showSuggestions();
-                        } else if (hasInsertionController()) {
-                            getInsertionController().show();
-                        }
+                hideControllers();
+                if (!selectAllGotFocus && mText.length() > 0) {
+                    if (isCursorInsideEasyCorrectionSpan()) {
+                        showSuggestions();
+                    } else if (hasInsertionController()) {
+                        getInsertionController().show();
                     }
                 }
 
@@ -8328,6 +8328,26 @@
         return false;
     }
 
+    /**
+     * Downgrades to simple suggestions all the easy correction spans that are not a spell check
+     * span.
+     */
+    private void downgradeEasyCorrectionSpans() {
+        if (mText instanceof Spannable) {
+            Spannable spannable = (Spannable) mText;
+            SuggestionSpan[] suggestionSpans = spannable.getSpans(0,
+                    spannable.length(), SuggestionSpan.class);
+            for (int i = 0; i < suggestionSpans.length; i++) {
+                int flags = suggestionSpans[i].getFlags();
+                if ((flags & SuggestionSpan.FLAG_EASY_CORRECT) != 0
+                        && (flags & SuggestionSpan.FLAG_MISSPELLED) == 0) {
+                    flags = flags & ~SuggestionSpan.FLAG_EASY_CORRECT;
+                    suggestionSpans[i].setFlags(flags);
+                }
+            }
+        }
+    }
+
     @Override
     public boolean onGenericMotionEvent(MotionEvent event) {
         if (mMovement != null && mText instanceof Spannable && mLayout != null) {
@@ -8398,7 +8418,18 @@
         super.cancelLongPress();
         mIgnoreActionUpEvent = true;
     }
-    
+
+    /**
+     * This method is only valid during a touch event.
+     *
+     * @return true when the ACTION_UP event should be ignored, false otherwise.
+     *
+     * @hide
+     */
+    public boolean shouldIgnoreActionUpEvent() {
+        return mIgnoreActionUpEvent;
+    }
+
     @Override
     public boolean onTrackballEvent(MotionEvent event) {
         if (mMovement != null && mText instanceof Spannable &&
@@ -9152,6 +9183,7 @@
                 startDrag(data, getTextThumbnailBuilder(selectedText), localState, 0);
                 stopSelectionActionMode();
             } else {
+                getSelectionController().hide();
                 selectCurrentWord();
                 getSelectionController().show();
             }
@@ -9199,7 +9231,8 @@
     }
 
     private interface TextViewPositionListener {
-        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified);
+        public void updatePosition(int parentPositionX, int parentPositionY,
+                boolean parentPositionChanged, boolean parentScrolled);
     }
 
     private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
@@ -9212,6 +9245,7 @@
         // Absolute position of the TextView with respect to its parent window
         private int mPositionX, mPositionY;
         private int mNumberOfListeners;
+        private boolean mScrollHasChanged;
 
         public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
             if (mNumberOfListeners == 0) {
@@ -9263,15 +9297,16 @@
             updatePosition();
 
             for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
-                if (mPositionHasChanged || mCanMove[i]) {
+                if (mPositionHasChanged || mScrollHasChanged || mCanMove[i]) {
                     TextViewPositionListener positionListener = mPositionListeners[i];
                     if (positionListener != null) {
                         positionListener.updatePosition(mPositionX, mPositionY,
-                                mPositionHasChanged);
+                                mPositionHasChanged, mScrollHasChanged);
                     }
                 }
             }
 
+            mScrollHasChanged = false;
             return true;
         }
 
@@ -9313,6 +9348,18 @@
             final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
             return isVisible(primaryHorizontal, lineBottom);
         }
+
+        public void onScrollChanged() {
+            mScrollHasChanged = true;
+        }
+    }
+
+    @Override
+    protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) {
+        super.onScrollChanged(horiz, vert, oldHoriz, oldVert);
+        if (mPositionListener != null) {
+            mPositionListener.onScrollChanged();
+        }
     }
 
     private abstract class PinnedPopupWindow implements TextViewPositionListener {
@@ -9343,7 +9390,7 @@
         }
 
         public void show() {
-            TextView.this.getPositionListener().addSubscriber(this, false);
+            TextView.this.getPositionListener().addSubscriber(this, false /* offset is fixed */);
 
             computeLocalPosition();
 
@@ -9402,8 +9449,11 @@
         }
 
         @Override
-        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
+        public void updatePosition(int parentPositionX, int parentPositionY,
+                boolean parentPositionChanged, boolean parentScrolled) {
+            // Either parentPositionChanged or parentScrolled is true, check if still visible
             if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
+                if (parentScrolled) computeLocalPosition();
                 updatePosition(parentPositionX, parentPositionY);
             } else {
                 hide();
@@ -9417,7 +9467,6 @@
 
     private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
         private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
-        private static final int NO_SUGGESTIONS = -1;
         private static final float AVERAGE_HIGHLIGHTS_PER_SUGGESTION = 1.4f;
         private WordIterator mSuggestionWordIterator;
         private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan
@@ -9472,9 +9521,9 @@
             listView.setOnItemClickListener(this);
             mContentView = listView;
 
-            // Inflate the suggestion items once and for all.
-            mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS];
-            for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
+            // Inflate the suggestion items once and for all. +1 for add to dictionary
+            mSuggestionInfos = new SuggestionInfo[MAX_NUMBER_SUGGESTIONS + 1];
+            for (int i = 0; i < MAX_NUMBER_SUGGESTIONS + 1; i++) {
                 mSuggestionInfos[i] = new SuggestionInfo();
             }
         }
@@ -9485,6 +9534,15 @@
             SuggestionSpan suggestionSpan; // the SuggestionSpan that this TextView represents
             int suggestionIndex; // the index of the suggestion inside suggestionSpan
             SpannableStringBuilder text = new SpannableStringBuilder();
+
+            void removeMisspelledFlag() {
+                int suggestionSpanFlags = suggestionSpan.getFlags();
+                if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
+                    suggestionSpanFlags &= ~(SuggestionSpan.FLAG_MISSPELLED);
+                    suggestionSpanFlags &= ~(SuggestionSpan.FLAG_EASY_CORRECT);
+                    suggestionSpan.setFlags(suggestionSpanFlags);
+                }
+            }
         }
 
         private class SuggestionAdapter extends BaseAdapter {
@@ -9623,6 +9681,8 @@
             int spanUnionStart = mText.length();
             int spanUnionEnd = 0;
 
+            SuggestionSpan misspelledSpan = null;
+
             for (int spanIndex = 0; spanIndex < nbSpans; spanIndex++) {
                 SuggestionSpan suggestionSpan = suggestionSpans[spanIndex];
                 final int spanStart = spannable.getSpanStart(suggestionSpan);
@@ -9630,6 +9690,10 @@
                 spanUnionStart = Math.min(spanStart, spanUnionStart);
                 spanUnionEnd = Math.max(spanEnd, spanUnionEnd);
 
+                if ((suggestionSpan.getFlags() & SuggestionSpan.FLAG_MISSPELLED) != 0) {
+                    misspelledSpan = suggestionSpan;
+                }
+
                 String[] suggestions = suggestionSpan.getSuggestions();
                 int nbSuggestions = suggestions.length;
                 for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
@@ -9638,7 +9702,8 @@
                     suggestionInfo.spanEnd = spanEnd;
                     suggestionInfo.suggestionSpan = suggestionSpan;
                     suggestionInfo.suggestionIndex = suggestionIndex;
-                    suggestionInfo.text = new SpannableStringBuilder(suggestions[suggestionIndex]);
+                    suggestionInfo.text.replace(0, suggestionInfo.text.length(),
+                            suggestions[suggestionIndex]);
 
                     mNumberOfSuggestions++;
                     if (mNumberOfSuggestions == MAX_NUMBER_SUGGESTIONS) {
@@ -9649,41 +9714,38 @@
                 }
             }
 
+            for (int i = 0; i < mNumberOfSuggestions; i++) {
+                highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
+            }
+
+            if (misspelledSpan != null) {
+                final int misspelledStart = spannable.getSpanStart(misspelledSpan);
+                final int misspelledEnd = spannable.getSpanEnd(misspelledSpan);
+                if (misspelledStart >= 0 && misspelledEnd > misspelledStart) {
+                    SuggestionInfo suggestionInfo = mSuggestionInfos[mNumberOfSuggestions];
+                    suggestionInfo.spanStart = misspelledStart;
+                    suggestionInfo.spanEnd = misspelledEnd;
+                    suggestionInfo.suggestionSpan = misspelledSpan;
+                    suggestionInfo.suggestionIndex = -1;
+                    suggestionInfo.text.replace(0, suggestionInfo.text.length(),
+                            getContext().getString(com.android.internal.R.string.addToDictionary));
+
+                    mNumberOfSuggestions++;
+                }
+            }
+
             if (mNumberOfSuggestions == 0) return false;
 
             if (mSuggestionRangeSpan == null) mSuggestionRangeSpan =
                     new SuggestionRangeSpan(mHighlightColor);
-
             ((Editable) mText).setSpan(mSuggestionRangeSpan, spanUnionStart, spanUnionEnd,
                     Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
-            for (int i = 0; i < mNumberOfSuggestions; i++) {
-                highlightTextDifferences(mSuggestionInfos[i], spanUnionStart, spanUnionEnd);
-            }
             mSuggestionsAdapter.notifyDataSetChanged();
 
             return true;
         }
 
-        private void onDictionarySuggestionsReceived(String[] suggestions) {
-            if (suggestions.length == 0) {
-                // TODO Actual implementation of this feature
-                suggestions = new String[] {"Add to dictionary"};
-            }
-
-            WordIterator wordIterator = getWordIterator();
-            wordIterator.setCharSequence(mText);
-
-            final int pos = getSelectionStart();
-            int wordStart = wordIterator.getBeginning(pos);
-            int wordEnd = wordIterator.getEnd(pos);
-
-            SuggestionSpan suggestionSpan = new SuggestionSpan(getContext(), suggestions, 0);
-            ((Editable) mText).setSpan(suggestionSpan, wordStart, wordEnd,
-                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            show();
-        }
-
         private long[] getWordLimits(CharSequence text) {
             // TODO locale for mSuggestionWordIterator
             if (mSuggestionWordIterator == null) mSuggestionWordIterator = new WordIterator();
@@ -9836,10 +9898,19 @@
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
             if (view instanceof TextView) {
                 TextView textView = (TextView) view;
+
                 SuggestionInfo suggestionInfo = mSuggestionInfos[position];
                 final int spanStart = suggestionInfo.spanStart;
                 final int spanEnd = suggestionInfo.spanEnd;
-                if (spanStart != NO_SUGGESTIONS) {
+                final String originalText = mText.subSequence(spanStart, spanEnd).toString();
+
+                if (suggestionInfo.suggestionIndex < 0) {
+                    Intent intent = new Intent(Settings.ACTION_USER_DICTIONARY_INSERT);
+                    intent.putExtra("word", originalText);
+                    intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
+                    getContext().startActivity(intent);
+                    suggestionInfo.removeMisspelledFlag();
+                } else {
                     // SuggestionSpans are removed by replace: save them before
                     Editable editable = (Editable) mText;
                     SuggestionSpan[] suggestionSpans = editable.getSpans(spanStart, spanEnd,
@@ -9859,17 +9930,9 @@
                     final int suggestionEnd = suggestionInfo.suggestionEnd;
                     final String suggestion = textView.getText().subSequence(
                             suggestionStart, suggestionEnd).toString();
-                    final String originalText = mText.subSequence(spanStart, spanEnd).toString();
                     editable.replace(spanStart, spanEnd, suggestion);
 
-                    // A replacement on a misspelled text removes the misspelled flag.
-                    // TODO restore the flag if the misspelled word is selected back?
-                    int suggestionSpanFlags = suggestionInfo.suggestionSpan.getFlags();
-                    if ((suggestionSpanFlags & SuggestionSpan.FLAG_MISSPELLED) > 0) {
-                        suggestionSpanFlags &= ~(SuggestionSpan.FLAG_MISSPELLED);
-                        suggestionSpanFlags &= ~(SuggestionSpan.FLAG_EASY_CORRECT);
-                        suggestionInfo.suggestionSpan.setFlags(suggestionSpanFlags);
-                    }
+                    suggestionInfo.removeMisspelledFlag();
 
                     // Notify source IME of the suggestion pick. Do this before swaping texts.
                     if (!TextUtils.isEmpty(
@@ -9916,12 +9979,6 @@
         return mSuggestionsPopupWindow != null && mSuggestionsPopupWindow.isShowing();
     }
 
-    void onDictionarySuggestionsReceived(String[] suggestions) {
-        if (mSuggestionsPopupWindow != null) {
-            mSuggestionsPopupWindow.onDictionarySuggestionsReceived(suggestions);
-        }
-    }
-
     /**
      * Return whether or not suggestions are enabled on this TextView. The suggestions are generated
      * by the IME or by the spell checker as the user types. This is done by adding
@@ -10276,6 +10333,8 @@
 
     private abstract class HandleView extends View implements TextViewPositionListener {
         protected Drawable mDrawable;
+        protected Drawable mDrawableLtr;
+        protected Drawable mDrawableRtl;
         private final PopupWindow mContainer;
         // Position with respect to the parent TextView
         private int mPositionX, mPositionY;
@@ -10298,7 +10357,7 @@
         // Used to delay the appearance of the action popup window
         private Runnable mActionPopupShower;
 
-        public HandleView() {
+        public HandleView(Drawable drawableLtr, Drawable drawableRtl) {
             super(TextView.this.mContext);
             mContainer = new PopupWindow(TextView.this.mContext, null,
                     com.android.internal.R.attr.textSelectHandleWindowStyle);
@@ -10307,14 +10366,24 @@
             mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
             mContainer.setContentView(this);
 
-            initDrawable();
+            mDrawableLtr = drawableLtr;
+            mDrawableRtl = drawableRtl;
+
+            updateDrawable();
 
             final int handleHeight = mDrawable.getIntrinsicHeight();
             mTouchOffsetY = -0.3f * handleHeight;
             mIdealVerticalOffset = 0.7f * handleHeight;
         }
 
-        protected abstract void initDrawable();
+        protected void updateDrawable() {
+            final int offset = getCurrentCursorOffset();
+            final boolean isRtlCharAtOffset = mLayout.isRtlCharAt(offset);
+            mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
+            mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
+        }
+
+        protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun);
 
         // Touch-up filter: number of previous positions remembered
         private static final int HISTORY_SIZE = 5;
@@ -10349,7 +10418,7 @@
 
             if (i > 0 && i < iMax &&
                     (now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
-                positionAtCursorOffset(mPreviousOffsets[index]);
+                positionAtCursorOffset(mPreviousOffsets[index], false);
             }
         }
 
@@ -10365,11 +10434,11 @@
         public void show() {
             if (isShowing()) return;
 
-            getPositionListener().addSubscriber(this, true);
+            getPositionListener().addSubscriber(this, true /* local position may change */);
 
             // Make sure the offset is always considered new, even when focusing at same position
             mPreviousOffset = -1;
-            positionAtCursorOffset(getCurrentCursorOffset());
+            positionAtCursorOffset(getCurrentCursorOffset(), false);
 
             hideActionPopupWindow();
         }
@@ -10430,11 +10499,13 @@
 
         public abstract int getCurrentCursorOffset();
 
-        public abstract void updateSelection(int offset);
+        protected void updateSelection(int offset) {
+            updateDrawable();
+        }
 
         public abstract void updatePosition(float x, float y);
 
-        protected void positionAtCursorOffset(int offset) {
+        protected void positionAtCursorOffset(int offset, boolean parentScrolled) {
             // A HandleView relies on the layout, which may be nulled by external methods
             if (mLayout == null) {
                 // Will update controllers' state, hiding them and stopping selection mode if needed
@@ -10442,7 +10513,7 @@
                 return;
             }
 
-            if (offset != mPreviousOffset) {
+            if (offset != mPreviousOffset || parentScrolled) {
                 updateSelection(offset);
                 addPositionToTouchUpFilter(offset);
                 final int line = mLayout.getLineForOffset(offset);
@@ -10459,9 +10530,10 @@
             }
         }
 
-        public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
-            positionAtCursorOffset(getCurrentCursorOffset());
-            if (modified || mPositionHasChanged) {
+        public void updatePosition(int parentPositionX, int parentPositionY,
+                boolean parentPositionChanged, boolean parentScrolled) {
+            positionAtCursorOffset(getCurrentCursorOffset(), parentScrolled);
+            if (parentPositionChanged || mPositionHasChanged) {
                 if (mIsDragging) {
                     // Update touchToWindow offset in case of parent scrolling while dragging
                     if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
@@ -10571,6 +10643,10 @@
         private float mDownPositionX, mDownPositionY;
         private Runnable mHider;
 
+        public InsertionHandleView(Drawable drawable) {
+            super(drawable, drawable);
+        }
+
         @Override
         public void show() {
             super.show();
@@ -10607,13 +10683,8 @@
         }
 
         @Override
-        protected void initDrawable() {
-            if (mSelectHandleCenter == null) {
-                mSelectHandleCenter = mContext.getResources().getDrawable(
-                        mTextSelectHandleRes);
-            }
-            mDrawable = mSelectHandleCenter;
-            mHotspotX = mDrawable.getIntrinsicWidth() / 2;
+        protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
+            return drawable.getIntrinsicWidth() / 2;
         }
 
         @Override
@@ -10666,7 +10737,7 @@
 
         @Override
         public void updatePosition(float x, float y) {
-            positionAtCursorOffset(getOffsetForPosition(x, y));
+            positionAtCursorOffset(getOffsetForPosition(x, y), false);
         }
 
         @Override
@@ -10683,14 +10754,18 @@
     }
 
     private class SelectionStartHandleView extends HandleView {
+
+        public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
+            super(drawableLtr, drawableRtl);
+        }
+
         @Override
-        protected void initDrawable() {
-            if (mSelectHandleLeft == null) {
-                mSelectHandleLeft = mContext.getResources().getDrawable(
-                        mTextSelectHandleLeftRes);
+        protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
+            if (isRtlRun) {
+                return drawable.getIntrinsicWidth() / 4;
+            } else {
+                return (drawable.getIntrinsicWidth() * 3) / 4;
             }
-            mDrawable = mSelectHandleLeft;
-            mHotspotX = (mDrawable.getIntrinsicWidth() * 3) / 4;
         }
 
         @Override
@@ -10700,22 +10775,19 @@
 
         @Override
         public void updateSelection(int offset) {
+            super.updateSelection(offset);
             Selection.setSelection((Spannable) mText, offset, getSelectionEnd());
         }
 
         @Override
         public void updatePosition(float x, float y) {
-            final int selectionStart = getSelectionStart();
-            final int selectionEnd = getSelectionEnd();
-
             int offset = getOffsetForPosition(x, y);
 
-            // No need to redraw when the offset is unchanged
-            if (offset == selectionStart) return;
             // Handles can not cross and selection is at least one character
+            final int selectionEnd = getSelectionEnd();
             if (offset >= selectionEnd) offset = selectionEnd - 1;
 
-            positionAtCursorOffset(offset);
+            positionAtCursorOffset(offset, false);
         }
 
         public ActionPopupWindow getActionPopupWindow() {
@@ -10724,14 +10796,18 @@
     }
 
     private class SelectionEndHandleView extends HandleView {
+
+        public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
+            super(drawableLtr, drawableRtl);
+        }
+
         @Override
-        protected void initDrawable() {
-            if (mSelectHandleRight == null) {
-                mSelectHandleRight = mContext.getResources().getDrawable(
-                        mTextSelectHandleRightRes);
+        protected int getHotspotX(Drawable drawable, boolean isRtlRun) {
+            if (isRtlRun) {
+                return (drawable.getIntrinsicWidth() * 3) / 4;
+            } else {
+                return drawable.getIntrinsicWidth() / 4;
             }
-            mDrawable = mSelectHandleRight;
-            mHotspotX = mDrawable.getIntrinsicWidth() / 4;
         }
 
         @Override
@@ -10741,22 +10817,19 @@
 
         @Override
         public void updateSelection(int offset) {
+            super.updateSelection(offset);
             Selection.setSelection((Spannable) mText, getSelectionStart(), offset);
         }
 
         @Override
         public void updatePosition(float x, float y) {
-            final int selectionStart = getSelectionStart();
-            final int selectionEnd = getSelectionEnd();
-
             int offset = getOffsetForPosition(x, y);
 
-            // No need to redraw when the offset is unchanged
-            if (offset == selectionEnd) return;
             // Handles can not cross and selection is at least one character
+            final int selectionStart = getSelectionStart();
             if (offset <= selectionStart) offset = selectionStart + 1;
 
-            positionAtCursorOffset(offset);
+            positionAtCursorOffset(offset, false);
         }
 
         public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
@@ -10814,8 +10887,12 @@
         }
 
         private InsertionHandleView getHandle() {
+            if (mSelectHandleCenter == null) {
+                mSelectHandleCenter = mContext.getResources().getDrawable(
+                        mTextSelectHandleRes);
+            }
             if (mHandle == null) {
-                mHandle = new InsertionHandleView();
+                mHandle = new InsertionHandleView(mSelectHandleCenter);
             }
             return mHandle;
         }
@@ -10849,10 +10926,30 @@
             if (isInBatchEditMode()) {
                 return;
             }
+            initDrawables();
+            initHandles();
+            hideInsertionPointCursorController();
+        }
 
+        private void initDrawables() {
+            if (mSelectHandleLeft == null) {
+                mSelectHandleLeft = mContext.getResources().getDrawable(
+                        mTextSelectHandleLeftRes);
+            }
+            if (mSelectHandleRight == null) {
+                mSelectHandleRight = mContext.getResources().getDrawable(
+                        mTextSelectHandleRightRes);
+            }
+        }
+
+        private void initHandles() {
             // Lazy object creation has to be done before updatePosition() is called.
-            if (mStartHandle == null) mStartHandle = new SelectionStartHandleView();
-            if (mEndHandle == null) mEndHandle = new SelectionEndHandleView();
+            if (mStartHandle == null) {
+                mStartHandle = new SelectionStartHandleView(mSelectHandleLeft, mSelectHandleRight);
+            }
+            if (mEndHandle == null) {
+                mEndHandle = new SelectionEndHandleView(mSelectHandleRight, mSelectHandleLeft);
+            }
 
             mStartHandle.show();
             mEndHandle.show();
diff --git a/core/java/com/android/internal/widget/LockScreenWidgetInterface.java b/core/java/com/android/internal/widget/LockScreenWidgetInterface.java
index 6dfcc75..8f80cfc 100644
--- a/core/java/com/android/internal/widget/LockScreenWidgetInterface.java
+++ b/core/java/com/android/internal/widget/LockScreenWidgetInterface.java
@@ -20,4 +20,6 @@
 
     public void setCallback(LockScreenWidgetCallback callback);
 
+    public boolean providesClock();
+
 }
diff --git a/core/java/com/android/internal/widget/TransportControlView.java b/core/java/com/android/internal/widget/TransportControlView.java
index 1c47ca88a..29ad15b 100644
--- a/core/java/com/android/internal/widget/TransportControlView.java
+++ b/core/java/com/android/internal/widget/TransportControlView.java
@@ -381,4 +381,8 @@
         mWidgetCallbacks = callback;
     }
 
+    public boolean providesClock() {
+        return false;
+    }
+
 }
diff --git a/core/res/res/layout/simple_list_item_2_single_choice.xml b/core/res/res/layout/simple_list_item_2_single_choice.xml
new file mode 100644
index 0000000..90dfe37
--- /dev/null
+++ b/core/res/res/layout/simple_list_item_2_single_choice.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:gravity="center_vertical"
+    android:paddingLeft="16dip"
+    android:paddingRight="12dip"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall">
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:gravity="center_vertical">
+        <TextView android:id="@android:id/text1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textColor="?android:attr/textColorAlertDialogListItem"
+            android:gravity="center_vertical|left"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+        />
+        <TextView android:id="@android:id/text2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorAlertDialogListItem"
+            android:gravity="center_vertical|left"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+        />
+    </LinearLayout>
+    <RadioButton
+        android:id="@+id/radio"
+        android:layout_width="35dip"
+        android:layout_height="wrap_content"
+        android:paddingRight="12dip"
+        android:gravity="center_vertical"
+        android:focusable="false"
+        android:clickable="false"
+    />
+</LinearLayout>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 685ebb7..5e010fe 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2484,6 +2484,9 @@
     <!-- Text selection contextual mode title, displayed in the CAB. [CHAR LIMIT=20] -->
     <string name="textSelectionCABTitle">Text selection</string>
 
+    <!-- Option to add the current misspelled word to the user dictionary. [CHAR LIMIT=25] -->
+    <string name="addToDictionary">+ add to dictionary</string>
+
     <!-- EditText context menu -->
     <string name="inputMethod">Input method</string>
 
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 1bee47a..e468558 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -46,6 +46,16 @@
     </family>
     <family>
         <fileset>
+            <file>DroidSansArmenian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
+            <file>DroidSansGeorgian.ttf</file>
+        </fileset>
+    </family>
+    <family>
+        <fileset>
             <file>Lohit_Hindi.ttf</file>
         </fileset>
     </family>
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 56bd2ce..5bac8f0 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -31,6 +31,8 @@
     frameworks/base/data/fonts/DroidSerif-BoldItalic.ttf:system/fonts/DroidSerif-BoldItalic.ttf \
     frameworks/base/data/fonts/DroidSansMono.ttf:system/fonts/DroidSansMono.ttf \
     frameworks/base/data/fonts/Lohit_Hindi.ttf:system/fonts/Lohit_Hindi.ttf \
+    frameworks/base/data/fonts/DroidSansArmenian.ttf:system/fonts/DroidSansArmenian.ttf \
+    frameworks/base/data/fonts/DroidSansGeorgian.ttf:system/fonts/DroidSansGeorgian.ttf \
     frameworks/base/data/fonts/Clockopia.ttf:system/fonts/Clockopia.ttf \
     frameworks/base/data/fonts/AndroidClock.ttf:system/fonts/AndroidClock.ttf \
     frameworks/base/data/fonts/AndroidClock_Highlight.ttf:system/fonts/AndroidClock_Highlight.ttf \
diff --git a/data/sounds/alarms/wav/Copernicium.wav b/data/sounds/alarms/wav/Copernicium.wav
new file mode 100644
index 0000000..935ea75
--- /dev/null
+++ b/data/sounds/alarms/wav/Copernicium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Curium.wav b/data/sounds/alarms/wav/Curium.wav
new file mode 100644
index 0000000..a9942d3
--- /dev/null
+++ b/data/sounds/alarms/wav/Curium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Fermium.wav b/data/sounds/alarms/wav/Fermium.wav
new file mode 100644
index 0000000..0174884
--- /dev/null
+++ b/data/sounds/alarms/wav/Fermium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Hassium.wav b/data/sounds/alarms/wav/Hassium.wav
new file mode 100644
index 0000000..e3992cf
--- /dev/null
+++ b/data/sounds/alarms/wav/Hassium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Neptunium.wav b/data/sounds/alarms/wav/Neptunium.wav
new file mode 100644
index 0000000..cf3684a
--- /dev/null
+++ b/data/sounds/alarms/wav/Neptunium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Nobelium.wav b/data/sounds/alarms/wav/Nobelium.wav
new file mode 100644
index 0000000..0e9101a
--- /dev/null
+++ b/data/sounds/alarms/wav/Nobelium.wav
Binary files differ
diff --git a/data/sounds/effects/wav/CameraClick.wav b/data/sounds/effects/wav/CameraClick.wav
new file mode 100644
index 0000000..9fe75f2
--- /dev/null
+++ b/data/sounds/effects/wav/CameraClick.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Dock.wav b/data/sounds/effects/wav/Dock.wav
index 7fa6a7e..7ec64a8 100644
--- a/data/sounds/effects/wav/Dock.wav
+++ b/data/sounds/effects/wav/Dock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressDelete_14.wav b/data/sounds/effects/wav/KeypressDelete_14.wav
new file mode 100644
index 0000000..1d3498e
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressDelete_14.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressDelete_49.wav b/data/sounds/effects/wav/KeypressDelete_49.wav
new file mode 100644
index 0000000..2404759
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressDelete_49.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressReturn_14.wav b/data/sounds/effects/wav/KeypressReturn_14.wav
new file mode 100644
index 0000000..01573ff
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressReturn_14.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressReturn_49.wav b/data/sounds/effects/wav/KeypressReturn_49.wav
new file mode 100644
index 0000000..6bf216f
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressReturn_49.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressSpacebar_14.wav b/data/sounds/effects/wav/KeypressSpacebar_14.wav
new file mode 100644
index 0000000..77269a6
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressSpacebar_14.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressSpacebar_49.wav b/data/sounds/effects/wav/KeypressSpacebar_49.wav
new file mode 100644
index 0000000..8504a25
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressSpacebar_49.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressStandard_14.wav b/data/sounds/effects/wav/KeypressStandard_14.wav
new file mode 100644
index 0000000..93389ac
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressStandard_14.wav
Binary files differ
diff --git a/data/sounds/effects/wav/KeypressStandard_49.wav b/data/sounds/effects/wav/KeypressStandard_49.wav
new file mode 100644
index 0000000..9a660a1
--- /dev/null
+++ b/data/sounds/effects/wav/KeypressStandard_49.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Lock.wav b/data/sounds/effects/wav/Lock.wav
index 88be052..fead37f 100644
--- a/data/sounds/effects/wav/Lock.wav
+++ b/data/sounds/effects/wav/Lock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/LowBattery.wav b/data/sounds/effects/wav/LowBattery.wav
index 8905534..5d8b48d 100644
--- a/data/sounds/effects/wav/LowBattery.wav
+++ b/data/sounds/effects/wav/LowBattery.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Undock.wav b/data/sounds/effects/wav/Undock.wav
index 358eb18..79abb4e 100644
--- a/data/sounds/effects/wav/Undock.wav
+++ b/data/sounds/effects/wav/Undock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/Unlock.wav b/data/sounds/effects/wav/Unlock.wav
index 4b39c5c..33b80ff 100644
--- a/data/sounds/effects/wav/Unlock.wav
+++ b/data/sounds/effects/wav/Unlock.wav
Binary files differ
diff --git a/data/sounds/effects/wav/VideoRecord.wav b/data/sounds/effects/wav/VideoRecord.wav
index 6880b29..f431023 100644
--- a/data/sounds/effects/wav/VideoRecord.wav
+++ b/data/sounds/effects/wav/VideoRecord.wav
Binary files differ
diff --git a/data/sounds/effects/wav/camera_click.wav b/data/sounds/effects/wav/camera_click.wav
deleted file mode 100644
index 420da7c..0000000
--- a/data/sounds/effects/wav/camera_click.wav
+++ /dev/null
Binary files differ
diff --git a/data/sounds/notifications/wav/Altair.wav b/data/sounds/notifications/wav/Altair.wav
new file mode 100644
index 0000000..0fb9788
--- /dev/null
+++ b/data/sounds/notifications/wav/Altair.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Antares.wav b/data/sounds/notifications/wav/Antares.wav
new file mode 100644
index 0000000..7c2dd23
--- /dev/null
+++ b/data/sounds/notifications/wav/Antares.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Betelgeuse.wav b/data/sounds/notifications/wav/Betelgeuse.wav
new file mode 100644
index 0000000..9ad799f
--- /dev/null
+++ b/data/sounds/notifications/wav/Betelgeuse.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Deneb.wav b/data/sounds/notifications/wav/Deneb.wav
new file mode 100644
index 0000000..ffe7c31
--- /dev/null
+++ b/data/sounds/notifications/wav/Deneb.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Hojus.wav b/data/sounds/notifications/wav/Hojus.wav
new file mode 100644
index 0000000..076a0c7
--- /dev/null
+++ b/data/sounds/notifications/wav/Hojus.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Lalande.wav b/data/sounds/notifications/wav/Lalande.wav
new file mode 100644
index 0000000..14c9fec
--- /dev/null
+++ b/data/sounds/notifications/wav/Lalande.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Mira.wav b/data/sounds/notifications/wav/Mira.wav
new file mode 100644
index 0000000..71be516
--- /dev/null
+++ b/data/sounds/notifications/wav/Mira.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Proxima.wav b/data/sounds/notifications/wav/Proxima.wav
new file mode 100644
index 0000000..109bfdd
--- /dev/null
+++ b/data/sounds/notifications/wav/Proxima.wav
Binary files differ
diff --git a/data/sounds/notifications/wav/Upsilon.wav b/data/sounds/notifications/wav/Upsilon.wav
new file mode 100644
index 0000000..ffc959b
--- /dev/null
+++ b/data/sounds/notifications/wav/Upsilon.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/Cassiopeia.wav b/data/sounds/ringtones/wav/Cassiopeia.wav
new file mode 100644
index 0000000..5c5c6e0
--- /dev/null
+++ b/data/sounds/ringtones/wav/Cassiopeia.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/Lyra.wav b/data/sounds/ringtones/wav/Lyra.wav
new file mode 100644
index 0000000..2943cf5
--- /dev/null
+++ b/data/sounds/ringtones/wav/Lyra.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/Sceptrum.wav b/data/sounds/ringtones/wav/Sceptrum.wav
new file mode 100644
index 0000000..3694373
--- /dev/null
+++ b/data/sounds/ringtones/wav/Sceptrum.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/Solarium.wav b/data/sounds/ringtones/wav/Solarium.wav
new file mode 100644
index 0000000..93f1e01
--- /dev/null
+++ b/data/sounds/ringtones/wav/Solarium.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/UrsaMinor.wav b/data/sounds/ringtones/wav/UrsaMinor.wav
new file mode 100644
index 0000000..5e16c94
--- /dev/null
+++ b/data/sounds/ringtones/wav/UrsaMinor.wav
Binary files differ
diff --git a/data/sounds/ringtones/wav/Vespa.wav b/data/sounds/ringtones/wav/Vespa.wav
new file mode 100644
index 0000000..7d696f8
--- /dev/null
+++ b/data/sounds/ringtones/wav/Vespa.wav
Binary files differ
diff --git a/docs/html/resources/dashboard/opengl.jd b/docs/html/resources/dashboard/opengl.jd
index 362ee16..2b94b28 100644
--- a/docs/html/resources/dashboard/opengl.jd
+++ b/docs/html/resources/dashboard/opengl.jd
@@ -57,7 +57,7 @@
 <div class="dashboard-panel">
 
 <img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A8.9,91" />
+src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=GL%201.1|GL%202.0%20%26%201.1&chd=t%3A9.4,90.6" />
 
 <table>
 <tr>
@@ -66,14 +66,14 @@
 </tr>
 <tr>
 <td>1.1</th>
-<td>9%</td>
+<td>9.4%</td>
 </tr>
 <tr>
 <td>2.0</th>
-<td>91%</td>
+<td>90.6%</td>
 </tr>
 </table>
 
-<p><em>Data collected during a 7-day period ending on July 1, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on September 2, 2011</em></p>
 </div>
 
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index d9adb36..51cbae3 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,27 +52,30 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="470"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.4,2.2,17.5,59.4,1.0,17.6,0.4,0.5&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3%20-%202.3.2|Android%202.3.3%20-%202.3.4|Android%203.0|Android%203.1&chco=c4df9b,6fad0c" />
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:1.0,1.8,13.3,51.2,0.6,30.7,0.2,0.7,0.5&chl=Android%201.5|Android%201.6|Android%202.1|Android%202.2|Android%202.3|Android%202.3.3|Android%203.0|Android%203.1|Android%203.2&chco=c4df9b,6fad0c" />
 
 <table>
 <tr>
   <th>Platform</th>
+  <th>Codename</th>
   <th>API Level</th>
   <th>Distribution</th>
 </tr>
-<tr><td>Android 1.5</td><td>3</td><td>1.4%</td></tr>
-<tr><td>Android 1.6</td><td>4</td><td>2.2%</td></tr>
-<tr><td>Android 2.1</td><td>7</td><td>17.5%</td></tr>
-<tr><td>Android 2.2</td><td>8</td><td>59.4%</td></tr>
-<tr><td>Android 2.3 -<br/>
-        Android 2.3.2</td><td>9</td><td>1%</td></tr>
-<tr><td>Android 2.3.3 -<br/>
-        Android 2.3.4</td><td>10</td><td>17.6%</td></tr>
-<tr><td>Android 3.0</td><td>11</td><td>0.4%</td></tr>
-<tr><td>Android 3.1</td><td>12</td><td>0.5%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.5.html">Android 1.5</a></td><td>Cupcake</td>  <td>3</td><td>1.0%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-1.6.html">Android 1.6</a></td><td>Donut</td>    <td>4</td><td>1.8%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.1.html">Android 2.1</a></td><td>Eclair</td>   <td>7</td><td>13.3%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.2.html">Android 2.2</a></td><td>Froyo</td>    <td>8</td><td>51.2%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.3.html">Android 2.3 -<br/>
+                             Android 2.3.2</a></td><td rowspan="2">Gingerbread</td>    <td>9</td><td>0.6%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-2.3.3.html">Android 2.3.3 -<br/>
+      Android 2.3.4</a></td><!-- Gingerbread -->                                       <td>10</td><td>30.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.0.html">Android 3.0</a></td>
+                                                   <td rowspan="3">Honeycomb</td>      <td>11</td><td>0.2%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.1.html">Android 3.1</a></td><!-- Honeycomb --><td>12</td><td>0.7%</td></tr>
+<tr><td><a href="{@docRoot}sdk/android-3.2.html">Android 3.2</a></td><!-- Honeycomb --><td>13</td><td>0.5%</td></tr> 
 </table>
 
-<p><em>Data collected during a 14-day period ending on July 5, 2011</em></p>
+<p><em>Data collected during a 14-day period ending on September 2, 2011</em></p>
 <!--
 <p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
 -->
@@ -101,9 +104,9 @@
 <div class="dashboard-panel">
 
 <img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C01/01%7C01/15%7C02/01%7C02/15%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:100.0,99.9,99.9,99.9,100.0,99.8,99.7,99.6,99.6,99.5,99.4,99.3,99.2|95.2,95.6,96.0,96.3,96.7,96.8,97.0,97.1,97.3,97.5,97.5,97.5,97.7|87.2,88.3,89.7,90.5,91.5,92.0,93.5,93.9,94.3,94.8,95.0,95.2,95.5|51.8,54.3,58.3,59.7,61.5,63.0,66.4,68.0,69.8,71.5,73.9,75.4,77.6|0.4,0.6,0.7,0.8,1.1,1.7,2.5,3.1,4.0,6.1,9.5,13.6,17.8|0.0,0.0,0.0,0.0,0.0,1.0,1.7,2.2,3.0,5.1,8.4,12.6,16.8&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid2.3.3,131d02,5,11,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
+src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,x,y,r&chxr=0,0,12|1,0,12|2,0,100|3,0,100&chxl=0%3A%7C03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/01%7C08/15%7C09/01%7C1%3A%7C2011%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C2011%7C2%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C3%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:100.0,99.8,99.7,99.6,99.6,99.5,99.4,99.3,99.2,99.0,98.8,98.7,98.6|96.7,96.8,97.0,97.1,97.3,97.5,97.5,97.5,97.7,97.6,97.5,97.5,97.5|91.5,92.0,93.5,93.9,94.3,94.8,95.0,95.2,95.5,95.5,95.5,95.6,95.8|61.5,63.0,66.4,68.0,69.8,71.5,73.9,75.4,77.6,79.0,80.2,81.1,82.4|1.1,1.7,2.5,3.1,4.0,6.1,9.5,13.6,17.8,20.6,24.3,27.5,31.1|0.0,1.0,1.7,2.2,3.0,5.1,8.4,12.6,16.8,20.0,23.7,26.9,30.5&chm=b,c3df9b,0,1,0|b,b4db77,1,2,0|tAndroid 2.1,547a19,2,0,15,,t::-5|b,a5db51,2,3,0|tAndroid 2.2,3f5e0e,3,0,15,,t::-5|b,96dd28,3,4,0|b,83c916,4,5,0|tAndroid 2.3.3,131d02,5,7,15,,t::-5|B,6fad0c,5,6,0&chg=7,25&chdl=Android 1.5|Android 1.6|Android 2.1|Android 2.2|Android 2.3|Android 2.3.3&chco=add274,9dd14f,8ece2a,7ab61c,659b11,507d08" />
 
-<p><em>Last historical dataset collected during a 14-day period ending on July 5, 2011</em></p>
+<p><em>Last historical dataset collected during a 14-day period ending on September 2, 2011</em></p>
 
 
 </div><!-- end dashboard-panel -->
diff --git a/docs/html/resources/dashboard/screens.jd b/docs/html/resources/dashboard/screens.jd
index e61e799..77fd2d2 100644
--- a/docs/html/resources/dashboard/screens.jd
+++ b/docs/html/resources/dashboard/screens.jd
@@ -59,8 +59,7 @@
 
 <div class="dashboard-panel">
 
-<img alt="" width="400" height="250"
-src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi|Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi&chd=t%3A0.9,2.8,75,1.0,17,3.3" />
+<img alt="" width="400" height="250" src="http://chart.googleapis.com/chart?cht=p&chs=400x250&chco=c4df9b,6fad0c&chl=Xlarge%20/%20mdpi| Large%20/%20mdpi|Normal%20/%20hdpi|Normal%20/%20ldpi|Normal%20/%20mdpi|Small%20/%20hdpi&chd=t%3A1.5, 3.2,74,0.9,16.9,3.5" />
 
 <table>
 <tr>
@@ -73,29 +72,29 @@
 <tr><th scope="row">small</th> 
 <td></td>     <!-- small/ldpi -->
 <td></td>     <!-- small/mdpi -->
-<td>3.3%</td> <!-- small/hdpi -->
+<td>3.5%</td> <!-- small/hdpi -->
 <td></td>     <!-- small/xhdpi -->
 </tr> 
 <tr><th scope="row">normal</th> 
-<td>1%</td>  <!-- normal/ldpi -->
-<td>17%</td> <!-- normal/mdpi -->
-<td>75%</td> <!-- normal/hdpi -->
+<td>0.9%</td>  <!-- normal/ldpi -->
+<td>16.9%</td> <!-- normal/mdpi -->
+<td>74%</td> <!-- normal/hdpi -->
 <td></td>      <!-- normal/xhdpi -->
 </tr> 
 <tr><th scope="row">large</th> 
 <td></td>     <!-- large/ldpi -->
-<td>2.8%</td> <!-- large/mdpi -->
+<td>3.2%</td> <!-- large/mdpi -->
 <td></td>     <!-- large/hdpi -->
 <td></td>     <!-- large/xhdpi -->
 </tr> 
 <tr><th scope="row">xlarge</th> 
 <td></td>     <!-- xlarge/ldpi -->
-<td>0.9%</td> <!-- xlarge/mdpi -->
+<td>1.5%</td> <!-- xlarge/mdpi -->
 <td></td>     <!-- xlarge/hdpi -->
 <td></td>     <!-- xlarge/xhdpi -->
 </tr> 
 </table>
 
-<p><em>Data collected during a 7-day period ending on July 1, 2011</em></p>
+<p><em>Data collected during a 7-day period ending on September 2, 2011</em></p>
 </div>
 
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 4418e02..88c9155 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -111,8 +111,11 @@
         alpha += alpha >> 7;   // make it 0..256
         int baseAlpha = mState.mBaseColor >>> 24;
         int useAlpha = baseAlpha * alpha >> 8;
+        int oldUseColor = mState.mUseColor;
         mState.mUseColor = (mState.mBaseColor << 8 >>> 8) | (useAlpha << 24);
-        invalidateSelf();
+        if (oldUseColor != mState.mUseColor) {
+            invalidateSelf();
+        }
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 4f74b37..e987679 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -83,7 +83,7 @@
         float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
         float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
 
-        canvas.rotate(st.mCurrentDegrees, px, py);
+        canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
 
         st.mDrawable.draw(canvas);
 
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 710ef94..0bee0f1 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -219,9 +219,12 @@
     if (i < 0) {
         return i;
     }
-    mSurfaceTexture->queueBuffer(i, timestamp,
+    status_t err = mSurfaceTexture->queueBuffer(i, timestamp,
             &mDefaultWidth, &mDefaultHeight, &mTransformHint);
-    return OK;
+    if (err != OK)  {
+        LOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
+    }
+    return err;
 }
 
 int SurfaceTextureClient::query(int what, int* value) const {
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 44babcf..b8bc454 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -974,8 +974,6 @@
 
     eglSwapBuffers(mEglDisplay, stcEglSurface);
 
-    eglDestroySurface(mEglDisplay, stcEglSurface);
-
     // Do the consumer side of things
     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
             mEglContext));
@@ -985,6 +983,10 @@
 
     mST->updateTexImage();
 
+    // We must wait until updateTexImage has been called to destroy the
+    // EGLSurface because we're in synchronous mode.
+    eglDestroySurface(mEglDisplay, stcEglSurface);
+
     glClearColor(0.2, 0.2, 0.2, 0.2);
     glClear(GL_COLOR_BUFFER_BIT);
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index cd15718..d233f92 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -2295,7 +2295,13 @@
                 int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                                BluetoothProfile.STATE_DISCONNECTED);
                 BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                if (btDevice == null) {
+                    return;
+                }
                 String address = btDevice.getAddress();
+                if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+                    address = "";
+                }
                 boolean isConnected =
                     (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
                      mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP).equals(address));
@@ -2331,24 +2337,30 @@
                 int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
                                                BluetoothProfile.STATE_DISCONNECTED);
                 int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
-                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 String address = null;
-                if (btDevice != null) {
-                    address = btDevice.getAddress();
-                    BluetoothClass btClass = btDevice.getBluetoothClass();
-                    if (btClass != null) {
-                        switch (btClass.getDeviceClass()) {
-                        case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
-                        case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-                            device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
-                            break;
-                        case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
-                            device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
-                            break;
-                        }
+
+                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                if (btDevice == null) {
+                    return;
+                }
+
+                address = btDevice.getAddress();
+                BluetoothClass btClass = btDevice.getBluetoothClass();
+                if (btClass != null) {
+                    switch (btClass.getDeviceClass()) {
+                    case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+                    case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
+                        device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+                        break;
+                    case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+                        device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                        break;
                     }
                 }
 
+                if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+                    address = "";
+                }
                 boolean isConnected = (mConnectedDevices.containsKey(device) &&
                                        mConnectedDevices.get(device).equals(address));
 
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index e25f654..ec1c27a 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -658,40 +658,6 @@
     }
 
     /**
-     * Sets the {@link SurfaceTexture} to be used as the sink for the
-     * video portion of the media. Either a surface or surface texture
-     * must be set if a video sink is needed.  The same surface texture
-     * can be re-set without harm. Setting a surface texture will un-set
-     * any surface that was set via {@link #setDisplay(SurfaceHolder)}.
-     * Not calling this method or {@link #setDisplay(SurfaceHolder)}
-     * when playing back a video will result in only the audio track
-     * being played. Note that if a SurfaceTexture is used, the value
-     * set via setScreenOnWhilePlaying has no effect.
-     *
-     * The timestamps provided by {@link SurfaceTexture#getTimestamp()} for a
-     * SurfaceTexture set as the video sink have an unspecified zero point,
-     * and cannot be directly compared between different media sources or different
-     * instances of the same media source, or across multiple runs of the same
-     * program.  The timestamp is normally monotonically increasing and unaffected
-     * by time-of-day adjustments, but is reset when the position is set.
-     */
-    public void setTexture(SurfaceTexture st) {
-        // TODO: This method should be hidden before it is published and setSurface
-        // should be unhidden and made public instead.
-        if (st != null) {
-            Surface surface = new Surface(st);
-            setSurface(surface);
-
-            // It is safe and desired to release the newly created Surface here since the
-            // native code will grab a reference to the underlying ISurfaceTexture. At that
-            // point the Surface we just created is no longer needed.
-            surface.release();
-        } else {
-            setSurface(null);
-        }
-    }
-
-    /**
      * Convenience method to create a MediaPlayer for a given Uri.
      * On success, {@link #prepare()} will already have been called and must not be called again.
      * <p>When done with the MediaPlayer, you should call  {@link #release()},
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 2b4e85f..aa0a2e9 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -2318,12 +2318,11 @@
             editSettings.audioBitrate = Bitrate.BR_64_KBPS;
             editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
 
-            editSettings.videoBitrate = Bitrate.BR_5_MBPS;
-            //editSettings.videoFormat = VideoFormat.MPEG4;
             editSettings.videoFormat = VideoFormat.H264;
             editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
             editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
                     m.getHeight());
+            editSettings.videoBitrate = findVideoBitrate(editSettings.videoFrameSize);
         } else {
             MediaImageItem m = (MediaImageItem)lMediaItem;
             editSettings.audioBitrate = Bitrate.BR_64_KBPS;
@@ -2331,11 +2330,11 @@
             editSettings.audioFormat = AudioFormat.AAC;
             editSettings.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
 
-            editSettings.videoBitrate = Bitrate.BR_5_MBPS;
             editSettings.videoFormat = VideoFormat.H264;
             editSettings.videoFrameRate = VideoFrameRate.FR_30_FPS;
             editSettings.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
                     m.getScaledHeight());
+            editSettings.videoBitrate = findVideoBitrate(editSettings.videoFrameSize);
         }
 
         editSettings.outputFile = EffectClipPath;
@@ -2395,11 +2394,12 @@
         e.audioFormat = AudioFormat.AAC;
         e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
 
-        e.videoBitrate = Bitrate.BR_5_MBPS;
         e.videoFormat = VideoFormat.H264;
         e.videoFrameRate = VideoFrameRate.FR_30_FPS;
         e.videoFrameSize = findVideoResolution(mVideoEditor.getAspectRatio(),
                                                            m.getScaledHeight());
+        e.videoBitrate = findVideoBitrate(e.videoFrameSize);
+
         mProcessingState  = PROCESSING_KENBURNS;
         mProcessingObject = m;
         err = generateClip(e);
@@ -2490,10 +2490,10 @@
         e.audioFormat = AudioFormat.AAC;
         e.audioSamplingFreq = AudioSamplingFrequency.FREQ_32000;
 
-        e.videoBitrate = Bitrate.BR_5_MBPS;
         e.videoFormat = VideoFormat.H264;
         e.videoFrameRate = VideoFrameRate.FR_30_FPS;
         e.videoFrameSize = getTransitionResolution(m1, m2);
+        e.videoBitrate = findVideoBitrate(e.videoFrameSize);
 
         if (new File(outputFilename).exists()) {
             new File(outputFilename).delete();
@@ -3568,6 +3568,34 @@
     }
 
     /**
+     *  Calculate a reasonable bitrate for generating intermediate clips.
+     */
+    private int findVideoBitrate(int videoFrameSize) {
+        switch (videoFrameSize) {
+            case VideoFrameSize.SQCIF:
+            case VideoFrameSize.QQVGA:
+            case VideoFrameSize.QCIF:
+                return Bitrate.BR_128_KBPS;
+            case VideoFrameSize.QVGA:
+            case VideoFrameSize.CIF:
+                return Bitrate.BR_384_KBPS;
+            case VideoFrameSize.VGA:
+            case VideoFrameSize.WVGA:
+            case VideoFrameSize.NTSC:
+            case VideoFrameSize.nHD:
+            case VideoFrameSize.WVGA16x9:
+                return Bitrate.BR_2_MBPS;
+            case VideoFrameSize.V720p:
+            case VideoFrameSize.W720p:
+            case VideoFrameSize.S720p:
+                return Bitrate.BR_5_MBPS;
+            case VideoFrameSize.V1080p:
+            default:
+                return Bitrate.BR_8_MBPS;
+        }
+    }
+
+    /**
      * This method is responsible for exporting a movie
      *
      * @param filePath The output file path
@@ -3643,7 +3671,6 @@
             case MediaProperties.BITRATE_2M:
                 outBitrate = Bitrate.BR_2_MBPS;
                 break;
-
             case MediaProperties.BITRATE_5M:
                 outBitrate = Bitrate.BR_5_MBPS;
                 break;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 853a5f6..7b14c18 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -511,9 +511,15 @@
                                                const char *device_address)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    const char *address = "";
+
     if (aps == 0) return PERMISSION_DENIED;
 
-    return aps->setDeviceConnectionState(device, state, device_address);
+    if (device_address != NULL) {
+        address = device_address;
+    }
+
+    return aps->setDeviceConnectionState(device, state, address);
 }
 
 audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index d5b013d..fb49d7b 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2442,8 +2442,10 @@
                 // Don't notify clients if the output port settings change
                 // wasn't of importance to them, i.e. it may be that just the
                 // number of buffers has changed and nothing else.
-                mOutputPortSettingsHaveChanged =
-                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
+                bool formatChanged = formatHasNotablyChanged(oldOutputFormat, mOutputFormat);
+                if (!mOutputPortSettingsHaveChanged) {
+                    mOutputPortSettingsHaveChanged = formatChanged;
+                }
 
                 enablePortAsync(portIndex);
 
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index e94e50e..325193c 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -23,6 +23,7 @@
 #include <limits.h>
 
 #include <cutils/log.h>
+#include <cutils/properties.h>
 
 #include <EGL/egl.h>
 
@@ -45,6 +46,39 @@
 
 ANDROID_SINGLETON_STATIC_INSTANCE( Loader )
 
+/* This function is called to check whether we run inside the emulator,
+ * and if this is the case whether GLES GPU emulation is supported.
+ *
+ * Returned values are:
+ *  -1   -> not running inside the emulator
+ *   0   -> running inside the emulator, but GPU emulation not supported
+ *   1   -> running inside the emulator, GPU emulation is supported
+ *          through the "emulation" config.
+ */
+static int
+checkGlesEmulationStatus(void)
+{
+    /* We're going to check for the following kernel parameters:
+     *
+     *    qemu=1                      -> tells us that we run inside the emulator
+     *    android.qemu.gles=<number>  -> tells us the GLES GPU emulation status
+     *
+     * Note that we will return <number> if we find it. This let us support
+     * more additionnal emulation modes in the future.
+     */
+    char  prop[PROPERTY_VALUE_MAX];
+    int   result = -1;
+
+    /* First, check for qemu=1 */
+    property_get("ro.kernel.qemu",prop,"0");
+    if (atoi(prop) != 1)
+        return -1;
+
+    /* We are in the emulator, get GPU status value */
+    property_get("ro.kernel.qemu.gles",prop,"0");
+    return atoi(prop);
+}
+
 // ----------------------------------------------------------------------------
 
 Loader::driver_t::driver_t(void* gles) 
@@ -94,6 +128,15 @@
 {
     char line[256];
     char tag[256];
+
+    /* Special case for GLES emulation */
+    if (checkGlesEmulationStatus() == 0) {
+        LOGD("Emulator without GPU support detected. Fallback to software renderer.");
+        gConfig.add( entry_t(0, 0, "android") );
+        return;
+    }
+
+    /* Otherwise, use egl.cfg */
     FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
     if (cfg == NULL) {
         // default config
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg.9.png
rename to packages/SystemUI/res/drawable-hdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png
deleted file mode 100644
index 82ba091..0000000
--- a/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png b/packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/recents_thumbnail_bg.9.png
rename to packages/SystemUI/res/drawable-mdpi/recents_thumbnail_bg_dragging.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml b/packages/SystemUI/res/drawable/recents_thumbnail_bg.xml
similarity index 80%
rename from packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml
rename to packages/SystemUI/res/drawable/recents_thumbnail_bg.xml
index 6d05095..320ed40 100644
--- a/packages/SystemUI/res/drawable/recents_thumbnail_overlay.xml
+++ b/packages/SystemUI/res/drawable/recents_thumbnail_bg.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:drawable="@drawable/recents_thumbnail_bg_press" android:state_pressed="true" />
-    <item android:drawable="@drawable/recents_thumbnail_bg" android:state_activated="true" />
+    <item android:drawable="@drawable/recents_thumbnail_bg_dragging" android:state_activated="true" />
     <item android:drawable="@*android:color/transparent"/>
 </selector>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index e99888c..4b2468a 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -18,7 +18,6 @@
 */
 -->
 
-<!--    android:background="@drawable/status_bar_closed_default_background" -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
@@ -37,8 +36,7 @@
             android:layout_alignParentTop="true"
             android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
             android:scaleType="center"
-            android:clickable="true"
-            android:background="@drawable/recents_thumbnail_overlay">
+            android:background="@drawable/recents_thumbnail_bg">
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index 73ca335..a327d42 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -18,7 +18,6 @@
 */
 -->
 
-<!--    android:background="@drawable/status_bar_closed_default_background" -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
@@ -33,10 +32,9 @@
             android:layout_height="wrap_content"
             android:layout_alignParentLeft="true"
             android:layout_alignParentTop="true"
-            android:clickable="true"
             android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
             android:scaleType="center"
-            android:background="@drawable/recents_thumbnail_overlay">
+            android:background="@drawable/recents_thumbnail_bg">
             <ImageView android:id="@+id/app_thumbnail_image"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index dd25cf9..ed9ea7a 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -38,6 +38,7 @@
             android:orientation="horizontal"
             android:clipChildren="false"
             android:layout_marginTop="@*android:dimen/status_bar_height">
+
             <com.android.systemui.recent.RecentsVerticalScrollView
                 android:id="@+id/recents_container"
                 android:layout_width="match_parent"
@@ -62,7 +63,6 @@
 
             </com.android.systemui.recent.RecentsVerticalScrollView>
 
-
         </LinearLayout>
 
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index cab90fd..0f45bcd 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -18,7 +18,6 @@
 */
 -->
 
-<!--    android:background="@drawable/status_bar_closed_default_background" -->
 <RelativeLayout android:id="@+id/recent_item"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="wrap_content"
@@ -29,10 +28,9 @@
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
-        android:clickable="true"
         android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
         android:scaleType="center"
-        android:background="@drawable/recents_thumbnail_overlay">
+        android:background="@drawable/recents_thumbnail_bg">
         <ImageView android:id="@+id/app_thumbnail_image"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index d627dc4..ff86878 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -22,6 +22,7 @@
         android:layout_alignParentTop="true"
         android:layout_alignParentLeft="true"
         android:scaleType="center"
+        android:clickable="true"
         />
 
     <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
diff --git a/packages/SystemUI/res/values-hdpi/dimens.xml b/packages/SystemUI/res/values-hdpi/dimens.xml
index 6b6fd4d..277626e 100644
--- a/packages/SystemUI/res/values-hdpi/dimens.xml
+++ b/packages/SystemUI/res/values-hdpi/dimens.xml
@@ -16,6 +16,10 @@
 */
 -->
 <resources>
+    <!-- padding of pressed drawable for recents thumbnails (should be the same on left, right,
+         top, and bottom -->
+    <dimen name="recents_thumbnail_bg_press_padding">3px</dimen>
+
     <!-- thickness (height) of each notification row, including any separators or padding -->
     <!-- Note: this is 64dip + 1px divider = 97px. -->
     <dimen name="notification_height">97px</dimen>
diff --git a/packages/SystemUI/res/values-mdpi/dimens.xml b/packages/SystemUI/res/values-mdpi/dimens.xml
new file mode 100644
index 0000000..d16d549b
--- /dev/null
+++ b/packages/SystemUI/res/values-mdpi/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+*/
+-->
+<resources>
+    <!-- padding of pressed drawable for recents thumbnails (should be the same on left, right,
+         top, and bottom -->
+    <dimen name="recents_thumbnail_bg_press_padding">2px</dimen>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 14743f4..0354fd7 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -165,11 +165,13 @@
             case MotionEvent.ACTION_DOWN:
                 mDragging = false;
                 mCurrView = mCallback.getChildAtPosition(ev);
-                mCurrAnimView = mCallback.getChildContentView(mCurrView);
-                mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
                 mVelocityTracker.clear();
-                mVelocityTracker.addMovement(ev);
-                mInitialTouchPos = getPos(ev);
+                if (mCurrView != null) {
+                    mCurrAnimView = mCallback.getChildContentView(mCurrView);
+                    mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
+                    mVelocityTracker.addMovement(ev);
+                    mInitialTouchPos = getPos(ev);
+                }
                 break;
             case MotionEvent.ACTION_MOVE:
                 if (mCurrView != null) {
@@ -196,7 +198,11 @@
         final View animView = mCallback.getChildContentView(view);
         final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
         float newPos;
-        if (velocity < 0 || (velocity == 0 && getTranslation(animView) < 0)) {
+
+        if (velocity < 0
+                || (velocity == 0 && getTranslation(animView) < 0)
+                // if we use the Menu to dismiss an item in landscape, animate up
+                || (velocity == 0 && getTranslation(animView) == 0 && mSwipeDirection == Y)) {
             newPos = -getSize(animView);
         } else {
             newPos = getSize(animView);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
index 2de4185..78050a2 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsCallback.java
@@ -26,8 +26,9 @@
 
     void handleOnClick(View selectedView);
     void handleSwipe(View selectedView);
-    void handleLongPress(View selectedView, View anchorView);
+    void handleLongPress(View selectedView, View anchorView, View thumbnailView);
     void handleShowBackground(boolean show);
+    void dismiss();
 
     // TODO: find another way to get this info from RecentsPanelView
     boolean isRecentsVisible();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 85cde7c..fc03a27 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -47,7 +47,8 @@
     private OnLongClickListener mOnLongClick = new OnLongClickListener() {
         public boolean onLongClick(View v) {
             final View anchorView = v.findViewById(R.id.app_description);
-            mCallback.handleLongPress(v, anchorView);
+            final View thumbnailView = v.findViewById(R.id.app_thumbnail);
+            mCallback.handleLongPress(v, anchorView, thumbnailView);
             return true;
         }
     };
@@ -75,13 +76,23 @@
                 mPerformanceHelper.addViewCallback(view);
             }
 
-            final View thumbnail = view.findViewById(R.id.app_thumbnail);
-            // thumbnail is set to clickable in the layout file
-            thumbnail.setOnClickListener(new OnClickListener() {
+            view.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    mCallback.dismiss();
+                }
+            });
+
+            OnClickListener launchAppListener = new OnClickListener() {
                 public void onClick(View v) {
                     mCallback.handleOnClick(view);
                 }
-            });
+            };
+            final View thumbnail = view.findViewById(R.id.app_thumbnail);
+            thumbnail.setClickable(true);
+            thumbnail.setOnClickListener(launchAppListener);
+            final View appTitle = view.findViewById(R.id.app_label);
+            appTitle.setClickable(true);
+            appTitle.setOnClickListener(launchAppListener);
             mLinearLayout.addView(view);
         }
         // Scroll to end after layout.
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e59c109..43905dd 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -30,15 +30,14 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Shader.TileMode;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
@@ -57,6 +56,7 @@
 import android.view.animation.AnimationUtils;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
 import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.PopupMenu;
@@ -84,7 +84,8 @@
     private View mRecentsScrim;
     private View mRecentsGlowView;
     private ViewGroup mRecentsContainer;
-    private Bitmap mAppThumbnailBackground;
+    private Bitmap mDefaultThumbnailBackground;
+    private BitmapDrawable mPressedDrawable;
 
     private boolean mShowing;
     private Choreographer mChoreo;
@@ -125,7 +126,7 @@
         }
 
         public void setThumbnail(Bitmap thumbnail) {
-            mThumbnail = compositeBitmap(mAppThumbnailBackground, thumbnail);
+            mThumbnail = compositeBitmap(mDefaultThumbnailBackground, thumbnail);
         }
 
         public Bitmap getThumbnail() {
@@ -182,6 +183,13 @@
                 holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
                 holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
                 holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
+
+                StateListDrawable thumbnailForegroundDrawable = new StateListDrawable();
+                thumbnailForegroundDrawable.addState(new int[] { android.R.attr.state_pressed },
+                        mPressedDrawable);
+                thumbnailForegroundDrawable.addState(new int[] { android.R.attr.state_selected },
+                        mPressedDrawable);
+                ((FrameLayout)holder.thumbnailView).setForeground(thumbnailForegroundDrawable);
                 convertView.setTag(holder);
             } else {
                 holder = (ViewHolder) convertView.getTag();
@@ -243,8 +251,11 @@
         }
     }
 
+    public void dismiss() {
+        hide(true);
+    }
+
     public void hide(boolean animate) {
-        mShowing = false;
         if (!animate) {
             setVisibility(View.GONE);
         }
@@ -336,9 +347,23 @@
         int width = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_width);
         int height = (int) res.getDimension(R.dimen.status_bar_recents_thumbnail_height);
         int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
-        mAppThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        Canvas c = new Canvas(mAppThumbnailBackground);
+
+        // Render the default thumbnail background
+        mDefaultThumbnailBackground = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas(mDefaultThumbnailBackground);
         c.drawColor(color);
+
+        // Render the pressed state (setting the 9 patch drawable directly causes padding issues)
+        int bgPadding = (int) res.getDimension(R.dimen.recents_thumbnail_bg_press_padding);
+        Bitmap pressedOverlay = Bitmap.createBitmap(
+                width + 2 * bgPadding, height + 2 * bgPadding, Bitmap.Config.ARGB_8888);
+        c.setBitmap(pressedOverlay);
+
+        Drawable pressedDrawable9Patch = res.getDrawable(R.drawable.recents_thumbnail_bg_press);
+        pressedDrawable9Patch.getCurrent().setBounds(
+                0, 0, pressedOverlay.getWidth(), pressedOverlay.getHeight());
+        pressedDrawable9Patch.draw(c);
+        mPressedDrawable = new BitmapDrawable(res, pressedOverlay);
     }
 
     @Override
@@ -514,7 +539,7 @@
         synchronized (ad) {
             ad.mLabel = label;
             ad.mIcon = icon;
-            ad.setThumbnail(thumbs != null ? thumbs.mainThumbnail : null);
+            ad.setThumbnail(thumbs != null ? thumbs.mainThumbnail : mDefaultThumbnailBackground);
         }
     }
 
@@ -574,7 +599,7 @@
         }
         mActivityDescriptions = getRecentTasks();
         for (ActivityDescription ad : mActivityDescriptions) {
-            ad.setThumbnail(mAppThumbnailBackground);
+            ad.setThumbnail(mDefaultThumbnailBackground);
         }
         mListAdapter.notifyDataSetInvalidated();
         if (mActivityDescriptions.size() > 0) {
@@ -712,7 +737,9 @@
         getContext().startActivity(intent);
     }
 
-    public void handleLongPress(final View selectedView, final View anchorView) {
+    public void handleLongPress(
+            final View selectedView, final View anchorView, final View thumbnailView) {
+        thumbnailView.setSelected(true);
         PopupMenu popup = new PopupMenu(mContext, anchorView == null ? selectedView : anchorView);
         popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu());
         popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@@ -734,6 +761,11 @@
                 return true;
             }
         });
+        popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
+            public void onDismiss(PopupMenu menu) {
+                thumbnailView.setSelected(false);
+            }
+        });
         popup.show();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 3acef08..b12387a 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -46,7 +46,8 @@
     private OnLongClickListener mOnLongClick = new OnLongClickListener() {
         public boolean onLongClick(View v) {
             final View anchorView = v.findViewById(R.id.app_description);
-            mCallback.handleLongPress(v, anchorView);
+            final View thumbnailView = v.findViewById(R.id.app_thumbnail);
+            mCallback.handleLongPress(v, anchorView, thumbnailView);
             return true;
         }
     };
@@ -84,15 +85,26 @@
             if (old == null) {
                 view.setClickable(true);
                 view.setOnLongClickListener(mOnLongClick);
-
-                final View thumbnail = view.findViewById(R.id.app_thumbnail);
-                // thumbnail is set to clickable in the layout file
-                thumbnail.setOnClickListener(new OnClickListener() {
+                view.setOnClickListener(new OnClickListener() {
                     public void onClick(View v) {
-                        mCallback.handleOnClick(view);
+                        mCallback.dismiss();
                     }
                 });
 
+                OnClickListener launchAppListener = new OnClickListener() {
+                    public void onClick(View v) {
+                        mCallback.handleOnClick(view);
+                    }
+                };
+                final View thumbnail = view.findViewById(R.id.app_thumbnail);
+                thumbnail.setClickable(true);
+                thumbnail.setOnClickListener(launchAppListener);
+                final View appTitle = view.findViewById(R.id.app_label);
+                appTitle.setClickable(true);
+                appTitle.setOnClickListener(launchAppListener);
+                final View calloutLine = view.findViewById(R.id.recents_callout_line);
+                calloutLine.setClickable(true);
+                calloutLine.setOnClickListener(launchAppListener);
                 mLinearLayout.addView(view);
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index fe255cb..3fa3078 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -232,7 +232,6 @@
                 WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
                 WindowManager.LayoutParams.FLAG_FULLSCREEN
                     | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
-                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
                     | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                     | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
                 PixelFormat.TRANSLUCENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 3d23abe..8be250b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -662,9 +662,12 @@
                 // update the contentIntent
                 final PendingIntent contentIntent = notification.notification.contentIntent;
                 if (contentIntent != null) {
-                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
-                                notification.pkg, notification.tag, notification.id));
+                    final View.OnClickListener listener = new NotificationClicker(contentIntent,
+                            notification.pkg, notification.tag, notification.id);
+                    oldEntry.largeIcon.setOnClickListener(listener);
+                    oldEntry.content.setOnClickListener(listener);
                 } else {
+                    oldEntry.largeIcon.setOnClickListener(null);
                     oldEntry.content.setOnClickListener(null);
                 }
                 // Update the icon.
@@ -779,9 +782,12 @@
         content.setOnFocusChangeListener(mFocusChangeListener);
         PendingIntent contentIntent = n.contentIntent;
         if (contentIntent != null) {
-            content.setOnClickListener(new NotificationClicker(contentIntent, notification.pkg,
-                        notification.tag, notification.id));
+            final View.OnClickListener listener = new NotificationClicker(contentIntent,
+                    notification.pkg, notification.tag, notification.id);
+            largeIcon.setOnClickListener(listener);
+            content.setOnClickListener(listener);
         } else {
+            largeIcon.setOnClickListener(null);
             content.setOnClickListener(null);
         }
 
@@ -979,9 +985,12 @@
 //        content.setOnFocusChangeListener(mFocusChangeListener);
         PendingIntent contentIntent = sbn.notification.contentIntent;
         if (contentIntent != null) {
-            content.setOnClickListener(new NotificationClicker(contentIntent,
-                        sbn.pkg, sbn.tag, sbn.id));
+            final View.OnClickListener listener = new NotificationClicker(contentIntent,
+                    sbn.pkg, sbn.tag, sbn.id);
+            largeIcon.setOnClickListener(listener);
+            content.setOnClickListener(listener);
         } else {
+            largeIcon.setOnClickListener(null);
             content.setOnClickListener(null);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index d9cb4e8..510fd3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -28,6 +28,10 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.widget.RelativeLayout;
 
 import com.android.systemui.R;
@@ -52,6 +56,8 @@
     ViewGroup mContentParent;
     TabletStatusBar mBar;
     View mClearButton;
+    static Interpolator sAccelerateInterpolator = new AccelerateInterpolator();
+    static Interpolator sDecelerateInterpolator = new DecelerateInterpolator();
 
     // amount to slide mContentParent down by when mContentFrame is missing
     float mContentFrameMissingTranslation;
@@ -117,8 +123,13 @@
                 mShowing = show;
                 if (show) {
                     setVisibility(View.VISIBLE);
+                    // Don't start the animation until we've created the layer, which is done
+                    // right before we are drawn
+                    mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                    getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
+                } else {
+                    mChoreo.startAnimation(show);
                 }
-                mChoreo.startAnimation(show);
             }
         } else {
             mShowing = show;
@@ -127,6 +138,20 @@
     }
 
     /**
+     * This is used only when we've created a hardware layer and are waiting until it's
+     * been created in order to start the appearing animation.
+     */
+    private ViewTreeObserver.OnPreDrawListener mPreDrawListener =
+            new ViewTreeObserver.OnPreDrawListener() {
+        @Override
+        public boolean onPreDraw() {
+            getViewTreeObserver().removeOnPreDrawListener(this);
+            mChoreo.startAnimation(true);
+            return false;
+        }
+    };
+
+    /**
      * Whether the panel is showing, or, if it's animating, whether it will be
      * when the animation is done.
      */
@@ -330,8 +355,8 @@
         AnimatorSet mContentAnim;
 
         // should group this into a multi-property animation
-        final static int OPEN_DURATION = 300;
-        final static int CLOSE_DURATION = 300;
+        final static int OPEN_DURATION = 250;
+        final static int CLOSE_DURATION = 250;
 
         // the panel will start to appear this many px from the end
         final int HYPERSPACE_OFFRAMP = 200;
@@ -362,19 +387,15 @@
 
             Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY",
                     start, end);
-            posAnim.setInterpolator(appearing
-                    ? new android.view.animation.DecelerateInterpolator(1.0f)
-                    : new android.view.animation.AccelerateInterpolator(1.0f));
+            posAnim.setInterpolator(appearing ? sDecelerateInterpolator : sAccelerateInterpolator);
 
             if (mContentAnim != null && mContentAnim.isRunning()) {
                 mContentAnim.cancel();
             }
 
             Animator fadeAnim = ObjectAnimator.ofFloat(mContentParent, "alpha",
-                                mContentParent.getAlpha(), appearing ? 1.0f : 0.0f);
-            fadeAnim.setInterpolator(appearing
-                    ? new android.view.animation.AccelerateInterpolator(2.0f)
-                    : new android.view.animation.DecelerateInterpolator(2.0f));
+                    appearing ? 1.0f : 0.0f);
+            fadeAnim.setInterpolator(appearing ? sAccelerateInterpolator : sDecelerateInterpolator);
 
             mContentAnim = new AnimatorSet();
             mContentAnim
@@ -389,8 +410,6 @@
             if (DEBUG) Slog.d(TAG, "startAnimation(appearing=" + appearing + ")");
 
             createAnimation(appearing);
-
-            mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
             mContentAnim.start();
 
             mVisible = appearing;
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 cc73d7b..b4c480b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -838,9 +838,12 @@
                 // update the contentIntent
                 final PendingIntent contentIntent = notification.notification.contentIntent;
                 if (contentIntent != null) {
-                    oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent,
-                                notification.pkg, notification.tag, notification.id));
+                    final View.OnClickListener listener = new NotificationClicker(contentIntent,
+                            notification.pkg, notification.tag, notification.id);
+                    oldEntry.largeIcon.setOnClickListener(listener);
+                    oldEntry.content.setOnClickListener(listener);
                 } else {
+                    oldEntry.largeIcon.setOnClickListener(null);
                     oldEntry.content.setOnClickListener(null);
                 }
                 // Update the icon.
@@ -1766,9 +1769,12 @@
 //        content.setOnFocusChangeListener(mFocusChangeListener);
         PendingIntent contentIntent = sbn.notification.contentIntent;
         if (contentIntent != null) {
-            content.setOnClickListener(new NotificationClicker(contentIntent,
-                        sbn.pkg, sbn.tag, sbn.id));
+            final View.OnClickListener listener = new NotificationClicker(
+                    contentIntent, sbn.pkg, sbn.tag, sbn.id);
+            largeIcon.setOnClickListener(listener);
+            content.setOnClickListener(listener);
         } else {
+            largeIcon.setOnClickListener(null);
             content.setOnClickListener(null);
         }
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 40cc7d8..8654a25 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -589,6 +589,11 @@
         public void onPhoneStateChanged(String newState) {
             updateEmergencyCallButtonState();
         }
+
+        /** {@inheritDoc} */
+        public void onClockVisibilityChanged() {
+            // ignored
+        }
     };
 
     private SimStateCallback mSimStateCallback = new SimStateCallback() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 2955de3..958f555 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -81,6 +81,8 @@
 
     private int mFailedAttempts = 0;
 
+    private boolean mClockVisible;
+
     private Handler mHandler;
 
     private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList();
@@ -94,6 +96,7 @@
     private static final int MSG_SIM_STATE_CHANGE = 304;
     private static final int MSG_RINGER_MODE_CHANGED = 305;
     private static final int MSG_PHONE_STATE_CHANGED = 306;
+    private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
 
     /**
      * When we receive a
@@ -170,6 +173,9 @@
                     case MSG_PHONE_STATE_CHANGED:
                         handlePhoneStateChanged((String)msg.obj);
                         break;
+                    case MSG_CLOCK_VISIBILITY_CHANGED:
+                        handleClockVisibilityChanged();
+                        break;
                 }
             }
         };
@@ -334,6 +340,13 @@
         }
     }
 
+    private void handleClockVisibilityChanged() {
+        if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
+        for (int i = 0; i < mInfoCallbacks.size(); i++) {
+            mInfoCallbacks.get(i).onClockVisibilityChanged();
+        }
+    }
+
     /**
      * @param status One of the statuses of {@link android.os.BatteryManager}
      * @return Whether the status maps to a status for being plugged in.
@@ -448,6 +461,12 @@
          */
         void onPhoneStateChanged(String newState);
 
+        /**
+         * Called when visibility of lockscreen clock changes, such as when
+         * obscured by a widget.
+         */
+        void onClockVisibilityChanged();
+
     }
 
     /**
@@ -484,6 +503,11 @@
         }
     }
 
+    public void reportClockVisible(boolean visible) {
+        mClockVisible = visible;
+        mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
+    }
+
     public IccCard.State getSimState() {
         return mSimState;
     }
@@ -546,4 +570,8 @@
         mFailedAttempts++;
     }
 
+    public boolean isClockVisible() {
+        return mClockVisible;
+    }
+
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index f52bb26..c1f1151 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -115,15 +115,19 @@
             }
             if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
                     Context.WINDOW_SERVICE)).getDefaultDisplay())) {
-                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
-                        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM;
+                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
             }
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
                     flags, PixelFormat.TRANSLUCENT);
             lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
             lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
-
+            if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
+                    Context.WINDOW_SERVICE)).getDefaultDisplay())) {
+                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+                lp.privateFlags |=
+                        WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
+            }
             lp.setTitle("Keyguard");
             mWindowLayoutParams = lp;
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index a544167..2a34f18 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -92,7 +92,7 @@
  * thread of the keyguard.
  */
 public class KeyguardViewMediator implements KeyguardViewCallback,
-        KeyguardUpdateMonitor.SimStateCallback {
+        KeyguardUpdateMonitor.InfoCallback, KeyguardUpdateMonitor.SimStateCallback {
     private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
     private final static boolean DEBUG = false;
     private final static boolean DBG_WAKE = false;
@@ -284,6 +284,7 @@
 
         mUpdateMonitor = new KeyguardUpdateMonitor(context);
 
+        mUpdateMonitor.registerInfoCallback(this);
         mUpdateMonitor.registerSimStateCallback(this);
 
         mLockPatternUtils = new LockPatternUtils(mContext);
@@ -1190,9 +1191,12 @@
                 flags |= StatusBarManager.DISABLE_NAVIGATION;
                 if (!mHidden) {
                     // showing lockscreen exclusively (no activities in front of it)
-                    // disable clock and back button too
+                    // disable back button too
                     flags |= StatusBarManager.DISABLE_BACK;
-                    flags |= StatusBarManager.DISABLE_CLOCK;
+                    if (mUpdateMonitor.isClockVisible()) {
+                        // lockscreen showing a clock, so hide statusbar clock
+                        flags |= StatusBarManager.DISABLE_CLOCK;
+                    }
                 }
                 if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) {
                     // showing secure lockscreen; disable expanding.
@@ -1283,4 +1287,34 @@
             mKeyguardViewManager.onScreenTurnedOn();
         }
     }
+
+    /** {@inheritDoc} */
+    public void onClockVisibilityChanged() {
+        adjustStatusBarLocked();
+    }
+
+    /** {@inheritDoc} */
+    public void onPhoneStateChanged(String newState) {
+        // ignored
+    }
+
+    /** {@inheritDoc} */
+    public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+        // ignored
+    }
+
+    /** {@inheritDoc} */
+    public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+        // ignored
+    }
+
+    /** {@inheritDoc} */
+    public void onRingerModeChanged(int state) {
+        // ignored
+    }
+
+    /** {@inheritDoc} */
+    public void onTimeChanged() {
+        // ignored
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 9c14734..62abf20 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -21,6 +21,7 @@
 import com.android.internal.telephony.IccCard;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.LockScreenWidgetCallback;
+import com.android.internal.widget.LockScreenWidgetInterface;
 import com.android.internal.widget.TransportControlView;
 
 import android.accounts.Account;
@@ -191,11 +192,17 @@
         public void requestShow(View view) {
             if (DEBUG) Log.v(TAG, "View " + view + " requested show transports");
             view.setVisibility(View.VISIBLE);
+
+            // TODO: examine all widgets to derive clock status
+            mUpdateMonitor.reportClockVisible(false);
         }
 
         public void requestHide(View view) {
             if (DEBUG) Log.v(TAG, "View " + view + " requested hide transports");
             view.setVisibility(View.GONE);
+
+            // TODO: examine all widgets to derive clock status
+            mUpdateMonitor.reportClockVisible(true);
         }
     };
 
@@ -743,6 +750,7 @@
         if (tcv == null) {
             if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
         } else {
+            mUpdateMonitor.reportClockVisible(true);
             tcv.setVisibility(View.GONE); // hide tcv until we get the callback below to show it.
             tcv.setCallback(mWidgetCallback);
         }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 2f5deba..304df72 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1226,6 +1226,8 @@
             params.packageName = packageName;
             params.windowAnimations = win.getWindowStyle().getResourceId(
                     com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+            params.privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
             params.setTitle("Starting " + packageName);
 
             WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index f5fd6bd..9f4936df 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -170,6 +170,7 @@
     final ArrayList<AppWidgetId> mAppWidgetIds = new ArrayList<AppWidgetId>();
     ArrayList<Host> mHosts = new ArrayList<Host>();
     boolean mSafeMode;
+    boolean mStateLoaded;
 
     AppWidgetService(Context context) {
         mContext = context;
@@ -180,8 +181,9 @@
     public void systemReady(boolean safeMode) {
         mSafeMode = safeMode;
 
-        loadAppWidgetList();
-        loadStateLocked();
+        synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
+        }
 
         // Register for the boot completed broadcast, so we can send the
         // ENABLE broacasts.  If we try to send them now, they time out,
@@ -209,6 +211,14 @@
         mContext.registerReceiver(mBroadcastReceiver, sdFilter);
     }
 
+    private void ensureStateLoadedLocked() {
+        if (!mStateLoaded) {
+            loadAppWidgetList();
+            loadStateLocked();
+            mStateLoaded = true;
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
@@ -285,6 +295,7 @@
     public int allocateAppWidgetId(String packageName, int hostId) {
         int callingUid = enforceCallingUid(packageName);
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             int appWidgetId = mNextAppWidgetId++;
 
             Host host = lookupOrAddHostLocked(callingUid, packageName, hostId);
@@ -304,6 +315,7 @@
 
     public void deleteAppWidgetId(int appWidgetId) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
             if (id != null) {
                 deleteAppWidgetLocked(id);
@@ -314,6 +326,7 @@
 
     public void deleteHost(int hostId) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             int callingUid = getCallingUid();
             Host host = lookupHostLocked(callingUid, hostId);
             if (host != null) {
@@ -325,6 +338,7 @@
 
     public void deleteAllHosts() {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             int callingUid = getCallingUid();
             final int N = mHosts.size();
             boolean changed = false;
@@ -405,6 +419,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mAppWidgetIds) {
+                ensureStateLoadedLocked();
                 AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
                 if (id == null) {
                     throw new IllegalArgumentException("bad appWidgetId");
@@ -448,6 +463,7 @@
     // Binds to a specific RemoteViewsService
     public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
             if (id == null) {
                 throw new IllegalArgumentException("bad appWidgetId");
@@ -499,6 +515,7 @@
     // Unbinds from a specific RemoteViewsService
     public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             // Unbind from the RemoteViewsService (which will trigger a callback to the bound
             // RemoteViewsAdapter)
             Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
@@ -610,6 +627,7 @@
 
     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
             if (id != null && id.provider != null && !id.provider.zombie) {
                 return id.provider.info;
@@ -620,6 +638,7 @@
 
     public RemoteViews getAppWidgetViews(int appWidgetId) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
             if (id != null) {
                 return id.views;
@@ -630,6 +649,7 @@
 
     public List<AppWidgetProviderInfo> getInstalledProviders() {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             final int N = mInstalledProviders.size();
             ArrayList<AppWidgetProviderInfo> result = new ArrayList<AppWidgetProviderInfo>(N);
             for (int i=0; i<N; i++) {
@@ -652,6 +672,7 @@
         final int N = appWidgetIds.length;
 
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             for (int i=0; i<N; i++) {
                 AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
                 updateAppWidgetInstanceLocked(id, views);
@@ -669,6 +690,7 @@
         final int N = appWidgetIds.length;
 
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             for (int i=0; i<N; i++) {
                 AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
                 updateAppWidgetInstanceLocked(id, views, true);
@@ -686,6 +708,7 @@
         final int N = appWidgetIds.length;
 
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             for (int i=0; i<N; i++) {
                 AppWidgetId id = lookupAppWidgetIdLocked(appWidgetIds[i]);
                 notifyAppWidgetViewDataChangedInstanceLocked(id, viewId);
@@ -695,6 +718,7 @@
 
     public void updateAppWidgetProvider(ComponentName provider, RemoteViews views) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             Provider p = lookupProviderLocked(provider);
             if (p == null) {
                 Slog.w(TAG, "updateAppWidgetProvider: provider doesn't exist: " + provider);
@@ -759,6 +783,7 @@
             List<RemoteViews> updatedViews) {
         int callingUid = enforceCallingUid(packageName);
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             Host host = lookupOrAddHostLocked(callingUid, packageName, hostId);
             host.callbacks = callbacks;
 
@@ -778,6 +803,7 @@
 
     public void stopListening(int hostId) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             Host host = lookupHostLocked(getCallingUid(), hostId);
             if (host != null) {
                 host.callbacks = null;
@@ -965,6 +991,7 @@
     
     public int[] getAppWidgetIds(ComponentName provider) {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             Provider p = lookupProviderLocked(provider);
             if (p != null && getCallingUid() == p.uid) {
                 return getAppWidgetIds(p);                
@@ -1087,6 +1114,7 @@
 
     void sendInitialBroadcasts() {
         synchronized (mAppWidgetIds) {
+            ensureStateLoadedLocked();
             final int N = mInstalledProviders.size();
             for (int i=0; i<N; i++) {
                 Provider p = mInstalledProviders.get(i);
@@ -1391,6 +1419,7 @@
                     mLocale = revised;
 
                     synchronized (mAppWidgetIds) {
+                        ensureStateLoadedLocked();
                         int N = mInstalledProviders.size();
                         for (int i=N-1; i>=0; i--) {
                             Provider p = mInstalledProviders.get(i);
@@ -1428,6 +1457,7 @@
                 }
                 if (added || changed) {
                     synchronized (mAppWidgetIds) {
+                        ensureStateLoadedLocked();
                         Bundle extras = intent.getExtras();
                         if (changed || (extras != null &&
                                     extras.getBoolean(Intent.EXTRA_REPLACING, false))) {
@@ -1449,6 +1479,7 @@
                         // The package is being updated.  We'll receive a PACKAGE_ADDED shortly.
                     } else {
                         synchronized (mAppWidgetIds) {
+                            ensureStateLoadedLocked();
                             for (String pkgName : pkgList) {
                                 removeProvidersForPackageLocked(pkgName);
                                 saveStateLocked();
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 0e1a1e3..ab70d6c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -80,6 +80,9 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.IWindowManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputBinding;
@@ -87,6 +90,9 @@
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
+import android.widget.ArrayAdapter;
+import android.widget.RadioButton;
+import android.widget.TextView;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -337,11 +343,10 @@
     int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
     int mImeWindowVis;
 
-    AlertDialog.Builder mDialogBuilder;
-    AlertDialog mSwitchingDialog;
-    InputMethodInfo[] mIms;
-    CharSequence[] mItems;
-    int[] mSubtypeIds;
+    private AlertDialog.Builder mDialogBuilder;
+    private AlertDialog mSwitchingDialog;
+    private InputMethodInfo[] mIms;
+    private int[] mSubtypeIds;
 
     class SettingsObserver extends ContentObserver {
         SettingsObserver(Handler handler) {
@@ -1148,7 +1153,7 @@
                             ? TextUtils.concat(mCurrentSubtype.getDisplayName(mContext,
                                         imi.getPackageName(), imi.getServiceInfo().applicationInfo),
                                                 (TextUtils.isEmpty(imiLabel) ?
-                                                        "" : " (" + imiLabel + ")"))
+                                                        "" : " - " + imiLabel))
                             : imiLabel;
 
                     mImeSwitcherNotification.setLatestEventInfo(
@@ -2073,8 +2078,7 @@
 
             sortedImmis.putAll(immis);
 
-            final ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>> imList =
-                    new ArrayList<Pair<CharSequence, Pair<InputMethodInfo, Integer>>>();
+            final ArrayList<ImeSubtypeListItem> imList = new ArrayList<ImeSubtypeListItem>();
 
             for (InputMethodInfo imi : sortedImmis.keySet()) {
                 if (imi == null) continue;
@@ -2084,7 +2088,7 @@
                     enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
                 }
                 ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi);
-                final CharSequence label = imi.loadLabel(pm);
+                final CharSequence imeLabel = imi.loadLabel(pm);
                 if (showSubtypes && enabledSubtypeSet.size() > 0) {
                     final int subtypeCount = imi.getSubtypeCount();
                     if (DEBUG) {
@@ -2096,13 +2100,12 @@
                         // We show all enabled IMEs and subtypes when an IME is shown.
                         if (enabledSubtypeSet.contains(subtypeHashCode)
                                 && ((mInputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
-                            final CharSequence title;
-                            final String mode = subtype.getMode();
-                            title = TextUtils.concat(subtype.getDisplayName(context,
-                                    imi.getPackageName(), imi.getServiceInfo().applicationInfo),
-                                    (TextUtils.isEmpty(label) ? "" : " (" + label + ")"));
-                            imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
-                                    title, new Pair<InputMethodInfo, Integer>(imi, j)));
+                            final CharSequence subtypeLabel =
+                                    subtype.overridesImplicitlyEnabledSubtype() ? null
+                                            : subtype.getDisplayName(context, imi.getPackageName(),
+                                                    imi.getServiceInfo().applicationInfo);
+                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j));
+
                             // Removing this subtype from enabledSubtypeSet because we no longer
                             // need to add an entry of this subtype to imList to avoid duplicated
                             // entries.
@@ -2110,23 +2113,18 @@
                         }
                     }
                 } else {
-                    imList.add(new Pair<CharSequence, Pair<InputMethodInfo, Integer>>(
-                            label, new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID)));
+                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID));
                 }
             }
 
             final int N = imList.size();
-            mItems = new CharSequence[N];
-            for (int i = 0; i < N; ++i) {
-                mItems[i] = imList.get(i).first;
-            }
             mIms = new InputMethodInfo[N];
             mSubtypeIds = new int[N];
             int checkedItem = 0;
             for (int i = 0; i < N; ++i) {
-                Pair<InputMethodInfo, Integer> value = imList.get(i).second;
-                mIms[i] = value.first;
-                mSubtypeIds[i] = value.second;
+                final ImeSubtypeListItem item = imList.get(i);
+                mIms[i] = item.mImi;
+                mSubtypeIds[i] = item.mSubtypeId;
                 if (mIms[i].getId().equals(lastInputMethodId)) {
                     int subtypeId = mSubtypeIds[i];
                     if ((subtypeId == NOT_A_SUBTYPE_ID)
@@ -2137,14 +2135,7 @@
                 }
             }
 
-            AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    hideInputMethodMenu();
-                }
-            };
-
-            TypedArray a = context.obtainStyledAttributes(null,
+            final TypedArray a = context.obtainStyledAttributes(null,
                     com.android.internal.R.styleable.DialogPreference,
                     com.android.internal.R.attr.alertDialogStyle, 0);
             mDialogBuilder = new AlertDialog.Builder(context)
@@ -2159,7 +2150,11 @@
                             com.android.internal.R.styleable.DialogPreference_dialogTitle));
             a.recycle();
 
-            mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
+            final ImeSubtypeListAdapter adapter = new ImeSubtypeListAdapter(context,
+                    com.android.internal.R.layout.simple_list_item_2_single_choice, imList,
+                    checkedItem);
+
+            mDialogBuilder.setSingleChoiceItems(adapter, checkedItem,
                     new AlertDialog.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
@@ -2201,6 +2196,59 @@
         }
     }
 
+    private static class ImeSubtypeListItem {
+        public final CharSequence mImeName;
+        public final CharSequence mSubtypeName;
+        public final InputMethodInfo mImi;
+        public final int mSubtypeId;
+        public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
+                InputMethodInfo imi, int subtypeId) {
+            mImeName = imeName;
+            mSubtypeName = subtypeName;
+            mImi = imi;
+            mSubtypeId = subtypeId;
+        }
+    }
+
+    private static class ImeSubtypeListAdapter extends ArrayAdapter<ImeSubtypeListItem> {
+        private final LayoutInflater mInflater;
+        private final int mTextViewResourceId;
+        private final List<ImeSubtypeListItem> mItemsList;
+        private final int mCheckedItem;
+        public ImeSubtypeListAdapter(Context context, int textViewResourceId,
+                List<ImeSubtypeListItem> itemsList, int checkedItem) {
+            super(context, textViewResourceId, itemsList);
+            mTextViewResourceId = textViewResourceId;
+            mItemsList = itemsList;
+            mCheckedItem = checkedItem;
+            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final View view = convertView != null ? convertView
+                    : mInflater.inflate(mTextViewResourceId, null);
+            if (position < 0 || position >= mItemsList.size()) return view;
+            final ImeSubtypeListItem item = mItemsList.get(position);
+            final CharSequence imeName = item.mImeName;
+            final CharSequence subtypeName = item.mSubtypeName;
+            final TextView firstTextView = (TextView)view.findViewById(android.R.id.text1);
+            final TextView secondTextView = (TextView)view.findViewById(android.R.id.text2);
+            if (TextUtils.isEmpty(subtypeName)) {
+                firstTextView.setText(imeName);
+                secondTextView.setVisibility(View.GONE);
+            } else {
+                firstTextView.setText(subtypeName);
+                secondTextView.setText(imeName);
+                secondTextView.setVisibility(View.VISIBLE);
+            }
+            final RadioButton radioButton =
+                    (RadioButton)view.findViewById(com.android.internal.R.id.radio);
+            radioButton.setChecked(position == mCheckedItem);
+            return view;
+        }
+    }
+
     void hideInputMethodMenu() {
         synchronized (mMethodMap) {
             hideInputMethodMenuLocked();
@@ -2216,7 +2264,6 @@
         }
 
         mDialogBuilder = null;
-        mItems = null;
         mIms = null;
     }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index bb5e989..9db56ce 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3598,7 +3598,7 @@
             thread.bindApplication(processName, appInfo, providers,
                     app.instrumentationClass, profileFile, profileFd, profileAutoStop,
                     app.instrumentationArguments, app.instrumentationWatcher, testMode, 
-                    isRestrictedBackupMode || !normalMode,
+                    isRestrictedBackupMode || !normalMode, app.persistent,
                     mConfiguration, app.compat, getCommonServicesLocked(),
                     mCoreSettingsObserver.getCoreSettingsLocked());
             updateLruProcessLocked(app, false, true);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 7d1bdf0..0ff1cce 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -108,8 +108,21 @@
 }
 
 status_t HWComposer::release() const {
-    int err = mHwc->set(mHwc, NULL, NULL, NULL);
-    return (status_t)err;
+    if (mHwc) {
+        int err = mHwc->set(mHwc, NULL, NULL, NULL);
+        return (status_t)err;
+    }
+    return NO_ERROR;
+}
+
+status_t HWComposer::disable() {
+    if (mHwc) {
+        free(mList);
+        mList = NULL;
+        int err = mHwc->prepare(mHwc, NULL);
+        return (status_t)err;
+    }
+    return NO_ERROR;
 }
 
 size_t HWComposer::getNumLayers() const {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 983898a..77c1a4b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -50,6 +50,9 @@
     // Asks the HAL what it can do
     status_t prepare() const;
 
+    // disable hwc until next createWorkList
+    status_t disable();
+
     // commits the list
     status_t commit() const;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b4c5dec..4a3a8ea 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2113,6 +2113,12 @@
         // we're already off
         return NO_ERROR;
     }
+
+    // turn off hwc while we're doing the animation
+    hw.getHwComposer().disable();
+    // and make sure to turn it back on (if needed) next time we compose
+    invalidateHwcGeometry();
+
     if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
         electronBeamOffAnimationImplLocked();
     }
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index e37e9b5..c038478 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -70,6 +70,7 @@
         unitTests.add(new UT_rstime(this, mRes, mCtx));
         unitTests.add(new UT_rstypes(this, mRes, mCtx));
         unitTests.add(new UT_alloc(this, mRes, mCtx));
+        unitTests.add(new UT_refcount(this, mRes, mCtx));
         unitTests.add(new UT_foreach(this, mRes, mCtx));
         unitTests.add(new UT_math(this, mRes, mCtx));
         unitTests.add(new UT_fp_mad(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_refcount.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_refcount.java
new file mode 100644
index 0000000..6bb28f8
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_refcount.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_refcount extends UnitTest {
+    private Resources mRes;
+
+    protected UT_refcount(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Refcount", ctx);
+        mRes = res;
+    }
+
+    private void initializeGlobals(RenderScript RS, ScriptC_refcount s) {
+        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
+        int X = 500;
+        int Y = 700;
+        typeBuilder.setX(X).setY(Y);
+        Allocation A = Allocation.createTyped(RS, typeBuilder.create());
+        s.set_globalA(A);
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        pRS.setMessageHandler(mRsMessage);
+        ScriptC_refcount s = new ScriptC_refcount(pRS, mRes, R.raw.refcount);
+        initializeGlobals(pRS, s);
+        s.invoke_refcount_test();
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+    }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/refcount.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/refcount.rs
new file mode 100644
index 0000000..4ea70e2
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/refcount.rs
@@ -0,0 +1,13 @@
+#include "shared.rsh"
+
+// Testing reference counting of RS object types
+
+rs_allocation globalA;
+static rs_allocation staticGlobalA;
+
+void refcount_test() {
+    staticGlobalA = globalA;
+    rsClearObject(&globalA);
+    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+}
+