Merge "Rename WpsConfiguration to Wps"
diff --git a/api/current.txt b/api/current.txt
index f8b7bd9..cc6cce9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2487,12 +2487,15 @@
 
   public static abstract class ActionBar.Tab {
     ctor public ActionBar.Tab();
+    method public abstract java.lang.CharSequence getContentDescription();
     method public abstract android.view.View getCustomView();
     method public abstract android.graphics.drawable.Drawable getIcon();
     method public abstract int getPosition();
     method public abstract java.lang.Object getTag();
     method public abstract java.lang.CharSequence getText();
     method public abstract void select();
+    method public abstract android.app.ActionBar.Tab setContentDescription(int);
+    method public abstract android.app.ActionBar.Tab setContentDescription(java.lang.CharSequence);
     method public abstract android.app.ActionBar.Tab setCustomView(android.view.View);
     method public abstract android.app.ActionBar.Tab setCustomView(int);
     method public abstract android.app.ActionBar.Tab setIcon(android.graphics.drawable.Drawable);
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 7acaec8..46dc5ff 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -790,6 +790,37 @@
          * Select this tab. Only valid if the tab has been added to the action bar.
          */
         public abstract void select();
+
+        /**
+         * Set a description of this tab's content for use in accessibility support.
+         * If no content description is provided the title will be used.
+         *
+         * @param resId A resource ID referring to the description text
+         * @return The current instance for call chaining
+         * @see #setContentDescription(CharSequence)
+         * @see #getContentDescription()
+         */
+        public abstract Tab setContentDescription(int resId);
+
+        /**
+         * Set a description of this tab's content for use in accessibility support.
+         * If no content description is provided the title will be used.
+         *
+         * @param contentDesc Description of this tab's content
+         * @return The current instance for call chaining
+         * @see #setContentDescription(int)
+         * @see #getContentDescription()
+         */
+        public abstract Tab setContentDescription(CharSequence contentDesc);
+
+        /**
+         * Gets a brief description of this tab's content for use in accessibility support.
+         *
+         * @return Description of this tab's content
+         * @see #setContentDescription(CharSequence)
+         * @see #setContentDescription(int)
+         */
+        public abstract CharSequence getContentDescription();
     }
 
     /**
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 24f8319..d7f901a 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -73,6 +73,7 @@
     private static final boolean DEBUG_LOAD = false;
     private static final boolean DEBUG_CONFIG = false;
     private static final boolean TRACE_FOR_PRELOAD = false;
+    private static final boolean TRACE_FOR_MISS_PRELOAD = false;
 
     private static final int ID_OTHER = 0x01000004;
 
@@ -1899,6 +1900,16 @@
 
                 String file = value.string.toString();
 
+                if (TRACE_FOR_MISS_PRELOAD) {
+                    // Log only framework resources
+                    if ((id >>> 24) == 0x1) {
+                        final String name = getResourceName(id);
+                        if (name != null) android.util.Log.d(TAG, "Loading framework drawable #"
+                                + Integer.toHexString(id) + ": " + name
+                                + " at " + file);
+                    }
+                }
+
                 if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
                         + value.assetCookie + ": " + file);
 
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 9302060..e0130b5 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -36,7 +36,7 @@
     /** Local-side IPC implementation stub class. */
     public static abstract class Stub extends Binder implements IMountService {
         private static class Proxy implements IMountService {
-            private IBinder mRemote;
+            private final IBinder mRemote;
 
             Proxy(IBinder remote) {
                 mRemote = remote;
@@ -589,6 +589,22 @@
                 return _result;
             }
 
+            public int getEncryptionState() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getEncryptionState, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
             public int decryptStorage(String password) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -741,6 +757,8 @@
 
         static final int TRANSACTION_getSecureContainerFilesystemPath = IBinder.FIRST_CALL_TRANSACTION + 30;
 
+        static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1062,6 +1080,13 @@
                     reply.writeString(path);
                     return true;
                 }
+                case TRANSACTION_getEncryptionState: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int result = getEncryptionState();
+                    reply.writeNoException();
+                    reply.writeInt(result);
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1222,6 +1247,21 @@
      */
     public boolean isExternalStorageEmulated() throws RemoteException;
 
+    /** The volume is not encrypted. */
+    static final int ENCRYPTION_STATE_NONE = 1;
+    /** The volume has been encrypted succesfully. */
+    static final int ENCRYPTION_STATE_OK = 0;
+    /** The volume is in a bad state. */
+    static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
+    /** The volume is in a bad state - partially encrypted. Data is likely irrecoverable. */
+    static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
+
+    /**
+     * Determines the encryption state of the volume.
+     * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible values.
+     */
+    public int getEncryptionState() throws RemoteException;
+
     /**
      * Decrypts any encrypted volumes.
      */
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index a08ba2a..48739ba 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -260,6 +260,17 @@
             return old;
         }
 
+        private synchronized SpeechItem maybeRemoveCurrentSpeechItem(String callingApp) {
+            if (mCurrentSpeechItem != null &&
+                    TextUtils.equals(mCurrentSpeechItem.getCallingApp(), callingApp)) {
+                SpeechItem current = mCurrentSpeechItem;
+                mCurrentSpeechItem = null;
+                return current;
+            }
+
+            return null;
+        }
+
         public boolean isSpeaking() {
             return getCurrentSpeechItem() != null;
         }
@@ -287,14 +298,9 @@
             }
 
             if (queueMode == TextToSpeech.QUEUE_FLUSH) {
-                stop(speechItem.getCallingApp());
+                stopForApp(speechItem.getCallingApp());
             } else if (queueMode == TextToSpeech.QUEUE_DESTROY) {
-                // Stop the current speech item.
-                stop(speechItem.getCallingApp());
-                // Remove all other items from the queue.
-                removeCallbacksAndMessages(null);
-                // Remove all pending playback as well.
-                mAudioPlaybackHandler.removeAllItems();
+                stopAll();
             }
             Runnable runnable = new Runnable() {
                 @Override
@@ -305,7 +311,8 @@
                 }
             };
             Message msg = Message.obtain(this, runnable);
-            // The obj is used to remove all callbacks from the given app in stop(String).
+            // The obj is used to remove all callbacks from the given app in
+            // stopForApp(String).
             //
             // Note that this string is interned, so the == comparison works.
             msg.obj = speechItem.getCallingApp();
@@ -323,7 +330,7 @@
          *
          * Called on a service binder thread.
          */
-        public int stop(String callingApp) {
+        public int stopForApp(String callingApp) {
             if (TextUtils.isEmpty(callingApp)) {
                 return TextToSpeech.ERROR;
             }
@@ -331,8 +338,13 @@
             removeCallbacksAndMessages(callingApp);
             // This stops writing data to the file / or publishing
             // items to the audio playback handler.
-            SpeechItem current = setCurrentSpeechItem(null);
-            if (current != null && TextUtils.equals(callingApp, current.getCallingApp())) {
+            //
+            // Note that the current speech item must be removed only if it
+            // belongs to the callingApp, else the item will be "orphaned" and
+            // not stopped correctly if a stop request comes along for the item
+            // from the app it belongs to.
+            SpeechItem current = maybeRemoveCurrentSpeechItem(callingApp);
+            if (current != null) {
                 current.stop();
             }
 
@@ -341,6 +353,20 @@
 
             return TextToSpeech.SUCCESS;
         }
+
+        public int stopAll() {
+            // Stop the current speech item unconditionally.
+            SpeechItem current = setCurrentSpeechItem(null);
+            if (current != null) {
+                current.stop();
+            }
+            // Remove all other items from the queue.
+            removeCallbacksAndMessages(null);
+            // Remove all pending playback as well.
+            mAudioPlaybackHandler.removeAllItems();
+
+            return TextToSpeech.SUCCESS;
+        }
     }
 
     interface UtteranceCompletedDispatcher {
@@ -412,6 +438,10 @@
             }
         }
 
+        protected synchronized boolean isStopped() {
+             return mStopped;
+        }
+
         protected abstract int playImpl();
 
         protected abstract void stopImpl();
@@ -473,7 +503,7 @@
                 Log.w(TAG, "Got empty text");
                 return false;
             }
-            if (mText.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH){
+            if (mText.length() >= MAX_SPEECH_ITEM_CHAR_LENGTH) {
                 Log.w(TAG, "Text too long: " + mText.length() + " chars");
                 return false;
             }
@@ -485,6 +515,11 @@
             AbstractSynthesisCallback synthesisCallback;
             mEventLogger.onRequestProcessingStart();
             synchronized (this) {
+                // stop() might have been called before we enter this
+                // synchronized block.
+                if (isStopped()) {
+                    return TextToSpeech.ERROR;
+                }
                 mSynthesisCallback = createSynthesisCallback();
                 synthesisCallback = mSynthesisCallback;
             }
@@ -510,8 +545,13 @@
             synchronized (this) {
                 synthesisCallback = mSynthesisCallback;
             }
-            synthesisCallback.stop();
-            TextToSpeechService.this.onStop();
+            if (synthesisCallback != null) {
+                // If the synthesis callback is null, it implies that we haven't
+                // entered the synchronized(this) block in playImpl which in
+                // turn implies that synthesis would not have started.
+                synthesisCallback.stop();
+                TextToSpeechService.this.onStop();
+            }
         }
 
         public String getLanguage() {
@@ -719,7 +759,7 @@
                 return TextToSpeech.ERROR;
             }
 
-            return mSynthHandler.stop(intern(callingApp));
+            return mSynthHandler.stopForApp(intern(callingApp));
         }
 
         public String[] getLanguage() {
@@ -811,7 +851,7 @@
             synchronized (mAppToCallback) {
                 mAppToCallback.remove(packageName);
             }
-            mSynthHandler.stop(packageName);
+            mSynthHandler.stopForApp(packageName);
         }
 
         @Override
diff --git a/core/java/android/text/TextDirectionHeuristics.java b/core/java/android/text/TextDirectionHeuristics.java
index 18b4040..e5c1e5b 100644
--- a/core/java/android/text/TextDirectionHeuristics.java
+++ b/core/java/android/text/TextDirectionHeuristics.java
@@ -62,24 +62,6 @@
         new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
 
     /**
-     * Examines only the strong directional non-format characters, and if either
-     * left to right or right to left characters are 60% or more of this total,
-     * determines that the direction follows the majority of characters.  Falls
-     * back to left to right if neither direction meets this threshold.
-     */
-    public static final TextDirectionHeuristic CHARCOUNT_LTR =
-        new TextDirectionHeuristicInternal(CharCount.INSTANCE_DEFAULT, false);
-
-    /**
-     * Examines only the strong directional non-format characters, and if either
-     * left to right or right to left characters are 60% or more of this total,
-     * determines that the direction follows the majority of characters.  Falls
-     * back to right to left if neither direction meets this threshold.
-     */
-    public static final TextDirectionHeuristic CHARCOUNT_RTL =
-        new TextDirectionHeuristicInternal(CharCount.INSTANCE_DEFAULT, true);
-
-    /**
      * Force the paragraph direction to the Locale direction. Falls back to left to right.
      */
     public static final TextDirectionHeuristic LOCALE = TextDirectionHeuristicLocale.INSTANCE;
