Merge "Make animations persist after completion." into jb-dev
diff --git a/Android.mk b/Android.mk
index 5aaea97..79e3140 100644
--- a/Android.mk
+++ b/Android.mk
@@ -193,11 +193,12 @@
 	location/java/android/location/INetInitiatedListener.aidl \
 	media/java/android/media/IAudioService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
-    media/java/android/media/IAudioRoutesObserver.aidl \
+	media/java/android/media/IAudioRoutesObserver.aidl \
 	media/java/android/media/IMediaScannerListener.aidl \
 	media/java/android/media/IMediaScannerService.aidl \
 	media/java/android/media/IRemoteControlClient.aidl \
 	media/java/android/media/IRemoteControlDisplay.aidl \
+	media/java/android/media/IRemoteVolumeObserver.aidl \
 	media/java/android/media/IRingtonePlayer.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
diff --git a/api/current.txt b/api/current.txt
index 4a23046..3069221 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -676,6 +676,7 @@
     field public static final int measureAllChildren = 16843018; // 0x101010a
     field public static final int measureWithLargestChild = 16843476; // 0x10102d4
     field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
+    field public static final int mediaRouteTypes = 16843694; // 0x10103ae
     field public static final int menuCategory = 16843230; // 0x10101de
     field public static final int mimeType = 16842790; // 0x1010026
     field public static final int minDate = 16843583; // 0x101033f
@@ -11564,10 +11565,19 @@
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
     method public java.lang.CharSequence getName(android.content.Context);
+    method public int getPlaybackStream();
+    method public int getPlaybackType();
     method public java.lang.CharSequence getStatus();
     method public int getSupportedTypes();
     method public java.lang.Object getTag();
+    method public int getVolume();
+    method public int getVolumeHandling();
+    method public int getVolumeMax();
     method public void setTag(java.lang.Object);
+    field public static final int PLAYBACK_TYPE_LOCAL = 0; // 0x0
+    field public static final int PLAYBACK_TYPE_REMOTE = 1; // 0x1
+    field public static final int PLAYBACK_VOLUME_FIXED = 0; // 0x0
+    field public static final int PLAYBACK_VOLUME_VARIABLE = 1; // 0x1
   }
 
   public static class MediaRouter.SimpleCallback extends android.media.MediaRouter.Callback {
@@ -11587,8 +11597,20 @@
     method public void setIconResource(int);
     method public void setName(java.lang.CharSequence);
     method public void setName(int);
+    method public void setPlaybackStream(int);
+    method public void setPlaybackType(int);
     method public void setRemoteControlClient(android.media.RemoteControlClient);
     method public void setStatus(java.lang.CharSequence);
+    method public void setVolume(int);
+    method public void setVolumeCallback(android.media.MediaRouter.VolumeCallback);
+    method public void setVolumeHandling(int);
+    method public void setVolumeMax(int);
+  }
+
+  public static abstract class MediaRouter.VolumeCallback {
+    ctor public MediaRouter.VolumeCallback();
+    method public abstract void onVolumeSetRequest(android.media.MediaRouter.RouteInfo, int);
+    method public abstract void onVolumeUpdateRequest(android.media.MediaRouter.RouteInfo, int);
   }
 
   public class MediaScannerConnection implements android.content.ServiceConnection {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 225be9c..6b5048607 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -54,6 +54,7 @@
 #define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip"
 #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip"
 #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip"
+#define EXIT_PROP_NAME "service.bootanim.exit"
 
 extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
                            const struct timespec *request,
@@ -297,6 +298,9 @@
         r = movie();
     }
 
+    // No need to force exit anymore
+    property_set(EXIT_PROP_NAME, "0");
+
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglDestroyContext(mDisplay, mContext);
     eglDestroySurface(mDisplay, mSurface);
@@ -363,6 +367,8 @@
         const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
         if (sleepTime > 0)
             usleep(sleepTime);
+
+        checkExit();
     } while (!exitPending());
 
     glDeleteTextures(1, &mAndroid[0].name);
@@ -371,6 +377,16 @@
 }
 
 
+void BootAnimation::checkExit() {
+    // Allow surface flinger to gracefully request shutdown
+    char value[PROPERTY_VALUE_MAX];
+    property_get(EXIT_PROP_NAME, value, "0");
+    int exitnow = atoi(value);
+    if (exitnow) {
+        requestExit();
+    }
+}
+
 bool BootAnimation::movie()
 {
     ZipFileRO& zip(mZip);
@@ -397,20 +413,23 @@
         const char* l = line.string();
         int fps, width, height, count, pause;
         char path[256];
+        char pathType;
         if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
-            //ALOGD("> w=%d, h=%d, fps=%d", fps, width, height);
+            //LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
             animation.width = width;
             animation.height = height;
             animation.fps = fps;
         }
-        if (sscanf(l, "p %d %d %s", &count, &pause, path) == 3) {
-            //ALOGD("> count=%d, pause=%d, path=%s", count, pause, path);
+        else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
+            //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
             Animation::Part part;
+            part.playUntilComplete = pathType == 'c';
             part.count = count;
             part.pause = pause;
             part.path = path;
             animation.parts.add(part);
         }
+
         s = ++endl;
     }
 
@@ -472,13 +491,17 @@
     Region clearReg(Rect(mWidth, mHeight));
     clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height));
 
-    for (int i=0 ; i<pcount && !exitPending() ; i++) {
+    for (int i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
         glBindTexture(GL_TEXTURE_2D, 0);
 
         for (int r=0 ; !part.count || r<part.count ; r++) {
-            for (int j=0 ; j<fcount && !exitPending(); j++) {
+            // Exit any non playuntil complete parts immediately
+            if(exitPending() && !part.playUntilComplete)
+                break;
+
+            for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
                 const Animation::Frame& frame(part.frames[j]);
                 nsecs_t lastFrame = systemTime();
 
@@ -525,8 +548,15 @@
                         err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
                     } while (err<0 && errno == EINTR);
                 }
+
+                checkExit();
             }
+
             usleep(part.pause * ns2us(frameDuration));
+
+            // For infinite parts, we've now played them at least once, so perhaps exit
+            if(exitPending() && !part.count)
+                break;
         }
 
         // free the textures for this part
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 62da82f..fa908eb 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -70,6 +70,7 @@
             int pause;
             String8 path;
             SortedVector<Frame> frames;
+            bool playUntilComplete;
         };
         int fps;
         int width;
@@ -82,6 +83,8 @@
     bool android();
     bool movie();
 
+    void checkExit();
+
     sp<SurfaceComposerClient>       mSession;
     AssetManager mAssets;
     Texture     mAndroid[2];
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 4d3a519..d8f9e49 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -942,8 +942,10 @@
 
             @Override
             public void onAnimationStart(Animator animator) {
-                if (mListeners != null) {
-                    for (TransitionListener listener : mListeners) {
+                if (hasListeners()) {
+                    ArrayList<TransitionListener> listeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    for (TransitionListener listener : listeners) {
                         listener.startTransition(LayoutTransition.this, parent, child,
                                 changeReason == APPEARING ?
                                         CHANGE_APPEARING : changeReason == DISAPPEARING ?
@@ -961,8 +963,10 @@
             @Override
             public void onAnimationEnd(Animator animator) {
                 currentChangingAnimations.remove(child);
-                if (mListeners != null) {
-                    for (TransitionListener listener : mListeners) {
+                if (hasListeners()) {
+                    ArrayList<TransitionListener> listeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    for (TransitionListener listener : listeners) {
                         listener.endTransition(LayoutTransition.this, parent, child,
                                 changeReason == APPEARING ?
                                         CHANGE_APPEARING : changeReason == DISAPPEARING ?
@@ -1131,8 +1135,10 @@
             currentAnimation.cancel();
         }
         if (mAppearingAnim == null) {
-            if (mListeners != null) {
-                for (TransitionListener listener : mListeners) {
+            if (hasListeners()) {
+                ArrayList<TransitionListener> listeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                for (TransitionListener listener : listeners) {
                     listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
                 }
             }
@@ -1149,8 +1155,10 @@
             @Override
             public void onAnimationEnd(Animator anim) {
                 currentAppearingAnimations.remove(child);
-                if (mListeners != null) {
-                    for (TransitionListener listener : mListeners) {
+                if (hasListeners()) {
+                    ArrayList<TransitionListener> listeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    for (TransitionListener listener : listeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, APPEARING);
                     }
                 }
@@ -1172,8 +1180,10 @@
             currentAnimation.cancel();
         }
         if (mDisappearingAnim == null) {
-            if (mListeners != null) {
-                for (TransitionListener listener : mListeners) {
+            if (hasListeners()) {
+                ArrayList<TransitionListener> listeners =
+                        (ArrayList<TransitionListener>) mListeners.clone();
+                for (TransitionListener listener : listeners) {
                     listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                 }
             }
@@ -1189,8 +1199,10 @@
             public void onAnimationEnd(Animator anim) {
                 currentDisappearingAnimations.remove(child);
                 child.setAlpha(preAnimAlpha);
-                if (mListeners != null) {
-                    for (TransitionListener listener : mListeners) {
+                if (hasListeners()) {
+                    ArrayList<TransitionListener> listeners =
+                            (ArrayList<TransitionListener>) mListeners.clone();
+                    for (TransitionListener listener : listeners) {
                         listener.endTransition(LayoutTransition.this, parent, child, DISAPPEARING);
                     }
                 }
@@ -1228,8 +1240,10 @@
             cancel(CHANGE_APPEARING);
             cancel(CHANGING);
         }
-        if (mListeners != null && (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
-            for (TransitionListener listener : mListeners) {
+        if (hasListeners() && (mTransitionTypes & FLAG_APPEARING) == FLAG_APPEARING) {
+            ArrayList<TransitionListener> listeners =
+                    (ArrayList<TransitionListener>) mListeners.clone();
+            for (TransitionListener listener : listeners) {
                 listener.startTransition(this, parent, child, APPEARING);
             }
         }
@@ -1241,6 +1255,10 @@
         }
     }
 
+    private boolean hasListeners() {
+        return mListeners != null && mListeners.size() > 0;
+    }
+
     /**
      * This method is called by ViewGroup when there is a call to layout() on the container
      * with this LayoutTransition. If the CHANGING transition is enabled and if there is no other
@@ -1328,8 +1346,10 @@
             cancel(CHANGE_DISAPPEARING);
             cancel(CHANGING);
         }
-        if (mListeners != null && (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
-            for (TransitionListener listener : mListeners) {
+        if (hasListeners() && (mTransitionTypes & FLAG_DISAPPEARING) == FLAG_DISAPPEARING) {
+            ArrayList<TransitionListener> listeners = (ArrayList<TransitionListener>) mListeners
+                    .clone();
+            for (TransitionListener listener : listeners) {
                 listener.startTransition(this, parent, child, DISAPPEARING);
             }
         }
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9ba5305..39e2423 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1118,7 +1118,9 @@
         if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
         final boolean inactive = !fragment.isInBackStack();
         if (!fragment.mDetached || inactive) {
-            mAdded.remove(fragment);
+            if (mAdded != null) {
+                mAdded.remove(fragment);
+            }
             if (fragment.mHasMenu && fragment.mMenuVisible) {
                 mNeedMenuInvalidate = true;
             }
@@ -1187,7 +1189,9 @@
             fragment.mDetached = true;
             if (fragment.mAdded) {
                 // We are not already in back stack, so need to remove the fragment.
-                mAdded.remove(fragment);
+                if (mAdded != null) {
+                    mAdded.remove(fragment);
+                }
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
                 }
@@ -1202,6 +1206,9 @@
         if (fragment.mDetached) {
             fragment.mDetached = false;
             if (!fragment.mAdded) {
+                if (mAdded == null) {
+                    mAdded = new ArrayList<Fragment>();
+                }
                 mAdded.add(fragment);
                 fragment.mAdded = true;
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
@@ -1213,7 +1220,7 @@
     }
 
     public Fragment findFragmentById(int id) {
-        if (mActive != null) {
+        if (mAdded != null) {
             // First look through added fragments.
             for (int i=mAdded.size()-1; i>=0; i--) {
                 Fragment f = mAdded.get(i);
@@ -1221,6 +1228,8 @@
                     return f;
                 }
             }
+        }
+        if (mActive != null) {
             // Now for any known fragment.
             for (int i=mActive.size()-1; i>=0; i--) {
                 Fragment f = mActive.get(i);
@@ -1233,7 +1242,7 @@
     }
     
     public Fragment findFragmentByTag(String tag) {
-        if (mActive != null && tag != null) {
+        if (mAdded != null && tag != null) {
             // First look through added fragments.
             for (int i=mAdded.size()-1; i>=0; i--) {
                 Fragment f = mAdded.get(i);
@@ -1241,6 +1250,8 @@
                     return f;
                 }
             }
+        }
+        if (mActive != null && tag != null) {
             // Now for any known fragment.
             for (int i=mActive.size()-1; i>=0; i--) {
                 Fragment f = mActive.get(i);
@@ -1817,7 +1828,7 @@
     }
     
     public void dispatchConfigurationChanged(Configuration newConfig) {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null) {
@@ -1828,7 +1839,7 @@
     }
 
     public void dispatchLowMemory() {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null) {
@@ -1839,7 +1850,7 @@
     }
 
     public void dispatchTrimMemory(int level) {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null) {
@@ -1852,7 +1863,7 @@
     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         boolean show = false;
         ArrayList<Fragment> newMenus = null;
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
@@ -1882,7 +1893,7 @@
     
     public boolean dispatchPrepareOptionsMenu(Menu menu) {
         boolean show = false;
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
@@ -1895,7 +1906,7 @@
     }
     
     public boolean dispatchOptionsItemSelected(MenuItem item) {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
@@ -1909,7 +1920,7 @@
     }
     
     public boolean dispatchContextItemSelected(MenuItem item) {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null && !f.mHidden && f.mUserVisibleHint) {
@@ -1923,7 +1934,7 @@
     }
     
     public void dispatchOptionsMenuClosed(Menu menu) {
-        if (mActive != null) {
+        if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
                 Fragment f = mAdded.get(i);
                 if (f != null && !f.mHidden && f.mHasMenu && f.mMenuVisible) {
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index e28a415..18713f5 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -73,9 +73,14 @@
                 com.android.internal.R.styleable.MediaRouteButton_minWidth, 0);
         mMinHeight = a.getDimensionPixelSize(
                 com.android.internal.R.styleable.MediaRouteButton_minHeight, 0);
+        final int routeTypes = a.getInteger(
+                com.android.internal.R.styleable.MediaRouteButton_mediaRouteTypes,
+                MediaRouter.ROUTE_TYPE_LIVE_AUDIO);
         a.recycle();
 
         setClickable(true);
+
+        setRouteTypes(routeTypes);
     }
 
     private void setRemoteIndicatorDrawable(Drawable d) {
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 50972e8..76dfac4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2153,19 +2153,6 @@
             "android.intent.action.USB_AUDIO_DEVICE_PLUG";
 
     /**
-     * @hide (to be un-hidden)
-     * Broadcast Action: the volume handled by the receiver should be updated based on the
-     * mutually exclusive extras, {@link #EXTRA_VOLUME_UPDATE_DIRECTION}
-     * and {@link #EXTRA_VOLUME_UPDATE_VALUE}.
-     *
-     * @see #EXTRA_VOLUME_UPDATE_DIRECTION
-     * @see #EXTRA_VOLUME_UPDATE_VALUE
-     * @see android.media.RemoteControlClient
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_VOLUME_UPDATE = "android.intent.action.VOLUME_UPDATE";
-
-    /**
      * <p>Broadcast Action: The user has switched on advanced settings in the settings app:</p>
      * <ul>
      *   <li><em>state</em> - A boolean value indicating whether the settings is on or off.</li>
@@ -2854,26 +2841,6 @@
     public static final String EXTRA_USERID =
             "android.intent.extra.user_id";
 
-    /**
-     * @hide (to be un-hidden)
-     * An integer indicating whether the volume is to be increased (positive value) or decreased
-     * (negative value). For bundled changes, the absolute value indicates the number of changes
-     * in the same direction, e.g. +3 corresponds to three "volume up" changes.
-     * @see #ACTION_VOLUME_UPDATE
-     */
-    public static final String EXTRA_VOLUME_UPDATE_DIRECTION =
-            "android.intent.extra.VOLUME_UPDATE_DIRECTION";
-
-    /**
-     * @hide (to be un-hidden)
-     * An integer indicating the new volume value, always between 0 and the value set for
-     * {@link RemoteControlClient#PLAYBACKINFO_VOLUME_MAX} with
-     * {@link RemoteControlClient#setPlaybackInformation(int, int)}
-     * @see #ACTION_VOLUME_UPDATE
-     */
-    public static final String EXTRA_VOLUME_UPDATE_VALUE =
-            "android.intent.extra.VOLUME_UPDATE_VALUE";
-
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 1029161..140bff0 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -651,6 +651,14 @@
     }
 
     /**
+     * Returns the Header list
+     * @hide
+     */
+    public List<Header> getHeaders() {
+        return mHeaders;
+    }
+
+    /**
      * Returns true if this activity is showing multiple panes -- the headers
      * and a preference fragment.
      */
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index cb5a5e7..dab48b1 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -27,6 +27,7 @@
 import android.os.Looper;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.Trace;
 import android.util.Log;
 import com.google.android.gles_jni.EGLImpl;
 
@@ -40,6 +41,7 @@
 
 import java.io.File;
 import java.io.PrintWriter;
+import java.util.concurrent.locks.ReentrantLock;
 
 import static javax.microedition.khronos.egl.EGL10.*;
 
@@ -623,6 +625,7 @@
 
         final boolean mProfileEnabled;
         final float[] mProfileData;
+        final ReentrantLock mProfileLock;
         int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
         
         final boolean mDebugDirtyRegions;
@@ -663,8 +666,11 @@
                 for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
                     mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
                 }
+
+                mProfileLock = new ReentrantLock();
             } else {
                 mProfileData = null;
+                mProfileLock = null;
             }
 
             property = SystemProperties.get(DEBUG_DIRTY_REGIONS_PROPERTY, "false");
@@ -678,15 +684,21 @@
         void dumpGfxInfo(PrintWriter pw) {
             if (mProfileEnabled) {
                 pw.printf("\n\tDraw\tProcess\tExecute\n");
-                for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
-                    if (mProfileData[i] < 0) {
-                        break;
+
+                mProfileLock.lock();
+                try {
+                    for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
+                        if (mProfileData[i] < 0) {
+                            break;
+                        }
+                        pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
+                                mProfileData[i + 2]);
+                        mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
                     }
-                    pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
-                            mProfileData[i + 2]);
-                    mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
+                    mProfileCurrentFrame = mProfileData.length;
+                } finally {
+                    mProfileLock.unlock();
                 }
-                mProfileCurrentFrame = mProfileData.length;
             }
         }
 
@@ -1083,7 +1095,11 @@
                 if (surfaceState != SURFACE_STATE_ERROR) {
                     HardwareCanvas canvas = mCanvas;
                     attachInfo.mHardwareCanvas = canvas;
-                    
+
+                    if (mProfileEnabled) {
+                        mProfileLock.lock();
+                    }
+
                     // We had to change the current surface and/or context, redraw everything
                     if (surfaceState == SURFACE_STATE_UPDATED) {
                         dirty = null;
@@ -1121,7 +1137,14 @@
                             getDisplayListStartTime = System.nanoTime();
                         }
 
-                        DisplayList displayList = view.getDisplayList();
+                        DisplayList displayList;
+
+                        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
+                        try {
+                            displayList = view.getDisplayList();
+                        } finally {
+                            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+                        }
 
                         if (mProfileEnabled) {
                             long now = System.nanoTime();
@@ -1136,8 +1159,13 @@
                                 drawDisplayListStartTime = System.nanoTime();
                             }
 
-                            status |= canvas.drawDisplayList(displayList, mRedrawClip,
-                                    DisplayList.FLAG_CLIP_CHILDREN);
+                            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
+                            try {
+                                status |= canvas.drawDisplayList(displayList, mRedrawClip,
+                                        DisplayList.FLAG_CLIP_CHILDREN);
+                            } finally {
+                                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+                            }
 
                             if (mProfileEnabled) {
                                 long now = System.nanoTime();
@@ -1174,7 +1202,6 @@
                     attachInfo.mIgnoreDirtyState = false;
                     
                     if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
-
                         long eglSwapBuffersStartTime = 0;
                         if (mProfileEnabled) {
                             eglSwapBuffersStartTime = System.nanoTime();
@@ -1191,6 +1218,10 @@
                         checkEglErrors();
                     }
 
+                    if (mProfileEnabled) {
+                        mProfileLock.unlock();
+                    }
+
                     return dirty == null;
                 }
             }
diff --git a/core/java/android/widget/SimpleCursorAdapter.java b/core/java/android/widget/SimpleCursorAdapter.java
index f74a314..3dd0a95 100644
--- a/core/java/android/widget/SimpleCursorAdapter.java
+++ b/core/java/android/widget/SimpleCursorAdapter.java
@@ -78,7 +78,7 @@
         super(context, layout, c);
         mTo = to;
         mOriginalFrom = from;
-        findColumns(from);
+        findColumns(c, from);
     }
 
     /**
@@ -104,7 +104,7 @@
         super(context, layout, c, flags);
         mTo = to;
         mOriginalFrom = from;
-        findColumns(from);
+        findColumns(c, from);
     }
 
     /**
@@ -316,20 +316,21 @@
     }
 
     /**
-     * Create a map from an array of strings to an array of column-id integers in mCursor.
-     * If mCursor is null, the array will be discarded.
-     * 
+     * Create a map from an array of strings to an array of column-id integers in cursor c.
+     * If c is null, the array will be discarded.
+     *
+     * @param c the cursor to find the columns from
      * @param from the Strings naming the columns of interest
      */
-    private void findColumns(String[] from) {
-        if (mCursor != null) {
+    private void findColumns(Cursor c, String[] from) {
+        if (c != null) {
             int i;
             int count = from.length;
             if (mFrom == null || mFrom.length != count) {
                 mFrom = new int[count];
             }
             for (i = 0; i < count; i++) {
-                mFrom[i] = mCursor.getColumnIndexOrThrow(from[i]);
+                mFrom[i] = c.getColumnIndexOrThrow(from[i]);
             }
         } else {
             mFrom = null;
@@ -341,13 +342,8 @@
         // super.swapCursor() will notify observers before we have
         // a valid mapping, make sure we have a mapping before this
         // happens
-        if (mFrom == null) {
-            findColumns(mOriginalFrom);
-        }
-        Cursor res = super.swapCursor(c);
-        // rescan columns in case cursor layout is different
-        findColumns(mOriginalFrom);
-        return res;
+        findColumns(c, mOriginalFrom);
+        return super.swapCursor(c);
     }
     
     /**
@@ -367,11 +363,8 @@
         // super.changeCursor() will notify observers before we have
         // a valid mapping, make sure we have a mapping before this
         // happens
-        if (mFrom == null) {
-            findColumns(mOriginalFrom);
-        }
+        findColumns(c, mOriginalFrom);
         super.changeCursor(c);
-        findColumns(mOriginalFrom);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index 62410ed..4e60b75 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -881,7 +881,7 @@
                 }
                 if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                     String targetContentDescription = getTargetDescription(activeTarget);
-                    announceText(targetContentDescription);
+                    announceForAccessibility(targetContentDescription);
                 }
             }
         }
@@ -1089,16 +1089,10 @@
                 String text = String.format(directionDescription, targetDescription);
                 utterance.append(text);
             }
-            if (utterance.length() > 0) {
-                announceText(utterance.toString());
-            }
         }
-    }
-
-    private void announceText(String text) {
-        setContentDescription(text);
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-        setContentDescription(null);
+        if (utterance.length() > 0) {
+            announceForAccessibility(utterance.toString());
+        }
     }
 
     private String getTargetDescription(int index) {
diff --git a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
index 1a5a9a2..bbd1276 100644
--- a/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
+++ b/core/java/com/android/internal/widget/multiwaveview/PointCloud.java
@@ -202,25 +202,25 @@
 
     public void draw(Canvas canvas) {
         ArrayList<Point> points = mPointCloud;
-        final float cx = mDrawable != null ? (-mDrawable.getIntrinsicWidth() / 2) : 0;
-        final float cy = mDrawable != null ? (-mDrawable.getIntrinsicHeight() / 2) : 0;
         canvas.save(Canvas.MATRIX_SAVE_FLAG);
         canvas.scale(mScale, mScale, mCenterX, mCenterY);
         for (int i = 0; i < points.size(); i++) {
             Point point = points.get(i);
             final float pointSize = interp(MAX_POINT_SIZE, MIN_POINT_SIZE,
                     point.radius / mOuterRadius);
-            final float px = point.x + cx + mCenterX;
-            final float py = point.y + cy + mCenterY;
+            final float px = point.x + mCenterX;
+            final float py = point.y + mCenterY;
             int alpha = getAlphaForPoint(point);
 
             if (alpha == 0) continue;
 
             if (mDrawable != null) {
                 canvas.save(Canvas.MATRIX_SAVE_FLAG);
-                float s = pointSize / MAX_POINT_SIZE;
+                final float cx = mDrawable.getIntrinsicWidth() * 0.5f;
+                final float cy = mDrawable.getIntrinsicHeight() * 0.5f;
+                final float s = pointSize / MAX_POINT_SIZE;
                 canvas.scale(s, s, px, py);
-                canvas.translate(px, py);
+                canvas.translate(px - cx, py - cy);
                 mDrawable.setAlpha(alpha);
                 mDrawable.draw(canvas);
                 canvas.restore();
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
index 356e7cf..af7d011 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
@@ -89,6 +89,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal"
             android:gravity="center"
+            android:focusable="true"
 
             android:targetDrawables="@array/lockscreen_targets_with_camera"
             android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
index cb1cb21..9c18b7e 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock_land.xml
@@ -89,6 +89,7 @@
             android:layout_rowSpan="7"
             android:layout_gravity="center_vertical|right"
             android:gravity="center"
+            android:focusable="true"
 
             android:targetDrawables="@array/lockscreen_targets_with_camera"
             android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 91f65e9..81166222 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -130,6 +130,7 @@
             android:layout_height="match_parent"
             android:layout_alignParentBottom="true"
             android:gravity="top"
+            android:focusable="true"
 
             android:targetDrawables="@array/lockscreen_targets_with_camera"
             android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 8b9d8e4..35e4d11 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -135,6 +135,7 @@
         android:layout_height="match_parent"
         android:layout_rowSpan="7"
         android:gravity="left|center_vertical"
+        android:focusable="true"
 
         android:targetDrawables="@array/lockscreen_targets_with_camera"
         android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 3340d0c..94e9729 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -942,8 +942,8 @@
     <string name="no" msgid="5141531044935541497">"Cancel·la"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Atenció"</string>
     <string name="loading" msgid="7933681260296021180">"S\'està carregant…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"ACTIVAT"</string>
-    <string name="capital_off" msgid="6815870386972805832">"DESACTIVAT"</string>
+    <string name="capital_on" msgid="1544682755514494298">"Activa"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Desactiva"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Completa l\'acció mitjançant"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utilitza-ho de manera predeterminada per a aquesta acció."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Esborra els paràmetres predeterminats a Configuració del sistema &gt; Aplicacions &gt; Baixades."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 481b6cb..922013d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -942,8 +942,8 @@
     <string name="no" msgid="5141531044935541497">"Ακύρωση"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Προσοχή"</string>
     <string name="loading" msgid="7933681260296021180">"Φόρτωση…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"Ενεργοποιημένο"</string>
-    <string name="capital_off" msgid="6815870386972805832">"Απενεργοποίηση"</string>
+    <string name="capital_on" msgid="1544682755514494298">"Ενεργό"</string>
+    <string name="capital_off" msgid="6815870386972805832">"Ανενεργό"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Ολοκλήρωση ενέργειας με τη χρήση"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Χρήση από προεπιλογή για αυτήν την ενέργεια."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Εκκθάριση προεπιλογής στις Ρυθμίσεις συστήματος &gt; Εφαρμογές &gt; Ληφθείσες."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 80dc095..a144b97 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -942,8 +942,8 @@
     <string name="no" msgid="5141531044935541497">"Odustani"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Pažnja"</string>
     <string name="loading" msgid="7933681260296021180">"Učitavanje…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"Uključeno"</string>
-    <string name="capital_off" msgid="6815870386972805832">"Isključeno"</string>
+    <string name="capital_on" msgid="1544682755514494298">"Uklj."</string>
+    <string name="capital_off" msgid="6815870386972805832">"Isklj."</string>
     <string name="whichApplication" msgid="4533185947064773386">"Radnju dovrši pomoću stavke"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Koristi se kao zadana postavka za ovu lokaciju."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Izbrisati zadano u Postavkama sustava &gt; Aplikacije &gt; Preuzimanja."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ffd8c03..f95546b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -220,7 +220,7 @@
     <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"실행 중인 앱 세부정보 검색"</string>
     <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"앱이 현재 실행 중이거나 최근에 실행된 작업에 대한 상세한 정보를 검색할 수 있도록 허용합니다. 이 경우 악성 앱이 다른 앱에 대한 개인 정보를 검색할 수 있습니다."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"실행 중인 앱 순서 재지정"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"앱이 작업을 포그라운드나 백그라운드로 이동할 수 있도록 허용합니다. 이 경우 악성 앱이 사용자의 조작 없이 앞으로 이동할 수 있습니다. 사용자의 입력 없이 이를 수행할 수 있습니다."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"앱이 사용자의 입력 없이 작업을 포그라운드나 백그라운드로 이동할 수 있도록 허용합니다."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"실행 중인 앱 중지"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"애플리케이션이 작업을 삭제하거나 다른 애플리케이션을 중지시킬 수 있도록 허용합니다. 이 경우 악성 애플리케이션이 다른 애플리케이션의 동작을 멈추게 할 수 있습니다."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"원하는 활동 시작"</string>
@@ -234,7 +234,7 @@
     <string name="permlab_enableCarMode" msgid="5684504058192921098">"운전모드 사용"</string>
     <string name="permdesc_enableCarMode" msgid="4853187425751419467">"앱이 운전모드를 사용할 수 있도록 허용합니다."</string>
     <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"다른 앱 종료"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"앱이 다른 앱의 백그라운드 프로세스를 종료할 수 있도록 허용합니다. 이 경우 해당 앱이 실행 중지될 수 있습니다."</string>
+    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"앱이 다른 앱의 백그라운드 프로세스를 종료할 수 있도록 허용합니다. 이 경우 다른 앱이 실행 중지될 수 있습니다."</string>
     <string name="permlab_forceStopPackages" msgid="2329627428832067700">"다른 앱 강제 종료"</string>
     <string name="permdesc_forceStopPackages" msgid="5253157296183940812">"앱이 다른 앱을 강제로 종료할 수 있도록 허용합니다."</string>
     <string name="permlab_forceBack" msgid="652935204072584616">"앱 강제 종료"</string>
@@ -368,8 +368,8 @@
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"앱이 친구나 동료의 일정을 포함하여 태블릿에 저장된 모든 캘린더 일정을 읽을 수 있도록 허용합니다. 이 경우 앱이 비밀유지 또는 기밀성을 무시하고 캘린더 데이터를 공유 또는 저장할 수도 있습니다."</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"앱이 친구나 동료의 일정을 포함하여 휴대전화에 저장된 모든 캘린더 일정을 읽을 수 있도록 허용합니다. 이 경우 앱이 비밀유지 또는 기밀성과 관계 없이 캘린더 데이터를 공유 또는 저장할 수도 있습니다."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"소유자 몰래 캘린더 일정을 추가 또는 수정하고 참석자에게 이메일 전송"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"앱이 친구나 동료의 일정을 포함하여 태블릿에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자로부터 온 것으로 보이는 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"앱이 친구나 동료의 일정을 포함하여 휴대전화에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자로부터 온 것으로 보이는 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"앱이 친구나 동료의 일정을 포함하여 태블릿에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자가 보내는 것처럼 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"앱이 친구나 동료의 일정을 포함하여 휴대전화에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자가 보내는 것처럼 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"테스트를 위해 위치 정보제공자로 가장"</string>
     <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"테스트용 가상 위치 소스를 만들거나 새로운 위치 정보 제공업체를 설치합니다. 이 경우 앱이 GPS 또는 위치 정보 제공업체 등 기타 위치 소스가 반환한 위치 또는 상태를 덮어쓸 수 있습니다."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"추가 위치 제공업체 명령에 액세스"</string>
@@ -468,8 +468,8 @@
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"AccountManagerService로 활동"</string>
     <string name="permdesc_accountManagerService" msgid="1948455552333615954">"애플리케이션이 AccountAuthenticators를 호출할 수 있도록 허용합니다."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"기기에서 계정 검색"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"앱이 태블릿에 의해 알려진 계정 목록을 가져올 수 있도록 허용합니다. 이 경우 설치한 애플리케이션에 의해 만들어진 모든 계정을 포함할 수 있습니다."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"앱이 휴대전화에 의해 알려진 계정 목록을 가져올 수 있도록 허용합니다. 이 경우 설치한 애플리케이션에 의해 만들어진 모든 계정을 포함할 수 있습니다."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"앱이 태블릿이 알고 있는 계정 목록을 가져올 수 있도록 허용합니다. 이 경우 설치한 애플리케이션에 의해 만들어진 모든 계정을 포함할 수 있습니다."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"앱이 휴대전화가 알고 있는 계정 목록을 가져올 수 있도록 허용합니다. 이 경우 설치한 애플리케이션에 의해 만들어진 모든 계정을 포함할 수 있습니다."</string>
     <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"계정 만들기 및 비밀번호 설정"</string>
     <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"앱이 계정 만들기, 비밀번호 가져오기 및 설정 등과 같은 관리자의 계정 인증자 기능을 사용할 수 있도록 허용합니다."</string>
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"계정 추가 또는 삭제"</string>
@@ -493,8 +493,8 @@
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi 연결 및 연결 해제"</string>
     <string name="permdesc_changeWifiState" msgid="7137950297386127533">"앱이 Wi-Fi 액세스 포인트에 연결하거나 연결을 끊고, Wi-Fi 네트워크의 기기 설정을 변경할 수 있도록 허용합니다."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi 멀티캐스트 수신 허용"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"앱이 사용자의 태블릿뿐 아니라 여러 주소를 사용하여 Wi-Fi 네트워크에서 모든 기기로 전송된 패킷을 받도록 허용합니다. 이 경우 비멀티캐스트 모드보다 전력을 더 많이 소비합니다."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"앱이 사용자의 휴대전화뿐 아니라 여러 주소를 사용하여 Wi-Fi 네트워크에서 모든 기기로 전송된 패킷을 받을 수 있도록 허용합니다. 이 경우 비멀티캐스트 모드보다 전력을 더 많이 소비합니다."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"앱이 사용자의 태블릿뿐 아니라 멀티캐스트 주소를 사용하여 Wi-Fi 네트워크에서 모든 기기로 전송된 패킷을 받도록 허용합니다. 이 경우 비멀티캐스트 모드보다 전력을 더 많이 소비합니다."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"앱이 사용자의 휴대전화뿐 아니라 멀티캐스트 주소를 사용하여 Wi-Fi 네트워크에서 모든 기기로 전송된 패킷을 받을 수 있도록 허용합니다. 이 경우 비멀티캐스트 모드보다 전력을 더 많이 소비합니다."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"블루투스 설정에 액세스"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"앱이 로컬 블루투스 태블릿을 설정한 다음 원격 기기를 검색하여 페어링할 수 있도록 허용합니다."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"앱이 로컬 블루투스 휴대전화를 설정한 다음 원격 기기를 검색하여 페어링할 수 있도록 허용합니다."</string>
@@ -511,9 +511,9 @@
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"화면 잠금 사용 중지"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"앱이 키 잠금 및 관련 비밀번호 보안을 사용중지할 수 있도록 허용합니다. 예를 들어, 휴대전화가 수신전화를 받을 때 키 잠금을 사용중지했다가 통화가 끝나면 키 잠금을 다시 사용할 수 있습니다."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"동기화 설정 읽기"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"앱이 계정의 동기화 설정을 읽을 수 있도록 허용합니다. 예를 들어, 계정에서 피플 앱(People app)을 동기화할지 여부를 확인할 수 있습니다."</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"앱이 계정의 동기화 설정을 읽을 수 있도록 허용합니다. 예를 들어, 계정에서 피플 앱을 동기화할지 여부를 확인할 수 있습니다."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"동기화 사용 및 사용 중지 전환"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"앱이 계정의 동기화 설정을 수정할 수 있도록 허용합니다. 예를 들어, 계정에서 피플 앱 동기화를 사용하도록 설정할 목적으로 앱이 사용될 수 있습니다."</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"앱이 계정의 동기화 설정을 수정할 수 있도록 허용합니다. 예를 들어, 계정에서 피플 앱을 동기화할 목적으로 앱이 사용될 수 있습니다."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"동기화 통계 읽기"</string>
     <string name="permdesc_readSyncStats" msgid="1510143761757606156">"앱이 동기화된 일정의 기록이나 동기화된 데이터의 양 등을 포함하여 계정의 동기화 통계를 읽을 수 있도록 허용합니다."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"가입된 피드 읽기"</string>
@@ -1118,7 +1118,7 @@
     <string name="permdesc_pkgUsageStats" msgid="1106612424254277630">"앱이 수집된 구성요소 사용 통계를 수정하도록 합니다. 일반 앱에서는 사용하지 않습니다."</string>
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"콘텐츠 복사"</string>
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"기본 컨테이너 서비스를 호출하여 콘텐츠를 복사할 수 있도록 허용합니다. 일반 앱에서는 사용하지 않습니다."</string>
-    <string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력을 연결"</string>
+    <string name="permlab_route_media_output" msgid="1642024455750414694">"미디어 출력 연결"</string>
     <string name="permdesc_route_media_output" msgid="4932818749547244346">"앱이 미디어 출력을 기타 외부 기기에 연결할 수 있도록 허용합니다."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"확대/축소하려면 두 번 터치하세요."</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"위젯을 추가할 수 없습니다."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b6a4b23..c911e14 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -942,8 +942,8 @@
     <string name="no" msgid="5141531044935541497">"Atšaukti"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Dėmesio"</string>
     <string name="loading" msgid="7933681260296021180">"Įkeliama..."</string>
-    <string name="capital_on" msgid="1544682755514494298">"ĮJUNGTA"</string>
-    <string name="capital_off" msgid="6815870386972805832">"IŠJUNGTA"</string>
+    <string name="capital_on" msgid="1544682755514494298">"ĮJ."</string>
+    <string name="capital_off" msgid="6815870386972805832">"IŠJ."</string>
     <string name="whichApplication" msgid="4533185947064773386">"Užbaigti veiksmą naudojant"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Šiam veiksmui tai naudoti pagal numatytuosius nustatymus."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Numatytuosius nustatymus išvalykite nuėję į „Sistemos nustatymai“ &gt; „Programos“ &gt; „Atsisiųsta“."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f497083..f28217c 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -934,7 +934,7 @@
     <string name="deleteText" msgid="7070985395199629156">"dzēst"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Ievades metode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Brīvās krātuves apjoms samazinās"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Paliek maz brīvas vietas"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Dažas sistēmas funkcijas var nedarboties."</string>
     <string name="ok" msgid="5970060430562524910">"Labi"</string>
     <string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index b238e16..c86082d 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -934,7 +934,7 @@
     <string name="deleteText" msgid="7070985395199629156">"удалить"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Заканчивается пространство"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Заканчивается свободное место"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Некоторые системные функции могут не работать"</string>
     <string name="ok" msgid="5970060430562524910">"ОК"</string>
     <string name="cancel" msgid="6442560571259935130">"Отмена"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index a7aca87..a0a6e49 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1079,7 +1079,7 @@
     <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Vse datoteke, shranjene v v pomnilniku USB, bodo izbrisane. Tega dejanja ni mogoče razveljaviti!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Vsi podatki v napravi bodo izgubljeni."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatiraj"</string>
-    <string name="adb_active_notification_title" msgid="6729044778949189918">"iskanje in odpravljanje napak USB je povezano"</string>
+    <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje in odpravljanje napak USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
     <string name="select_input_method" msgid="4653387336791222978">"Izberite način vnosa"</string>
     <string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c0e9a62..79ab8ca 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -934,7 +934,7 @@
     <string name="deleteText" msgid="7070985395199629156">"избриши"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метод уноса"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
-    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Недовољно простора за складиштење"</string>
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Простор за складиштење је на измаку"</string>
     <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Неке системске функције можда не функционишу"</string>
     <string name="ok" msgid="5970060430562524910">"Потврди"</string>
     <string name="cancel" msgid="6442560571259935130">"Откажи"</string>
@@ -942,8 +942,8 @@
     <string name="no" msgid="5141531044935541497">"Откажи"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Пажња"</string>
     <string name="loading" msgid="7933681260296021180">"Учитавање…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"УКЉУЧЕНО"</string>
-    <string name="capital_off" msgid="6815870386972805832">"ИСКЉУЧЕНО"</string>
+    <string name="capital_on" msgid="1544682755514494298">"ДА"</string>
+    <string name="capital_off" msgid="6815870386972805832">"НЕ"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Довршавање радње помоћу"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Подразумевано користи за ову радњу."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Обришите подразумевано подешавање у менију Подешавања система &gt; Апликације &gt; Преузето."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fcab4f3..9cd04e4 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5703,6 +5703,15 @@
              @hide -->
         <attr name="externalRouteEnabledDrawable" format="reference" />
 
+        <!-- The types of media routes the button and its resulting
+             chooser will filter by. -->
+        <attr name="mediaRouteTypes" format="integer">
+            <!-- Allow selection of live audio routes. -->
+            <enum name="liveAudio" value="0x1" />
+            <!-- Allow selection of user (app-specified) routes. -->
+            <enum name="user" value="0x800000" />
+        </attr>
+
         <attr name="minWidth" />
         <attr name="minHeight" />
     </declare-styleable>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 946bfe6..303cf78 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3644,6 +3644,7 @@
   <public type="attr" name="fontFamily" id="0x010103ac" />
 
   <public type="attr" name="mediaRouteButtonStyle" id="0x010103ad" />
+  <public type="attr" name="mediaRouteTypes" id="0x010103ae" />
   <public type="style" name="Widget.Holo.MediaRouteButton" id="0x010301d5" />
   <public type="style" name="Widget.Holo.Light.MediaRouteButton" id="0x010301d6" />
   <public type="style" name="Widget.DeviceDefault.MediaRouteButton" id="0x010301d7" />
diff --git a/docs/html/design/building-blocks/buttons.jd b/docs/html/design/building-blocks/buttons.jd
index 18beab0..1c28cbef 100644
--- a/docs/html/design/building-blocks/buttons.jd
+++ b/docs/html/design/building-blocks/buttons.jd
@@ -5,9 +5,7 @@
 user touches it. Android supports two different types of buttons: <em>basic buttons</em> and <em>borderless
 buttons</em>. Both can contain text labels and/or images.</p>
 
-<div style="text-align: center">
-  <img src="{@docRoot}design/media/buttons_basic.png">
-</div>
+<img src="{@docRoot}design/media/buttons_basic.png">
 
 <h2 id="basic">Basic Buttons</h2>
 
diff --git a/docs/html/design/building-blocks/pickers.jd b/docs/html/design/building-blocks/pickers.jd
index 85f2187..e3cf642 100644
--- a/docs/html/design/building-blocks/pickers.jd
+++ b/docs/html/design/building-blocks/pickers.jd
@@ -6,13 +6,12 @@
 gesture.</p>
 
 <div class="layout-content-row">
-  <div class="layout-content-col span-2">&nbsp;</div>
   <div class="layout-content-col span-6">
 
     <img src="{@docRoot}design/media/picker_space.png">
 
   </div>
-  <div class="layout-content-col span-5">
+  <div class="layout-content-col span-6">
 
 <h4>Space considerations</h4>
 <p>Pickers can be used inline on a form, but their relatively large footprint is best suited for
diff --git a/docs/html/design/building-blocks/switches.jd b/docs/html/design/building-blocks/switches.jd
index 607e0b6..c4dfc4b 100644
--- a/docs/html/design/building-blocks/switches.jd
+++ b/docs/html/design/building-blocks/switches.jd
@@ -8,9 +8,7 @@
 <p>Checkboxes allow the user to select multiple options from a set. Avoid using a single checkbox to
 turn an option off or on. Instead, use an on/off switch.</p>
 
-<div style="text-align: center">
   <img src="{@docRoot}design/media/switches_checkboxes.png">
-</div>
 
 <h2 id="radio-buttons">Radio Buttons</h2>
 
@@ -18,14 +16,10 @@
 selection if you think that the user needs to see all available options side-by-side. Otherwise,
 consider a spinner, which uses less space.</p>
 
-<div style="text-align: center">
   <img src="{@docRoot}design/media/switches_radios.png">
-</div>
 
 <h2 id="switches">On/off Switches</h2>
 
 <p>On/off switches toggle the state of a single settings option.</p>
 
-<div style="text-align: center">
   <img src="{@docRoot}design/media/switches_switches.png">
-</div>
diff --git a/docs/html/design/media/action_bar_basics.png b/docs/html/design/media/action_bar_basics.png
index 0bf3d56..4b4e987 100644
--- a/docs/html/design/media/action_bar_basics.png
+++ b/docs/html/design/media/action_bar_basics.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_cab.png b/docs/html/design/media/action_bar_cab.png
index aa629b9..405b494 100644
--- a/docs/html/design/media/action_bar_cab.png
+++ b/docs/html/design/media/action_bar_cab.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_considerations.png b/docs/html/design/media/action_bar_pattern_considerations.png
index 977e7f2..022288c 100644
--- a/docs/html/design/media/action_bar_pattern_considerations.png
+++ b/docs/html/design/media/action_bar_pattern_considerations.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_default_tabs.png b/docs/html/design/media/action_bar_pattern_default_tabs.png
index 69df289..a6d0d90 100644
--- a/docs/html/design/media/action_bar_pattern_default_tabs.png
+++ b/docs/html/design/media/action_bar_pattern_default_tabs.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_share_pack.png b/docs/html/design/media/action_bar_pattern_share_pack.png
index 7ae8a0a..dde18f3 100644
--- a/docs/html/design/media/action_bar_pattern_share_pack.png
+++ b/docs/html/design/media/action_bar_pattern_share_pack.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_spinner.png b/docs/html/design/media/action_bar_pattern_spinner.png
index 9c054b5..9aff412 100644
--- a/docs/html/design/media/action_bar_pattern_spinner.png
+++ b/docs/html/design/media/action_bar_pattern_spinner.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_table.png b/docs/html/design/media/action_bar_pattern_table.png
index dac7e21..6a8c371 100644
--- a/docs/html/design/media/action_bar_pattern_table.png
+++ b/docs/html/design/media/action_bar_pattern_table.png
Binary files differ
diff --git a/docs/html/design/media/action_bar_pattern_up_app_icon.png b/docs/html/design/media/action_bar_pattern_up_app_icon.png
index 11b8aa9..cfc0333 100644
--- a/docs/html/design/media/action_bar_pattern_up_app_icon.png
+++ b/docs/html/design/media/action_bar_pattern_up_app_icon.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_book_detail_page_flip.png b/docs/html/design/media/app_structure_book_detail_page_flip.png
index 13c9c52..0cca587 100644
--- a/docs/html/design/media/app_structure_book_detail_page_flip.png
+++ b/docs/html/design/media/app_structure_book_detail_page_flip.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_fixedtabs.png b/docs/html/design/media/app_structure_fixedtabs.png
index e41f97e..6d1c63b 100644
--- a/docs/html/design/media/app_structure_fixedtabs.png
+++ b/docs/html/design/media/app_structure_fixedtabs.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_gallery_filmstrip.png b/docs/html/design/media/app_structure_gallery_filmstrip.png
index deed672..483bafa 100644
--- a/docs/html/design/media/app_structure_gallery_filmstrip.png
+++ b/docs/html/design/media/app_structure_gallery_filmstrip.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_gmail.png b/docs/html/design/media/app_structure_gmail.png
index 862ac75..33ae092 100644
--- a/docs/html/design/media/app_structure_gmail.png
+++ b/docs/html/design/media/app_structure_gmail.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_gmail_swipe.png b/docs/html/design/media/app_structure_gmail_swipe.png
index 21da4ac..8f6f71c 100644
--- a/docs/html/design/media/app_structure_gmail_swipe.png
+++ b/docs/html/design/media/app_structure_gmail_swipe.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_market.png b/docs/html/design/media/app_structure_market.png
index 5aa595e..7ab0189 100644
--- a/docs/html/design/media/app_structure_market.png
+++ b/docs/html/design/media/app_structure_market.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_music_lndscp.png b/docs/html/design/media/app_structure_music_lndscp.png
index 67354de..f6aaf3b 100644
--- a/docs/html/design/media/app_structure_music_lndscp.png
+++ b/docs/html/design/media/app_structure_music_lndscp.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_people_detail.png b/docs/html/design/media/app_structure_people_detail.png
index b870796..de54e82 100644
--- a/docs/html/design/media/app_structure_people_detail.png
+++ b/docs/html/design/media/app_structure_people_detail.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_scrolltabs.png b/docs/html/design/media/app_structure_scrolltabs.png
index ea742c2..3c20436 100644
--- a/docs/html/design/media/app_structure_scrolltabs.png
+++ b/docs/html/design/media/app_structure_scrolltabs.png
Binary files differ
diff --git a/docs/html/design/media/app_structure_shortcut_on_item.png b/docs/html/design/media/app_structure_shortcut_on_item.png
index 1341f1f..3b10cb9 100644
--- a/docs/html/design/media/app_structure_shortcut_on_item.png
+++ b/docs/html/design/media/app_structure_shortcut_on_item.png
Binary files differ
diff --git a/docs/html/design/media/buttons_basic.png b/docs/html/design/media/buttons_basic.png
index 7fa3d09..d91ab5c 100644
--- a/docs/html/design/media/buttons_basic.png
+++ b/docs/html/design/media/buttons_basic.png
Binary files differ
diff --git a/docs/html/design/media/color_spectrum.png b/docs/html/design/media/color_spectrum.png
index 3fd7a57..7d2c023 100644
--- a/docs/html/design/media/color_spectrum.png
+++ b/docs/html/design/media/color_spectrum.png
Binary files differ
diff --git a/docs/html/design/media/creative_vision_main.png b/docs/html/design/media/creative_vision_main.png
index c9d31cb..2b3bb2f 100644
--- a/docs/html/design/media/creative_vision_main.png
+++ b/docs/html/design/media/creative_vision_main.png
Binary files differ
diff --git a/docs/html/design/media/devices_displays_density.png b/docs/html/design/media/devices_displays_density.png
index a21b482..7ddad31 100644
--- a/docs/html/design/media/devices_displays_density.png
+++ b/docs/html/design/media/devices_displays_density.png
Binary files differ
diff --git a/docs/html/design/media/devices_displays_main.png b/docs/html/design/media/devices_displays_main.png
index fd1c645..1b0b16c 100644
--- a/docs/html/design/media/devices_displays_main.png
+++ b/docs/html/design/media/devices_displays_main.png
Binary files differ
diff --git a/docs/html/design/media/dialogs_popups_example.png b/docs/html/design/media/dialogs_popups_example.png
index c2a66f6..2deb00d 100644
--- a/docs/html/design/media/dialogs_popups_example.png
+++ b/docs/html/design/media/dialogs_popups_example.png
Binary files differ
diff --git a/docs/html/design/media/dialogs_w_no_title.png b/docs/html/design/media/dialogs_w_no_title.png
index 47e2dbf..a4abebc 100644
--- a/docs/html/design/media/dialogs_w_no_title.png
+++ b/docs/html/design/media/dialogs_w_no_title.png
Binary files differ
diff --git a/docs/html/design/media/dialogs_w_title.png b/docs/html/design/media/dialogs_w_title.png
index 4f2b81f..24428fe 100644
--- a/docs/html/design/media/dialogs_w_title.png
+++ b/docs/html/design/media/dialogs_w_title.png
Binary files differ
diff --git a/docs/html/design/media/gesture_doubletouch.png b/docs/html/design/media/gesture_doubletouch.png
index 693a593..4c68ae6 100644
--- a/docs/html/design/media/gesture_doubletouch.png
+++ b/docs/html/design/media/gesture_doubletouch.png
Binary files differ
diff --git a/docs/html/design/media/gesture_drag.png b/docs/html/design/media/gesture_drag.png
index 6262644..cb0d72c 100644
--- a/docs/html/design/media/gesture_drag.png
+++ b/docs/html/design/media/gesture_drag.png
Binary files differ
diff --git a/docs/html/design/media/gesture_longtouch.png b/docs/html/design/media/gesture_longtouch.png
index 3eb3cbc..30d13d4 100644
--- a/docs/html/design/media/gesture_longtouch.png
+++ b/docs/html/design/media/gesture_longtouch.png
Binary files differ
diff --git a/docs/html/design/media/gesture_pinchclose.png b/docs/html/design/media/gesture_pinchclose.png
index 471251f..daf2905 100644
--- a/docs/html/design/media/gesture_pinchclose.png
+++ b/docs/html/design/media/gesture_pinchclose.png
Binary files differ
diff --git a/docs/html/design/media/gesture_pinchopen.png b/docs/html/design/media/gesture_pinchopen.png
index b7c3ee3..c05b633 100644
--- a/docs/html/design/media/gesture_pinchopen.png
+++ b/docs/html/design/media/gesture_pinchopen.png
Binary files differ
diff --git a/docs/html/design/media/gesture_swipe.png b/docs/html/design/media/gesture_swipe.png
index f8e8a26..6f47df6 100644
--- a/docs/html/design/media/gesture_swipe.png
+++ b/docs/html/design/media/gesture_swipe.png
Binary files differ
diff --git a/docs/html/design/media/gesture_touch.png b/docs/html/design/media/gesture_touch.png
index 5c49b17..365c352 100644
--- a/docs/html/design/media/gesture_touch.png
+++ b/docs/html/design/media/gesture_touch.png
Binary files differ
diff --git a/docs/html/design/media/lists_main.png b/docs/html/design/media/lists_main.png
index d89ac79..3762ba5 100644
--- a/docs/html/design/media/lists_main.png
+++ b/docs/html/design/media/lists_main.png
Binary files differ
diff --git a/docs/html/design/media/metrics_48.png b/docs/html/design/media/metrics_48.png
index 5e6c57e..d1fbc82 100644
--- a/docs/html/design/media/metrics_48.png
+++ b/docs/html/design/media/metrics_48.png
Binary files differ
diff --git a/docs/html/design/media/metrics_diagram.png b/docs/html/design/media/metrics_diagram.png
index b5e6cd2..3cdc5e6 100644
--- a/docs/html/design/media/metrics_diagram.png
+++ b/docs/html/design/media/metrics_diagram.png
Binary files differ
diff --git a/docs/html/design/media/migrating_intents.png b/docs/html/design/media/migrating_intents.png
index 65fc1a5..9ec5da8 100644
--- a/docs/html/design/media/migrating_intents.png
+++ b/docs/html/design/media/migrating_intents.png
Binary files differ
diff --git a/docs/html/design/media/migrating_ios_dialers.png b/docs/html/design/media/migrating_ios_dialers.png
index 27751d8..a9230bc 100644
--- a/docs/html/design/media/migrating_ios_dialers.png
+++ b/docs/html/design/media/migrating_ios_dialers.png
Binary files differ
diff --git a/docs/html/design/media/migrating_ios_galleries.png b/docs/html/design/media/migrating_ios_galleries.png
index 04472fe..6bc1351 100644
--- a/docs/html/design/media/migrating_ios_galleries.png
+++ b/docs/html/design/media/migrating_ios_galleries.png
Binary files differ
diff --git a/docs/html/design/media/migrating_ios_settings.png b/docs/html/design/media/migrating_ios_settings.png
index b17cb72..5b335fe 100644
--- a/docs/html/design/media/migrating_ios_settings.png
+++ b/docs/html/design/media/migrating_ios_settings.png
Binary files differ
diff --git a/docs/html/design/media/multipane_expand.png b/docs/html/design/media/multipane_expand.png
index bb4f371..f761e5f 100644
--- a/docs/html/design/media/multipane_expand.png
+++ b/docs/html/design/media/multipane_expand.png
Binary files differ
diff --git a/docs/html/design/media/multipane_show.png b/docs/html/design/media/multipane_show.png
index 0231adb..b10c91c 100644
--- a/docs/html/design/media/multipane_show.png
+++ b/docs/html/design/media/multipane_show.png
Binary files differ
diff --git a/docs/html/design/media/multipane_stack.png b/docs/html/design/media/multipane_stack.png
index 7769f0c..567099e 100644
--- a/docs/html/design/media/multipane_stack.png
+++ b/docs/html/design/media/multipane_stack.png
Binary files differ
diff --git a/docs/html/design/media/multipane_stretch.png b/docs/html/design/media/multipane_stretch.png
index 5075af6..b2dca02 100644
--- a/docs/html/design/media/multipane_stretch.png
+++ b/docs/html/design/media/multipane_stretch.png
Binary files differ
diff --git a/docs/html/design/media/multipane_view_tablet.png b/docs/html/design/media/multipane_view_tablet.png
index 56a6718..f116b6f 100644
--- a/docs/html/design/media/multipane_view_tablet.png
+++ b/docs/html/design/media/multipane_view_tablet.png
Binary files differ
diff --git a/docs/html/design/media/multipane_views.png b/docs/html/design/media/multipane_views.png
index 9fdfcfd..40b8af6 100644
--- a/docs/html/design/media/multipane_views.png
+++ b/docs/html/design/media/multipane_views.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_back.png b/docs/html/design/media/navigation_between_apps_back.png
index ded5d0a..d5cd979 100755
--- a/docs/html/design/media/navigation_between_apps_back.png
+++ b/docs/html/design/media/navigation_between_apps_back.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_inward.png b/docs/html/design/media/navigation_between_apps_inward.png
index 1f5e401..7394b1c 100755
--- a/docs/html/design/media/navigation_between_apps_inward.png
+++ b/docs/html/design/media/navigation_between_apps_inward.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_apps_up.png b/docs/html/design/media/navigation_between_apps_up.png
index f192c88..99c3112 100755
--- a/docs/html/design/media/navigation_between_apps_up.png
+++ b/docs/html/design/media/navigation_between_apps_up.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_siblings_gmail.png b/docs/html/design/media/navigation_between_siblings_gmail.png
index fe01ed3..64f06c6 100644
--- a/docs/html/design/media/navigation_between_siblings_gmail.png
+++ b/docs/html/design/media/navigation_between_siblings_gmail.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_siblings_market1.png b/docs/html/design/media/navigation_between_siblings_market1.png
index 8f2b3dc..b12a432 100755
--- a/docs/html/design/media/navigation_between_siblings_market1.png
+++ b/docs/html/design/media/navigation_between_siblings_market1.png
Binary files differ
diff --git a/docs/html/design/media/navigation_between_siblings_market2.png b/docs/html/design/media/navigation_between_siblings_market2.png
index 33b654c..a09d9d7 100755
--- a/docs/html/design/media/navigation_between_siblings_market2.png
+++ b/docs/html/design/media/navigation_between_siblings_market2.png
Binary files differ
diff --git a/docs/html/design/media/navigation_from_outside_back.png b/docs/html/design/media/navigation_from_outside_back.png
index 971ee57..a94e9c3 100644
--- a/docs/html/design/media/navigation_from_outside_back.png
+++ b/docs/html/design/media/navigation_from_outside_back.png
Binary files differ
diff --git a/docs/html/design/media/navigation_indirect_notification.png b/docs/html/design/media/navigation_indirect_notification.png
index 6f99267..ca9a1b5 100644
--- a/docs/html/design/media/navigation_indirect_notification.png
+++ b/docs/html/design/media/navigation_indirect_notification.png
Binary files differ
diff --git a/docs/html/design/media/navigation_popup_notification.png b/docs/html/design/media/navigation_popup_notification.png
index a0a3ee7..76ed984 100644
--- a/docs/html/design/media/navigation_popup_notification.png
+++ b/docs/html/design/media/navigation_popup_notification.png
Binary files differ
diff --git a/docs/html/design/media/navigation_up_vs_back_gmail.png b/docs/html/design/media/navigation_up_vs_back_gmail.png
index ff7adfe..fdeeb90 100644
--- a/docs/html/design/media/navigation_up_vs_back_gmail.png
+++ b/docs/html/design/media/navigation_up_vs_back_gmail.png
Binary files differ
diff --git a/docs/html/design/media/navigation_with_back_and_up.png b/docs/html/design/media/navigation_with_back_and_up.png
index 5440220..af2de78 100644
--- a/docs/html/design/media/navigation_with_back_and_up.png
+++ b/docs/html/design/media/navigation_with_back_and_up.png
Binary files differ
diff --git a/docs/html/design/media/notifications_pattern_additional_fail.png b/docs/html/design/media/notifications_pattern_additional_fail.png
index 3945ffb..707c98c 100644
--- a/docs/html/design/media/notifications_pattern_additional_fail.png
+++ b/docs/html/design/media/notifications_pattern_additional_fail.png
Binary files differ
diff --git a/docs/html/design/media/notifications_pattern_additional_win.png b/docs/html/design/media/notifications_pattern_additional_win.png
index 74472c3..eb193d8 100644
--- a/docs/html/design/media/notifications_pattern_additional_win.png
+++ b/docs/html/design/media/notifications_pattern_additional_win.png
Binary files differ
diff --git a/docs/html/design/media/notifications_pattern_real_time_people.png b/docs/html/design/media/notifications_pattern_real_time_people.png
index 32e62eb..2af40b8 100644
--- a/docs/html/design/media/notifications_pattern_real_time_people.png
+++ b/docs/html/design/media/notifications_pattern_real_time_people.png
Binary files differ
diff --git a/docs/html/design/media/picker_datetime.png b/docs/html/design/media/picker_datetime.png
index 9876ab2..fb495ee 100644
--- a/docs/html/design/media/picker_datetime.png
+++ b/docs/html/design/media/picker_datetime.png
Binary files differ
diff --git a/docs/html/design/media/picker_space.png b/docs/html/design/media/picker_space.png
index 024776f..8b8e3b3 100644
--- a/docs/html/design/media/picker_space.png
+++ b/docs/html/design/media/picker_space.png
Binary files differ
diff --git a/docs/html/design/media/progress_activity.png b/docs/html/design/media/progress_activity.png
index 32cf1f5..f4dffab 100644
--- a/docs/html/design/media/progress_activity.png
+++ b/docs/html/design/media/progress_activity.png
Binary files differ
diff --git a/docs/html/design/media/progress_activity2.png b/docs/html/design/media/progress_activity2.png
index ec3df99..07205f5 100644
--- a/docs/html/design/media/progress_activity2.png
+++ b/docs/html/design/media/progress_activity2.png
Binary files differ
diff --git a/docs/html/design/media/seekbar_example.png b/docs/html/design/media/seekbar_example.png
index 70b7e5e..4c0790a 100644
--- a/docs/html/design/media/seekbar_example.png
+++ b/docs/html/design/media/seekbar_example.png
Binary files differ
diff --git a/docs/html/design/media/selection_cab_big.png b/docs/html/design/media/selection_cab_big.png
index 72567cb..ee21fa4 100644
--- a/docs/html/design/media/selection_cab_big.png
+++ b/docs/html/design/media/selection_cab_big.png
Binary files differ
diff --git a/docs/html/design/media/selection_context_menu.png b/docs/html/design/media/selection_context_menu.png
index c711546..93b00b0 100644
--- a/docs/html/design/media/selection_context_menu.png
+++ b/docs/html/design/media/selection_context_menu.png
Binary files differ
diff --git a/docs/html/design/media/settings_flowchart.png b/docs/html/design/media/settings_flowchart.png
index 7e8623c..d92cfa0 100644
--- a/docs/html/design/media/settings_flowchart.png
+++ b/docs/html/design/media/settings_flowchart.png
Binary files differ
diff --git a/docs/html/design/media/settings_overflow.png b/docs/html/design/media/settings_overflow.png
index 9000bec..c13b9fc 100644
--- a/docs/html/design/media/settings_overflow.png
+++ b/docs/html/design/media/settings_overflow.png
Binary files differ
diff --git a/docs/html/design/media/spinners_form.png b/docs/html/design/media/spinners_form.png
index 79ee4e4..5556e2b 100644
--- a/docs/html/design/media/spinners_form.png
+++ b/docs/html/design/media/spinners_form.png
Binary files differ
diff --git a/docs/html/design/media/spinners_hololightanddark.png b/docs/html/design/media/spinners_hololightanddark.png
index 9b0601e..cea5ec2 100644
--- a/docs/html/design/media/spinners_hololightanddark.png
+++ b/docs/html/design/media/spinners_hololightanddark.png
Binary files differ
diff --git a/docs/html/design/media/swipe_tabs.png b/docs/html/design/media/swipe_tabs.png
index f25f061..1f6b5e6 100644
--- a/docs/html/design/media/swipe_tabs.png
+++ b/docs/html/design/media/swipe_tabs.png
Binary files differ
diff --git a/docs/html/design/media/swipe_views.png b/docs/html/design/media/swipe_views.png
index 3b6ecaf..ea1e635 100644
--- a/docs/html/design/media/swipe_views.png
+++ b/docs/html/design/media/swipe_views.png
Binary files differ
diff --git a/docs/html/design/media/swipe_views2.png b/docs/html/design/media/swipe_views2.png
index 2ed366c..6479a2f 100644
--- a/docs/html/design/media/swipe_views2.png
+++ b/docs/html/design/media/swipe_views2.png
Binary files differ
diff --git a/docs/html/design/media/text_input_holodarkandlight.png b/docs/html/design/media/text_input_holodarkandlight.png
index aff61fc..5ef20ee 100644
--- a/docs/html/design/media/text_input_holodarkandlight.png
+++ b/docs/html/design/media/text_input_holodarkandlight.png
Binary files differ
diff --git a/docs/html/design/media/text_input_singlevsmultiline.png b/docs/html/design/media/text_input_singlevsmultiline.png
index 7bb9a5c..4890a83 100644
--- a/docs/html/design/media/text_input_singlevsmultiline.png
+++ b/docs/html/design/media/text_input_singlevsmultiline.png
Binary files differ
diff --git a/docs/html/design/media/text_input_textselection.png b/docs/html/design/media/text_input_textselection.png
index 85689cf..f2ede0d 100644
--- a/docs/html/design/media/text_input_textselection.png
+++ b/docs/html/design/media/text_input_textselection.png
Binary files differ
diff --git a/docs/html/design/media/text_input_typesandtypedown.png b/docs/html/design/media/text_input_typesandtypedown.png
index 32f761c..1feac28 100644
--- a/docs/html/design/media/text_input_typesandtypedown.png
+++ b/docs/html/design/media/text_input_typesandtypedown.png
Binary files differ
diff --git a/docs/html/design/media/themes_holo_dark.png b/docs/html/design/media/themes_holo_dark.png
index 916ad27..0a5876a 100644
--- a/docs/html/design/media/themes_holo_dark.png
+++ b/docs/html/design/media/themes_holo_dark.png
Binary files differ
diff --git a/docs/html/design/media/themes_holo_inverse.png b/docs/html/design/media/themes_holo_inverse.png
index 72c0244..50be4fb 100644
--- a/docs/html/design/media/themes_holo_inverse.png
+++ b/docs/html/design/media/themes_holo_inverse.png
Binary files differ
diff --git a/docs/html/design/media/themes_holo_light.png b/docs/html/design/media/themes_holo_light.png
index d4b0861..edc7f77 100644
--- a/docs/html/design/media/themes_holo_light.png
+++ b/docs/html/design/media/themes_holo_light.png
Binary files differ
diff --git a/docs/html/design/media/touch_feedback_communication.png b/docs/html/design/media/touch_feedback_communication.png
index bb27250..6388b77 100644
--- a/docs/html/design/media/touch_feedback_communication.png
+++ b/docs/html/design/media/touch_feedback_communication.png
Binary files differ
diff --git a/docs/html/design/media/touch_feedback_states.png b/docs/html/design/media/touch_feedback_states.png
index 972198c..9e306bb 100644
--- a/docs/html/design/media/touch_feedback_states.png
+++ b/docs/html/design/media/touch_feedback_states.png
Binary files differ
diff --git a/docs/html/design/media/typography_sizes.png b/docs/html/design/media/typography_sizes.png
index eda1d99..fe6cdce 100644
--- a/docs/html/design/media/typography_sizes.png
+++ b/docs/html/design/media/typography_sizes.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_all_apps.png b/docs/html/design/media/ui_overview_all_apps.png
index 17e7ece..d44e5a4 100644
--- a/docs/html/design/media/ui_overview_all_apps.png
+++ b/docs/html/design/media/ui_overview_all_apps.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_home_screen.png b/docs/html/design/media/ui_overview_home_screen.png
index ee0e4d6..d1376b5 100644
--- a/docs/html/design/media/ui_overview_home_screen.png
+++ b/docs/html/design/media/ui_overview_home_screen.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_notifications.png b/docs/html/design/media/ui_overview_notifications.png
index fd7438a..bc0513f 100644
--- a/docs/html/design/media/ui_overview_notifications.png
+++ b/docs/html/design/media/ui_overview_notifications.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_recents.png b/docs/html/design/media/ui_overview_recents.png
index 4ea0583..aabd7c7 100644
--- a/docs/html/design/media/ui_overview_recents.png
+++ b/docs/html/design/media/ui_overview_recents.png
Binary files differ
diff --git a/docs/html/design/media/ui_overview_system_ui.png b/docs/html/design/media/ui_overview_system_ui.png
index ecc4b7d..8993fff 100644
--- a/docs/html/design/media/ui_overview_system_ui.png
+++ b/docs/html/design/media/ui_overview_system_ui.png
Binary files differ
diff --git a/docs/html/design/media/whats_new_action_bar.png b/docs/html/design/media/whats_new_action_bar.png
index 713187e..7bb89d1 100644
--- a/docs/html/design/media/whats_new_action_bar.png
+++ b/docs/html/design/media/whats_new_action_bar.png
Binary files differ
diff --git a/docs/html/design/media/whats_new_multipanel.png b/docs/html/design/media/whats_new_multipanel.png
index 8e9c2f0..fbe2d56 100644
--- a/docs/html/design/media/whats_new_multipanel.png
+++ b/docs/html/design/media/whats_new_multipanel.png
Binary files differ
diff --git a/docs/html/design/media/whats_new_multiselect.png b/docs/html/design/media/whats_new_multiselect.png
index ab34b24..6d97939 100644
--- a/docs/html/design/media/whats_new_multiselect.png
+++ b/docs/html/design/media/whats_new_multiselect.png
Binary files differ
diff --git a/docs/html/design/media/whats_new_nav_bar.png b/docs/html/design/media/whats_new_nav_bar.png
index 46239e5..b0c490c 100644
--- a/docs/html/design/media/whats_new_nav_bar.png
+++ b/docs/html/design/media/whats_new_nav_bar.png
Binary files differ
diff --git a/docs/html/design/patterns/actionbar.jd b/docs/html/design/patterns/actionbar.jd
index 2226fec..fe77e79 100644
--- a/docs/html/design/patterns/actionbar.jd
+++ b/docs/html/design/patterns/actionbar.jd
@@ -34,15 +34,13 @@
 Important: If the app is currently not displaying the top-level screen, be sure to display the Up
 caret to the left of the app icon, so the user can navigate up the hierarchy. For more discussion of
 Up navigation, see the <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> pattern.
+        </p>
 
-<div class="figure">
-  <img src="{@docRoot}design/media/action_bar_pattern_up_app_icon.png">
-  <div class="figure-caption">
-    App icon with and without "up" affordance.
-  </div>
+<img src="{@docRoot}design/media/action_bar_pattern_up_app_icon.png">
+<div class="figure-caption">
+  App icon with and without "up" affordance.
 </div>
 
-        </p>
       </li>
     </ol>
 
@@ -114,7 +112,7 @@
 <p>To display actions and, if necessary, the action overflow, use the bottom bar.</p>
 
   </div>
-  <div class="layout-content-col span-3">
+  <div class="layout-content-col span-5">
 
     <img src="{@docRoot}design/media/action_bar_pattern_considerations.png">
 
diff --git a/docs/html/design/patterns/gestures.jd b/docs/html/design/patterns/gestures.jd
index 9868df2..e579cee 100644
--- a/docs/html/design/patterns/gestures.jd
+++ b/docs/html/design/patterns/gestures.jd
@@ -82,7 +82,7 @@
   </div>
   <div class="layout-content-col span-4">
 
-    <img src="{@docRoot}design/media/gesture_pinchopen.png">
+    <img src="{@docRoot}design/media/gesture_pinchopen.png" style="margin-left:-4px">
 
 <h4>Pinch open</h4>
 <p>Zooms into content.</p>
diff --git a/docs/html/design/style/color.jd b/docs/html/design/style/color.jd
index e25f7c6..9c7b6b6 100644
--- a/docs/html/design/style/color.jd
+++ b/docs/html/design/style/color.jd
@@ -3,9 +3,8 @@
 
 <style>
   .color-row {
-    width: 740px;
-    margin-left: 10px !important;
-    margin-right: 10px !important;
+    width: 760px;
+    margin:0;
 
     display: -webkit-box;
     display:    -moz-box;
diff --git a/docs/html/design/style/devices-displays.jd b/docs/html/design/style/devices-displays.jd
index e5fe26d..df77c1b 100644
--- a/docs/html/design/style/devices-displays.jd
+++ b/docs/html/design/style/devices-displays.jd
@@ -32,9 +32,7 @@
   </div>
 </div>
 
-<div style="text-align:center">
   <img src="{@docRoot}design/media/devices_displays_density.png">
-</div>
 
 <h4>Strategies</h4>
 <p>So where do you begin when designing for multiple screens? One approach is to work in the base
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 775e45d..c4e8bd6 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -139,7 +139,7 @@
 
     <ul>
       <li class="no-bullet with-icon tablet">
-        <p>Action bar icons for phones should be <strong>32x32 <acronym title="Density-independent pixels. One dp is one pixel on a 160 dpi screen.">dp</acronym></strong>.</p></li>
+        <p>Action bar icons for phones and tablets should be <strong>32x32 <acronym title="Density-independent pixels. One dp is one pixel on a 160 dpi screen.">dp</acronym></strong>.</p></li>
     </ul>
 
   </div>
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 418dc52..2e153dd 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -141,11 +141,13 @@
     private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
     private static final int MSG_REPORT_NEW_ROUTES = 16;
     private static final int MSG_REEVALUATE_REMOTE = 17;
+    private static final int MSG_RCC_NEW_PLAYBACK_INFO = 18;
+    private static final int MSG_RCC_NEW_VOLUME_OBS = 19;
     // start of messages handled under wakelock
     //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
     //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
-    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 18;
-    private static final int MSG_SET_A2DP_CONNECTION_STATE = 19;
+    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 20;
+    private static final int MSG_SET_A2DP_CONNECTION_STATE = 21;
     // end of messages handled under wakelock
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -3100,6 +3102,15 @@
                 case MSG_REEVALUATE_REMOTE:
                     onReevaluateRemote();
                     break;
+
+                case MSG_RCC_NEW_PLAYBACK_INFO:
+                    onNewPlaybackInfoForRcc(msg.arg1 /* rccId */, msg.arg2 /* key */,
+                            ((Integer)msg.obj).intValue() /* value */);
+                    break;
+                case MSG_RCC_NEW_VOLUME_OBS:
+                    onRegisterVolumeObserverForRcc(msg.arg1 /* rccId */,
+                            (IRemoteVolumeObserver)msg.obj /* rvo */);
+                    break;
             }
         }
     }
@@ -4243,6 +4254,7 @@
         public int mPlaybackVolumeHandling;
         public int mPlaybackStream;
         public int mPlaybackState;
+        public IRemoteVolumeObserver mRemoteVolumeObs;
 
         public void resetPlaybackInfo() {
             mPlaybackType = RemoteControlClient.PLAYBACK_TYPE_LOCAL;
@@ -4251,6 +4263,7 @@
             mPlaybackVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
             mPlaybackStream = AudioManager.STREAM_MUSIC;
             mPlaybackState = RemoteControlClient.PLAYSTATE_STOPPED;
+            mRemoteVolumeObs = null;
         }
 
         /** precondition: mediaIntent != null, eventReceiver != null */
@@ -4335,7 +4348,9 @@
                         "  -- state: " + rcse.mPlaybackState +
                         "  -- vol handling: " + rcse.mPlaybackVolumeHandling +
                         "  -- vol: " + rcse.mPlaybackVolume +
-                        "  -- volMax: " + rcse.mPlaybackVolumeMax);
+                        "  -- volMax: " + rcse.mPlaybackVolumeMax +
+                        "  -- volObs: " + rcse.mRemoteVolumeObs);
+                
             }
         }
         synchronized (mMainRemote) {
@@ -4956,15 +4971,21 @@
         }
     }
 
-    // FIXME send a message instead of updating the stack synchronously
     public void setPlaybackInfoForRcc(int rccId, int what, int value) {
-        if(DEBUG_RC) Log.d(TAG, "setPlaybackInfoForRcc(id="+rccId+", what="+what+",val="+value+")");
+        sendMsg(mAudioHandler, MSG_RCC_NEW_PLAYBACK_INFO, SENDMSG_QUEUE,
+                rccId /* arg1 */, what /* arg2 */, Integer.valueOf(value) /* obj */, 0 /* delay */);
+    }
+
+    // handler for MSG_RCC_NEW_PLAYBACK_INFO
+    private void onNewPlaybackInfoForRcc(int rccId, int key, int value) {
+        if(DEBUG_RC) Log.d(TAG, "onNewPlaybackInfoForRcc(id=" + rccId +
+                ", what=" + key + ",val=" + value + ")");
         synchronized(mRCStack) {
             Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
             while(stackIterator.hasNext()) {
                 RemoteControlStackEntry rcse = stackIterator.next();
                 if (rcse.mRccId == rccId) {
-                    switch (what) {
+                    switch (key) {
                         case RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE:
                             rcse.mPlaybackType = value;
                             postReevaluateRemote();
@@ -5009,7 +5030,7 @@
                             }
                             break;
                         default:
-                            Log.e(TAG, "unhandled key " + what + " for RCC " + rccId);
+                            Log.e(TAG, "unhandled key " + key + " for RCC " + rccId);
                             break;
                     }
                     return;
@@ -5018,6 +5039,25 @@
         }
     }
 
+    public void registerRemoteVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
+        sendMsg(mAudioHandler, MSG_RCC_NEW_VOLUME_OBS, SENDMSG_QUEUE,
+                rccId /* arg1 */, 0, rvo /* obj */, 0 /* delay */);
+    }
+
+    // handler for MSG_RCC_NEW_VOLUME_OBS
+    private void onRegisterVolumeObserverForRcc(int rccId, IRemoteVolumeObserver rvo) {
+        synchronized(mRCStack) {
+            Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
+            while(stackIterator.hasNext()) {
+                RemoteControlStackEntry rcse = stackIterator.next();
+                if (rcse.mRccId == rccId) {
+                    rcse.mRemoteVolumeObs = rvo;
+                    break;
+                }
+            }
+        }
+    }
+
     /**
      * Checks if a remote client is active on the supplied stream type. Update the remote stream
      * volume state if found and playing
@@ -5100,23 +5140,24 @@
             // only handling discrete events
             return;
         }
-        String packageForRcc = null;
+        IRemoteVolumeObserver rvo = null;
         synchronized (mRCStack) {
             Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
             while(stackIterator.hasNext()) {
                 RemoteControlStackEntry rcse = stackIterator.next();
                 //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
                 if (rcse.mRccId == rccId) {
-                    packageForRcc = rcse.mReceiverComponent.getPackageName();
+                    rvo = rcse.mRemoteVolumeObs;
                     break;
                 }
             }
         }
-        if (packageForRcc != null) {
-            Intent intent = new Intent(Intent.ACTION_VOLUME_UPDATE);
-            intent.putExtra(Intent.EXTRA_VOLUME_UPDATE_DIRECTION, direction);
-            intent.setPackage(packageForRcc);
-            mContext.sendBroadcast(intent);
+        if (rvo != null) {
+            try {
+                rvo.dispatchRemoteVolumeUpdate(direction, -1);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error dispatching relative volume update", e);
+            }
         }
     }
 
@@ -5147,23 +5188,24 @@
             }
             rccId = mMainRemote.mRccId;
         }
-        String packageForRcc = null;
+        IRemoteVolumeObserver rvo = null;
         synchronized (mRCStack) {
             Iterator<RemoteControlStackEntry> stackIterator = mRCStack.iterator();
             while(stackIterator.hasNext()) {
                 RemoteControlStackEntry rcse = stackIterator.next();
                 if (rcse.mRccId == rccId) {
                     //FIXME OPTIMIZE store this info in mMainRemote so we don't have to iterate?
-                    packageForRcc = rcse.mReceiverComponent.getPackageName();
+                    rvo = rcse.mRemoteVolumeObs;
                     break;
                 }
             }
         }
-        if (packageForRcc != null) {
-            Intent intent = new Intent(Intent.ACTION_VOLUME_UPDATE);
-            intent.putExtra(Intent.EXTRA_VOLUME_UPDATE_VALUE, vol);
-            intent.setPackage(packageForRcc);
-            mContext.sendBroadcast(intent);
+        if (rvo != null) {
+            try {
+                rvo.dispatchRemoteVolumeUpdate(0, vol);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error dispatching absolute volume update", e);
+            }
         }
     }
 
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 83483c6..854eb3f 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -24,6 +24,7 @@
 import android.media.IAudioRoutesObserver;
 import android.media.IRemoteControlClient;
 import android.media.IRemoteControlDisplay;
+import android.media.IRemoteVolumeObserver;
 import android.media.IRingtonePlayer;
 import android.net.Uri;
 import android.view.KeyEvent;
@@ -135,6 +136,7 @@
     oneway void setPlaybackInfoForRcc(int rccId, int what, int value);
            int  getRemoteStreamMaxVolume();
            int  getRemoteStreamVolume();
+    oneway void registerRemoteVolumeObserverForRcc(int rccId, in IRemoteVolumeObserver rvo);
 
     void startBluetoothSco(IBinder cb);
     void stopBluetoothSco(IBinder cb);
diff --git a/media/java/android/media/IRemoteVolumeObserver.aidl b/media/java/android/media/IRemoteVolumeObserver.aidl
new file mode 100644
index 0000000..7ff0c06
--- /dev/null
+++ b/media/java/android/media/IRemoteVolumeObserver.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+
+/**
+ * AIDL for the AudioService to report requests for remote volume update requests.
+ * @hide
+ */
+oneway interface IRemoteVolumeObserver {
+    void dispatchRemoteVolumeUpdate(int direction, int value);
+}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index a9e6e3d..b6187da 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -589,9 +589,42 @@
         RouteGroup mGroup;
         final RouteCategory mCategory;
         Drawable mIcon;
+        // playback information
+        int mPlaybackType = PLAYBACK_TYPE_LOCAL;
+        int mVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+        int mVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME;
+        int mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING;
+        int mPlaybackStream = AudioManager.STREAM_MUSIC;
+        VolumeCallbackInfo mVcb;
 
         private Object mTag;
 
+        /**
+         * The default playback type, "local", indicating the presentation of the media is happening
+         * on the same device (e.g. a phone, a tablet) as where it is controlled from.
+         * @see #setPlaybackType(int)
+         */
+        public final static int PLAYBACK_TYPE_LOCAL = 0;
+        /**
+         * A playback type indicating the presentation of the media is happening on
+         * a different device (i.e. the remote device) than where it is controlled from.
+         * @see #setPlaybackType(int)
+         */
+        public final static int PLAYBACK_TYPE_REMOTE = 1;
+        /**
+         * Playback information indicating the playback volume is fixed, i.e. it cannot be
+         * controlled from this object. An example of fixed playback volume is a remote player,
+         * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
+         * than attenuate at the source.
+         * @see #setVolumeHandling(int)
+         */
+        public final static int PLAYBACK_VOLUME_FIXED = 0;
+        /**
+         * Playback information indicating the playback volume is variable and can be controlled
+         * from this object.
+         */
+        public final static int PLAYBACK_VOLUME_VARIABLE = 1;
+
         RouteInfo(RouteCategory category) {
             mCategory = category;
         }
@@ -685,6 +718,66 @@
             return mTag;
         }
 
+        /**
+         * @return the type of playback associated with this route
+         * @see UserRouteInfo#setPlaybackType(int)
+         */
+        public int getPlaybackType() {
+            return mPlaybackType;
+        }
+
+        /**
+         * @return the stream over which the playback associated with this route is performed
+         * @see UserRouteInfo#setPlaybackStream(int)
+         */
+        public int getPlaybackStream() {
+            return mPlaybackStream;
+        }
+
+        /**
+         * @return the volume at which the playback associated with this route is performed
+         * @see UserRouteInfo#setVolume(int)
+         */
+        public int getVolume() {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                int vol = 0;
+                try {
+                    vol = sStatic.mAudioService.getStreamVolume(mPlaybackStream);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error getting local stream volume", e);
+                }
+                return vol;
+            } else {
+                return mVolume;
+            }
+        }
+
+        /**
+         * @return the maximum volume at which the playback associated with this route is performed
+         * @see UserRouteInfo#setVolumeMax(int)
+         */
+        public int getVolumeMax() {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                int volMax = 0;
+                try {
+                    volMax = sStatic.mAudioService.getStreamMaxVolume(mPlaybackStream);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error getting local stream volume", e);
+                }
+                return volMax;
+            } else {
+                return mVolumeMax;
+            }
+        }
+
+        /**
+         * @return how volume is handling on the route
+         * @see UserRouteInfo#setVolumeHandling(int)
+         */
+        public int getVolumeHandling() {
+            return mVolumeHandling;
+        }
+
         void setStatusInt(CharSequence status) {
             if (!status.equals(mStatus)) {
                 mStatus = status;
@@ -695,6 +788,24 @@
             }
         }
 
+        final IRemoteVolumeObserver.Stub mRemoteVolObserver = new IRemoteVolumeObserver.Stub() {
+            public void dispatchRemoteVolumeUpdate(final int direction, final int value) {
+                sStatic.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                      //Log.d(TAG, "dispatchRemoteVolumeUpdate dir=" + direction + " val=" + value);
+                        if (mVcb != null) {
+                            if (direction != 0) {
+                                mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
+                            } else {
+                                mVcb.vcb.onVolumeSetRequest(mVcb.route, value);
+                            }
+                        }
+                    }
+                });
+            }
+        };
+
         void routeUpdated() {
             updateRoute(this);
         }
@@ -757,10 +868,14 @@
          * RemoteControlClient will be used to reflect and update information
          * such as route volume info in related UIs.</p>
          *
+         * <p>The RemoteControlClient must have been previously registered with
+         * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.</p>
+         *
          * @param rcc RemoteControlClient associated with this route
          */
         public void setRemoteControlClient(RemoteControlClient rcc) {
             mRcc = rcc;
+            updatePlaybackInfoOnRcc();
         }
 
         /**
@@ -792,6 +907,105 @@
         public void setIconResource(int resId) {
             setIconDrawable(sStatic.mResources.getDrawable(resId));
         }
+
+        /**
+         * Set a callback to be notified of volume update requests
+         * @param vcb
+         */
+        public void setVolumeCallback(VolumeCallback vcb) {
+            mVcb = new VolumeCallbackInfo(vcb, this);
+        }
+
+        /**
+         * Defines whether playback associated with this route is "local"
+         *    ({@link RouteInfo#PLAYBACK_TYPE_LOCAL}) or "remote"
+         *    ({@link RouteInfo#PLAYBACK_TYPE_REMOTE}).
+         * @param type
+         */
+        public void setPlaybackType(int type) {
+            if (mPlaybackType != type) {
+                mPlaybackType = type;
+                setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE, type);
+            }
+        }
+
+        /**
+         * Defines whether volume for the playback associated with this route is fixed
+         * ({@link RouteInfo#PLAYBACK_VOLUME_FIXED}) or can modified
+         * ({@link RouteInfo#PLAYBACK_VOLUME_VARIABLE}).
+         * @param volumeHandling
+         */
+        public void setVolumeHandling(int volumeHandling) {
+            if (mVolumeHandling != volumeHandling) {
+                mVolumeHandling = volumeHandling;
+                setPlaybackInfoOnRcc(
+                        RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING, volumeHandling);
+            }
+        }
+
+        /**
+         * Defines at what volume the playback associated with this route is performed (for user
+         * feedback purposes). This information is only used when the playback is not local.
+         * @param volume
+         */
+        public void setVolume(int volume) {
+            if (mVolume != volume) {
+                mVolume = volume;
+                setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_VOLUME, volume);
+            }
+        }
+
+        /**
+         * Defines the maximum volume at which the playback associated with this route is performed
+         * (for user feedback purposes). This information is only used when the playback is not
+         * local.
+         * @param volumeMax
+         */
+        public void setVolumeMax(int volumeMax) {
+            if (mVolumeMax != volumeMax) {
+                mVolumeMax = volumeMax;
+                setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_VOLUME_MAX, volumeMax);
+            }
+        }
+
+        /**
+         * Defines over what stream type the media is presented.
+         * @param stream
+         */
+        public void setPlaybackStream(int stream) {
+            if (mPlaybackStream != stream) {
+                mPlaybackStream = stream;
+                setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_USES_STREAM, stream);
+            }
+        }
+
+        private void updatePlaybackInfoOnRcc() {
+            if ((mRcc != null) && (mRcc.getRcseId() != RemoteControlClient.RCSE_ID_UNREGISTERED)) {
+                mRcc.setPlaybackInformation(
+                        RemoteControlClient.PLAYBACKINFO_VOLUME_MAX, mVolumeMax);
+                mRcc.setPlaybackInformation(
+                        RemoteControlClient.PLAYBACKINFO_VOLUME, mVolume);
+                mRcc.setPlaybackInformation(
+                        RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING, mVolumeHandling);
+                mRcc.setPlaybackInformation(
+                        RemoteControlClient.PLAYBACKINFO_USES_STREAM, mPlaybackStream);
+                mRcc.setPlaybackInformation(
+                        RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE, mPlaybackType);
+                // let AudioService know whom to call when remote volume needs to be updated
+                try {
+                    sStatic.mAudioService.registerRemoteVolumeObserverForRcc(
+                            mRcc.getRcseId() /* rccId */, mRemoteVolObserver /* rvo */);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error registering remote volume observer", e);
+                }
+            }
+        }
+
+        private void setPlaybackInfoOnRcc(int what, int value) {
+            if (mRcc != null) {
+                mRcc.setPlaybackInformation(what, value);
+            }
+        }
     }
 
     /**
@@ -1206,4 +1420,43 @@
         }
 
     }
+
+    static class VolumeCallbackInfo {
+        public final VolumeCallback vcb;
+        public final RouteInfo route;
+
+        public VolumeCallbackInfo(VolumeCallback vcb, RouteInfo route) {
+            this.vcb = vcb;
+            this.route = route;
+        }
+    }
+
+    /**
+     * Interface for receiving events about volume changes.
+     * All methods of this interface will be called from the application's main thread.
+     *
+     * <p>A VolumeCallback will only receive events relevant to routes that the callback
+     * was registered for.</p>
+     *
+     * @see UserRouteInfo#setVolumeCallback(VolumeCallback)
+     */
+    public static abstract class VolumeCallback {
+        /**
+         * Called when the volume for the route should be increased or decreased.
+         * @param info the route affected by this event
+         * @param direction an integer indicating whether the volume is to be increased
+         *     (positive value) or decreased (negative value).
+         *     For bundled changes, the absolute value indicates the number of changes
+         *     in the same direction, e.g. +3 corresponds to three "volume up" changes.
+         */
+        public abstract void onVolumeUpdateRequest(RouteInfo info, int direction);
+        /**
+         * Called when the volume for the route should be set to the given value
+         * @param info the route affected by this event
+         * @param volume an integer indicating the new volume value that should be used, always
+         *     between 0 and the value set by {@link UserRouteInfo#setVolumeMax(int)}.
+         */
+        public abstract void onVolumeSetRequest(RouteInfo info, int volume);
+    }
+
 }
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 5b8035e..4c71ace 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -134,13 +134,13 @@
     public final static int PLAYSTATE_NONE               = 0;
 
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * The default playback type, "local", indicating the presentation of the media is happening on
      * the same device (e.g. a phone, a tablet) as where it is controlled from.
      */
     public final static int PLAYBACK_TYPE_LOCAL = 0;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * A playback type indicating the presentation of the media is happening on
      * a different device (i.e. the remote device) than where it is controlled from.
      */