@@ -255,62 +237,6 @@
     }
 
     /**
-     * Algorithm that uses the relative proportion of strong directional
-     * characters (excluding LRE, LRO, RLE, RLO) to determine the direction
-     * of the paragraph, if the proportion exceeds a given threshold.
-     *
-     * @hide
-     */
-    public static class CharCount implements TextDirectionAlgorithm {
-        private final float mThreshold;
-
-        @Override
-        public TriState checkRtl(char[] text, int start, int count) {
-            int countLtr = 0;
-            int countRtl = 0;
-            for(int i = start, e = start + count; i < e; ++i) {
-                switch (isRtlText(Character.getDirectionality(text[i]))) {
-                    case TRUE:
-                        ++countLtr;
-                        break;
-                    case FALSE:
-                        ++countRtl;
-                        break;
-                    default:
-                        break;
-                }
-            }
-            int limit = (int)((countLtr + countRtl) * mThreshold);
-            if (limit > 0) {
-                if (countLtr > limit) {
-                    return TriState.FALSE;
-                }
-                if (countRtl > limit) {
-                    return TriState.TRUE;
-                }
-            }
-            return TriState.UNKNOWN;
-        }
-
-        private CharCount(float threshold) {
-            mThreshold = threshold;
-        }
-
-        public static CharCount withThreshold(float threshold) {
-            if (threshold < 0 || threshold > 1) {
-                throw new IllegalArgumentException();
-            }
-            if (threshold == DEFAULT_THRESHOLD) {
-                return INSTANCE_DEFAULT;
-            }
-            return new CharCount(threshold);
-        }
-
-        public static final float DEFAULT_THRESHOLD = 0.6f;
-        public static final CharCount INSTANCE_DEFAULT = new CharCount(DEFAULT_THRESHOLD);
-    }
-
-    /**
      * Algorithm that uses the Locale direction to force the direction of a paragraph.
      */
     public static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fa1d249..ba23218 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2568,26 +2568,18 @@
     public static final int TEXT_DIRECTION_ANY_RTL = 2;
 
     /**
-     * Text direction is the same as the one held by a 60% majority of the characters. If there is
-     * no majority then the paragraph direction is the resolved layout direction of the View.
-     *
-     * @hide
-     */
-    public static final int TEXT_DIRECTION_CHAR_COUNT = 3;
-
-    /**
      * Text direction is forced to LTR.
      *
      * @hide
      */
-    public static final int TEXT_DIRECTION_LTR = 4;
+    public static final int TEXT_DIRECTION_LTR = 3;
 
     /**
      * Text direction is forced to RTL.
      *
      * @hide
      */
-    public static final int TEXT_DIRECTION_RTL = 5;
+    public static final int TEXT_DIRECTION_RTL = 4;
 
     /**
      * Default text direction is inherited
@@ -2603,7 +2595,6 @@
             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_CHAR_COUNT, to = "CHAR_COUNT"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
     })
@@ -2621,7 +2612,6 @@
             @ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
-            @ViewDebug.IntToString(from = TEXT_DIRECTION_CHAR_COUNT, to = "CHAR_COUNT"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
             @ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
     })
@@ -10320,7 +10310,10 @@
             throw new OutOfMemoryError();
         }
 
-        bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
+        Resources resources = getResources();
+        if (resources != null) {
+            bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
+        }
 
         Canvas canvas;
         if (attachInfo != null) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0d160a9..2e2b3d6 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -215,6 +215,7 @@
     boolean mLastWasImTarget;
 
     boolean mWindowAttributesChanged = false;
+    int mWindowAttributesChangesFlag = 0;
 
     // These can be accessed by any thread, must be protected with a lock.
     // Surface can never be reassigned or cleared (use Surface.clear()).
@@ -439,6 +440,7 @@
 
                 mSoftInputMode = attrs.softInputMode;
                 mWindowAttributesChanged = true;
+                mWindowAttributesChangesFlag = WindowManager.LayoutParams.EVERYTHING_CHANGED;
                 mAttachInfo.mRootView = view;
                 mAttachInfo.mScalingRequired = mTranslator != null;
                 mAttachInfo.mApplicationScale =
@@ -640,7 +642,7 @@
             // preserve compatible window flag if exists.
             int compatibleWindowFlag =
                 mWindowAttributes.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
-            mWindowAttributes.copyFrom(attrs);
+            mWindowAttributesChangesFlag = mWindowAttributes.copyFrom(attrs);
             mWindowAttributes.flags |= compatibleWindowFlag;
             
             if (newView) {
@@ -844,14 +846,17 @@
                 || mNewSurfaceNeeded;
 
         WindowManager.LayoutParams params = null;
+        int windowAttributesChanges = 0;
         if (mWindowAttributesChanged) {
             mWindowAttributesChanged = false;
             surfaceChanged = true;
             params = lp;
+            windowAttributesChanges = mWindowAttributesChangesFlag;
         }
         CompatibilityInfo compatibilityInfo = mCompatibilityInfo.get();
         if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
             params = lp;
+            windowAttributesChanges |= WindowManager.LayoutParams.BUFFER_CHANGED;
             fullRedrawNeeded = true;
             mLayoutRequested = true;
             if (mLastInCompatMode) {
@@ -862,6 +867,9 @@
                 mLastInCompatMode = true;
             }
         }
+        
+        mWindowAttributesChangesFlag = 0;
+        
         Rect frame = mWinFrame;
         if (mFirst) {
             fullRedrawNeeded = true;
@@ -1041,6 +1049,7 @@
                     || attachInfo.mSystemUiVisibility != oldVis
                     || attachInfo.mHasSystemUiListeners) {
                 params = lp;
+                windowAttributesChanges |= WindowManager.LayoutParams.BUFFER_CHANGED;
             }
         }
 
@@ -1066,6 +1075,7 @@
                             ~WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) |
                             resizeMode;
                     params = lp;
+                    windowAttributesChanges |= WindowManager.LayoutParams.BUFFER_CHANGED;
                 }
             }
         }
@@ -1362,7 +1372,8 @@
                 }
             }
 
-            if (hwInitialized || ((windowShouldResize || params != null) &&
+            if (hwInitialized || ((windowShouldResize || (params != null &&
+                    (windowAttributesChanges & WindowManager.LayoutParams.BUFFER_CHANGED) != 0)) &&
                     mAttachInfo.mHardwareRenderer != null &&
                     mAttachInfo.mHardwareRenderer.isEnabled())) {
                 mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
@@ -1564,13 +1575,13 @@
         boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw() ||
                 viewVisibility != View.VISIBLE;
 
-        if (!cancelDraw && !newSurface) {
-            if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
-                for (int i = 0; i < mPendingTransitions.size(); ++i) {
-                    mPendingTransitions.get(i).startChangingAnimations();
-                }
-                mPendingTransitions.clear();
+        if (mPendingTransitions != null && mPendingTransitions.size() > 0) {
+            for (int i = 0; i < mPendingTransitions.size(); ++i) {
+                mPendingTransitions.get(i).startChangingAnimations();
             }
+            mPendingTransitions.clear();
+        }
+        if (!cancelDraw && !newSurface) {
             mFullRedrawNeeded = false;
 
             final long drawStartTime;
@@ -1608,10 +1619,6 @@
                 }
             }
         } 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.
@@ -1621,7 +1628,7 @@
             if (fullRedrawNeeded) {
                 mFullRedrawNeeded = true;
             }
-            
+
             if (viewVisibility == View.VISIBLE) {
                 // Try again
                 scheduleTraversals();
@@ -1637,6 +1644,7 @@
             // Need to make sure we re-evaluate the window attributes next
             // time around, to ensure the window has the correct format.
             mWindowAttributesChanged = true;
+            mWindowAttributesChangesFlag = 0;
             requestLayout();
         }
     }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index fb31e7d..96c1512 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1252,7 +1252,11 @@
         public static final int INPUT_FEATURES_CHANGED = 1<<15;
         /** {@hide} */
         public static final int PRIVATE_FLAGS_CHANGED = 1<<16;
-    
+        /** {@hide} */
+        public static final int BUFFER_CHANGED = 1<<17;
+        /** {@hide} */
+        public static final int EVERYTHING_CHANGED = 0xffffffff;
+
         // internal buffer to backup/restore parameters under compatibility mode.
         private int[] mCompatibilityParamsBackup = null;
         