@@ -148,7 +148,7 @@
     private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL;
     private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled
      * from this object. An example of fixed playback volume is a remote player, playing over HDMI
      * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the
@@ -157,7 +157,7 @@
      */
     public final static int PLAYBACK_VOLUME_FIXED = 0;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information indicating the playback volume is variable and can be controlled from
      * this object.
      * @see #PLAYBACKINFO_VOLUME_HANDLING.
@@ -173,34 +173,34 @@
     //==========================================
     // Public keys for playback information
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information that defines the type of playback associated with this
      * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}.
      */
     public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information that defines at what volume the playback associated with this
      * RemoteControlClient is performed. This information is only used when the playback type is not
      * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
      */
     public final static int PLAYBACKINFO_VOLUME = 2;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information that defines the maximum volume volume value that is supported
      * by the playback associated with this RemoteControlClient. This information is only used
      * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
      */
     public final static int PLAYBACKINFO_VOLUME_MAX = 3;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information that defines how volume is handled for the presentation of the media.
      * @see #PLAYBACK_VOLUME_FIXED
      * @see #PLAYBACK_VOLUME_VARIABLE
      */
     public final static int PLAYBACKINFO_VOLUME_HANDLING = 4;
     /**
-     * @hide (to be un-hidden)
+     * @hide
      * Playback information that defines over what stream type the media is presented.
      */
     public final static int PLAYBACKINFO_USES_STREAM = 5;
@@ -642,7 +642,7 @@
     private int mPlaybackStream = AudioManager.STREAM_MUSIC;
 
     /**
-     * @hide  (to be un-hidden)
+     * @hide
      * Set information describing information related to the playback of media so the system
      * can implement additional behavior to handle non-local playback usecases.
      * @param what a key to specify the type of information to set. Valid keys are
@@ -713,7 +713,7 @@
     }
 
     /**
-     * @hide  (to be un-hidden)
+     * @hide
      * Return playback information represented as an integer value.
      * @param what a key to specify the type of information to retrieve. Valid keys are
      *        {@link #PLAYBACKINFO_PLAYBACK_TYPE},
@@ -899,6 +899,13 @@
         mRcseId = id;
     }
 
+    /**
+     * @hide
+     */
+    public int getRcseId() {
+        return mRcseId;
+    }
+
     private EventHandler mEventHandler;
     private final static int MSG_REQUEST_PLAYBACK_STATE = 1;
     private final static int MSG_REQUEST_METADATA = 2;
@@ -1048,7 +1055,7 @@
         if (mRcseId == RCSE_ID_UNREGISTERED) {
             return;
         }
-        Log.d(TAG, "sending to AudioService key=" + what + ", value=" + value);
+        //Log.d(TAG, "sending to AudioService key=" + what + ", value=" + value);
         IAudioService service = getService();
         try {
             service.setPlaybackInfoForRcc(mRcseId, what, value);
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 3a8e3fc..cd0da5a 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -120,7 +120,7 @@
 
     <!-- Default for Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION_URL -->
     <string name="def_accessibility_screen_reader_url" translatable="false">
-        https://ssl.gstatic.com/accessibility/javascript/android/AndroidScriptChooser.user.js
+        https://ssl.gstatic.com/accessibility/javascript/android/AndroidVox_v1.js
     </string>
 
     <!-- Default for Settings.Secure.TOUCH_EXPLORATION_ENABLED -->
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 4785abd..beeea8e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -4395,7 +4395,7 @@
         pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
                 pw.print(" mUserRotation="); pw.print(mUserRotation);
                 pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations);