@@ -1261,11 +1265,11 @@
     
             if (width != o.width) {
                 width = o.width;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (height != o.height) {
                 height = o.height;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (x != o.x) {
                 x = o.x;
@@ -1277,19 +1281,19 @@
             }
             if (horizontalWeight != o.horizontalWeight) {
                 horizontalWeight = o.horizontalWeight;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (verticalWeight != o.verticalWeight) {
                 verticalWeight = o.verticalWeight;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (horizontalMargin != o.horizontalMargin) {
                 horizontalMargin = o.horizontalMargin;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (verticalMargin != o.verticalMargin) {
                 verticalMargin = o.verticalMargin;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (type != o.type) {
                 type = o.type;
@@ -1297,7 +1301,7 @@
             }
             if (flags != o.flags) {
                 flags = o.flags;
-                changes |= FLAGS_CHANGED;
+                changes |= FLAGS_CHANGED | BUFFER_CHANGED;
             }
             if (privateFlags != o.privateFlags) {
                 privateFlags = o.privateFlags;
@@ -1309,11 +1313,11 @@
             }
             if (gravity != o.gravity) {
                 gravity = o.gravity;
-                changes |= LAYOUT_CHANGED;
+                changes |= LAYOUT_CHANGED | BUFFER_CHANGED;
             }
             if (format != o.format) {
                 format = o.format;
-                changes |= FORMAT_CHANGED;
+                changes |= FORMAT_CHANGED | BUFFER_CHANGED;
             }
             if (windowAnimations != o.windowAnimations) {
                 windowAnimations = o.windowAnimations;
@@ -1352,7 +1356,7 @@
     
             if (screenOrientation != o.screenOrientation) {
                 screenOrientation = o.screenOrientation;
-                changes |= SCREEN_ORIENTATION_CHANGED;
+                changes |= SCREEN_ORIENTATION_CHANGED | BUFFER_CHANGED;
             }
 
             if (systemUiVisibility != o.systemUiVisibility
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index f89d490..49b4f66 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -43,6 +43,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.Charsets;
 import java.security.PrivateKey;
@@ -1171,7 +1172,8 @@
             X509Certificate cert = new X509CertImpl(cert_der);
             SslCertificate sslCert = new SslCertificate(cert);
             if (JniUtil.useChromiumHttpStack()) {
-                ssl_error = SslError.SslErrorFromChromiumErrorCode(cert_error, sslCert, url);
+                ssl_error = SslError.SslErrorFromChromiumErrorCode(cert_error, sslCert,
+                        new URL(url).getHost());
             } else {
                 ssl_error = new SslError(cert_error, cert, url);
             }
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 4ba604d..b945038 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -926,8 +926,10 @@
         }
         event.setItemCount(getCount());
         event.setCurrentItemIndex(getSelectedItemPosition());
-        event.setFromIndex(mFirstPosition);
-        event.setToIndex(mFirstPosition + getChildCount());
+        if (getChildCount() > 0) {
+            event.setFromIndex(getFirstVisiblePosition());
+            event.setToIndex(getLastVisiblePosition());
+        }
     }
 
     @Override
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 4b08f2d..0cd14d0 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -148,14 +148,23 @@
     private int mFramePadding;
     private final Rect stackInvalidateRect = new Rect();
 
+    /**
+     * {@inheritDoc}
+     */
     public StackView(Context context) {
         this(context, null);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public StackView(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.stackViewStyle);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     public StackView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         TypedArray a = context.obtainStyledAttributes(attrs,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0f30734..7f410aa 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -7591,7 +7591,9 @@
 
         // Hide the controllers if the amount of content changed
         if (before != after) {
-            hideControllers();
+            // We do not hide the span controllers, as they can be added when a new text is
+            // inserted into the text view
+            hideCursorControllers();
         }
     }
     
@@ -7799,20 +7801,23 @@
      * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related
      * pop-up should be displayed.
      */
-    private class EditTextShortcutController {
+    private class EasyEditSpanController {
 
-        private EditTextShortcutPopupWindow mPopupWindow;
+        private static final int DISPLAY_TIMEOUT_MS = 3000; // 3 secs
 
-        private EasyEditSpan mEditTextShortcutSpan;
+        private EasyEditPopupWindow mPopupWindow;
+
+        private EasyEditSpan mEasyEditSpan;
+
+        private Runnable mHidePopup;
 
         private void hide() {
-            if (mEditTextShortcutSpan != null) {
+            if (mPopupWindow != null) {
                 mPopupWindow.hide();
-                if (mText instanceof Spannable) {
-                    ((Spannable) mText).removeSpan(mEditTextShortcutSpan);
-                }
-                mEditTextShortcutSpan = null;
+                TextView.this.removeCallbacks(mHidePopup);
             }
+            removeSpans(mText);
+            mEasyEditSpan = null;
         }
 
         /**
@@ -7822,43 +7827,111 @@
          * as the notifications are not sent when a spannable (with spans) is inserted.
          */
         public void onTextChange(CharSequence buffer) {
-            if (mEditTextShortcutSpan != null) {
-                hide();
+            adjustSpans(mText);
+
+            if (getWindowVisibility() != View.VISIBLE) {
+                // The window is not visible yet, ignore the text change.
+                return;
             }
 
+            if (mLayout == null) {
+                // The view has not been layout yet, ignore the text change
+                return;
+            }
+
+            InputMethodManager imm = InputMethodManager.peekInstance();
+            if (!(TextView.this instanceof ExtractEditText)
+                    && imm != null && imm.isFullscreenMode()) {
+                // The input is in extract mode. We do not have to handle the easy edit in the
+                // original TextView, as the ExtractEditText will do
+                return;
+            }
+
+            // Remove the current easy edit span, as the text changed, and remove the pop-up
+            // (if any)
+            if (mEasyEditSpan != null) {
+                if (mText instanceof Spannable) {
+                    ((Spannable) mText).removeSpan(mEasyEditSpan);
+                }
+                mEasyEditSpan = null;
+            }
+            if (mPopupWindow != null && mPopupWindow.isShowing()) {
+                mPopupWindow.hide();
+            }
+
+            // Display the new easy edit span (if any).
             if (buffer instanceof Spanned) {
-                mEditTextShortcutSpan = getSpan((Spanned) buffer);
-                if (mEditTextShortcutSpan != null) {
+                mEasyEditSpan = getSpan((Spanned) buffer);
+                if (mEasyEditSpan != null) {
                     if (mPopupWindow == null) {
-                        mPopupWindow = new EditTextShortcutPopupWindow();
+                        mPopupWindow = new EasyEditPopupWindow();
+                        mHidePopup = new Runnable() {
+                            @Override
+                            public void run() {
+                                hide();
+                            }
+                        };
                     }
-                    mPopupWindow.show(mEditTextShortcutSpan);
+                    mPopupWindow.show(mEasyEditSpan);
+                    TextView.this.removeCallbacks(mHidePopup);
+                    TextView.this.postDelayed(mHidePopup, DISPLAY_TIMEOUT_MS);
+                }
+            }
+        }
+
+        /**
+         * Adjusts the spans by removing all of them except the last one.
+         */
+        private void adjustSpans(CharSequence buffer) {
+            // This method enforces that only one easy edit span is attached to the text.
+            // A better way to enforce this would be to listen for onSpanAdded, but this method
+            // cannot be used in this scenario as no notification is triggered when a text with
+            // spans is inserted into a text.
+            if (buffer instanceof Spannable) {
+                Spannable spannable = (Spannable) buffer;
+                EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
+                        EasyEditSpan.class);
+                for (int i = 0; i < spans.length - 1; i++) {
+                    spannable.removeSpan(spans[i]);
+                }
+            }
+        }
+
+        /**
+         * Removes all the {@link EasyEditSpan} currently attached.
+         */
+        private void removeSpans(CharSequence buffer) {
+            if (buffer instanceof Spannable) {
+                Spannable spannable = (Spannable) buffer;
+                EasyEditSpan[] spans = spannable.getSpans(0, spannable.length(),
+                        EasyEditSpan.class);
+                for (int i = 0; i < spans.length; i++) {
+                    spannable.removeSpan(spans[i]);
                 }
             }
         }
 
         private EasyEditSpan getSpan(Spanned spanned) {
-            EasyEditSpan[] inputMethodSpans = spanned.getSpans(0, spanned.length(),
+            EasyEditSpan[] easyEditSpans = spanned.getSpans(0, spanned.length(),
                     EasyEditSpan.class);
-
-            if (inputMethodSpans.length == 0) {
+            if (easyEditSpans.length == 0) {
                 return null;
             } else {
-                return inputMethodSpans[0];
+                return easyEditSpans[0];
             }
         }
     }
 
     /**
      * Displays the actions associated to an {@link EasyEditSpan}. The pop-up is controlled
-     * by {@link EditTextShortcutController}.
+     * by {@link EasyEditSpanController}.
      */
-    private class EditTextShortcutPopupWindow extends PinnedPopupWindow
+    private class EasyEditPopupWindow extends PinnedPopupWindow
             implements OnClickListener {
         private static final int POPUP_TEXT_LAYOUT =
                 com.android.internal.R.layout.text_edit_action_popup_text;
         private TextView mDeleteTextView;
-        private EasyEditSpan mEditTextShortcutSpan;
+        private EasyEditSpan mEasyEditSpan;
 
         @Override
         protected void createPopupWindow() {
@@ -7889,8 +7962,8 @@
             mContentView.addView(mDeleteTextView);
         }
 
-        public void show(EasyEditSpan inputMethodSpan) {
-            mEditTextShortcutSpan = inputMethodSpan;
+        public void show(EasyEditSpan easyEditSpan) {
+            mEasyEditSpan = easyEditSpan;
             super.show();
         }
 
@@ -7903,8 +7976,8 @@
 
         private void deleteText() {
             Editable editable = (Editable) mText;
-            int start = editable.getSpanStart(mEditTextShortcutSpan);
-            int end = editable.getSpanEnd(mEditTextShortcutSpan);
+            int start = editable.getSpanStart(mEasyEditSpan);
+            int end = editable.getSpanEnd(mEasyEditSpan);
             if (start >= 0 && end >= 0) {
                 editable.delete(start, end);
             }
@@ -7914,7 +7987,7 @@
         protected int getTextOffset() {
             // Place the pop-up at the end of the span
             Editable editable = (Editable) mText;
-            return editable.getSpanEnd(mEditTextShortcutSpan);
+            return editable.getSpanEnd(mEasyEditSpan);
         }
 
         @Override
@@ -7933,10 +8006,10 @@
 
         private CharSequence mBeforeText;
 
-        private EditTextShortcutController mEditTextShortcutController;
+        private EasyEditSpanController mEasyEditSpanController;
 
         private ChangeWatcher() {
-            mEditTextShortcutController = new EditTextShortcutController();
+            mEasyEditSpanController = new EasyEditSpanController();
         }
 
         public void beforeTextChanged(CharSequence buffer, int start,
@@ -7959,7 +8032,7 @@
                     + " before=" + before + " after=" + after + ": " + buffer);
             TextView.this.handleTextChanged(buffer, start, before, after);
 
-            mEditTextShortcutController.onTextChange(buffer);
+            mEasyEditSpanController.onTextChange(buffer);
 
             if (AccessibilityManager.getInstance(mContext).isEnabled() &&
                     (isFocused() || isSelected() && isShown())) {
@@ -7997,7 +8070,7 @@
         }
 
         private void hideControllers() {
-            mEditTextShortcutController.hide();
+            mEasyEditSpanController.hide();
         }
     }
 
@@ -9236,8 +9309,9 @@
     }
 
     private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
-        // 3 handles, 2 ActionPopup (suggestionsPopup first hides the others)
-        private final int MAXIMUM_NUMBER_OF_LISTENERS = 5;
+        // 3 handles
+        // 3 ActionPopup [replace, suggestion, easyedit] (suggestionsPopup first hides the others)
+        private final int MAXIMUM_NUMBER_OF_LISTENERS = 6;
         private TextViewPositionListener[] mPositionListeners =
                 new TextViewPositionListener[MAXIMUM_NUMBER_OF_LISTENERS];
         private boolean mCanMove[] = new boolean[MAXIMUM_NUMBER_OF_LISTENERS];
@@ -9467,10 +9541,6 @@
 
     private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnItemClickListener {
         private static final int MAX_NUMBER_SUGGESTIONS = SuggestionSpan.SUGGESTIONS_MAX_SIZE;
-        private static final float AVERAGE_HIGHLIGHTS_PER_SUGGESTION = 1.4f;
-        private WordIterator mSuggestionWordIterator;
-        private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan
-                [(int) (AVERAGE_HIGHLIGHTS_PER_SUGGESTION * MAX_NUMBER_SUGGESTIONS)];
         private SuggestionInfo[] mSuggestionInfos;
         private int mNumberOfSuggestions;
         private boolean mCursorWasVisibleBeforeSuggestions;
@@ -9497,10 +9567,6 @@
         }
 
         public SuggestionsPopupWindow() {
-            for (int i = 0; i < mHighlightSpans.length; i++) {
-                mHighlightSpans[i] = new TextAppearanceSpan(mContext,
-                        android.R.style.TextAppearance_SuggestionHighlight);
-            }
             mCursorWasVisibleBeforeSuggestions = mCursorVisible;
         }
 
@@ -9534,6 +9600,8 @@
             SuggestionSpan suggestionSpan; // the SuggestionSpan that this TextView represents
             int suggestionIndex; // the index of the suggestion inside suggestionSpan
             SpannableStringBuilder text = new SpannableStringBuilder();
+            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(mContext,
+                    android.R.style.TextAppearance_SuggestionHighlight);
 
             void removeMisspelledFlag() {
                 int suggestionSpanFlags = suggestionSpan.getFlags();
@@ -9746,152 +9814,23 @@
             return true;
         }
 
-        private long[] getWordLimits(CharSequence text) {
-            // TODO locale for mSuggestionWordIterator
-            if (mSuggestionWordIterator == null) mSuggestionWordIterator = new WordIterator();
-            mSuggestionWordIterator.setCharSequence(text);
-
-            // First pass will simply count the number of words to be able to create an array
-            // Not too expensive since previous break positions are cached by the BreakIterator
-            int nbWords = 0;
-            int position = mSuggestionWordIterator.following(0);
-            while (position != BreakIterator.DONE) {
-                nbWords++;
-                position = mSuggestionWordIterator.following(position);
-            }
-
-            int index = 0;
-            long[] result = new long[nbWords];
-
-            position = mSuggestionWordIterator.following(0);
-            while (position != BreakIterator.DONE) {
-                int wordStart = mSuggestionWordIterator.getBeginning(position);
-                result[index++] = packRangeInLong(wordStart, position);
-                position = mSuggestionWordIterator.following(position);
-            }
-
-            return result;
-        }
-
-        private TextAppearanceSpan highlightSpan(int index) {
-            final int length = mHighlightSpans.length;
-            if (index < length) {
-                return mHighlightSpans[index];
-            }
-
-            // Assumes indexes are requested in sequence: simply append one more item
-            TextAppearanceSpan[] newArray = new TextAppearanceSpan[length + 1];
-            System.arraycopy(mHighlightSpans, 0, newArray, 0, length);
-            TextAppearanceSpan highlightSpan = new TextAppearanceSpan(mContext,
-                    android.R.style.TextAppearance_SuggestionHighlight);
-            newArray[length] = highlightSpan;
-            mHighlightSpans = newArray;
-            return highlightSpan;
-        }
-
-        private void highlightTextDifferences(SuggestionInfo suggestionInfo,
-                int unionStart, int unionEnd) {
+        private void highlightTextDifferences(SuggestionInfo suggestionInfo, int unionStart,
+                int unionEnd) {
             final int spanStart = suggestionInfo.spanStart;
             final int spanEnd = suggestionInfo.spanEnd;
 
-            // Remove all text formating by converting to Strings
-            final String text = suggestionInfo.text.toString();
-            final String sourceText = mText.subSequence(spanStart, spanEnd).toString();
+            // Adjust the start/end of the suggestion span
+            suggestionInfo.suggestionStart = spanStart - unionStart;
+            suggestionInfo.suggestionEnd = suggestionInfo.suggestionStart 
+                    + suggestionInfo.text.length();
+            
+            suggestionInfo.text.clearSpans();
+            suggestionInfo.text.setSpan(suggestionInfo.highlightSpan, 0,
+                    suggestionInfo.text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 
-            long[] sourceWordLimits = getWordLimits(sourceText);
-            long[] wordLimits = getWordLimits(text);
-
-            SpannableStringBuilder ssb = new SpannableStringBuilder();
-            // span [spanStart, spanEnd] is included in union [spanUnionStart, int spanUnionEnd]
-            // The final result is made of 3 parts: the text before, between and after the span
-            // This is the text before, provided for context
-            ssb.append(mText.subSequence(unionStart, spanStart).toString());
-
-            // shift is used to offset spans positions wrt span's beginning
-            final int shift = spanStart - unionStart;
-            suggestionInfo.suggestionStart = shift;
-            suggestionInfo.suggestionEnd = shift + text.length();
-
-            // This is the actual suggestion text, which will be highlighted by the following code
-            ssb.append(text);
-
-            String[] words = new String[wordLimits.length];
-            for (int i = 0; i < wordLimits.length; i++) {
-                int wordStart = extractRangeStartFromLong(wordLimits[i]);
-                int wordEnd = extractRangeEndFromLong(wordLimits[i]);
-                words[i] = text.substring(wordStart, wordEnd);
-            }
-
-            // Highlighted word algorithm is based on word matching between source and text
-            // Matching words are found from left to right. TODO: change for RTL languages
-            // Characters between matching words are highlighted
-            int previousCommonWordIndex = -1;
-            int nbHighlightSpans = 0;
-            for (int i = 0; i < sourceWordLimits.length; i++) {
-                int wordStart = extractRangeStartFromLong(sourceWordLimits[i]);
-                int wordEnd = extractRangeEndFromLong(sourceWordLimits[i]);
-                String sourceWord = sourceText.substring(wordStart, wordEnd);
-
-                for (int j = previousCommonWordIndex + 1; j < words.length; j++) {
-                    if (sourceWord.equals(words[j])) {
-                        if (j != previousCommonWordIndex + 1) {
-                            int firstDifferentPosition = previousCommonWordIndex < 0 ? 0 :
-                                extractRangeEndFromLong(wordLimits[previousCommonWordIndex]);
-                            int lastDifferentPosition = extractRangeStartFromLong(wordLimits[j]);
-                            ssb.setSpan(highlightSpan(nbHighlightSpans++),
-                                    shift + firstDifferentPosition, shift + lastDifferentPosition,
-                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-                        } else {
-                            // Compare characters between words
-                            int previousSourceWordEnd = i == 0 ? 0 :
-                                extractRangeEndFromLong(sourceWordLimits[i - 1]);
-                            int sourceWordStart = extractRangeStartFromLong(sourceWordLimits[i]);
-                            String sourceSpaces = sourceText.substring(previousSourceWordEnd,
-                                    sourceWordStart);
-
-                            int previousWordEnd = j == 0 ? 0 :
-                                extractRangeEndFromLong(wordLimits[j - 1]);
-                            int currentWordStart = extractRangeStartFromLong(wordLimits[j]);
-                            String textSpaces = text.substring(previousWordEnd, currentWordStart);
-
-                            if (!sourceSpaces.equals(textSpaces)) {
-                                ssb.setSpan(highlightSpan(nbHighlightSpans++),
-                                        shift + previousWordEnd, shift + currentWordStart,
-                                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-                            }
-                        }
-                        previousCommonWordIndex = j;
-                        break;
-                    }
-                }
-            }
-
-            // Finally, compare ends of Strings
-            if (previousCommonWordIndex < words.length - 1) {
-                int firstDifferentPosition = previousCommonWordIndex < 0 ? 0 :
-                    extractRangeEndFromLong(wordLimits[previousCommonWordIndex]);
-                int lastDifferentPosition = text.length();
-                ssb.setSpan(highlightSpan(nbHighlightSpans++),
-                        shift + firstDifferentPosition, shift + lastDifferentPosition,
-                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            } else {
-                int lastSourceWordEnd = sourceWordLimits.length == 0 ? 0 :
-                    extractRangeEndFromLong(sourceWordLimits[sourceWordLimits.length - 1]);
-                String sourceSpaces = sourceText.substring(lastSourceWordEnd, sourceText.length());
-
-                int lastCommonTextWordEnd = previousCommonWordIndex < 0 ? 0 :
-                    extractRangeEndFromLong(wordLimits[previousCommonWordIndex]);
-                String textSpaces = text.substring(lastCommonTextWordEnd, text.length());
-
-                if (!sourceSpaces.equals(textSpaces) && textSpaces.length() > 0) {
-                    ssb.setSpan(highlightSpan(nbHighlightSpans++),
-                            shift + lastCommonTextWordEnd, shift + text.length(),
-                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-                }
-            }
-
-            // Final part, text after the current suggestion range.
-            ssb.append(mText.subSequence(spanEnd, unionEnd).toString());
+            // Add the text before and after the span.
+            suggestionInfo.text.insert(0, mText.subSequence(unionStart, spanStart).toString());
+            suggestionInfo.text.append(mText.subSequence(spanEnd, unionEnd).toString());
         }
 
         @Override
@@ -11069,14 +11008,21 @@
      * Hides the insertion controller and stops text selection mode, hiding the selection controller
      */
     private void hideControllers() {
-        hideInsertionPointCursorController();
-        stopSelectionActionMode();
+        hideCursorControllers();
+        hideSpanControllers();
+    }
 
+    private void hideSpanControllers() {
         if (mChangeWatcher != null) {
             mChangeWatcher.hideControllers();
         }
     }
 
+    private void hideCursorControllers() {
+        hideInsertionPointCursorController();
+        stopSelectionActionMode();
+    }
+
     /**
      * Get the character offset closest to the specified absolute position. A typical use case is to
      * pass the result of {@link MotionEvent#getX()} and {@link MotionEvent#getY()} to this method.
@@ -11291,10 +11237,6 @@
             case TEXT_DIRECTION_ANY_RTL:
                 mTextDir = TextDirectionHeuristics.ANYRTL_LTR;
                 break;
-            case TEXT_DIRECTION_CHAR_COUNT:
-                mTextDir = (defaultIsRtl ? TextDirectionHeuristics.CHARCOUNT_RTL:
-                        TextDirectionHeuristics.CHARCOUNT_LTR);
-                break;
             case TEXT_DIRECTION_LTR:
                 mTextDir = TextDirectionHeuristics.LTR;
                 break;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index cfecca5..90d19fd 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -783,6 +783,7 @@
         private Object mTag;
         private Drawable mIcon;
         private CharSequence mText;
+        private CharSequence mContentDesc;
         private int mPosition = -1;
         private View mCustomView;
 
@@ -878,6 +879,25 @@
         public void select() {
             selectTab(this);
         }
+
+        @Override
+        public Tab setContentDescription(int resId) {
+            return setContentDescription(mContext.getResources().getText(resId));
+        }
+
+        @Override
+        public Tab setContentDescription(CharSequence contentDesc) {
+            mContentDesc = contentDesc;
+            if (mPosition >= 0) {
+                mTabScrollView.updateTab(mPosition);
+            }
+            return this;
+        }
+
+        @Override
+        public CharSequence getContentDescription() {
+            return mContentDesc;
+        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index 71f9364..5baed75 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -443,6 +443,8 @@
                     mTextView.setVisibility(GONE);
                     mTextView.setText(null);
                 }
+
+                setContentDescription(tab.getContentDescription());
             }
         }
 
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index cd1f8ba..173279e 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -79,6 +79,7 @@
     private static final int HIDE_ANIMATION_DURATION = RETURN_TO_HOME_DELAY;
     private static final int SHOW_ANIMATION_DURATION = 0;
     private static final int SHOW_ANIMATION_DELAY = 0;
+    private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f;
     private TimeInterpolator mChevronAnimationInterpolator = Ease.Quad.easeOut;
 
     private ArrayList<TargetDrawable> mTargetDrawables = new ArrayList<TargetDrawable>();
@@ -663,7 +664,7 @@
         final float y = event.getY();
         final float dx = x - mWaveCenterX;
         final float dy = y - mWaveCenterY;
-        if (dist2(dx,dy) <= square(mTapRadius)) {
+        if (dist2(dx,dy) <= getScaledTapRadiusSquared()) {
             if (DEBUG) Log.v(TAG, "** Handle HIT");
             switchToState(STATE_FIRST_TOUCH, x, y);
             moveHandleTo(x, y, false);
@@ -684,7 +685,7 @@
                 case MotionEvent.ACTION_HOVER_MOVE:
                     final float dx = event.getX() - mWaveCenterX;
                     final float dy = event.getY() - mWaveCenterY;
-                    if (dist2(dx,dy) <= square(mTapRadius)) {
+                    if (dist2(dx,dy) <= getScaledTapRadiusSquared()) {
                         if (!mWaveHovered) {
                             mWaveHovered = true;
                             final long timeSinceLastHoverExitMillis =
@@ -894,6 +895,16 @@
         return dx*dx + dy*dy;
     }
 
+    private float getScaledTapRadiusSquared() {
+        final float scaledTapRadius;
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            scaledTapRadius = TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mTapRadius;
+        } else {
+            scaledTapRadius = mTapRadius;
+        }
+        return square(scaledTapRadius);
+    }
+
     private void announceTargets() {
         StringBuilder utterance = new StringBuilder();
         final int targetCount = mTargetDrawables.size();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f50cecd..3fa4d48 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -75,6 +75,7 @@
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
     <protected-broadcast android:name="android.bluetooth.adapter.action.LOCAL_NAME_CHANGED" />
+    <protected-broadcast android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
     <protected-broadcast android:name="android.bluetooth.device.action.DISAPPEARED" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
@@ -86,6 +87,23 @@
     <protected-broadcast android:name="android.bluetooth.device.action.NAME_FAILED" />
     <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
     <protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
+    <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST" />
+    <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_REPLY" />
+    <protected-broadcast android:name="android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL" />
+    <protected-broadcast
+        android:name="android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast
+        android:name="android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED" />
+    <protected-broadcast
+        android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
+    <protected-broadcast
+        android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast
+        android:name="android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED" />
+    <protected-broadcast
+        android:name="android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED" />
+    <protected-broadcast
+        android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
 
     <protected-broadcast android:name="android.hardware.usb.action.USB_STATE" />
     <protected-broadcast android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index 2cc39438..b39d551 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -18,17 +18,17 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false">
-    <scale 	android:fromXScale="1.0" android:toXScale="1.0"
+        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+    <scale android:fromXScale="0.95" android:toXScale="1.0"
             android:fromYScale="0.95" android:toYScale="1.0"
             android:pivotX="50%p" android:pivotY="50%p"
-			android:fillEnabled="true" android:fillBefore="true"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
             android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="150"
-            android:duration="250" />
-    <alpha 	android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="150"
-            android:duration="250"/>
-</set>
+            android:startOffset="200"
+            android:duration="300" />
+    <alpha android:fromAlpha="0" android:toAlpha="1.0"
+            android:interpolator="@interpolator/decelerate_cubic"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+            android:startOffset="200"
+            android:duration="300"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index fded0be..ffbd38a 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -18,15 +18,18 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale="1.0" android:toYScale="0.0"
-            android:pivotX="50%p" android:pivotY="50%p"
-			android:fillEnabled="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="150" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"
-			android:fillEnabled="true" android:fillAfter="true"
-            android:interpolator="@interpolator/decelerate_cubic"
-            android:duration="150"/>
+        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+                android:interpolator="@interpolator/accelerate_cubic"
+                android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+                android:duration="200" />
+        <scale android:fromXScale="1.0" android:toXScale="1.2"
+                android:fromYScale="1.0" android:toYScale="0.8"
+                android:pivotX="50%p" android:pivotY="50%p"
+                android:interpolator="@interpolator/accelerate_quint"
+                android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+                android:duration="200" />
+        <!-- This is needed to keep the animation running while task_close_enter completes -->
+        <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+                android:duration="500" />
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index c8ffaaf..d64f856 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -18,17 +18,17 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale=".9" android:toYScale="1.0"
+        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top">
+    <scale android:fromXScale="1.2" android:toXScale="1.0"
+            android:fromYScale=".8" android:toYScale="1.0"
             android:pivotX="50%p" android:pivotY="50%p"
-            android:fillEnabled="true" android:fillBefore="true"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
             android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="150"
-            android:duration="250" />
+            android:startOffset="300"
+            android:duration="240" />
     <alpha android:fromAlpha="0" android:toAlpha="1.0"
-            android:fillEnabled="true" android:fillBefore="true"
-            android:interpolator="@interpolator/decelerate_quint"
-            android:startOffset="150"
-            android:duration="250"/>
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+            android:interpolator="@interpolator/decelerate_quad"
+            android:startOffset="300"
+            android:duration="300"/>
 </set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index 06f3fc4..19f92c0 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -18,15 +18,18 @@
 -->
 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:background="#ff000000" android:shareInterpolator="false">
-    <scale android:fromXScale="1.0" android:toXScale="1.0"
-            android:fromYScale="1.0" android:toYScale="0.0"
-            android:pivotX="50%p" android:pivotY="50%p"
-			android:fillEnabled="true" android:fillAfter="true"
-            android:interpolator="@interpolator/accelerate_cubic"
-            android:duration="150" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0"		
-			android:fillEnabled="true" android:fillAfter="true"
+        android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal">
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
             android:interpolator="@interpolator/decelerate_cubic"
-            android:duration="150"/>
+            android:duration="200"/>
+    <scale android:fromXScale="1.0" android:toXScale="0.95"
+            android:fromYScale="1.0" android:toYScale="0.95"
+            android:pivotX="50%p" android:pivotY="50%p"
+            android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+            android:interpolator="@interpolator/decelerate_quint"
+            android:duration="300" />
+    <!-- This is needed to keep the animation running while task_open_enter completes -->
+    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
+            android:duration="540" />
 </set>
\ No newline at end of file
diff --git a/core/res/res/values-bg/donottranslate-cldr.xml b/core/res/res/values-bg/donottranslate-cldr.xml
index c15e4a7..62f550a 100644
--- a/core/res/res/values-bg/donottranslate-cldr.xml
+++ b/core/res/res/values-bg/donottranslate-cldr.xml
@@ -144,6 +144,6 @@
     <string name="same_month_mdy1_mdy2">%3$s-%8$s %2$s %9$s</string>
     <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s %9$s, %1$s - %8$s %7$s y, %6$s</string>
     <string name="short_format_month">%b</string>
-    <string name="full_wday_month_day_no_year">E MMMM d</string>
+    <string name="full_wday_month_day_no_year">E, d MMMM</string>
     <string name="abbrev_wday_month_day_year">d MMM y, E</string>
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 8d5bd0b..ce6bbc2 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -60,7 +60,10 @@
        <item>@drawable/btn_check_off_disabled_focused_holo_dark</item>
        <item>@drawable/btn_check_off_disable_focused</item>
        <item>@drawable/btn_check_off_disable</item>
-       <item>@drawable/btn_check_off</item>
+       <item>@drawable/btn_check_label_background</item>
+       <item>@drawable/btn_check_holo_light</item>
+       <item>@drawable/btn_check_holo_dark</item>
+       <item>@drawable/btn_check</item>
        <item>@drawable/btn_radio_on_selected</item>
        <item>@drawable/btn_radio_on_pressed_holo_light</item>
        <item>@drawable/btn_radio_on_pressed_holo_dark</item>
@@ -86,7 +89,8 @@
        <item>@drawable/btn_radio_off_disabled_holo_dark</item>
        <item>@drawable/btn_radio_off_disabled_focused_holo_light</item>
        <item>@drawable/btn_radio_off_disabled_focused_holo_dark</item>
-       <item>@drawable/btn_radio_off</item>
+       <item>@drawable/btn_radio_label_background</item>
+       <item>@drawable/btn_radio</item>
        <item>@drawable/btn_default_transparent_normal</item>
        <item>@drawable/btn_default_small_selected</item>
        <item>@drawable/btn_default_small_pressed</item>
@@ -108,11 +112,49 @@
        <item>@drawable/btn_default_disabled_holo_dark</item>
        <item>@drawable/btn_default_disabled_focused_holo_light</item>
        <item>@drawable/btn_default_disabled_focused_holo_dark</item>
+       <item>@drawable/btn_default_holo_dark</item>
+       <item>@drawable/btn_default_holo_light</item>
+       <item>@drawable/btn_default</item>
+       <item>@drawable/btn_default_small</item>
        <item>@drawable/btn_dropdown_disabled</item>
        <item>@drawable/btn_dropdown_disabled_focused</item>
        <item>@drawable/btn_dropdown_normal</item>
        <item>@drawable/btn_dropdown_pressed</item>
        <item>@drawable/btn_dropdown_selected</item>
+       <item>@drawable/btn_star_label_background</item>
+       <item>@drawable/btn_star_big_off</item>
+       <item>@drawable/btn_star_big_on</item>
+       <item>@drawable/btn_star_big_on_disable</item>
+       <item>@drawable/btn_star_big_off_disable</item>
+       <item>@drawable/btn_star_big_on_pressed</item>
+       <item>@drawable/btn_star_big_off_pressed</item>
+       <item>@drawable/btn_star_big_on_selected</item>
+       <item>@drawable/btn_star_big_off_selected</item>
+       <item>@drawable/btn_star_big_on_disable_focused</item>
+       <item>@drawable/btn_star_big_off_disable_focused</item>
+       <item>@drawable/btn_star_off_normal_holo_light</item>
+       <item>@drawable/btn_star_on_normal_holo_light</item>
+       <item>@drawable/btn_star_on_disabled_holo_light</item>
+       <item>@drawable/btn_star_off_disabled_holo_light</item>
+       <item>@drawable/btn_star_on_pressed_holo_light</item>
+       <item>@drawable/btn_star_off_pressed_holo_light</item>
+       <item>@drawable/btn_star_on_focused_holo_light</item>
+       <item>@drawable/btn_star_off_focused_holo_light</item>
+       <item>@drawable/btn_star_on_disabled_focused_holo_light</item>
+       <item>@drawable/btn_star_off_disabled_focused_holo_light</item>
+       <item>@drawable/btn_star_holo_light</item>
+       <item>@drawable/btn_star_off_normal_holo_dark</item>
+       <item>@drawable/btn_star_on_normal_holo_dark</item>
+       <item>@drawable/btn_star_on_disabled_holo_dark</item>
+       <item>@drawable/btn_star_off_disabled_holo_dark</item>
+       <item>@drawable/btn_star_on_pressed_holo_dark</item>
+       <item>@drawable/btn_star_off_pressed_holo_dark</item>
+       <item>@drawable/btn_star_on_focused_holo_dark</item>
+       <item>@drawable/btn_star_off_focused_holo_dark</item>
+       <item>@drawable/btn_star_on_disabled_focused_holo_dark</item>
+       <item>@drawable/btn_star_off_disabled_focused_holo_dark</item>
+       <item>@drawable/btn_star_holo_dark</item>
+       <item>@drawable/btn_star</item>
        <item>@drawable/btn_toggle_on_pressed_holo_light</item>
        <item>@drawable/btn_toggle_on_pressed_holo_dark</item>
        <item>@drawable/btn_toggle_on_normal_holo_light</item>
@@ -135,7 +177,13 @@
        <item>@drawable/btn_toggle_off_disabled_focused_holo_light</item>
        <item>@drawable/btn_toggle_off_disabled_focused_holo_dark</item>
        <item>@drawable/btn_toggle_off</item>
-       <item>@drawable/ic_emergency</item>
+       <item>@drawable/btn_toggle_holo_light</item>
+       <item>@drawable/btn_toggle_holo_dark</item>
+       <item>@drawable/btn_toggle</item>
+       <item>@drawable/btn_toggle_bg</item>
+       <item>@drawable/btn_dropdown</item>
+       <item>@drawable/btn_dropdown</item>
+       <item>@drawable/light_header_dither</item>
        <item>@drawable/divider_horizontal_textfield</item>
        <item>@drawable/divider_horizontal_dark_opaque</item>
        <item>@drawable/divider_horizontal_dark</item>
@@ -145,6 +193,11 @@
        <item>@drawable/edit_text_holo_light</item>
        <item>@drawable/edit_text_holo_dark</item>
        <item>@drawable/edit_text</item>
+       <item>@drawable/text_cursor_holo_light</item>
+       <item>@drawable/text_cursor_holo_dark</item>
+       <item>@drawable/text_select_handle_left</item>
+       <item>@drawable/text_select_handle_right</item>
+       <item>@drawable/text_edit_paste_window</item>
        <item>@drawable/expander_close_holo_dark</item>
        <item>@drawable/expander_close_holo_light</item>
        <item>@drawable/expander_ic_maximized</item>
@@ -161,12 +214,16 @@
        <item>@drawable/list_selector_background_selected</item>
        <item>@drawable/list_selector_holo_dark</item>
        <item>@drawable/list_selector_holo_light</item>
+       <item>@drawable/list_section_divider_holo_light</item>
+       <item>@drawable/list_section_divider_holo_dark</item>
        <item>@drawable/menu_background</item>
        <item>@drawable/menu_background_fill_parent_width</item>
        <item>@drawable/menu_hardkey_panel_holo_dark</item>
        <item>@drawable/menu_hardkey_panel_holo_light</item>
        <item>@drawable/menu_submenu_background</item>
        <item>@drawable/menu_selector</item>
+       <item>@drawable/menu_dropdown_panel_holo_light</item>
+       <item>@drawable/menu_dropdown_panel_holo_dark</item>
        <item>@drawable/overscroll_edge</item>
        <item>@drawable/overscroll_glow</item>
        <item>@drawable/panel_background</item>
@@ -252,6 +309,8 @@
        <item>@drawable/btn_cab_done_pressed_holo_dark</item>
        <item>@drawable/btn_cab_done_focused_holo_dark</item>
        <item>@drawable/btn_cab_done_pressed_holo_light</item>
+       <item>@drawable/btn_cab_done_holo_light</item>
+       <item>@drawable/btn_cab_done_holo_dark</item>
        <item>@drawable/ic_menu_close_clear_cancel</item>
        <item>@drawable/ic_menu_copy_holo_dark</item>
        <item>@drawable/ic_menu_copy_holo_light</item>
@@ -262,6 +321,14 @@
        <item>@drawable/ic_menu_moreoverflow_holo_light</item>
        <item>@drawable/ic_menu_paste_holo_dark</item>
        <item>@drawable/ic_menu_paste_holo_light</item>
+       <item>@drawable/ic_menu_selectall_holo_light</item>
+       <item>@drawable/ic_menu_selectall_holo_dark</item>
+       <item>@drawable/ic_clear</item>
+       <item>@drawable/ic_clear_disabled</item>
+       <item>@drawable/ic_clear_normal</item>
+       <item>@drawable/ic_search</item>
+       <item>@drawable/ic_go</item>
+       <item>@drawable/ic_voice_search</item>
        <item>@drawable/dialog_bottom_holo_dark</item>
        <item>@drawable/dialog_bottom_holo_light</item>
        <item>@drawable/dialog_full_holo_dark</item>
@@ -275,12 +342,67 @@
        <item>@drawable/ic_dialog_alert_holo_light</item>
        <item>@drawable/list_divider_holo_dark</item>
        <item>@drawable/list_divider_holo_light</item>
-        <!-- Visual lock screen -->
-        <item>@drawable/indicator_code_lock_drag_direction_green_up</item>
-        <item>@drawable/indicator_code_lock_drag_direction_red_up</item>
-        <item>@drawable/indicator_code_lock_point_area_default</item>
-        <item>@drawable/indicator_code_lock_point_area_green</item>
-        <item>@drawable/indicator_code_lock_point_area_red</item>
+       <item>@drawable/list_divider_holo_light</item>
+       <item>@drawable/ic_lockscreen_handle</item>
+       <item>@drawable/ic_lockscreen_outerring</item>
+       <item>@drawable/ic_lockscreen_chevron_left</item>
+       <item>@drawable/ic_lockscreen_chevron_right</item>
+       <item>@drawable/ab_transparent_dark_holo</item>
+       <item>@drawable/ab_stacked_transparent_dark_holo</item>
+       <item>@drawable/ab_bottom_transparent_dark_holo</item>
+       <item>@drawable/ab_solid_dark_holo</item>
+       <item>@drawable/ab_stacked_solid_dark_holo</item>
+       <item>@drawable/ab_bottom_solid_dark_holo</item>
+       <item>@drawable/ab_transparent_light_holo</item>
+       <item>@drawable/ab_stacked_transparent_light_holo</item>
+       <item>@drawable/ab_bottom_transparent_light_holo</item>
+       <item>@drawable/ab_solid_light_holo</item>
+       <item>@drawable/ab_stacked_solid_light_holo</item>
+       <item>@drawable/ab_bottom_solid_light_holo</item>
+       <item>@drawable/ab_solid_shadow_holo</item>
+       <item>@drawable/item_background_holo_dark</item>
+       <item>@drawable/item_background_holo_light</item>
+       <item>@drawable/ic_ab_back_holo_dark</item>
+       <item>@drawable/ic_ab_back_holo_light</item>
+       <item>@drawable/fastscroll_thumb_holo</item>
+       <item>@drawable/fastscroll_thumb_pressed_holo</item>
+       <item>@drawable/fastscroll_thumb_default_holo</item>
+       <item>@drawable/fastscroll_track_holo_dark</item>
+       <item>@drawable/fastscroll_track_pressed_holo_dark</item>
+       <item>@drawable/fastscroll_track_default_holo_dark</item>
+       <item>@drawable/fastscroll_label_left_holo_dark</item>
+       <item>@drawable/fastscroll_label_right_holo_dark</item>
+       <item>@drawable/fastscroll_track_holo_light</item>
+       <item>@drawable/fastscroll_track_pressed_holo_light</item>
+       <item>@drawable/fastscroll_track_default_holo_light</item>
+       <item>@drawable/fastscroll_label_left_holo_light</item>
+       <item>@drawable/fastscroll_label_right_holo_light</item>
+       <item>@drawable/editbox_dropdown_background_dark</item>
+       <item>@drawable/textfield_searchview_holo_dark</item>
+       <item>@drawable/textfield_searchview_right_holo_dark</item>
+       <item>@drawable/textfield_searchview_holo_light</item>
+       <item>@drawable/textfield_searchview_right_holo_light</item>
+       <item>@drawable/textfield_search_selected_holo_dark</item>
+       <item>@drawable/textfield_search_default_holo_dark</item>
+       <item>@drawable/textfield_search_right_selected_holo_dark</item>
+       <item>@drawable/textfield_search_right_default_holo_dark</item>
+       <item>@drawable/textfield_search_selected_holo_light</item>
+       <item>@drawable/textfield_search_default_holo_light</item>
+       <item>@drawable/textfield_search_right_selected_holo_light</item>
+       <item>@drawable/textfield_search_right_default_holo_light</item>
+       <item>@drawable/tab_indicator_holo</item>
+       <item>@drawable/tab_unselected_holo</item>
+       <item>@drawable/tab_selected_holo</item>
+       <item>@drawable/tab_unselected_focused_holo</item>
+       <item>@drawable/tab_selected_focused_holo</item>
+       <item>@drawable/tab_unselected_pressed_holo</item>
+       <item>@drawable/tab_selected_pressed_holo</item>
+       <item>@drawable/quickcontact_badge_overlay_dark</item>
+       <item>@drawable/quickcontact_badge_overlay_normal_dark</item>
+       <item>@drawable/quickcontact_badge_overlay_pressed_dark</item>
+       <item>@drawable/quickcontact_badge_overlay_light</item>
+       <item>@drawable/quickcontact_badge_overlay_normal_light</item>
+       <item>@drawable/quickcontact_badge_overlay_pressed_light</item>
     </array>
 
     <!-- Do not translate. These are all of the color state list resources that should be
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index fd525f3..ddb9942 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -133,8 +133,8 @@
     <color name="dim_foreground_inverse_holo_light">#bebebe</color>
     <color name="dim_foreground_inverse_disabled_holo_light">#80bebebe</color>
     <color name="hint_foreground_holo_light">#808080</color>
-    <color name="highlighted_text_holo_dark">#4c33b5e5</color>
-    <color name="highlighted_text_holo_light">#4c33b5e5</color>
+    <color name="highlighted_text_holo_dark">#6633b5e5</color>
+    <color name="highlighted_text_holo_light">#6633b5e5</color>
     <color name="link_text_holo_dark">#5c5cff</color>
     <color name="link_text_holo_light">#0000ee</color>
 
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 7dc95db..5f65faf 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -198,40 +198,6 @@
     }
 
     @SmallTest
-    public void testCharCountHeuristic() {
-        LinearLayout ll = new LinearLayout(getActivity());
-        ll.setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
-
-        TextView tv = new TextView(getActivity());
-        ll.addView(tv);
-
-        tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
-        tv.setText("this is a test");
-        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
-
-         // resetResolvedTextDirection is not part of the public API so simply use setTextDirection
-        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
-        tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
-        tv.setText("\u05DD\u05DE"); // hebrew
-        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
-
-        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
-        tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
-        tv.setText("this is a test \u05DD\u05DE"); // latin more than 60% + hebrew
-        assertEquals(View.TEXT_DIRECTION_LTR, tv.getResolvedTextDirection());
-
-        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
-        tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
-        tv.setText("t \u05DD\u05DE"); // latin + hebrew more than 60%
-        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
-
-        tv.setTextDirection(View.TEXT_DIRECTION_LTR);
-        tv.setTextDirection(View.TEXT_DIRECTION_CHAR_COUNT);
-        tv.setText("ab \u05DD\u05DE"); // latin + hebrew at 50% each
-        assertEquals(View.TEXT_DIRECTION_RTL, tv.getResolvedTextDirection());
-    }
-
-    @SmallTest
     public void testResetTextDirection() {
         final TextViewTestActivity activity = getActivity();
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index d233f92..9d9b6ea 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1347,11 +1347,10 @@
                     // currently controlled by the same client process.
                     if ((AudioService.this.mMode == AudioSystem.MODE_NORMAL ||
                             mSetModeDeathHandlers.get(0).getPid() == mCreatorPid) &&
-                            mBluetoothHeadsetDevice != null &&
                             (mScoAudioState == SCO_STATE_INACTIVE ||
                              mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) {
                         if (mScoAudioState == SCO_STATE_INACTIVE) {
-                            if (mBluetoothHeadset != null) {
+                            if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
                                 if (mBluetoothHeadset.startScoUsingVirtualVoiceCall(
                                         mBluetoothHeadsetDevice)) {
                                     mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
@@ -1370,11 +1369,10 @@
                         broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
                     }
                 } else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED &&
-                              mBluetoothHeadsetDevice != null &&
                               (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL ||
                                mScoAudioState == SCO_STATE_ACTIVATE_REQ)) {
                     if (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL) {
-                        if (mBluetoothHeadset != null) {
+                        if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
                             if (!mBluetoothHeadset.stopScoUsingVirtualVoiceCall(
                                     mBluetoothHeadsetDevice)) {
                                 mScoAudioState = SCO_STATE_INACTIVE;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 3b6c64d..7509239 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -1182,16 +1182,33 @@
                                false);
 
         if (result == NO_ERROR) {
+            uint32_t user = cblk->user;
+            uint32_t server = cblk->server;
             // restore write index and set other indexes to reflect empty buffer status
-            mCblk->user = cblk->user;
-            mCblk->server = cblk->user;
-            mCblk->userBase = cblk->user;
-            mCblk->serverBase = cblk->user;
+            mCblk->user = user;
+            mCblk->server = user;
+            mCblk->userBase = user;
+            mCblk->serverBase = user;
             // restore loop: this is not guaranteed to succeed if new frame count is not
             // compatible with loop length
             setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
             if (!fromStart) {
                 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+                // Make sure that a client relying on callback events indicating underrun or
+                // the actual amount of audio frames played (e.g SoundPool) receives them.
+                if (mSharedBuffer == 0) {
+                    uint32_t frames = 0;
+                    if (user > server) {
+                        frames = ((user - server) > mCblk->frameCount) ?
+                                mCblk->frameCount : (user - server);
+                        memset(mCblk->buffers, 0, frames * mCblk->frameSize);
+                    }
+                    // restart playback even if buffer is not completely filled.
+                    android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags);
+                    // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to
+                    // the client
+                    mCblk->stepUser(frames);
+                }
             }
             if (mActive) {
                 result = mAudioTrack->start();
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 0fc6a8a..37a82e9 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -148,10 +148,10 @@
         const sp<IMediaPlayerService>& service(getMediaPlayerService());
         if (service != 0) {
             sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
-            err = attachNewPlayer(player);
-            if (err == NO_ERROR) {
-                err = mPlayer->setDataSource(url, headers);
+            if (NO_ERROR != player->setDataSource(url, headers)) {
+                player.clear();
             }
+            err = attachNewPlayer(player);
         }
     }
     return err;
@@ -164,10 +164,10 @@
     const sp<IMediaPlayerService>& service(getMediaPlayerService());
     if (service != 0) {
         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
-        err = attachNewPlayer(player);
-        if (err == NO_ERROR) {
-            err = mPlayer->setDataSource(fd, offset, length);
+        if (NO_ERROR != player->setDataSource(fd, offset, length)) {
+            player.clear();
         }
+        err = attachNewPlayer(player);
     }
     return err;
 }
@@ -179,10 +179,10 @@
     const sp<IMediaPlayerService>& service(getMediaPlayerService());
     if (service != 0) {
         sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
-        err = attachNewPlayer(player);
-        if (err == NO_ERROR) {
-            err = mPlayer->setDataSource(source);
+        if (NO_ERROR != player->setDataSource(source)) {
+            player.clear();
         }
+        err = attachNewPlayer(player);
     }
     return err;
 }
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 09f91f5..92e84c2 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -52,10 +52,7 @@
         *post_id3_pos = 0;
     }
 
-    bool resync_from_head = false;
     if (*inout_pos == 0) {
-        resync_from_head = true;
-
         // Skip an optional ID3 header if syncing at the very beginning
         // of the datasource.
 
@@ -140,20 +137,22 @@
 
         uint32_t header = U32_AT(tmp);
 
+        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
+            ++pos;
+            ++tmp;
+            --remainingBytes;
+            continue;
+        }
+
         size_t frame_size;
-        if ((match_header != 0 && (header & kMask) != (match_header & kMask))
-                || !GetMPEGAudioFrameSize(header, &frame_size)) {
-            if (resync_from_head) {
-                // This isn't a valid mp3 file because it failed to detect
-                // a header while a valid mp3 file should have a valid
-                // header here.
-                break;
-            } else {
-                ++pos;
-                ++tmp;
-                --remainingBytes;
-                continue;
-            }
+        int sample_rate, num_channels, bitrate;
+        if (!GetMPEGAudioFrameSize(
+                    header, &frame_size,
+                    &sample_rate, &num_channels, &bitrate)) {
+            ++pos;
+            ++tmp;
+            --remainingBytes;
+            continue;
         }
 
         LOGV("found possible 1st frame at %lld (header = 0x%08x)", pos, header);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 778c0b5..c74cb5a 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -283,8 +283,15 @@
         return NULL;
     }
 
+    sp<MetaData> fileMeta = mExtractor->getMetaData();
+
+    if (fileMeta == NULL) {
+        LOGV("extractor doesn't publish metadata, failed to initialize?");
+        return NULL;
+    }
+
     int32_t drm = 0;
-    if (mExtractor->getMetaData()->findInt32(kKeyIsDRM, &drm) && drm != 0) {
+    if (fileMeta->findInt32(kKeyIsDRM, &drm) && drm != 0) {
         LOGE("frame grab not allowed.");
         return NULL;
     }
@@ -320,7 +327,7 @@
     const void *data;
     uint32_t type;
     size_t dataSize;
-    if (mExtractor->getMetaData()->findData(kKeyAlbumArt, &type, &data, &dataSize)
+    if (fileMeta->findData(kKeyAlbumArt, &type, &data, &dataSize)
             && mAlbumArt == NULL) {
         mAlbumArt = new MediaAlbumArt;
         mAlbumArt->mSize = dataSize;
@@ -387,6 +394,11 @@
 void StagefrightMetadataRetriever::parseMetaData() {
     sp<MetaData> meta = mExtractor->getMetaData();
 
+    if (meta == NULL) {
+        LOGV("extractor doesn't publish metadata, failed to initialize?");
+        return;
+    }
+
     struct Map {
         int from;
         int to;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 0810643..0f79515 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -26,6 +26,7 @@
 import android.hardware.Camera.PreviewCallback;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
+import android.media.EncoderCapabilities.VideoEncoderCap;
 import android.os.ConditionVariable;
 import android.os.Looper;
 import android.os.SystemClock;
@@ -35,6 +36,7 @@
 import android.util.Log;
 import android.view.SurfaceHolder;
 
+import java.util.List;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -48,11 +50,12 @@
 import android.media.MediaMetadataRetriever;
 import com.android.mediaframeworktest.MediaProfileReader;
 
-import android.hardware.Camera.PreviewCallback;
-
 /**
  * Junit / Instrumentation - performance measurement for media player and 
  * recorder
+ *
+ * FIXME:
+ * Add tests on H264 video encoder
  */
 public class MediaPlayerPerformance extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
 
@@ -81,6 +84,8 @@
     private static int DECODER_LIMIT = 150;
     private static int CAMERA_LIMIT = 80;
 
+    private static List<VideoEncoderCap> videoEncoders = MediaProfileReader.getVideoEncoders();
+
     Camera mCamera;
 
     public MediaPlayerPerformance() {
@@ -360,6 +365,16 @@
         assertTrue("H264 playback memory test", memoryResult);
     }
 
+    private int getMaxFrameRateForVideoEncoder(int codec) {
+        int frameRate = -1;
+        for (VideoEncoderCap cap: videoEncoders) {
+            if (cap.mCodec == MediaRecorder.VideoEncoder.H263) {
+                frameRate = cap.mMaxFrameRate;
+            }
+        }
+        return frameRate;
+    }
+
     // Test case 4: Capture the memory usage after every 20 video only recorded
     @LargeTest
     public void testH263RecordVideoOnlyMemoryUsage() throws Exception {
@@ -369,8 +384,10 @@
         File videoH263RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut, true));
         output.write("H263 video record only\n");
+        int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+        assertTrue("H263 video recording frame rate", frameRate != -1);
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
+            assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true));
             getMemoryWriteToLog(output, i);
         }
@@ -389,8 +406,10 @@
         File videoMp4RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut, true));
         output.write("MPEG4 video record only\n");
+        int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
+        assertTrue("MPEG4 video recording frame rate", frameRate != -1);
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
+            assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true));
             getMemoryWriteToLog(output, i);
         }
@@ -409,9 +428,11 @@
 
         File videoRecordAudioMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
         Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut, true));
+        int frameRate = getMaxFrameRateForVideoEncoder(MediaRecorder.VideoEncoder.H263);
+        assertTrue("H263 video recording frame rate", frameRate != -1);
         output.write("Audio and h263 video record\n");
         for (int i = 0; i < NUM_STRESS_LOOP; i++) {
-            assertTrue(stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
+            assertTrue(stressVideoRecord(frameRate, 352, 288, MediaRecorder.VideoEncoder.H263,
                     MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, false));
             getMemoryWriteToLog(output, i);
         }
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index ca62908..1e43195 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -148,10 +148,13 @@
     if (egl_tls_t::logNoContextCall()) {
         LOGE("call to OpenGL ES API with no current context "
              "(logged once per thread)");
-        LOGE("call stack before error:");
-        CallStack stack;
-        stack.update();
-        stack.dump();
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.callstack", value, "0");
+        if (atoi(value)) {
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
     }
     return 0;
 }
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index 961a61e..f3c8d2c 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -14,9 +14,13 @@
  ** limitations under the License.
  */
 
+#include <stdlib.h>
 #include <pthread.h>
 
 #include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/CallStack.h>
 
 #include <EGL/egl.h>
 
@@ -69,6 +73,13 @@
     if (tls->error != error) {
         LOGE("%s:%d error %x (%s)", caller, line, error, egl_strerror(error));
         tls->error = error;
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.callstack", value, "0");
+        if (atoi(value)) {
+            CallStack stack;
+            stack.update();
+            stack.dump();
+        }
     }
 }
 
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
index d17aae6..babddb1 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
index 5a89d76..56cd6f9 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
new file mode 100644
index 0000000..23ce001
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
new file mode 100644
index 0000000..d0754a39
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
index 9490833..bf1bad5 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
index 0ff3efd..320d92d 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
new file mode 100644
index 0000000..b58e4dc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
new file mode 100644
index 0000000..604eb75
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
index 6455423..cf9bd8e 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
index bfa8bb4..8eee4d9 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
new file mode 100644
index 0000000..5e67545
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
new file mode 100644
index 0000000..e56aeda
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
new file mode 100644
index 0000000..b37dc39
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+        android:drawable="@drawable/ic_notify_quicksettings_pressed" />
+    <item android:drawable="@drawable/ic_notify_quicksettings_normal" />
+</selector>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
index d235859..5e254e8 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml
@@ -89,9 +89,10 @@
             <TextView android:id="@+id/time_solid"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:textAppearance="@style/TextAppearance.StatusBar.Clock"
                 android:singleLine="true"
                 android:textSize="40sp"
-                android:textColor="#ff525e79" />
+                />
         </com.android.systemui.statusbar.tablet.HoloClock>
 
         <TextView
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index f3d0bee..a63893e 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -72,13 +72,12 @@
 
         <com.android.systemui.statusbar.policy.Clock
             android:id="@+id/clock"
-            android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
+            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:singleLine="true"
             android:paddingRight="6dip"
             android:textSize="16sp"
-            android:textStyle="bold"
             android:gravity="center_vertical|left"
             />
     </LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index b5274a3..0b3fb98 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -34,9 +34,7 @@
         android:paddingRight="3dp"
         >
         <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
-            android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title"
-            android:textColor="@android:color/holo_blue_light"
-            android:textStyle="normal"
+            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_alignParentLeft="true"
@@ -58,22 +56,24 @@
             android:textColor="?android:attr/textColorSecondary"
             />
         -->
+
         <ImageView android:id="@+id/settings_button"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_toRightOf="@id/date"
-            android:paddingLeft="16dp"
-            android:paddingRight="16dp"
-            android:src="@drawable/ic_sysbar_quicksettings"
+            android:paddingLeft="8dp"
+            android:paddingRight="8dp"
+            android:src="@drawable/ic_notify_quicksettings"
             />
+
         <ImageView android:id="@+id/clear_all_button"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
             android:layout_alignParentRight="true"
-            android:paddingLeft="16dp"
-            android:paddingRight="16dp"
+            android:paddingLeft="8dp"
+            android:paddingRight="8dp"
             android:src="@drawable/ic_notify_clear"
-            />
+            />            
     </RelativeLayout>
 
     <View
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ad236b7..3d49cd1 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -40,6 +40,12 @@
         <item name="android:textColor">#FFFFFFFF</item>
     </style>
 
+    <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
+        <item name="android:textSize">16sp</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">@android:color/holo_blue_light</item>
+    </style>
+
     <style name="Animation" />
 
     <style name="Animation.ShirtPocketPanel">
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 8be250b..6ec3443 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1829,7 +1829,6 @@
         Drawable bg;
 
         /// ---------- Tracking View --------------
-        pixelFormat = PixelFormat.RGBX_8888;
         bg = mTrackingView.getBackground();
         if (bg != null) {
             pixelFormat = bg.getOpacity();
@@ -1843,7 +1842,10 @@
                 | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                 | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                pixelFormat);
+                PixelFormat.OPAQUE);
+        if (ActivityManager.isHighEndGfx(mDisplay)) {
+            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        }
 //        lp.token = mStatusBarView.getWindowToken();
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.setTitle("TrackingView");
@@ -1870,6 +1872,9 @@
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                 | WindowManager.LayoutParams.FLAG_DITHER
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+        if (ActivityManager.isHighEndGfx(mDisplay)) {
+            lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+        }
         lp.format = pixelFormat;
         lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
         lp.setTitle("StatusBarExpanded");
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 62abf20..0de2de95 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -180,7 +180,7 @@
 
     private Runnable mRecreateRunnable = new Runnable() {
         public void run() {
-            updateScreen(mMode, false);
+            updateScreen(mMode, true);
         }
     };
 
@@ -400,7 +400,7 @@
             // then finish and get out
             if (mEnableFallback || mAccountIndex >= mAccounts.length) {
                 if (mUnlockScreen == null) {
-                    Log.w(TAG, "no unlock screen when trying to enable fallback");
+                    if (DEBUG) Log.w(TAG, "no unlock screen when trying to enable fallback");
                 } else if (mUnlockScreen instanceof PatternUnlockScreen) {
                     ((PatternUnlockScreen)mUnlockScreen).setEnableFallback(mEnableFallback);
                 }
@@ -459,7 +459,7 @@
     public void reset() {
         mIsVerifyUnlockOnly = false;
         mForgotPattern = false;
-        updateScreen(getInitialMode(), false);
+        post(mRecreateRunnable);
     }
 
     @Override
@@ -485,9 +485,7 @@
 
     private void recreateLockScreen() {
         if (mLockScreen != null) {
-            if (mLockScreen.getVisibility() == View.VISIBLE) {
-                ((KeyguardScreen) mLockScreen).onPause();
-            }
+            ((KeyguardScreen) mLockScreen).onPause();
             ((KeyguardScreen) mLockScreen).cleanUp();
             removeView(mLockScreen);
         }
@@ -499,9 +497,7 @@
 
     private void recreateUnlockScreen(UnlockMode unlockMode) {
         if (mUnlockScreen != null) {
-            if (mUnlockScreen.getVisibility() == View.VISIBLE) {
-                ((KeyguardScreen) mUnlockScreen).onPause();
-            }
+            ((KeyguardScreen) mUnlockScreen).onPause();
             ((KeyguardScreen) mUnlockScreen).cleanUp();
             removeView(mUnlockScreen);
         }
@@ -611,7 +607,7 @@
     private void updateScreen(Mode mode, boolean force) {
 
         if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode
-                + " last mode=" + mMode, new RuntimeException());
+                + " last mode=" + mMode + ", force = " + force, new RuntimeException());
 
         mMode = mode;
 
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 00aa14c..d806309 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -454,7 +454,7 @@
         }
     }
 
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -484,7 +484,7 @@
                             synchronized (mVolumeStates) {
                                 Set<String> keys = mVolumeStates.keySet();
                                 count = keys.size();
-                                paths = (String[])keys.toArray(new String[count]);
+                                paths = keys.toArray(new String[count]);
                                 states = new String[count];
                                 for (int i = 0; i < count; i++) {
                                     states[i] = mVolumeStates.get(paths[i]);
@@ -1761,6 +1761,37 @@
             Slog.i(TAG, "Send to OBB handler: " + action.toString());
     }
 
+    @Override
+    public int getEncryptionState() {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
+                "no permission to access the crypt keeper");
+
+        waitForReady();
+
+        try {
+            ArrayList<String> rsp = mConnector.doCommand("cryptfs cryptocomplete");
+            String[] tokens = rsp.get(0).split(" ");
+
+            if (tokens == null || tokens.length != 2) {
+                // Unexpected.
+                Slog.w(TAG, "Unexpected result from cryptfs cryptocomplete");
+                return ENCRYPTION_STATE_ERROR_UNKNOWN;
+            }
+
+            return Integer.parseInt(tokens[1]);
+
+        } catch (NumberFormatException e) {
+            // Bad result - unexpected.
+            Slog.w(TAG, "Unable to parse result from cryptfs cryptocomplete");
+            return ENCRYPTION_STATE_ERROR_UNKNOWN;
+        } catch (NativeDaemonConnectorException e) {
+            // Something bad happened.
+            Slog.w(TAG, "Error in communicating with cryptfs in validating");
+            return ENCRYPTION_STATE_ERROR_UNKNOWN;
+        }
+    }
+
+    @Override
     public int decryptStorage(String password) {
         if (TextUtils.isEmpty(password)) {
             throw new IllegalArgumentException("password cannot be empty");
@@ -2090,7 +2121,7 @@
         public void execute(ObbActionHandler handler) {
             try {
                 if (DEBUG_OBB)
-                    Slog.i(TAG, "Starting to execute action: " + this.toString());
+                    Slog.i(TAG, "Starting to execute action: " + toString());
                 mRetries++;
                 if (mRetries > MAX_RETRIES) {
                     Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
@@ -2147,7 +2178,7 @@
     }
 
     class MountObbAction extends ObbAction {
-        private String mKey;
+        private final String mKey;
 
         MountObbAction(ObbState obbState, String key) {
             super(obbState);
@@ -2258,7 +2289,7 @@
     }
 
     class UnmountObbAction extends ObbAction {
-        private boolean mForceUnmount;
+        private final boolean mForceUnmount;
 
         UnmountObbAction(ObbState obbState, boolean force) {
             super(obbState);
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 496210c..eb399ad 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -84,7 +84,7 @@
 
     // The minimum of the cosine between the vectors of two moving
     // pointers so they can be considered moving in the same direction.
-    private static final float MIN_ANGLE_COS = 0.866025404f; // cos(pi/6)
+    private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
 
     // The delay for sending a hover enter event.
     private static final long DELAY_SEND_HOVER_ENTER = 200;
@@ -364,13 +364,13 @@
                         }
 
                         mPerformLongPressDelayed.remove();
-                        mSendHoverDelayed.forceSendAndRemove();
-                        ensureHoverExitSent(event, pointerIdBits, policyFlags);
 
                         // If touch exploring announce the end of the gesture.
                         // Also do not click on the last explored location.
                         if (mTouchExploreGestureInProgress) {
                             mTouchExploreGestureInProgress = false;
+                            mSendHoverDelayed.forceSendAndRemove();
+                            ensureHoverExitSent(event, pointerIdBits, policyFlags);
                             mLastTouchExploreEvent = MotionEvent.obtain(event);
                             sendAccessibilityEvent(TYPE_TOUCH_EXPLORATION_GESTURE_END);
                             break;
@@ -384,6 +384,8 @@
                             final long exploreTime = mLastTouchExploreEvent.getEventTime();
                             final long deltaTime = eventTime - exploreTime;
                             if (deltaTime > ACTIVATION_TIME_SLOP) {
+                                mSendHoverDelayed.forceSendAndRemove();
+                                ensureHoverExitSent(event, pointerIdBits, policyFlags);
                                 mLastTouchExploreEvent = MotionEvent.obtain(event);
                                 break;
                             }
@@ -396,14 +398,25 @@
                                     - event.getY(pointerIndex);
                             final float deltaMove = (float) Math.hypot(deltaX, deltaY);
                             if (deltaMove > mTouchExplorationTapSlop) {
+                                mSendHoverDelayed.forceSendAndRemove();
+                                ensureHoverExitSent(event, pointerIdBits, policyFlags);
                                 mLastTouchExploreEvent = MotionEvent.obtain(event);
                                 break;
                             }
 
+                            // This is a tap so do not send hover events since
+                            // this events will result in firing the corresponding
+                            // accessibility events confusing the user about what
+                            // is actually clicked.
+                            mSendHoverDelayed.remove();
+                            ensureHoverExitSent(event, pointerIdBits, policyFlags);
+
                             // All preconditions are met, so click the last explored location.
                             sendActionDownAndUp(mLastTouchExploreEvent, policyFlags);
                             mLastTouchExploreEvent = null;
                         } else {
+                            mSendHoverDelayed.forceSendAndRemove();
+                            ensureHoverExitSent(event, pointerIdBits, policyFlags);
                             mLastTouchExploreEvent = MotionEvent.obtain(event);
                         }
                     } break;
@@ -782,7 +795,7 @@
         final float angleCos =
             firstXNormalized * secondXNormalized + firstYNormalized * secondYNormalized;
 
-        if (angleCos < MIN_ANGLE_COS) {
+        if (angleCos < MAX_DRAGGING_ANGLE_COS) {
             return false;
         }
 
diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java
index 49effa8..eb5cce7 100644
--- a/voip/java/com/android/server/sip/SipSessionGroup.java
+++ b/voip/java/com/android/server/sip/SipSessionGroup.java
@@ -883,12 +883,15 @@
             if (expires != null && (time < 0 || time > expires.getExpires())) {
                 time = expires.getExpires();
             }
+            if (time <= 0) {
+                time = EXPIRY_TIME;
+            }
             expires = (ExpiresHeader) response.getHeader(MinExpiresHeader.NAME);
             if (expires != null && time < expires.getExpires()) {
                 time = expires.getExpires();
             }
             Log.v(TAG, "Expiry time = " + time);
-            return (time > 0) ? time : EXPIRY_TIME;
+            return time;
         }
 
         private boolean registeringToReady(EventObject evt)
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
index 529b425..5f07bb5 100644
--- a/voip/jni/rtp/AudioGroup.cpp
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -628,12 +628,13 @@
     if (mode < 0 || mode > LAST_MODE) {
         return false;
     }
-    //FIXME: temporary code to overcome echo and mic gain issues on herring board.
-    // Must be modified/removed when proper support for voice processing query and control
-    // is included in audio framework
+    // FIXME: temporary code to overcome echo and mic gain issues on herring and tuna boards.
+    // Must be modified/removed when the root cause of the issue is fixed in the hardware or
+    // driver
     char value[PROPERTY_VALUE_MAX];
     property_get("ro.product.board", value, "");
-    if (mode == NORMAL && !strcmp(value, "herring")) {
+    if (mode == NORMAL &&
+            (!strcmp(value, "herring") || !strcmp(value, "tuna"))) {
         mode = ECHO_SUPPRESSION;
     }
     if (mMode == mode) {