-        pw.print(prefix); pw.print(" mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
+        pw.print(prefix); pw.print("mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
         pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
                 pw.print(mCarDockEnablesAccelerometer);
                 pw.print(" mDeskDockEnablesAccelerometer=");
@@ -4403,12 +4403,13 @@
         pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
                 pw.print(mLidKeyboardAccessibility);
                 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
-                pw.print(" mLidControlsSleep="); pw.print(mLidControlsSleep);
-                pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
+                pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep);
+        pw.print(prefix); pw.print("mLongPressOnPowerBehavior=");
+                pw.print(mLongPressOnPowerBehavior);
+                pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
         pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
                 pw.print(" mScreenOnFully="); pw.print(mScreenOnFully);
-                pw.print(" mOrientationSensorEnabled="); pw.print(mOrientationSensorEnabled);
-                pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
+                pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
         pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft);
                 pw.print(","); pw.print(mUnrestrictedScreenTop);
                 pw.print(") "); pw.print(mUnrestrictedScreenWidth);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 2d41f43..fdb278d 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -2668,7 +2668,16 @@
             }
         }
 
-        if (!setSubtypeOnly) {
+        // Workaround.
+        // ASEC is not ready in the IMMS constructor. Accordingly, forward-locked
+        // IMEs are not recognized and considered uninstalled.
+        // Actually, we can't move everything after SystemReady because
+        // IMMS needs to run in the encryption lock screen. So, we just skip changing
+        // the default IME here and try cheking the default IME again in systemReady().
+        // TODO: Do nothing before system ready and implement a separated logic for
+        // the encryption lock screen.
+        // TODO: ASEC should be ready before IMMS is instantiated.
+        if (mSystemReady && !setSubtypeOnly) {
             // Set InputMethod here
             mSettings.putSelectedInputMethod(imi != null ? imi.getId() : "");
         }
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index 152e1889..48c6b2a 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -21,6 +21,7 @@
 import android.gesture.GestureLibraries;
 import android.gesture.GestureLibrary;
 import android.gesture.GesturePoint;
+import android.gesture.GestureStore;
 import android.gesture.GestureStroke;
 import android.gesture.Prediction;
 import android.graphics.Rect;
@@ -220,7 +221,8 @@
         mPerformLongPressDelayed = new PerformLongPressDelayed();
         mExitGestureDetectionModeDelayed = new ExitGestureDetectionModeDelayed();
         mGestureLibrary = GestureLibraries.fromRawResource(context, R.raw.accessibility_gestures);
-        mGestureLibrary.setOrientationStyle(4);
+        mGestureLibrary.setOrientationStyle(8);
+        mGestureLibrary.setSequenceType(GestureStore.SEQUENCE_SENSITIVE);
         mGestureLibrary.load();
         mSendHoverEnterDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_ENTER, true);
         mSendHoverExitDelayed = new SendHoverDelayed(MotionEvent.ACTION_HOVER_EXIT, false);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index c329174..5cd4beb 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -9542,12 +9542,14 @@
                 }
             }
         }
-        pw.println();
-        if (mOpeningApps.size() > 0) {
-            pw.print("  mOpeningApps="); pw.println(mOpeningApps);
-        }
-        if (mClosingApps.size() > 0) {
-            pw.print("  mClosingApps="); pw.println(mClosingApps);
+        if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) {
+            pw.println();
+            if (mOpeningApps.size() > 0) {
+                pw.print("  mOpeningApps="); pw.println(mOpeningApps);
+            }
+            if (mClosingApps.size() > 0) {
+                pw.print("  mClosingApps="); pw.println(mClosingApps);
+            }
         }
     }
 
@@ -9761,7 +9763,7 @@
                     pw.print(" mTransitionWindowAnimationScale="); pw.print(mTransitionAnimationScale);
                     pw.print(" mAnimatorDurationScale="); pw.println(mAnimatorDurationScale);
             pw.print("  mTraversalScheduled="); pw.print(mTraversalScheduled);
-                    pw.print("  mNextAppTransition=0x");
+                    pw.print(" mNextAppTransition=0x");
                     pw.print(Integer.toHexString(mNextAppTransition));
                     pw.print(" mAppTransitionReady="); pw.println(mAppTransitionReady);
             pw.print("  mAppTransitionRunning="); pw.print(mAppTransitionRunning);
@@ -9803,7 +9805,7 @@
                         pw.println(mNextAppTransitionCallback);
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
-                    pw.print(", mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+                    pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
         }
     }
 
@@ -9971,6 +9973,12 @@
         }
 
         synchronized(mWindowMap) {
+            pw.println();
+            if (dumpAll) {
+                pw.println("-------------------------------------------------------------------------------");
+            }
+            dumpLastANRLocked(pw);
+            pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
@@ -9990,11 +9998,6 @@
                 pw.println("-------------------------------------------------------------------------------");
             }
             dumpWindowsLocked(pw, dumpAll, null);
-            pw.println();
-            if (dumpAll) {
-                pw.println("-------------------------------------------------------------------------------");
-            }
-            dumpLastANRLocked(pw);
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 8f2ef76..f94bacd 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -719,6 +719,28 @@
     }
 
     /**
+     * Like isReadyForDisplay(), but ignores any force hiding of the window due
+     * to the keyguard.
+     */
+    boolean isReadyForDisplayIgnoringKeyguard() {
+        if (mRootToken.waitingToShow &&
+                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+            return false;
+        }
+        final AppWindowToken atoken = mAppToken;
+        if (atoken == null && !mPolicyVisibility) {
+            // If this is not an app window, and the policy has asked to force
+            // hide, then we really do want to hide.
+            return false;
+        }
+        return mHasSurface && !mDestroying
+                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
+                                && !mRootToken.hidden)
+                        || mWinAnimator.mAnimation != null
+                        || ((atoken != null) && (atoken.mAppAnimator.animation != null)));
+    }
+
+    /**
      * Like isOnScreen, but returns false if the surface hasn't yet
      * been drawn.
      */
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 579cbb7..f2dd335f 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -1218,10 +1218,10 @@
             }
             Slog.v(TAG, "performShow on " + this
                     + ": mDrawState=" + mDrawState + " readyForDisplay="
-                    + mWin.isReadyForDisplay()
+                    + mWin.isReadyForDisplayIgnoringKeyguard()
                     + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
         }
-        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplay()) {
+        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
             if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 66481fd..daf520b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -470,7 +470,7 @@
         if (pair == null) {
             pair = sDynamicIds.resolveId(value);
             if (pair == null) {
-                System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
+                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
             }
         }
         return pair;