Merge "Fix 6665117: ACTION_ASSIST visual improvements" into jb-dev
diff --git a/Android.mk b/Android.mk
index b0a3dac..5aaea97 100644
--- a/Android.mk
+++ b/Android.mk
@@ -193,6 +193,7 @@
 	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/IMediaScannerListener.aidl \
 	media/java/android/media/IMediaScannerService.aidl \
 	media/java/android/media/IRemoteControlClient.aidl \
diff --git a/api/16.txt b/api/16.txt
index eb09d85..70c4032 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -3679,6 +3679,7 @@
   public class MediaRouteActionProvider extends android.view.ActionProvider {
     ctor public MediaRouteActionProvider(android.content.Context);
     method public android.view.View onCreateActionView();
+    method public void setExtendedSettingsClickListener(android.view.View.OnClickListener);
     method public void setRouteTypes(int);
   }
 
@@ -3687,7 +3688,9 @@
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
     method public int getRouteTypes();
+    method public void setExtendedSettingsClickListener(android.view.View.OnClickListener);
     method public void setRouteTypes(int);
+    method public void showDialog();
   }
 
   public class NativeActivity extends android.app.Activity implements android.view.InputQueue.Callback android.view.SurfaceHolder.Callback2 android.view.ViewTreeObserver.OnGlobalLayoutListener {
@@ -11511,6 +11514,7 @@
     method public void addUserRoute(android.media.MediaRouter.UserRouteInfo);
     method public void clearUserRoutes();
     method public android.media.MediaRouter.RouteCategory createRouteCategory(java.lang.CharSequence, boolean);
+    method public android.media.MediaRouter.RouteCategory createRouteCategory(int, boolean);
     method public android.media.MediaRouter.UserRouteInfo createUserRoute(android.media.MediaRouter.RouteCategory);
     method public android.media.MediaRouter.RouteCategory getCategoryAt(int);
     method public int getCategoryCount();
@@ -11524,7 +11528,8 @@
     field public static final int ROUTE_TYPE_USER = 8388608; // 0x800000
   }
 
-  public static abstract interface MediaRouter.Callback {
+  public static abstract class MediaRouter.Callback {
+    ctor public MediaRouter.Callback();
     method public abstract void onRouteAdded(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public abstract void onRouteChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public abstract void onRouteGrouped(android.media.MediaRouter, android.media.MediaRouter.RouteInfo, android.media.MediaRouter.RouteGroup, int);
@@ -11536,6 +11541,7 @@
 
   public static class MediaRouter.RouteCategory {
     method public java.lang.CharSequence getName();
+    method public java.lang.CharSequence getName(android.content.Context);
     method public java.util.List<android.media.MediaRouter.RouteInfo> getRoutes(java.util.List<android.media.MediaRouter.RouteInfo>);
     method public int getSupportedTypes();
     method public boolean isGroupable();
@@ -11548,17 +11554,23 @@
     method public int getRouteCount();
     method public void removeRoute(android.media.MediaRouter.RouteInfo);
     method public void removeRoute(int);
+    method public void setIconDrawable(android.graphics.drawable.Drawable);
+    method public void setIconResource(int);
   }
 
   public static class MediaRouter.RouteInfo {
     method public android.media.MediaRouter.RouteCategory getCategory();
     method public android.media.MediaRouter.RouteGroup getGroup();
+    method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
+    method public java.lang.CharSequence getName(android.content.Context);
     method public java.lang.CharSequence getStatus();
     method public int getSupportedTypes();
+    method public java.lang.Object getTag();
+    method public void setTag(java.lang.Object);
   }
 
-  public static class MediaRouter.SimpleCallback implements android.media.MediaRouter.Callback {
+  public static class MediaRouter.SimpleCallback extends android.media.MediaRouter.Callback {
     ctor public MediaRouter.SimpleCallback();
     method public void onRouteAdded(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public void onRouteChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
@@ -11570,7 +11582,11 @@
   }
 
   public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
+    method public void setIconDrawable(android.graphics.drawable.Drawable);
+    method public void setIconResource(int);
     method public void setName(java.lang.CharSequence);
+    method public void setName(int);
+    method public void setRemoteControlClient(android.media.RemoteControlClient);
     method public void setStatus(java.lang.CharSequence);
   }
 
@@ -17356,6 +17372,8 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String NORMALIZED_NUMBER = "data4";
     field public static final java.lang.String NUMBER = "data1";
+    field public static final java.lang.String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+    field public static final java.lang.String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
     field public static final int TYPE_ASSISTANT = 19; // 0x13
     field public static final int TYPE_CALLBACK = 8; // 0x8
     field public static final int TYPE_CAR = 9; // 0x9
@@ -24358,12 +24376,6 @@
     method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
     method public boolean willNotCacheDrawing();
     method public boolean willNotDraw();
-    field public static final int ACCESSIBILITY_FOCUS_BACKWARD = 4097; // 0x1001
-    field public static final int ACCESSIBILITY_FOCUS_DOWN = 4226; // 0x1082
-    field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
-    field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
-    field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
-    field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
     field public static final android.util.Property ALPHA;
     field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
     field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -24385,7 +24397,6 @@
     field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
     field protected static final int[] FOCUSED_STATE_SET;
     field protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
-    field public static final int FOCUS_ACCESSIBILITY = 4096; // 0x1000
     field public static final int FOCUS_BACKWARD = 1; // 0x1
     field public static final int FOCUS_DOWN = 130; // 0x82
     field public static final int FOCUS_FORWARD = 2; // 0x2
@@ -25332,9 +25343,7 @@
 
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
-    method public android.view.accessibility.AccessibilityNodeInfo accessibilityFocusSearch(int, int);
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
-    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public boolean performAction(int, int, android.os.Bundle);
   }
diff --git a/api/current.txt b/api/current.txt
index a62698e..4a23046 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11514,6 +11514,7 @@
     method public void addUserRoute(android.media.MediaRouter.UserRouteInfo);
     method public void clearUserRoutes();
     method public android.media.MediaRouter.RouteCategory createRouteCategory(java.lang.CharSequence, boolean);
+    method public android.media.MediaRouter.RouteCategory createRouteCategory(int, boolean);
     method public android.media.MediaRouter.UserRouteInfo createUserRoute(android.media.MediaRouter.RouteCategory);
     method public android.media.MediaRouter.RouteCategory getCategoryAt(int);
     method public int getCategoryCount();
@@ -11527,7 +11528,8 @@
     field public static final int ROUTE_TYPE_USER = 8388608; // 0x800000
   }
 
-  public static abstract interface MediaRouter.Callback {
+  public static abstract class MediaRouter.Callback {
+    ctor public MediaRouter.Callback();
     method public abstract void onRouteAdded(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public abstract void onRouteChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public abstract void onRouteGrouped(android.media.MediaRouter, android.media.MediaRouter.RouteInfo, android.media.MediaRouter.RouteGroup, int);
@@ -11539,6 +11541,7 @@
 
   public static class MediaRouter.RouteCategory {
     method public java.lang.CharSequence getName();
+    method public java.lang.CharSequence getName(android.content.Context);
     method public java.util.List<android.media.MediaRouter.RouteInfo> getRoutes(java.util.List<android.media.MediaRouter.RouteInfo>);
     method public int getSupportedTypes();
     method public boolean isGroupable();
@@ -11560,11 +11563,14 @@
     method public android.media.MediaRouter.RouteGroup getGroup();
     method public android.graphics.drawable.Drawable getIconDrawable();
     method public java.lang.CharSequence getName();
+    method public java.lang.CharSequence getName(android.content.Context);
     method public java.lang.CharSequence getStatus();
     method public int getSupportedTypes();
+    method public java.lang.Object getTag();
+    method public void setTag(java.lang.Object);
   }
 
-  public static class MediaRouter.SimpleCallback implements android.media.MediaRouter.Callback {
+  public static class MediaRouter.SimpleCallback extends android.media.MediaRouter.Callback {
     ctor public MediaRouter.SimpleCallback();
     method public void onRouteAdded(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
     method public void onRouteChanged(android.media.MediaRouter, android.media.MediaRouter.RouteInfo);
@@ -11576,13 +11582,13 @@
   }
 
   public static class MediaRouter.UserRouteInfo extends android.media.MediaRouter.RouteInfo {
-    method public java.lang.Object getTag();
+    method public android.media.RemoteControlClient getRemoteControlClient();
     method public void setIconDrawable(android.graphics.drawable.Drawable);
     method public void setIconResource(int);
     method public void setName(java.lang.CharSequence);
+    method public void setName(int);
     method public void setRemoteControlClient(android.media.RemoteControlClient);
     method public void setStatus(java.lang.CharSequence);
-    method public void setTag(java.lang.Object);
   }
 
   public class MediaScannerConnection implements android.content.ServiceConnection {
@@ -17367,6 +17373,8 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String NORMALIZED_NUMBER = "data4";
     field public static final java.lang.String NUMBER = "data1";
+    field public static final java.lang.String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+    field public static final java.lang.String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
     field public static final int TYPE_ASSISTANT = 19; // 0x13
     field public static final int TYPE_CALLBACK = 8; // 0x8
     field public static final int TYPE_CAR = 9; // 0x9
@@ -22809,10 +22817,18 @@
   public abstract class ActionProvider {
     ctor public ActionProvider(android.content.Context);
     method public boolean hasSubMenu();
+    method public boolean isVisible();
     method public abstract deprecated android.view.View onCreateActionView();
     method public android.view.View onCreateActionView(android.view.MenuItem);
     method public boolean onPerformDefaultAction();
     method public void onPrepareSubMenu(android.view.SubMenu);
+    method public boolean overridesItemVisibility();
+    method public void refreshVisibility();
+    method public void setVisibilityListener(android.view.ActionProvider.VisibilityListener);
+  }
+
+  public static abstract interface ActionProvider.VisibilityListener {
+    method public abstract void onActionProviderVisibilityChanged(boolean);
   }
 
   public final class Choreographer {
@@ -24369,12 +24385,6 @@
     method protected boolean verifyDrawable(android.graphics.drawable.Drawable);
     method public boolean willNotCacheDrawing();
     method public boolean willNotDraw();
-    field public static final int ACCESSIBILITY_FOCUS_BACKWARD = 4097; // 0x1001
-    field public static final int ACCESSIBILITY_FOCUS_DOWN = 4226; // 0x1082
-    field public static final int ACCESSIBILITY_FOCUS_FORWARD = 4098; // 0x1002
-    field public static final int ACCESSIBILITY_FOCUS_LEFT = 4113; // 0x1011
-    field public static final int ACCESSIBILITY_FOCUS_RIGHT = 4162; // 0x1042
-    field public static final int ACCESSIBILITY_FOCUS_UP = 4129; // 0x1021
     field public static final android.util.Property ALPHA;
     field public static final int DRAWING_CACHE_QUALITY_AUTO = 0; // 0x0
     field public static final int DRAWING_CACHE_QUALITY_HIGH = 1048576; // 0x100000
@@ -24396,7 +24406,6 @@
     field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
     field protected static final int[] FOCUSED_STATE_SET;
     field protected static final int[] FOCUSED_WINDOW_FOCUSED_STATE_SET;
-    field public static final int FOCUS_ACCESSIBILITY = 4096; // 0x1000
     field public static final int FOCUS_BACKWARD = 1; // 0x1
     field public static final int FOCUS_DOWN = 130; // 0x82
     field public static final int FOCUS_FORWARD = 2; // 0x2
@@ -25343,9 +25352,7 @@
 
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
-    method public android.view.accessibility.AccessibilityNodeInfo accessibilityFocusSearch(int, int);
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo(int);
-    method public android.view.accessibility.AccessibilityNodeInfo findAccessibilityFocus(int);
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public boolean performAction(int, int, android.os.Bundle);
   }
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 0bc7371..96a6438 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -53,11 +53,7 @@
         unlink(pkgdir);
         return -errno;
     }
-    if (chown(pkgdir, uid, gid) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
-        unlink(pkgdir);
-        return -errno;
-    }
+
     if (mkdir(libdir, 0755) < 0) {
         ALOGE("cannot create dir '%s': %s\n", libdir, strerror(errno));
         unlink(pkgdir);
@@ -75,6 +71,13 @@
         unlink(pkgdir);
         return -errno;
     }
+
+    if (chown(pkgdir, uid, gid) < 0) {
+        ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(libdir);
+        unlink(pkgdir);
+        return -errno;
+    }
     return 0;
 }
 
diff --git a/core/java/android/app/MediaRouteActionProvider.java b/core/java/android/app/MediaRouteActionProvider.java
index 4860182..c2f5ac1 100644
--- a/core/java/android/app/MediaRouteActionProvider.java
+++ b/core/java/android/app/MediaRouteActionProvider.java
@@ -27,6 +27,8 @@
 import android.view.MenuItem;
 import android.view.View;
 
+import java.lang.ref.WeakReference;
+
 public class MediaRouteActionProvider extends ActionProvider {
     private static final String TAG = "MediaRouteActionProvider";
 
@@ -35,13 +37,14 @@
     private MenuItem mMenuItem;
     private MediaRouteButton mView;
     private int mRouteTypes;
-    private final RouterCallback mRouterCallback = new RouterCallback();
     private View.OnClickListener mExtendedSettingsListener;
+    private RouterCallback mCallback;
 
     public MediaRouteActionProvider(Context context) {
         super(context);
         mContext = context;
         mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mCallback = new RouterCallback(this);
 
         // Start with live audio by default.
         // TODO Update this when new route types are added; segment by API level
@@ -50,18 +53,17 @@
     }
 
     public void setRouteTypes(int types) {
-        if (types == mRouteTypes) {
-            // Already registered; nothing to do.
-            return;
-        }
+        if (mRouteTypes == types) return;
         if (mRouteTypes != 0) {
-            mRouter.removeCallback(mRouterCallback);
+            mRouter.removeCallback(mCallback);
         }
         mRouteTypes = types;
+        if (types != 0) {
+            mRouter.addCallback(types, mCallback);
+        }
         if (mView != null) {
             mView.setRouteTypes(mRouteTypes);
         }
-        mRouter.addCallback(types, mRouterCallback);
     }
 
     @Override
@@ -78,7 +80,6 @@
         }
         mMenuItem = item;
         mView = new MediaRouteButton(mContext);
-        mMenuItem.setVisible(mRouter.getRouteCount() > 1);
         mView.setRouteTypes(mRouteTypes);
         mView.setExtendedSettingsClickListener(mExtendedSettingsListener);
         return mView;
@@ -124,15 +125,43 @@
         }
     }
 
-    private class RouterCallback extends MediaRouter.SimpleCallback {
+    @Override
+    public boolean overridesItemVisibility() {
+        return true;
+    }
+
+    @Override
+    public boolean isVisible() {
+        return mRouter.getRouteCount() > 1;
+    }
+
+    private static class RouterCallback extends MediaRouter.SimpleCallback {
+        private WeakReference<MediaRouteActionProvider> mAp;
+
+        RouterCallback(MediaRouteActionProvider ap) {
+            mAp = new WeakReference<MediaRouteActionProvider>(ap);
+        }
+
         @Override
         public void onRouteAdded(MediaRouter router, RouteInfo info) {
-            mMenuItem.setVisible(mRouter.getRouteCount() > 1);
+            final MediaRouteActionProvider ap = mAp.get();
+            if (ap == null) {
+                router.removeCallback(this);
+                return;
+            }
+
+            ap.refreshVisibility();
         }
 
         @Override
         public void onRouteRemoved(MediaRouter router, RouteInfo info) {
-            mMenuItem.setVisible(mRouter.getRouteCount() > 1);
+            final MediaRouteActionProvider ap = mAp.get();
+            if (ap == null) {
+                router.removeCallback(this);
+                return;
+            }
+
+            ap.refreshVisibility();
         }
     }
 }
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a4eebda..018b25d 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -103,7 +103,7 @@
 
         if (mToggleMode) {
             if (mRemoteActive) {
-                mRouter.selectRoute(mRouteTypes, mRouter.getSystemAudioRoute());
+                mRouter.selectRouteInt(mRouteTypes, mRouter.getSystemAudioRoute());
             } else {
                 final int N = mRouter.getRouteCount();
                 for (int i = 0; i < N; i++) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e8f87bb..8e123ac 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -5416,6 +5416,20 @@
             public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
                     "filter");
 
+            /**
+             * A boolean query parameter that can be used with {@link #CONTENT_FILTER_URI}.
+             * If "1" or "true", display names are searched.  If "0" or "false", display names
+             * are not searched.  Default is "1".
+             */
+            public static final String SEARCH_DISPLAY_NAME_KEY = "search_display_name";
+
+            /**
+             * A boolean query parameter that can be used with {@link #CONTENT_FILTER_URI}.
+             * If "1" or "true", phone numbers are searched.  If "0" or "false", phone numbers
+             * are not searched.  Default is "1".
+             */
+            public static final String SEARCH_PHONE_NUMBER_KEY = "search_phone_number";
+
             public static final int TYPE_HOME = 1;
             public static final int TYPE_MOBILE = 2;
             public static final int TYPE_WORK = 3;
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 29926ca..0aabc44 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -480,7 +480,10 @@
                         // focus instead fetching all provider nodes to do the search here.
                         AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
                         if (provider != null) {
-                            focused = provider.findAccessibilityFocus(virtualDescendantId);
+                            if (mViewRootImpl.mAccessibilityFocusedVirtualView != null) {
+                                focused = AccessibilityNodeInfo.obtain(
+                                        mViewRootImpl.mAccessibilityFocusedVirtualView);
+                            }
                         } else if (virtualDescendantId == View.NO_ID) {
                             focused = host.createAccessibilityNodeInfo();
                         }
@@ -804,7 +807,6 @@
             if (!(root instanceof ViewGroup)) {
                 return;
             }
-            ViewGroup rootGroup = (ViewGroup) root;
             HashMap<View, AccessibilityNodeInfo> addedChildren =
                 new HashMap<View, AccessibilityNodeInfo>();
             ArrayList<View> children = mTempViewList;
diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java
index fa79d36..c3aafde 100644
--- a/core/java/android/view/ActionProvider.java
+++ b/core/java/android/view/ActionProvider.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.content.Context;
+import android.util.Log;
 
 /**
  * An ActionProvider defines rich menu interaction in a single component.
@@ -55,7 +56,9 @@
  * @see MenuItem#getActionProvider()
  */
 public abstract class ActionProvider {
+    private static final String TAG = "ActionProvider";
     private SubUiVisibilityListener mSubUiVisibilityListener;
+    private VisibilityListener mVisibilityListener;
 
     /**
      * Creates a new instance. ActionProvider classes should always implement a
@@ -96,6 +99,44 @@
     }
 
     /**
+     * The result of this method determines whether or not {@link #isVisible()} will be used
+     * by the {@link MenuItem} this ActionProvider is bound to help determine its visibility.
+     *
+     * @return true if this ActionProvider overrides the visibility of the MenuItem
+     *         it is bound to, false otherwise. The default implementation returns false.
+     * @see #isVisible()
+     */
+    public boolean overridesItemVisibility() {
+        return false;
+    }
+
+    /**
+     * If {@link #overridesItemVisibility()} returns true, the return value of this method
+     * will help determine the visibility of the {@link MenuItem} this ActionProvider is bound to.
+     *
+     * <p>If the MenuItem's visibility is explicitly set to false by the application,
+     * the MenuItem will not be shown, even if this method returns true.</p>
+     *
+     * @return true if the MenuItem this ActionProvider is bound to is visible, false if
+     *         it is invisible. The default implementation returns true.
+     */
+    public boolean isVisible() {
+        return true;
+    }
+
+    /**
+     * If this ActionProvider is associated with an item in a menu,
+     * refresh the visibility of the item based on {@link #overridesItemVisibility()} and
+     * {@link #isVisible()}. If {@link #overridesItemVisibility()} returns false, this call
+     * will have no effect.
+     */
+    public void refreshVisibility() {
+        if (mVisibilityListener != null && overridesItemVisibility()) {
+            mVisibilityListener.onActionProviderVisibilityChanged(isVisible());
+        }
+    }
+
+    /**
      * Performs an optional default action.
      * <p>
      * For the case of an action provider placed in a menu item not shown as an action this
@@ -181,9 +222,34 @@
     }
 
     /**
+     * Set a listener to be notified when this ActionProvider's overridden visibility changes.
+     * This should only be used by MenuItem implementations.
+     *
+     * @param listener listener to set
+     */
+    public void setVisibilityListener(VisibilityListener listener) {
+        if (mVisibilityListener != null) {
+            Log.w(TAG, "setVisibilityListener: Setting a new ActionProvider.VisibilityListener " +
+                    "when one is already set. Are you reusing this " + getClass().getSimpleName() +
+                    " instance while it is still in use somewhere else?");
+        }
+        mVisibilityListener = listener;
+    }
+
+    /**
      * @hide Internal use only
      */
     public interface SubUiVisibilityListener {
         public void onSubUiVisibilityChanged(boolean isVisible);
     }
+
+    /**
+     * Listens to changes in visibility as reported by {@link ActionProvider#refreshVisibility()}.
+     *
+     * @see ActionProvider#overridesItemVisibility()
+     * @see ActionProvider#isVisible()
+     */
+    public interface VisibilityListener {
+        public void onActionProviderVisibilityChanged(boolean isVisible);
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 816b631..b1caa2f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1047,36 +1047,50 @@
     /**
      * The accessibility focus which is the current user position when
      * interacting with the accessibility framework.
+     *
+     * @hide
      */
     public static final int FOCUS_ACCESSIBILITY =  0x00001000;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus left.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_LEFT = FOCUS_LEFT | FOCUS_ACCESSIBILITY;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus up.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_UP = FOCUS_UP | FOCUS_ACCESSIBILITY;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus right.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_RIGHT = FOCUS_RIGHT | FOCUS_ACCESSIBILITY;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus down.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_DOWN = FOCUS_DOWN | FOCUS_ACCESSIBILITY;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus forward.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_FORWARD = FOCUS_FORWARD | FOCUS_ACCESSIBILITY;
 
     /**
      * Use with {@link #focusSearch(int)}. Move acessibility focus backward.
+     *
+     * @hide
      */
     public static final int ACCESSIBILITY_FOCUS_BACKWARD = FOCUS_BACKWARD | FOCUS_ACCESSIBILITY;
 
@@ -4544,31 +4558,6 @@
         if ((event.getEventType() & POPULATING_ACCESSIBILITY_EVENT_TYPES) != 0) {
             dispatchPopulateAccessibilityEvent(event);
         }
-        // Intercept accessibility focus events fired by virtual nodes to keep
-        // track of accessibility focus position in such nodes.
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
-                        event.getSourceNodeId());
-                if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
-                    ViewRootImpl viewRootImpl = getViewRootImpl();
-                    if (viewRootImpl != null) {
-                        viewRootImpl.setAccessibilityFocusedHost(this);
-                    }
-                }
-            } break;
-            case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                final long virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
-                        event.getSourceNodeId());
-                if (virtualNodeId != AccessibilityNodeInfo.UNDEFINED) {
-                    ViewRootImpl viewRootImpl = getViewRootImpl();
-                    if (viewRootImpl != null) {
-                        viewRootImpl.setAccessibilityFocusedHost(null);
-                    }
-                }
-            } break;
-        }
         // In the beginning we called #isShown(), so we know that getParent() is not null.
         getParent().requestSendAccessibilityEvent(this, event);
     }
@@ -6297,7 +6286,7 @@
             mPrivateFlags2 |= ACCESSIBILITY_FOCUSED;
             ViewRootImpl viewRootImpl = getViewRootImpl();
             if (viewRootImpl != null) {
-                viewRootImpl.setAccessibilityFocusedHost(this);
+                viewRootImpl.setAccessibilityFocus(this, null);
             }
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
@@ -6328,7 +6317,32 @@
         if (viewRootImpl != null) {
             View focusHost = viewRootImpl.getAccessibilityFocusedHost();
             if (focusHost != null && ViewRootImpl.isViewDescendantOf(focusHost, this)) {
-                viewRootImpl.setAccessibilityFocusedHost(null);
+                viewRootImpl.setAccessibilityFocus(null, null);
+            }
+        }
+    }
+
+    private void sendAccessibilityHoverEvent(int eventType) {
+        // Since we are not delivering to a client accessibility events from not
+        // important views (unless the clinet request that) we need to fire the
+        // event from the deepest view exposed to the client. As a consequence if
+        // the user crosses a not exposed view the client will see enter and exit
+        // of the exposed predecessor followed by and enter and exit of that same
+        // predecessor when entering and exiting the not exposed descendant. This
+        // is fine since the client has a clear idea which view is hovered at the
+        // price of a couple more events being sent. This is a simple and
+        // working solution.
+        View source = this;
+        while (true) {
+            if (source.includeForAccessibility()) {
+                source.sendAccessibilityEvent(eventType);
+                return;
+            }
+            ViewParent parent = source.getParent();
+            if (parent instanceof View) {
+                source = (View) parent;
+            } else {
+                return;
             }
         }
     }
@@ -7902,20 +7916,19 @@
                     || action == MotionEvent.ACTION_HOVER_MOVE)
                     && !hasHoveredChild()
                     && pointInView(event.getX(), event.getY())) {
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+                sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
                 mSendingHoverAccessibilityEvents = true;
-                requestAccessibilityFocusFromHover();
             }
         } else {
             if (action == MotionEvent.ACTION_HOVER_EXIT
                     || (action == MotionEvent.ACTION_MOVE
                             && !pointInView(event.getX(), event.getY()))) {
                 mSendingHoverAccessibilityEvents = false;
-                sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+                sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
                 // If the window does not have input focus we take away accessibility
                 // focus as soon as the user stop hovering over the view.
                 if (mAttachInfo != null && !mAttachInfo.mHasWindowFocus) {
-                    getViewRootImpl().setAccessibilityFocusedHost(null);
+                    getViewRootImpl().setAccessibilityFocus(null, null);
                 }
             }
         }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cdc51d1..6959b84 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -489,7 +489,7 @@
                 // Keep track of the actual window flags supplied by the client.
                 mClientWindowLayoutFlags = attrs.flags;
 
-                setAccessibilityFocusedHost(null);
+                setAccessibilityFocus(null, null);
 
                 if (view instanceof RootViewSurfaceTaker) {
                     mSurfaceHolderCallback =
@@ -558,7 +558,7 @@
                     mInputChannel = null;
                     mFallbackEventHandler.setView(null);
                     unscheduleTraversals();
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
                     throw new RuntimeException("Adding window failed", e);
                 } finally {
                     if (restore) {
@@ -578,7 +578,7 @@
                     mAdded = false;
                     mFallbackEventHandler.setView(null);
                     unscheduleTraversals();
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
                     switch (res) {
                         case WindowManagerImpl.ADD_BAD_APP_TOKEN:
                         case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN:
@@ -2320,9 +2320,6 @@
             }
         } else {
             if (mAccessibilityFocusedVirtualView == null) {
-                mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
-            }
-            if (mAccessibilityFocusedVirtualView == null) {
                 return;
             }
             mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
@@ -2498,7 +2495,7 @@
         return mAccessibilityFocusedVirtualView;
     }
 
-    void setAccessibilityFocusedHost(View host) {
+    void setAccessibilityFocus(View view, AccessibilityNodeInfo node) {
         // If we have a virtual view with accessibility focus we need
         // to clear the focus and invalidate the virtual view bounds.
         if (mAccessibilityFocusedVirtualView != null) {
@@ -2526,24 +2523,16 @@
                 provider.performAction(virtualNodeId,
                         AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
             }
+            focusNode.recycle();
         }
         if (mAccessibilityFocusedHost != null) {
             // Clear accessibility focus in the view.
             mAccessibilityFocusedHost.clearAccessibilityFocusNoCallbacks();
         }
 
-        // Set the new focus host.
-        mAccessibilityFocusedHost = host;
-
-        // If the host has a provide find the virtual descendant that has focus.
-        if (mAccessibilityFocusedHost != null) {
-            AccessibilityNodeProvider provider =
-                mAccessibilityFocusedHost.getAccessibilityNodeProvider();
-            if (provider != null) {
-                mAccessibilityFocusedVirtualView = provider.findAccessibilityFocus(View.NO_ID);
-                return;
-            }
-        }
+        // Set the new focus host and node.
+        mAccessibilityFocusedHost = view;
+        mAccessibilityFocusedVirtualView = node;
     }
 
     public void requestChildFocus(View child, View focused) {
@@ -2629,7 +2618,7 @@
 
         destroyHardwareRenderer();
 
-        setAccessibilityFocusedHost(null);
+        setAccessibilityFocus(null, null);
 
         mView = null;
         mAttachInfo.mRootView = null;
@@ -2910,7 +2899,7 @@
                         mHasHadWindowFocus = true;
                     }
 
-                    setAccessibilityFocusedHost(null);
+                    setAccessibilityFocus(null, null);
 
                     if (mView != null && mAccessibilityManager.isEnabled()) {
                         if (hasWindowFocus) {
@@ -2982,7 +2971,7 @@
                 invalidateDisplayLists();
             } break;
             case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
-                setAccessibilityFocusedHost(null);
+                setAccessibilityFocus(null, null);
             } break;
             case MSG_DISPATCH_DONE_ANIMATING: {
                 handleDispatchDoneAnimating();
@@ -3926,10 +3915,9 @@
     }
     
     public void dumpGfxInfo(int[] info) {
+        info[0] = info[1] = 0;
         if (mView != null) {
             getGfxInfo(mView, info);
-        } else {
-            info[0] = info[1] = 0;
         }
     }
 
@@ -4539,29 +4527,35 @@
         if (mView == null) {
             return false;
         }
-        // Watch for accessibility focus change events from virtual nodes
-        // to keep track of accessibility focus being on a virtual node.
+        // Intercept accessibility focus events fired by virtual nodes to keep
+        // track of accessibility focus position in such nodes.
         final int eventType = event.getEventType();
         switch (eventType) {
             case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
-                final long sourceId = event.getSourceNodeId();
-                // If the event is not from a virtual node we are not interested.
-                final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
-                if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
-                    break;
+                final long sourceNodeId = event.getSourceNodeId();
+                final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+                        sourceNodeId);
+                View source = mView.findViewByAccessibilityId(accessibilityViewId);
+                if (source != null) {
+                    AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+                    if (provider != null) {
+                        AccessibilityNodeInfo node = provider.createAccessibilityNodeInfo(
+                                AccessibilityNodeInfo.getVirtualDescendantId(sourceNodeId));
+                        setAccessibilityFocus(source, node);
+                    }
                 }
-                final int realViewId = AccessibilityNodeInfo.getAccessibilityViewId(sourceId);
-                View focusHost = mView.findViewByAccessibilityId(realViewId);
-                setAccessibilityFocusedHost(focusHost);
             } break;
             case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
-                final long sourceId = event.getSourceNodeId();
-                // If the event is not from a virtual node we are not interested.
-                final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(sourceId);
-                if (virtualViewId == AccessibilityNodeInfo.UNDEFINED) {
-                    break;
+                final long sourceNodeId = event.getSourceNodeId();
+                final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+                        sourceNodeId);
+                View source = mView.findViewByAccessibilityId(accessibilityViewId);
+                if (source != null) {
+                    AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
+                    if (provider != null) {
+                        setAccessibilityFocus(null, null);
+                    }
                 }
-                setAccessibilityFocusedHost(null);
             } break;
         }
         mAccessibilityManager.sendAccessibilityEvent(event);
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 5d33cec..dd6b537 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -530,13 +530,16 @@
 
                     for (int i = 0; i < count; i++) {
                         ViewRootImpl root = mRoots[i];
+                        String name = getWindowName(root);
+                        pw.printf("\n\t%s", name);
+
                         HardwareRenderer renderer = root.getView().mAttachInfo.mHardwareRenderer;
                         if (renderer != null) {
                             renderer.dumpGfxInfo(pw);
                         }
                     }
 
-                    pw.println("\nView hierarchy:");
+                    pw.println("\nView hierarchy:\n");
 
                     int viewsCount = 0;
                     int displayListsSize = 0;
@@ -546,15 +549,14 @@
                         ViewRootImpl root = mRoots[i];
                         root.dumpGfxInfo(info);
 
-                        String name = root.getClass().getName() + '@' +
-                                Integer.toHexString(hashCode());                        
-                        pw.printf("  %s: %d views, %.2f kB (display lists)",
+                        String name = getWindowName(root);
+                        pw.printf("  %s\n  %d views, %.2f kB of display lists",
                                 name, info[0], info[1] / 1024.0f);
                         HardwareRenderer renderer = root.getView().mAttachInfo.mHardwareRenderer;
                         if (renderer != null) {
                             pw.printf(", %d frames rendered", renderer.getFrameCount());
                         }
-                        pw.printf("\n");
+                        pw.printf("\n\n");
 
                         viewsCount += info[0];
                         displayListsSize += info[1];
@@ -570,6 +572,11 @@
         }        
     }
 
+    private static String getWindowName(ViewRootImpl root) {
+        return root.mWindowAttributes.getTitle() + "/" +
+                root.getClass().getName() + '@' + Integer.toHexString(root.hashCode());
+    }
+
     public void setStoppedState(IBinder token, boolean stopped) {
         synchronized (this) {
             if (mViews == null)
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ceb9fe6..09948b8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -26,7 +26,6 @@
 import android.os.Looper;
 import android.view.animation.Animation;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
 /**
@@ -1122,10 +1121,9 @@
      * Print the WindowManagerPolicy's state into the given stream.
      *
      * @param prefix Text to print at the front of each line.
-     * @param fd The raw file descriptor that the dump is being sent to.
      * @param writer The PrintWriter to which you should dump your state.  This will be
      * closed for you after you return.
      * @param args additional arguments to the dump request.
      */
-    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args);
+    public void dump(String prefix, PrintWriter writer, String[] args);
 }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 3834fd6..3ad3a55 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -469,13 +469,7 @@
      *     {@link View#FOCUS_LEFT},
      *     {@link View#FOCUS_RIGHT},
      *     {@link View#FOCUS_FORWARD},
-     *     {@link View#FOCUS_BACKWARD},
-     *     {@link View#ACCESSIBILITY_FOCUS_FORWARD},
-     *     {@link View#ACCESSIBILITY_FOCUS_BACKWARD},
-     *     {@link View#ACCESSIBILITY_FOCUS_UP},
-     *     {@link View#ACCESSIBILITY_FOCUS_RIGHT},
-     *     {@link View#ACCESSIBILITY_FOCUS_DOWN},
-     *     {@link View#ACCESSIBILITY_FOCUS_LEFT}.
+     *     {@link View#FOCUS_BACKWARD}.
      *
      * @return The node info for the view that can take accessibility focus.
      */
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index e60716d..b3f3cee 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -150,6 +150,8 @@
      *
      * @see #createAccessibilityNodeInfo(int)
      * @see AccessibilityNodeInfo
+     *
+     * @hide
      */
     public AccessibilityNodeInfo findAccessibilityFocus(int virtualViewId) {
         return null;
@@ -180,6 +182,8 @@
      *
      * @see #createAccessibilityNodeInfo(int)
      * @see AccessibilityNodeInfo
+     *
+     * @hide
      */
     public AccessibilityNodeInfo accessibilityFocusSearch(int direction, int virtualViewId) {
         return null;
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index cc490bd..7dfb5bb 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -43,11 +43,6 @@
  * APIs.
  */
 class AccessibilityInjector {
-    // Default result returned from AndroidVox. Using true here means if the
-    // script fails, an accessibility service will always think that traversal
-    // has succeeded.
-    private static final String DEFAULT_ANDROIDVOX_RESULT = "true";
-
     // The WebViewClassic this injector is responsible for managing.
     private final WebViewClassic mWebViewClassic;
 
@@ -488,15 +483,19 @@
             switch (action) {
                 case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
                 case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
-                    final int granularity = arguments.getInt(
-                            AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
-                    mAccessibilityJSONObject.accumulate("granularity", granularity);
+                    if (arguments != null) {
+                        final int granularity = arguments.getInt(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
+                        mAccessibilityJSONObject.accumulate("granularity", granularity);
+                    }
                     break;
                 case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
                 case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
-                    final String element = arguments.getString(
-                            AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
-                    mAccessibilityJSONObject.accumulate("element", element);
+                    if (arguments != null) {
+                        final String element = arguments.getString(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_HTML_ELEMENT_STRING);
+                        mAccessibilityJSONObject.accumulate("element", element);
+                    }
                     break;
             }
         } catch (JSONException e) {
@@ -505,9 +504,7 @@
 
         final String jsonString = mAccessibilityJSONObject.toString();
         final String jsCode = String.format(ACCESSIBILITY_ANDROIDVOX_TEMPLATE, jsonString);
-        final String result = mCallback.performAction(mWebView, jsCode, DEFAULT_ANDROIDVOX_RESULT);
-
-        return ("true".equalsIgnoreCase(result));
+        return mCallback.performAction(mWebView, jsCode);
     }
 
     /**
@@ -518,13 +515,13 @@
                 "javascript:(function() { %s.onResult(%d, %s); })();";
 
         // Time in milliseconds to wait for a result before failing.
-        private static final long RESULT_TIMEOUT = 200;
+        private static final long RESULT_TIMEOUT = 5000;
 
         private final AtomicInteger mResultIdCounter = new AtomicInteger();
         private final Object mResultLock = new Object();
         private final String mInterfaceName;
 
-        private String mResult = null;
+        private boolean mResult = false;
         private long mResultId = -1;
 
         private CallbackHandler(String interfaceName) {
@@ -536,29 +533,27 @@
          *
          * @param webView The WebView to perform the action on.
          * @param code JavaScript code that evaluates to a result.
-         * @param defaultResult The result to return if the action times out.
          * @return The result of the action, or false if it timed out.
          */
-        private String performAction(WebView webView, String code, String defaultResult) {
+        private boolean performAction(WebView webView, String code) {
             final int resultId = mResultIdCounter.getAndIncrement();
             final String url = String.format(
                     JAVASCRIPT_ACTION_TEMPLATE, mInterfaceName, resultId, code);
             webView.loadUrl(url);
 
-            return getResultAndClear(resultId, defaultResult);
+            return getResultAndClear(resultId);
         }
 
         /**
          * Gets the result of a request to perform an accessibility action.
          *
          * @param resultId The result id to match the result with the request.
-         * @param defaultResult The default result to return on timeout.
          * @return The result of the request.
          */
-        private String getResultAndClear(int resultId, String defaultResult) {
+        private boolean getResultAndClear(int resultId) {
             synchronized (mResultLock) {
                 final boolean success = waitForResultTimedLocked(resultId);
-                final String result = success ? mResult : defaultResult;
+                final boolean result = success ? mResult : false;
                 clearResultLocked();
                 return result;
             }
@@ -569,7 +564,7 @@
          */
         private void clearResultLocked() {
             mResultId = -1;
-            mResult = null;
+            mResult = false;
         }
 
         /**
@@ -620,7 +615,7 @@
 
             synchronized (mResultLock) {
                 if (resultId > mResultId) {
-                    mResult = result;
+                    mResult = Boolean.parseBoolean(result);
                     mResultId = resultId;
                 }
                 mResultLock.notifyAll();
diff --git a/core/java/android/webkit/AccessibilityInjectorFallback.java b/core/java/android/webkit/AccessibilityInjectorFallback.java
index 4d9c26c..783b3db 100644
--- a/core/java/android/webkit/AccessibilityInjectorFallback.java
+++ b/core/java/android/webkit/AccessibilityInjectorFallback.java
@@ -272,11 +272,19 @@
     boolean performAccessibilityAction(int action, Bundle arguments) {
         switch (action) {
             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
-            case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
                 final int direction = getDirectionForAction(action);
                 final int axis = getAxisForGranularity(arguments.getInt(
                         AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT));
                 return traverseGivenAxis(direction, axis, true, null);
+            }
+            case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT: {
+                final int direction = getDirectionForAction(action);
+                // TODO: Add support for moving by object.
+                final int axis = NAVIGATION_AXIS_SENTENCE;
+                return traverseGivenAxis(direction, axis, true, null);
+            }
             default:
                 return false;
         }
@@ -291,8 +299,10 @@
      */
     private static int getDirectionForAction(int action) {
         switch (action) {
+            case AccessibilityNodeInfo.ACTION_NEXT_HTML_ELEMENT:
             case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY:
                 return NAVIGATION_DIRECTION_FORWARD;
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_HTML_ELEMENT:
             case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY:
                 return NAVIGATION_DIRECTION_BACKWARD;
             default:
@@ -316,8 +326,8 @@
             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE:
                 return NAVIGATION_AXIS_SENTENCE;
             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH:
-                // TODO: Figure out what nextSibling() actually means.
-                return NAVIGATION_AXIS_SIBLING;
+                // TODO: This should map to object once we implement it.
+                return NAVIGATION_AXIS_SENTENCE;
             case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE:
                 return NAVIGATION_AXIS_DOCUMENT;
             default:
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index 62bc502..33eaad6 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -194,13 +194,6 @@
             mCanPause = mCanSeekBack = mCanSeekForward = true;
         }
 
-        // mMediaController status depends on the Metadata result, so put it
-        // after reading the MetaData
-        if (mMediaController != null) {
-            mMediaController.setEnabled(true);
-            mMediaController.show();
-        }
-
         if (mProgressView != null) {
             mProgressView.setVisibility(View.GONE);
         }
@@ -215,6 +208,16 @@
 
         if (getStartWhenPrepared()) {
             mPlayer.start();
+            // Clear the flag.
+            setStartWhenPrepared(false);
+        }
+
+        // mMediaController status depends on the Metadata result, so put it
+        // after reading the MetaData.
+        // And make sure mPlayer state is updated before showing the controller.
+        if (mMediaController != null) {
+            mMediaController.setEnabled(true);
+            mMediaController.show();
         }
     }
 
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 90db308..ab884df 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -147,6 +147,7 @@
                 // Save the inline video info and inherit it in the full screen
                 int savePosition = 0;
                 boolean canSkipPrepare = false;
+                boolean forceStart = false;
                 if (mHTML5VideoView != null) {
                     // We don't allow enter full screen mode while the previous
                     // full screen video hasn't finished yet.
@@ -154,11 +155,11 @@
                         Log.w(LOGTAG, "Try to reenter the full screen mode");
                         return;
                     }
+                    int playerState = mHTML5VideoView.getCurrentState();
                     // If we are playing the same video, then it is better to
                     // save the current position.
                     if (layerId == mHTML5VideoView.getVideoLayerId()) {
                         savePosition = mHTML5VideoView.getCurrentPosition();
-                        int playerState = mHTML5VideoView.getCurrentState();
                         canSkipPrepare = (playerState == HTML5VideoView.STATE_PREPARING
                                 || playerState == HTML5VideoView.STATE_PREPARED
                                 || playerState == HTML5VideoView.STATE_PLAYING)
@@ -166,10 +167,14 @@
                     }
                     if (!canSkipPrepare) {
                         mHTML5VideoView.reset();
+                    } else {
+                        forceStart = playerState == HTML5VideoView.STATE_PREPARING
+                                || playerState == HTML5VideoView.STATE_PLAYING;
                     }
                 }
                 mHTML5VideoView = new HTML5VideoFullScreen(proxy.getContext(),
                         layerId, savePosition, canSkipPrepare);
+                mHTML5VideoView.setStartWhenPrepared(forceStart);
                 mCurrentProxy = proxy;
                 mHTML5VideoView.setVideoURI(url, mCurrentProxy);
                 mHTML5VideoView.enterFullScreenVideoState(layerId, proxy, webView);
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 354bb5a..1288613 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -22,7 +22,8 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.util.DisplayMetrics;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 import android.util.EventLog;
 
 import java.util.Locale;
@@ -122,6 +123,7 @@
     private boolean         mLoadWithOverviewMode = false;
     private boolean         mEnableSmoothTransition = false;
     private boolean         mForceUserScalable = false;
+    private boolean         mPasswordEchoEnabled = true;
 
     // AutoFill Profile data
     public static class AutoFillProfile {
@@ -295,6 +297,13 @@
             mAllowUniversalAccessFromFileURLs = true;
             mAllowFileAccessFromFileURLs = true;
         }
+        try {
+            mPasswordEchoEnabled =
+                    Settings.System.getInt(context.getContentResolver(),
+                        Settings.System.TEXT_SHOW_PASSWORD) != 0;
+        } catch (SettingNotFoundException e) {
+            mPasswordEchoEnabled = true;
+        }
     }
 
     private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index cbb3011..119fcd3 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1686,6 +1686,10 @@
             WebView.super.computeScroll();
         }
 
+        public boolean super_onHoverEvent(MotionEvent event) {
+            return WebView.super.onHoverEvent(event);
+        }
+
         public boolean super_performAccessibilityAction(int action, Bundle arguments) {
             return WebView.super.performAccessibilityAction(action, arguments);
         }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index da61e74..84a6129 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -5711,6 +5711,7 @@
         int x = viewToContentX((int) event.getX() + getScrollX());
         int y = viewToContentY((int) event.getY() + getScrollY());
         mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, x, y);
+        mWebViewPrivate.super_onHoverEvent(event);
         return true;
     }
 
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index bfcfdfa..b615b9c 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -25,25 +25,33 @@
 import android.app.MediaRouteButton;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteCategory;
 import android.media.MediaRouter.RouteGroup;
 import android.media.MediaRouter.RouteInfo;
+import android.media.MediaRouter.UserRouteInfo;
+import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.text.TextUtils;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.Checkable;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.ListView;
+import android.widget.SeekBar;
 import android.widget.TextView;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 
 /**
  * This class implements the route chooser dialog for {@link MediaRouter}.
@@ -58,26 +66,26 @@
     private static final int[] ITEM_LAYOUTS = new int[] {
         R.layout.media_route_list_item_top_header,
         R.layout.media_route_list_item_section_header,
-        R.layout.media_route_list_item
-    };
-
-    private static final int[] GROUP_ITEM_LAYOUTS = new int[] {
-        R.layout.media_route_list_item_top_header,
+        R.layout.media_route_list_item,
         R.layout.media_route_list_item_checkable,
         R.layout.media_route_list_item_collapse_group
     };
 
     MediaRouter mRouter;
+    AudioManager mAudio;
     private int mRouteTypes;
 
     private LayoutInflater mInflater;
     private LauncherListener mLauncherListener;
     private View.OnClickListener mExtendedSettingsListener;
     private RouteAdapter mAdapter;
-    private GroupAdapter mGroupAdapter;
     private ListView mListView;
+    private SeekBar mVolumeSlider;
+    private ImageView mVolumeIcon;
 
-    static final RouteComparator sComparator = new RouteComparator();
+    final RouteComparator mComparator = new RouteComparator();
+    final MediaRouterCallback mCallback = new MediaRouterCallback();
+    private boolean mIgnoreVolumeChanges;
 
     public MediaRouteChooserDialogFragment() {
         setStyle(STYLE_NO_TITLE, R.style.Theme_DeviceDefault_Dialog);
@@ -91,6 +99,7 @@
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         mRouter = (MediaRouter) activity.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mAudio = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
     }
 
     @Override
@@ -99,25 +108,14 @@
         if (mLauncherListener != null) {
             mLauncherListener.onDetached(this);
         }
-        if (mGroupAdapter != null) {
-            mRouter.removeCallback(mGroupAdapter);
-            mGroupAdapter = null;
-        }
         if (mAdapter != null) {
-            mRouter.removeCallback(mAdapter);
             mAdapter = null;
         }
         mInflater = null;
+        mRouter.removeCallback(mCallback);
         mRouter = null;
     }
 
-    /**
-     * Implemented by the MediaRouteButton that launched this dialog
-     */
-    public interface LauncherListener {
-        public void onDetached(MediaRouteChooserDialogFragment detachedFragment);
-    }
-
     public void setExtendedSettingsClickListener(View.OnClickListener listener) {
         mExtendedSettingsListener = listener;
     }
@@ -126,58 +124,87 @@
         mRouteTypes = types;
     }
 
+    void updateVolume() {
+        final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes);
+        final boolean defaultAudioSelected = selectedRoute == mRouter.getSystemAudioRoute();
+        final boolean selectedSystemRoute =
+                selectedRoute.getCategory() == mRouter.getSystemAudioCategory();
+        mVolumeIcon.setImageResource(defaultAudioSelected ?
+                R.drawable.ic_audio_vol : R.drawable.ic_media_route_on_holo_dark);
+
+        mIgnoreVolumeChanges = true;
+        mVolumeSlider.setEnabled(true);
+        if (selectedSystemRoute) {
+            // Use the standard media audio stream
+            mVolumeSlider.setMax(mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
+            mVolumeSlider.setProgress(mAudio.getStreamVolume(AudioManager.STREAM_MUSIC));
+        } else {
+            final RouteInfo firstSelected;
+            if (selectedRoute instanceof RouteGroup) {
+                firstSelected = ((RouteGroup) selectedRoute).getRouteAt(0);
+            } else {
+                firstSelected = selectedRoute;
+            }
+
+            RemoteControlClient rcc = null;
+            if (firstSelected instanceof UserRouteInfo) {
+                rcc = ((UserRouteInfo) firstSelected).getRemoteControlClient();
+            }
+
+            if (rcc == null) {
+                // No RemoteControlClient? Assume volume can't be controlled.
+                // Disable the slider and show it at max volume.
+                mVolumeSlider.setMax(1);
+                mVolumeSlider.setProgress(1);
+                mVolumeSlider.setEnabled(false);
+            } else {
+                // TODO: Connect this to the remote control volume
+            }
+        }
+        mIgnoreVolumeChanges = false;
+    }
+
+    void changeVolume(int newValue) {
+        if (mIgnoreVolumeChanges) return;
+
+        RouteCategory selectedCategory = mRouter.getSelectedRoute(mRouteTypes).getCategory();
+        if (selectedCategory == mRouter.getSystemAudioCategory()) {
+            final int maxVolume = mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+            newValue = Math.max(0, Math.min(newValue, maxVolume));
+            mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, newValue, 0);
+        }
+    }
+
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         mInflater = inflater;
         final View layout = inflater.inflate(R.layout.media_route_chooser_layout, container, false);
-        final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
+
+        mVolumeIcon = (ImageView) layout.findViewById(R.id.volume_icon);
+        mVolumeSlider = (SeekBar) layout.findViewById(R.id.volume_slider);
+        updateVolume();
+        mVolumeSlider.setOnSeekBarChangeListener(new VolumeSliderChangeListener());
 
         if (mExtendedSettingsListener != null) {
+            final View extendedSettingsButton = layout.findViewById(R.id.extended_settings);
             extendedSettingsButton.setVisibility(View.VISIBLE);
             extendedSettingsButton.setOnClickListener(mExtendedSettingsListener);
         }
 
         final ListView list = (ListView) layout.findViewById(R.id.list);
-        list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
         list.setItemsCanFocus(true);
         list.setAdapter(mAdapter = new RouteAdapter());
-        list.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
         list.setOnItemClickListener(mAdapter);
 
         mListView = list;
-        mRouter.addCallback(mRouteTypes, mAdapter);
+        mRouter.addCallback(mRouteTypes, mCallback);
+
+        mAdapter.scrollToSelectedItem();
 
         return layout;
     }
 
-    void onExpandGroup(RouteGroup info) {
-        mGroupAdapter = new GroupAdapter(info);
-        mRouter.addCallback(mRouteTypes, mGroupAdapter);
-        mListView.setAdapter(mGroupAdapter);
-        mListView.setOnItemClickListener(mGroupAdapter);
-        mListView.setItemsCanFocus(false);
-        mListView.clearChoices();
-        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
-        mGroupAdapter.initCheckedItems();
-
-        getDialog().setCanceledOnTouchOutside(false);
-    }
-
-    void onDoneGrouping() {
-        mListView.setAdapter(mAdapter);
-        mListView.setOnItemClickListener(mAdapter);
-        mListView.setItemsCanFocus(true);
-        mListView.clearChoices();
-        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-        mListView.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
-
-        mRouter.removeCallback(mGroupAdapter);
-        mGroupAdapter = null;
-
-        getDialog().setCanceledOnTouchOutside(true);
-    }
-
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         return new RouteChooserDialog(getActivity(), getTheme());
@@ -186,14 +213,6 @@
     @Override
     public void onResume() {
         super.onResume();
-
-        if (mListView != null) {
-            if (mGroupAdapter != null) {
-                mGroupAdapter.initCheckedItems();
-            } else {
-                mListView.setItemChecked(mAdapter.getSelectedRoutePosition(), true);
-            }
-        }
     }
 
     private static class ViewHolder {
@@ -203,52 +222,138 @@
         public ImageButton expandGroupButton;
         public RouteAdapter.ExpandGroupListener expandGroupListener;
         public int position;
+        public CheckBox check;
     }
 
-    private class RouteAdapter extends BaseAdapter implements MediaRouter.Callback,
-            ListView.OnItemClickListener {
+    private class RouteAdapter extends BaseAdapter implements ListView.OnItemClickListener {
         private static final int VIEW_TOP_HEADER = 0;
         private static final int VIEW_SECTION_HEADER = 1;
         private static final int VIEW_ROUTE = 2;
+        private static final int VIEW_GROUPING_ROUTE = 3;
+        private static final int VIEW_GROUPING_DONE = 4;
 
-        private int mSelectedItemPosition;
+        private int mSelectedItemPosition = -1;
         private final ArrayList<Object> mItems = new ArrayList<Object>();
 
+        private RouteCategory mCategoryEditingGroups;
+        private RouteGroup mEditingGroup;
+
+        // Temporary lists for manipulation
+        private final ArrayList<RouteInfo> mCatRouteList = new ArrayList<RouteInfo>();
+        private final ArrayList<RouteInfo> mSortRouteList = new ArrayList<RouteInfo>();
+
+        private boolean mIgnoreUpdates;
+
         RouteAdapter() {
             update();
         }
 
         void update() {
-            // TODO this is kind of naive, but our data sets are going to be
-            // fairly small on average.
+            /*
+             * This is kind of wacky, but our data sets are going to be
+             * fairly small on average. Ideally we should be able to do some of this stuff
+             * in-place instead.
+             *
+             * Basic idea: each entry in mItems represents an item in the list for quick access.
+             * Entries can be a RouteCategory (section header), a RouteInfo with a category of
+             * mCategoryEditingGroups (a flattened RouteInfo pulled out of its group, allowing
+             * the user to change the group),
+             */
+            if (mIgnoreUpdates) return;
+
             mItems.clear();
 
             final RouteInfo selectedRoute = mRouter.getSelectedRoute(mRouteTypes);
+            mSelectedItemPosition = -1;
 
-            final ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
+            List<RouteInfo> routes;
             final int catCount = mRouter.getCategoryCount();
             for (int i = 0; i < catCount; i++) {
                 final RouteCategory cat = mRouter.getCategoryAt(i);
-                cat.getRoutes(routes);
+                routes = cat.getRoutes(mCatRouteList);
 
                 mItems.add(cat);
 
-                final int routeCount = routes.size();
-                for (int j = 0; j < routeCount; j++) {
-                    final RouteInfo info = routes.get(j);
-                    if (info == selectedRoute) {
-                        mSelectedItemPosition = mItems.size();
-                    }
-                    mItems.add(info);
+                if (cat == mCategoryEditingGroups) {
+                    addGroupEditingCategoryRoutes(routes);
+                } else {
+                    addSelectableRoutes(selectedRoute, routes);
                 }
+
+                routes.clear();
             }
 
             notifyDataSetChanged();
-            if (mListView != null) {
+            if (mListView != null && mSelectedItemPosition >= 0) {
                 mListView.setItemChecked(mSelectedItemPosition, true);
             }
         }
 
+        void scrollToEditingGroup() {
+            if (mCategoryEditingGroups == null || mListView == null) return;
+
+            int pos = 0;
+            int bound = 0;
+            final int itemCount = mItems.size();
+            for (int i = 0; i < itemCount; i++) {
+                final Object item = mItems.get(i);
+                if (item != null && item == mCategoryEditingGroups) {
+                    bound = i;
+                }
+                if (item == null) {
+                    pos = i;
+                    break; // this is always below the category header; we can stop here.
+                }
+            }
+
+            mListView.smoothScrollToPosition(pos, bound);
+        }
+
+        void scrollToSelectedItem() {
+            if (mListView == null || mSelectedItemPosition < 0) return;
+
+            mListView.smoothScrollToPosition(mSelectedItemPosition);
+        }
+
+        void addSelectableRoutes(RouteInfo selectedRoute, List<RouteInfo> from) {
+            final int routeCount = from.size();
+            for (int j = 0; j < routeCount; j++) {
+                final RouteInfo info = from.get(j);
+                if (info == selectedRoute) {
+                    mSelectedItemPosition = mItems.size();
+                }
+                mItems.add(info);
+            }
+        }
+
+        void addGroupEditingCategoryRoutes(List<RouteInfo> from) {
+            // Unpack groups and flatten for presentation
+            // mSortRouteList will always be empty here.
+            final int topCount = from.size();
+            for (int i = 0; i < topCount; i++) {
+                final RouteInfo route = from.get(i);
+                final RouteGroup group = route.getGroup();
+                if (group == route) {
+                    // This is a group, unpack it.
+                    final int groupCount = group.getRouteCount();
+                    for (int j = 0; j < groupCount; j++) {
+                        final RouteInfo innerRoute = group.getRouteAt(j);
+                        mSortRouteList.add(innerRoute);
+                    }
+                } else {
+                    mSortRouteList.add(route);
+                }
+            }
+            // Sort by name. This will keep the route positions relatively stable even though they
+            // will be repeatedly added and removed.
+            Collections.sort(mSortRouteList, mComparator);
+
+            mItems.addAll(mSortRouteList);
+            mSortRouteList.clear();
+
+            mItems.add(null); // Sentinel reserving space for the "done" button.
+        }
+
         @Override
         public int getCount() {
             return mItems.size();
@@ -256,7 +361,7 @@
 
         @Override
         public int getViewTypeCount() {
-            return 3;
+            return 5;
         }
 
         @Override
@@ -264,7 +369,13 @@
             final Object item = getItem(position);
             if (item instanceof RouteCategory) {
                 return position == 0 ? VIEW_TOP_HEADER : VIEW_SECTION_HEADER;
+            } else if (item == null) {
+                return VIEW_GROUPING_DONE;
             } else {
+                final RouteInfo info = (RouteInfo) item;
+                if (info.getCategory() == mCategoryEditingGroups) {
+                    return VIEW_GROUPING_ROUTE;
+                }
                 return VIEW_ROUTE;
             }
         }
@@ -276,7 +387,14 @@
 
         @Override
         public boolean isEnabled(int position) {
-            return getItemViewType(position) == VIEW_ROUTE;
+            switch (getItemViewType(position)) {
+                case VIEW_ROUTE:
+                case VIEW_GROUPING_ROUTE:
+                case VIEW_GROUPING_DONE:
+                    return true;
+                default:
+                    return false;
+            }
         }
 
         @Override
@@ -301,6 +419,7 @@
                 holder.text1 = (TextView) convertView.findViewById(R.id.text1);
                 holder.text2 = (TextView) convertView.findViewById(R.id.text2);
                 holder.icon = (ImageView) convertView.findViewById(R.id.icon);
+                holder.check = (CheckBox) convertView.findViewById(R.id.check);
                 holder.expandGroupButton = (ImageButton) convertView.findViewById(
                         R.id.expand_button);
                 if (holder.expandGroupButton != null) {
@@ -322,18 +441,25 @@
                 holder.position = position;
             }
 
-            if (viewType == VIEW_ROUTE) {
-                bindItemView(position, holder);
-            } else {
-                bindHeaderView(position, holder);
+            switch (viewType) {
+                case VIEW_ROUTE:
+                case VIEW_GROUPING_ROUTE:
+                    bindItemView(position, holder);
+                    break;
+                case VIEW_SECTION_HEADER:
+                case VIEW_TOP_HEADER:
+                    bindHeaderView(position, holder);
+                    break;
             }
 
+            convertView.setActivated(position == mSelectedItemPosition);
+
             return convertView;
         }
 
         void bindItemView(int position, ViewHolder holder) {
             RouteInfo info = (RouteInfo) mItems.get(position);
-            holder.text1.setText(info.getName());
+            holder.text1.setText(info.getName(getActivity()));
             final CharSequence status = info.getStatus();
             if (TextUtils.isEmpty(status)) {
                 holder.text2.setVisibility(View.GONE);
@@ -351,71 +477,89 @@
 
             RouteCategory cat = info.getCategory();
             boolean canGroup = false;
-            if (cat.isGroupable()) {
-                final RouteGroup group = (RouteGroup) info;
-                canGroup = group.getRouteCount() > 1 ||
-                        getItemViewType(position - 1) == VIEW_ROUTE ||
-                        (position < getCount() - 1 && getItemViewType(position + 1) == VIEW_ROUTE);
+            if (cat == mCategoryEditingGroups) {
+                RouteGroup group = info.getGroup();
+                holder.check.setEnabled(group.getRouteCount() > 1);
+                holder.check.setChecked(group == mEditingGroup);
+            } else {
+                if (cat.isGroupable()) {
+                    final RouteGroup group = (RouteGroup) info;
+                    canGroup = group.getRouteCount() > 1 ||
+                            getItemViewType(position - 1) == VIEW_ROUTE ||
+                            (position < getCount() - 1 &&
+                                    getItemViewType(position + 1) == VIEW_ROUTE);
+                }
             }
-            holder.expandGroupButton.setVisibility(canGroup ? View.VISIBLE : View.GONE);
-            holder.expandGroupListener.position = position;
+
+            if (holder.expandGroupButton != null) {
+                holder.expandGroupButton.setVisibility(canGroup ? View.VISIBLE : View.GONE);
+                holder.expandGroupListener.position = position;
+            }
         }
 
         void bindHeaderView(int position, ViewHolder holder) {
             RouteCategory cat = (RouteCategory) mItems.get(position);
-            holder.text1.setText(cat.getName());
-        }
-
-        public int getSelectedRoutePosition() {
-            return mSelectedItemPosition;
-        }
-
-        @Override
-        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
-            update();
-        }
-
-        @Override
-        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
-            update();
-        }
-
-        @Override
-        public void onRouteAdded(MediaRouter router, RouteInfo info) {
-            update();
-        }
-
-        @Override
-        public void onRouteRemoved(MediaRouter router, RouteInfo info) {
-            update();
-        }
-
-        @Override
-        public void onRouteChanged(MediaRouter router, RouteInfo info) {
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public void onRouteGrouped(MediaRouter router, RouteInfo info,
-                RouteGroup group, int index) {
-            update();
-        }
-
-        @Override
-        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
-            update();
+            holder.text1.setText(cat.getName(getActivity()));
         }
 
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            ListView lv = (ListView) parent;
-            final Object item = getItem(lv.getCheckedItemPosition());
-            if (!(item instanceof RouteInfo)) {
-                // Oops. Stale event running around? Skip it.
+            final int type = getItemViewType(position);
+            if (type == VIEW_SECTION_HEADER || type == VIEW_TOP_HEADER) {
                 return;
+            } else if (type == VIEW_GROUPING_DONE) {
+                finishGrouping();
+                return;
+            } else {
+                final Object item = getItem(position);
+                if (!(item instanceof RouteInfo)) {
+                    // Oops. Stale event running around? Skip it.
+                    return;
+                }
+
+                final RouteInfo route = (RouteInfo) item;
+                if (type == VIEW_ROUTE) {
+                    mRouter.selectRouteInt(mRouteTypes, route);
+                    dismiss();
+                } else if (type == VIEW_GROUPING_ROUTE) {
+                    final Checkable c = (Checkable) view;
+                    final boolean wasChecked = c.isChecked();
+
+                    mIgnoreUpdates = true;
+                    RouteGroup oldGroup = route.getGroup();
+                    if (!wasChecked && oldGroup != mEditingGroup) {
+                        // Assumption: in a groupable category oldGroup will never be null.
+                        if (mRouter.getSelectedRoute(mRouteTypes) == oldGroup) {
+                            // Old group was selected but is now empty. Select the group
+                            // we're manipulating since that's where the last route went.
+                            mRouter.selectRouteInt(mRouteTypes, mEditingGroup);
+                        }
+                        oldGroup.removeRoute(route);
+                        mEditingGroup.addRoute(route);
+                        c.setChecked(true);
+                    } else if (wasChecked && mEditingGroup.getRouteCount() > 1) {
+                        mEditingGroup.removeRoute(route);
+
+                        // In a groupable category this will add
+                        // the route into its own new group.
+                        mRouter.addRouteInt(route);
+                    }
+                    mIgnoreUpdates = false;
+                    update();
+                }
             }
-            mRouter.selectRoute(mRouteTypes, (RouteInfo) item);
-            dismiss();
+        }
+
+        boolean isGrouping() {
+            return mCategoryEditingGroups != null;
+        }
+
+        void finishGrouping() {
+            mCategoryEditingGroups = null;
+            mEditingGroup = null;
+            getDialog().setCanceledOnTouchOutside(true);
+            update();
+            scrollToSelectedItem();
         }
 
         class ExpandGroupListener implements View.OnClickListener {
@@ -425,251 +569,66 @@
             public void onClick(View v) {
                 // Assumption: this is only available for the user to click if we're presenting
                 // a groupable category, where every top-level route in the category is a group.
-                onExpandGroup((RouteGroup) getItem(position));
+                final RouteGroup group = (RouteGroup) getItem(position);
+                mEditingGroup = group;
+                mCategoryEditingGroups = group.getCategory();
+                getDialog().setCanceledOnTouchOutside(false);
+                mRouter.selectRouteInt(mRouteTypes, mEditingGroup);
+                update();
+                scrollToEditingGroup();
             }
         }
     }
 
-    private class GroupAdapter extends BaseAdapter implements MediaRouter.Callback,
-            ListView.OnItemClickListener {
-        private static final int VIEW_HEADER = 0;
-        private static final int VIEW_ROUTE = 1;
-        private static final int VIEW_DONE = 2;
-
-        private RouteGroup mPrimary;
-        private RouteCategory mCategory;
-        private final ArrayList<RouteInfo> mTempList = new ArrayList<RouteInfo>();
-        private final ArrayList<RouteInfo> mFlatRoutes = new ArrayList<RouteInfo>();
-        private boolean mIgnoreUpdates;
-
-        public GroupAdapter(RouteGroup primary) {
-            mPrimary = primary;
-            mCategory = primary.getCategory();
-            update();
-        }
-
-        @Override
-        public int getCount() {
-            return mFlatRoutes.size() + 2;
-        }
-
-        @Override
-        public int getViewTypeCount() {
-            return 3;
-        }
-
-        @Override
-        public int getItemViewType(int position) {
-            if (position == 0) {
-                return VIEW_HEADER;
-            } else if (position == getCount() - 1) {
-                return VIEW_DONE;
-            }
-            return VIEW_ROUTE;
-        }
-
-        void update() {
-            if (mIgnoreUpdates) return;
-            mFlatRoutes.clear();
-            mCategory.getRoutes(mTempList);
-
-            // Unpack groups and flatten for presentation
-            final int topCount = mTempList.size();
-            for (int i = 0; i < topCount; i++) {
-                final RouteInfo route = mTempList.get(i);
-                final RouteGroup group = route.getGroup();
-                if (group == route) {
-                    // This is a group, unpack it.
-                    final int groupCount = group.getRouteCount();
-                    for (int j = 0; j < groupCount; j++) {
-                        final RouteInfo innerRoute = group.getRouteAt(j);
-                        mFlatRoutes.add(innerRoute);
-                    }
-                } else {
-                    mFlatRoutes.add(route);
-                }
-            }
-            mTempList.clear();
-
-            // Sort by name. This will keep the route positions relatively stable even though they
-            // will be repeatedly added and removed.
-            Collections.sort(mFlatRoutes, sComparator);
-            notifyDataSetChanged();
-        }
-
-        void initCheckedItems() {
-            if (mIgnoreUpdates) return;
-            mListView.clearChoices();
-            int count = mFlatRoutes.size();
-            for (int i = 0; i < count; i++){
-                final RouteInfo route = mFlatRoutes.get(i);
-                if (route.getGroup() == mPrimary) {
-                    mListView.setItemChecked(i + 1, true);
-                }
-            }
-        }
-
-        @Override
-        public Object getItem(int position) {
-            if (position == 0) {
-                return mCategory;
-            } else if (position == getCount() - 1) {
-                return null; // Done
-            }
-            return mFlatRoutes.get(position - 1);
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            return position > 0;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final int viewType = getItemViewType(position);
-
-            ViewHolder holder;
-            if (convertView == null) {
-                convertView = mInflater.inflate(GROUP_ITEM_LAYOUTS[viewType], parent, false);
-                holder = new ViewHolder();
-                holder.position = position;
-                holder.text1 = (TextView) convertView.findViewById(R.id.text1);
-                holder.text2 = (TextView) convertView.findViewById(R.id.text2);
-                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
-                convertView.setTag(holder);
-            } else {
-                holder = (ViewHolder) convertView.getTag();
-                holder.position = position;
-            }
-
-            if (viewType == VIEW_ROUTE) {
-                bindItemView(position, holder);
-            } else if (viewType == VIEW_HEADER) {
-                bindHeaderView(position, holder);
-            }
-
-            return convertView;
-        }
-
-        void bindItemView(int position, ViewHolder holder) {
-            RouteInfo info = (RouteInfo) getItem(position);
-            holder.text1.setText(info.getName());
-            final CharSequence status = info.getStatus();
-            if (TextUtils.isEmpty(status)) {
-                holder.text2.setVisibility(View.GONE);
-            } else {
-                holder.text2.setVisibility(View.VISIBLE);
-                holder.text2.setText(status);
-            }
-        }
-
-        void bindHeaderView(int position, ViewHolder holder) {
-            holder.text1.setText(mCategory.getName());
-        }
-
+    class MediaRouterCallback extends MediaRouter.Callback {
         @Override
         public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+            mAdapter.update();
+            updateVolume();
         }
 
         @Override
         public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+            mAdapter.update();
         }
 
         @Override
         public void onRouteAdded(MediaRouter router, RouteInfo info) {
-            update();
-            initCheckedItems();
+            mAdapter.update();
+            updateVolume();
         }
 
         @Override
         public void onRouteRemoved(MediaRouter router, RouteInfo info) {
-            if (info == mPrimary) {
-                // Can't keep grouping, clean it up.
-                onDoneGrouping();
-            } else {
-                update();
-                initCheckedItems();
+            if (info == mAdapter.mEditingGroup) {
+                mAdapter.finishGrouping();
             }
+            mAdapter.update();
+            updateVolume();
         }
 
         @Override
         public void onRouteChanged(MediaRouter router, RouteInfo info) {
-            update();
+            mAdapter.notifyDataSetChanged();
         }
 
         @Override
-        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, int index) {
-            update();
-            initCheckedItems();
+        public void onRouteGrouped(MediaRouter router, RouteInfo info,
+                RouteGroup group, int index) {
+            mAdapter.update();
         }
 
         @Override
         public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
-            update();
-            initCheckedItems();
-        }
-
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            if (getItemViewType(position) == VIEW_DONE) {
-                onDoneGrouping();
-                return;
-            }
-
-            final ListView lv = (ListView) parent;
-            final RouteInfo route = mFlatRoutes.get(position - 1);
-            final boolean checked = lv.isItemChecked(position);
-
-            mIgnoreUpdates = true;
-            RouteGroup oldGroup = route.getGroup();
-            if (checked && oldGroup != mPrimary) {
-                // Assumption: in a groupable category oldGroup will never be null.
-                oldGroup.removeRoute(route);
-
-                // If the group is now empty, remove the group too.
-                if (oldGroup.getRouteCount() == 0) {
-                    if (mRouter.getSelectedRoute(mRouteTypes) == oldGroup) {
-                        // Old group was selected but is now empty. Select the group
-                        // we're manipulating since that's where the last route went.
-                        mRouter.selectRoute(mRouteTypes, mPrimary);
-                    }
-                    mRouter.removeRouteInt(oldGroup);
-                }
-
-                mPrimary.addRoute(route);
-            } else if (!checked) {
-                if (mPrimary.getRouteCount() > 1) {
-                    mPrimary.removeRoute(route);
-
-                    // In a groupable category this will add the route into its own new group.
-                    mRouter.addRouteInt(route);
-                } else {
-                    // We're about to remove the last route.
-                    // Don't let this happen, as it would be silly.
-                    // Turn the checkmark back on again. Silly user!
-                    lv.setItemChecked(position, true);
-                }
-            }
-            mIgnoreUpdates = false;
-            update();
-            initCheckedItems();
+            mAdapter.update();
         }
     }
 
-    static class RouteComparator implements Comparator<RouteInfo> {
+    class RouteComparator implements Comparator<RouteInfo> {
         @Override
         public int compare(RouteInfo lhs, RouteInfo rhs) {
-            return lhs.getName().toString().compareTo(rhs.getName().toString());
+            return lhs.getName(getActivity()).toString()
+                    .compareTo(rhs.getName(getActivity()).toString());
         }
     }
 
@@ -680,11 +639,47 @@
 
         @Override
         public void onBackPressed() {
-            if (mGroupAdapter != null) {
-                onDoneGrouping();
+            if (mAdapter != null && mAdapter.isGrouping()) {
+                mAdapter.finishGrouping();
             } else {
                 super.onBackPressed();
             }
         }
+        
+        public boolean onKeyDown(int keyCode, KeyEvent event) {
+            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && mVolumeSlider.isEnabled()) {
+                mVolumeSlider.incrementProgressBy(-1);
+                return true;
+            } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mVolumeSlider.isEnabled()) {
+                mVolumeSlider.incrementProgressBy(1);
+                return true;
+            } else {
+                return super.onKeyDown(keyCode, event);
+            }
+        }
+    }
+
+    /**
+     * Implemented by the MediaRouteButton that launched this dialog
+     */
+    public interface LauncherListener {
+        public void onDetached(MediaRouteChooserDialogFragment detachedFragment);
+    }
+
+    class VolumeSliderChangeListener implements SeekBar.OnSeekBarChangeListener {
+
+        @Override
+        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+            changeVolume(progress);
+        }
+
+        @Override
+        public void onStartTrackingTouch(SeekBar seekBar) {
+        }
+
+        @Override
+        public void onStopTrackingTouch(SeekBar seekBar) {
+        }
+
     }
 }
diff --git a/core/java/com/android/internal/view/ImageButtonNoParentPress.java b/core/java/com/android/internal/view/ImageButtonNoParentPress.java
deleted file mode 100644
index a6cfd86..0000000
--- a/core/java/com/android/internal/view/ImageButtonNoParentPress.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 com.android.internal.view;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-
-public class ImageButtonNoParentPress extends ImageButton {
-
-    public ImageButtonNoParentPress(Context context) {
-        super(context);
-    }
-
-    public ImageButtonNoParentPress(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public ImageButtonNoParentPress(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        // Normally parents propagate pressed state to their children.
-        // We don't want that to happen here; only press if our parent isn't.
-        super.setPressed(((ViewGroup) getParent()).isPressed() ? false : pressed);
-    }
-}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index de75962..9f7441d 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -456,6 +456,9 @@
     }
     
     public boolean isVisible() {
+        if (mActionProvider != null && mActionProvider.overridesItemVisibility()) {
+            return (mFlags & HIDDEN) == 0 && mActionProvider.isVisible();
+        }
         return (mFlags & HIDDEN) == 0;
     }
 
@@ -586,9 +589,17 @@
     }
 
     public MenuItem setActionProvider(ActionProvider actionProvider) {
+        if (mActionProvider != null) {
+            mActionProvider.setVisibilityListener(null);
+        }
         mActionView = null;
         mActionProvider = actionProvider;
         mMenu.onItemsChanged(true); // Measurement can be changed
+        mActionProvider.setVisibilityListener(new ActionProvider.VisibilityListener() {
+            @Override public void onActionProviderVisibilityChanged(boolean isVisible) {
+                mMenu.onItemVisibleChanged(MenuItemImpl.this);
+            }
+        });
         return this;
     }
 
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
index 0df211a..34447ef 100644
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ b/core/jni/android_bluetooth_HeadsetBase.cpp
@@ -115,7 +115,7 @@
     pfd.fd = fd;
     pfd.events = POLLIN;
     *err = errno = 0;
-    int ret = poll(&pfd, 1, timeout_ms);
+    int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, timeout_ms));
     if (ret < 0) {
         ALOGE("poll() error\n");
         *err = errno;
@@ -136,7 +136,7 @@
     while ((int)(bufit - buf) < (len - 1))
     {
         errno = 0;
-        int rc = read(fd, bufit, 1);
+        int rc = TEMP_FAILURE_RETRY(read(fd, bufit, 1));
 
         if (!rc)
             break;
@@ -427,7 +427,7 @@
             {
                 char ch;
                 errno = 0;
-                int nr = read(nat->rfcomm_sock, &ch, 1);
+                int nr = TEMP_FAILURE_RETRY(read(nat->rfcomm_sock, &ch, 1));
                 /* It should be that nr != 1 because we just opened a socket
                    and we haven't sent anything over it for the other side to
                    respond... but one can't be paranoid enough.
diff --git a/core/res/res/layout/media_route_list_item.xml b/core/res/res/layout/media_route_list_item.xml
index ba1aaf2..8ce6327 100644
--- a/core/res/res/layout/media_route_list_item.xml
+++ b/core/res/res/layout/media_route_list_item.xml
@@ -49,7 +49,7 @@
                   android:textAppearance="?android:attr/textAppearanceSmall" />
     </LinearLayout>
 
-    <com.android.internal.view.ImageButtonNoParentPress
+    <ImageButton
         android:layout_width="56dp"
         android:layout_height="56dp"
         android:id="@+id/expand_button"
diff --git a/core/res/res/layout/media_route_list_item_checkable.xml b/core/res/res/layout/media_route_list_item_checkable.xml
index f6ba09e..d0bffb6 100644
--- a/core/res/res/layout/media_route_list_item_checkable.xml
+++ b/core/res/res/layout/media_route_list_item_checkable.xml
@@ -17,6 +17,7 @@
 <com.android.internal.view.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:layout_width="match_parent"
               android:layout_height="?android:attr/listPreferredItemHeight"
+              android:background="?android:attr/selectableItemBackground"
               android:gravity="center_vertical">
 
     <ImageView android:layout_width="56dp"
diff --git a/core/res/res/layout/media_route_list_item_collapse_group.xml b/core/res/res/layout/media_route_list_item_collapse_group.xml
index 3f4b1c0..d605c18 100644
--- a/core/res/res/layout/media_route_list_item_collapse_group.xml
+++ b/core/res/res/layout/media_route_list_item_collapse_group.xml
@@ -14,26 +14,31 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="?android:attr/listPreferredItemHeightSmall"
-              android:background="#19ffffff"
-              android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
-              android:paddingRight="?android:attr/listPreferredItemPaddingRight"
-              android:gravity="center_vertical">
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:background="?android:attr/selectableItemBackground">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="?android:attr/listPreferredItemHeightSmall"
+        android:background="#19ffffff"
+        android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
+        android:paddingRight="?android:attr/listPreferredItemPaddingRight"
+        android:gravity="center_vertical">
 
-    <TextView android:layout_width="0dp"
-              android:layout_height="wrap_content"
-              android:layout_weight="1"
-              android:singleLine="true"
-              android:ellipsize="marquee"
-              android:text="@string/media_route_chooser_grouping_done"
-              android:textAppearance="?android:attr/textAppearanceMedium" />
+        <TextView android:layout_width="0dp"
+                  android:layout_height="wrap_content"
+                  android:layout_weight="1"
+                  android:singleLine="true"
+                  android:ellipsize="marquee"
+                  android:text="@string/media_route_chooser_grouping_done"
+                  android:textAppearance="?android:attr/textAppearanceMedium" />
 
-    <ImageView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:src="@drawable/ic_media_group_collapse"
-        android:scaleType="center" />
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/ic_media_group_collapse"
+            android:scaleType="center" />
 
-</LinearLayout>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index a19bc2b..3d63e84 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1290,6 +1290,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokluidsprekers"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-klank"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Stelsel"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-oudio"</string>
     <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index d2cb8bc..4cd27e0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"ሰርዝ"</string>
     <string name="inputMethod" msgid="1653630062304567879">"ግቤት ሜተድ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"እሺ"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"የትከል ድምፅ ማጉያዎች"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ድምጽ"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"ስርዓት"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"የብሉቱዝ ድምጽ"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"ተከናውኗል"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index aea32a8..fc7d09f 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"حذف"</string>
     <string name="inputMethod" msgid="1653630062304567879">"طريقة الإرسال"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"موافق"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"مكبرات صوت للإرساء"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صوت HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"النظام"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"صوت بلوتوث"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"تم"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index bfe0e27..8e01697 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"выдаліць"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дзеянні з тэкстам"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Дынамікі станцыi"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аўдыёвыхад"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Сістэма"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Гатова"</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index a972258..902cee5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"изтриване"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метод на въвеждане"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Отказ"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Докинг станц.: Високогов."</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8f8fb1d..3340d0c 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -170,7 +170,7 @@
     <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Informació personal"</string>
     <string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Accés directe als contactes i al calendari emmagatzemat a la tauleta."</string>
     <string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Accés directe als contactes i al calendari emmagatzemats al telèfon."</string>
-    <string name="permgrouplab_location" msgid="635149742436692049">"Ubicació"</string>
+    <string name="permgrouplab_location" msgid="635149742436692049">"La teva ubicació"</string>
     <string name="permgroupdesc_location" msgid="5704679763124170100">"Supervisa la teva ubicació física."</string>
     <string name="permgrouplab_network" msgid="5808983377727109831">"Comunicació de xarxa"</string>
     <string name="permgroupdesc_network" msgid="4478299413241861987">"Accedeix a diverses funcions de xarxa."</string>
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"suprimeix"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Mètode d\'entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Accions de text"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"S\'està acabant l\'espai d\'emmagatzematge"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"És possible que algunes funcions del sistema no funcionin"</string>
     <string name="ok" msgid="5970060430562524910">"D\'acord"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
     <string name="yes" msgid="5362982303337969312">"D\'acord"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altaveus del connector"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Àudio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Àudio per Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fet"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 35f0480..4697a2d 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"smazat"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"V úložišti je málo místa"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Některé systémové funkce nemusí fungovat"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6bc5f9f..25cba5f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"slet"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Inputmetode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der er snart ikke mere lagerplads"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nogle systemfunktioner virker måske ikke"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuller"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockstationens højttalere"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Udfør"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2bd623b..3fee27f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -196,31 +196,31 @@
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"Ausgehende Anrufe umleiten"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Ermöglicht der App, ausgehende Anrufe zu verarbeiten und die zu wählende Nummer zu ändern. Die Berechtigung erlaubt der App, ausgehende Anrufe zu überwachen, umzuleiten und zu unterbinden."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"SMS empfangen"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS-Nachrichten zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"MMS empfangen"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS-Nachrichten zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Ermöglicht der App, MMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Notfall-Broadcasts empfangen"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Ermöglicht der App, Notfall-Broadcasts zu empfangen und zu verarbeiten. Diese Berechtigung steht nur System-Apps zur Verfügung."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"Cell Broadcast-Nachrichten lesen"</string>
     <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Ermöglicht der App, von Ihrem Gerät empfangene Cell Broadcast-Nachrichten zu lesen. Cell Broadcast-Benachrichtigungen werden an einigen Standorten gesendet, um Sie über Notfallsituationen zu informieren. Schädliche Apps können die Leistung oder den Betrieb Ihres Geräts beeinträchtigen, wenn eine Cell Broadcast-Notfallbenachrichtigung eingeht."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"Kurznachrichten senden"</string>
-    <string name="permdesc_sendSms" msgid="7094729298204937667">"Ermöglicht der App, SMS-Nachrichten zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
-    <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS-Nachrichten ohne Bestätigung senden"</string>
-    <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Ermöglicht der App, SMS-Nachrichten zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
+    <string name="permdesc_sendSms" msgid="7094729298204937667">"Ermöglicht der App, SMS zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
+    <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"SMS ohne Bestätigung senden"</string>
+    <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Ermöglicht der App, SMS zu senden. Dies kann zu unerwarteten Kosten führen. Schädliche Apps können Kosten verursachen, indem sie Nachrichten ohne Ihre Bestätigung senden."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"SMS oder MMS lesen"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS-Nachrichten zu lesen. Die App kann alle SMS-Nachrichten lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS-Nachrichten zu lesen. Die App kann alle SMS-Nachrichten lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS zu lesen. Die App kann alle SMS lesen, unabhängig von Inhalt und Vertraulichkeit."</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"SMS oder MMS bearbeiten"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Ermöglicht der App, auf Ihrem Tablet oder Ihrer SIM-Karte gespeicherte SMS zu bearbeiten. Schädliche Apps können so Ihre Nachrichten löschen."</string>
     <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Ermöglicht der App, auf Ihrem Telefon oder Ihrer SIM-Karte gespeicherte SMS zu bearbeiten. Schädliche Apps können so Ihre Nachrichten löschen."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"Textnachrichten (WAP) empfangen"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Ermöglicht der App, WAP-Nachrichten zu empfangen und zu verarbeiten. Mit der Berechtigung können Nachrichten, die an Sie gesendet wurden, überwacht und gelöscht werden, bevor sie Ihnen angezeigt werden."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"aktive Apps abrufen"</string>
-    <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Anwendungen auf Ihrem Gerät zum Einsatz kommen."</string>
+    <string name="permdesc_getTasks" msgid="7454215995847658102">"Ermöglicht der App, Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Damit kann die App möglicherweise ermitteln, welche Apps auf Ihrem Gerät zum Einsatz kommen."</string>
     <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Details zu ausgeführten Apps abrufen"</string>
     <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ermöglicht der App, detaillierte Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Schädliche Apps können so geheime Informationen zu anderen Apps erhalten."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist"</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Ermöglicht der App, Aufgaben in den Vorder- und Hintergrund zu verschieben, ohne dass dazu ein Eingreifen Ihrerseits notwendig ist."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"Aktive Apps beenden"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Ermöglicht der App, Aufgaben zu entfernen und die entsprechenden Apps zu beenden. Schädliche Apps können das Verhalten anderer Apps stören."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"Beliebige Aktivität starten"</string>
@@ -301,8 +301,8 @@
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Linux-Signale an Apps senden"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Ermöglicht der App, das Senden des gelieferten Signals an alle andauernden Prozesse zu fordern"</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"App permanent ausführen"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Ermöglicht der App, Teile der eigenen Anwendung dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Tablet langsamer wird."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Ermöglicht der App, Teile der eigenen Anwendung dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Telefon langsamer wird."</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Ermöglicht der App, Teile der eigenen App dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Tablet langsamer wird."</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Ermöglicht der App, Teile der eigenen App dauerhaft im Speicher abzulegen. Dies kann dazu führen, dass anderen Apps weniger Arbeitsspeicher zur Verfügung steht und das Telefon langsamer wird."</string>
     <string name="permlab_deletePackages" msgid="184385129537705938">"Apps löschen"</string>
     <string name="permdesc_deletePackages" msgid="7411480275167205081">"Ermöglicht der App, Android-Pakete zu löschen. Schädliche Apps können so wichtige Apps löschen."</string>
     <string name="permlab_clearAppUserData" msgid="274109191845842756">"Daten anderer Apps löschen"</string>
@@ -386,7 +386,7 @@
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Frame-Puffer lesen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ermöglicht der App, den Inhalt des Frame-Puffers zu lesen"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
-    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe"</string>
+    <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Ermöglicht der App, globale Audio-Einstellungen zu ändern, etwa die Lautstärke und den Lautsprecher für die Ausgabe."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Audio aufnehmen"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ermöglicht der App, Ton mithilfe des Mikrofons aufzunehmen. Die Berechtigung erlaubt der App, Tonaufnahmen jederzeit und ohne Ihre Bestätigung durchzuführen."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
@@ -468,8 +468,8 @@
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"Als Konto-Manager fungieren"</string>
     <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Ermöglicht der App, Anrufe an Kontoauthentifizierer zu tätigen"</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"Konten auf dem Gerät suchen"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Ermöglicht der App, eine Liste der dem Tablet bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Anwendungen erstellt wurden."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Ermöglicht der App, eine Liste der dem Telefon bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Anwendungen erstellt wurden."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Ermöglicht der App, eine Liste der dem Tablet bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Apps erstellt wurden."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Ermöglicht der App, eine Liste der dem Telefon bekannten Konten abzurufen. Dabei kann es sich um Konten handeln, die von installierten Apps erstellt wurden."</string>
     <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"Konten erstellen und Passwörter festlegen"</string>
     <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Ermöglicht der App, die Kontoauthentifizierungsfunktionen des Konto-Managers zu verwenden, einschließlich der Funktionen zum Erstellen von Konten sowie zum Abrufen und Festlegen der entsprechenden Passwörter"</string>
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"Konten hinzufügen oder entfernen"</string>
@@ -477,9 +477,9 @@
     <string name="permlab_useCredentials" msgid="235481396163877642">"Konten auf dem Gerät verwenden"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"Ermöglicht der App, Authentifizierungs-Token anzufordern"</string>
     <string name="permlab_accessNetworkState" msgid="4951027964348974773">"Netzwerkverbindungen anzeigen"</string>
-    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Ermöglicht der App, Informationen zu Netzwerkverbindungen abzurufen, etwa welche Netzwerke existieren und verbunden sind"</string>
+    <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"Ermöglicht der App, Informationen zu Netzwerkverbindungen abzurufen, etwa welche Netzwerke existieren und verbunden sind."</string>
     <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"Voller Netzwerkzugriff"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Ermöglicht der App die Erstellung von Netzwerk-Sockets und die Verwendung benutzerdefinierter Netzwerkprotokolle. Der Browser und andere Anwendungen bieten die Möglichkeit, Daten über das Internet zu versenden. Daher ist diese Berechtigung nicht erforderlich, um Daten über das Internet versenden zu können."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Ermöglicht der App die Erstellung von Netzwerk-Sockets und die Verwendung benutzerdefinierter Netzwerkprotokolle. Der Browser und andere Apps bieten die Möglichkeit, Daten über das Internet zu versenden. Daher ist diese Berechtigung nicht erforderlich, um Daten über das Internet versenden zu können."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"Netzwerkeinstellungen und -verkehr ändern/abfangen"</string>
     <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"Ermöglicht der App, Netzwerkeinstellungen zu ändern und Netzwerkverkehr abzufangen und zu überprüfen, um beispielsweise den Proxy und den Port eines beliebigen Zugriffspunkts zu ändern. Schädliche Apps können so Netzwerkpakete ohne Ihr Wissen überwachen, weiterleiten oder ändern."</string>
     <string name="permlab_changeNetworkState" msgid="958884291454327309">"Netzwerkkonnektivität ändern"</string>
@@ -489,9 +489,9 @@
     <string name="permlab_changeBackgroundDataSetting" msgid="1400666012671648741">"Einstellung zur Verwendung von Hintergrunddaten ändern"</string>
     <string name="permdesc_changeBackgroundDataSetting" msgid="5347729578468744379">"Ermöglicht der App, die Einstellung zur Verwendung von Hintergrunddaten zu ändern"</string>
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"WLAN-Verbindungen anzeigen"</string>
-    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLANs abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte"</string>
+    <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Ermöglicht der App, Informationen zu WLANs abzurufen, etwa ob ein WLAN aktiviert ist, und den Namen verbundener WLAN-Geräte."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"WLAN-Verbindungen herstellen und trennen"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugriffspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen"</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Ermöglicht der App, eine Verbindung zu WLAN-Zugriffspunkten herzustellen und solche zu trennen und Änderungen an der Gerätekonfiguration für WLAN-Netzwerke vorzunehmen."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"WLAN-Multicast-Empfang zulassen"</string>
     <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Tablet. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
     <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Ermöglicht der App, Pakete zu empfangen, die mithilfe von Multicast-Adressen an sämtliche Geräte in einem WLAN versendet wurden, nicht nur an Ihr Telefon. Dies kostet mehr Leistung als der Nicht-Multicast-Modus."</string>
@@ -501,11 +501,11 @@
     <string name="permlab_accessWimaxState" msgid="7436749103151096452">"WiMAX-Verbindungen anzeigen"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Ermöglicht der App festzustellen, ob WiMAX aktiviert ist. Zudem kann sie Informationen zu verbundenen WiMAX-Netzwerken abrufen."</string>
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"WiMAX-Status ändern"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Ermöglicht der App, eine Verbindung zwischen dem Tablet und WiMAX-Netzwerken herzustellen und solche zu trennen"</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Ermöglicht der App, eine Verbindung zwischen dem Telefon und WiMAX-Netzwerken herzustellen und solche zu trennen"</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Ermöglicht der App, eine Verbindung zwischen dem Tablet und WiMAX-Netzwerken herzustellen und solche zu trennen."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Ermöglicht der App, eine Verbindung zwischen dem Telefon und WiMAX-Netzwerken herzustellen und solche zu trennen."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"Pairing mit Bluetooth-Geräten durchführen"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Ermöglicht der App, die Bluetooth-Konfiguration eines Tablets einzusehen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren"</string>
-    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Ermöglicht der App, die Bluetooth-Konfiguration des Telefons einzusehen und Verbindungen mit gekoppelten Geräten herzustellen und zu akzeptieren"</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Ermöglicht der App, die Bluetooth-Konfiguration eines Tablets einzusehen und Verbindungen zu gekoppelten Geräten herzustellen und zu akzeptieren."</string>
+    <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Ermöglicht der App, die Bluetooth-Konfiguration des Telefons einzusehen und Verbindungen mit gekoppelten Geräten herzustellen und zu akzeptieren."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"Nahfeldkommunikation steuern"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Ermöglicht der App die Kommunikation mit Tags für die Nahfeldkommunikation, Karten und Readern"</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"Bildschirmsperre deaktivieren"</string>
@@ -515,18 +515,18 @@
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"Synchronisierung aktivieren oder deaktivieren"</string>
     <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Ermöglicht der App, die Synchronisierungseinstellungen eines Kontos zu ändern. Dies kann beispielsweise dazu verwendet werden, die Synchronisierung von Kontakten mit einem Konto zu aktivieren."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"Synchronisierungsstatistiken lesen"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ermöglicht der App, die Synchronisierungsstatistiken eines Kontos zu lesen, einschließlich des Verlaufs von Synchronisierungsereignissen und der Menge synchronisierter Daten"</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Ermöglicht der App, die Synchronisierungsstatistiken eines Kontos zu lesen, einschließlich des Verlaufs von Synchronisierungsereignissen und der Menge synchronisierter Daten."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"Abonnierte Feeds lesen"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Ermöglicht der App, Details zu den zurzeit synchronisierten Feeds abzurufen"</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"Abonnierte Feeds schreiben"</string>
     <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Ermöglicht der App, Änderungen an kürzlich synchronisierten Feeds vorzunehmen. Schädliche Apps können so Ihre synchronisierten Feeds ändern."</string>
     <string name="permlab_readDictionary" msgid="4107101525746035718">"Begriffe lesen, die Sie zum Wörterbuch hinzugefügt haben"</string>
-    <string name="permdesc_readDictionary" msgid="659614600338904243">"Ermöglicht der App, alle Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat"</string>
+    <string name="permdesc_readDictionary" msgid="659614600338904243">"Ermöglicht der App, alle Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat."</string>
     <string name="permlab_writeDictionary" msgid="2296383164914812772">"In benutzerdefiniertes Wörterbuch schreiben"</string>
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Ermöglicht der App, dem Nutzerwörterbuch neue Einträge hinzuzufügen"</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"Zugriff auf geschützten Speicher testen"</string>
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"Zugriff auf geschützten Speicher testen"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Ermöglicht der App, eine Berechtigung für USB-Speicher zu testen, die künftig auf neuen Geräten verfügbar sein wird"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Ermöglicht der App, eine Berechtigung für USB-Speicher zu testen, die künftig auf neuen Geräten verfügbar sein wird."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Ermöglicht der App, eine Berechtigung für SD-Karten zu testen, die künftig auf neuen Geräten verfügbar sein wird"</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB-Speicherinhalte ändern oder löschen"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD-Karteninhalte ändern oder löschen"</string>
@@ -784,10 +784,10 @@
     <string name="autofill_area" msgid="3547409050889952423">"Gebiet"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirat"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"Lesezeichen für Webseiten und das Webprotokoll lesen"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Ermöglicht der App, den Verlauf aller mit dem Browser besuchten URLs und sämtliche Lesezeichen des Browsers zu lesen. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Ermöglicht der App, den Verlauf aller mit dem Browser besuchten URLs und sämtliche Lesezeichen des Browsers zu lesen. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"Lesezeichen für Webseiten setzen und das Webprotokoll aufzeichnen"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Anwendungen mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Tablet zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Ermöglicht der App, den Browserverlauf und die Lesezeichen auf Ihrem Telefon zu ändern. Damit kann die App Browserdaten löschen und ändern. Hinweis: Diese Berechtigung kann nicht von Browsern von Drittanbietern oder anderen Apps mit Internetfunktionen erzwungen werden."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"Wecker stellen"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Ermöglicht der App, einen Alarm in einer installierten Wecker-App einzurichten. Einige Wecker-Apps implementieren diese Funktion möglicherweise nicht."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"Mailbox-Nachrichten hinzufügen"</string>
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"Löschen"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Der Speicherplatz wird knapp"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Einige Systemfunktionen funktionieren möglicherweise nicht."</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Abbruch"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -974,7 +972,7 @@
     <string name="smv_process" msgid="5120397012047462446">"Der Prozess <xliff:g id="PROCESS">%1$s</xliff:g> hat gegen seine selbsterzwungene StrictMode-Richtlinie verstoßen."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android wird aktualisiert..."</string>
     <string name="android_upgrading_apk" msgid="7904042682111526169">"App <xliff:g id="NUMBER_0">%1$d</xliff:g> von <xliff:g id="NUMBER_1">%2$d</xliff:g> wird optimiert..."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Apps werden gestartet..."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Start wird abgeschlossen..."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> läuft"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Zum Wechseln in die App berühren"</string>
@@ -1121,7 +1119,7 @@
     <string name="permlab_copyProtectedData" msgid="4341036311211406692">"Inhalte kopieren"</string>
     <string name="permdesc_copyProtectedData" msgid="4390697124288317831">"Ermöglicht der App das Aufrufen des Standard-Containerdienstes zum Kopieren von Inhalten. Nicht für normale Apps vorgesehen."</string>
     <string name="permlab_route_media_output" msgid="1642024455750414694">"Medienausgabe umleiten"</string>
-    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer Anwendung, die Medienausgabe auf andere externe Geräte umzuleiten"</string>
+    <string name="permdesc_route_media_output" msgid="4932818749547244346">"Ermöglicht einer App, die Medienausgabe auf andere externe Geräte umzuleiten."</string>
     <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Für Zoomeinstellung zweimal berühren"</string>
     <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Widget konnte nicht hinzugefügt werden."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"Los"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock-Lautsprecher"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-Audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-Audio"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9f50ca3..481b6cb 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"διαγραφή"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Μέθοδος εισόδου"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Ηχεία βάσης σύνδεσης"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ήχος HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Σύστημα"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Ήχος Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Τέλος"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 1386ad5..6596393 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"delete"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Input method"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Text actions"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Storage space running out"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Some system functions may not work"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancel"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dock speakers"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Done"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c58b08e..76a7dfd 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio de almacenamiento"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no estén disponibles."</string>
     <string name="ok" msgid="5970060430562524910">"Aceptar"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 127abb5..b0dd12f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada de texto"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Queda poco espacio"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Es posible que algunas funciones del sistema no funcionen."</string>
     <string name="ok" msgid="5970060430562524910">"Aceptar"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"Aceptar"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altavoces del conector"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 6266353..ad27378 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"kustuta"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Sisestusmeetod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoimingud"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Talletusruum saab täis"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Mõned süsteemifunktsioonid ei pruugi töötada"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Tühista"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doki kõlarid"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI heli"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Süsteem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-heli"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index fcfbc0f..b633542 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1290,6 +1290,8 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"بلندگوهای جایگاه اتصال"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"صدای HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"سیستم"</string>
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+    <skip />
     <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5888acf..0318203 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1288,5 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Telineen kaiuttimet"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ääni"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Järjestelmä"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string>
     <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 99c7627..5b13636 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"supprimer"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Espace de stockage bientôt saturé"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Il est possible que certaines fonctionnalités du système ne soient pas opérationnelles."</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuler"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Haut-parleurs de la station d\'accueil"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Système"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"OK"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index dbb3878..5128132 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -371,14 +371,14 @@
     <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="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नया स्थान प्रदाता इंस्‍टॉल करें. यह एप्लिकेशन को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्‍थान प्रदाता आदेशों में पहुंचे"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"एप्लिकेशन को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देता है. यह एप्लिकेशन को GPS या अन्य स्थान स्रोतों के संचालन में बाधा पहुंचाने दे सकता है."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"किसी स्‍थान प्रदाता को इंस्‍टॉल करने की अनुमति"</string>
     <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नए स्थान प्रदाता को इंस्‍टॉल करें. यह एप्लिकेशन को स्‍थान और/या अन्‍य स्थान स्रोतों जैसे GPS या स्‍थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
     <string name="permlab_accessFineLocation" msgid="5885550969882561436">"सटीक (GPS) स्‍थान"</string>
     <string name="permdesc_accessFineLocation" product="tablet" msgid="8960597421469894181">"टेबलेट पर सटीक स्थान स्रोतों जैसे ग्लोबल पोजिशनिंग सिस्टम तक पहुंचें. जब स्थान सेवाएं उपलब्ध और चालू हैं, तो यह यह अनुमति एप्लिकेशन को आपका सटीक स्थान निर्धारित करने देती है."</string>
-    <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"फ़ोन पर सटीक स्थान स्रोतों जैसे ग्लोबल पोजिशनिंग सिस्टम तक पहुंचें. जब स्थान सेवाएं उपलब्ध और चालू हों, तो यह यह अनुमति एप्लिकेशन को आपका सटीक स्थान निर्धारित करने देती है."</string>
+    <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"फ़ोन पर सटीक स्थान स्रोतों जैसे ग्लोबल पोजिशनिंग सिस्टम तक पहुंचें. जब स्थान सेवाएं उपलब्ध और चालू हों, तो यह अनुमति एप्लिकेशन को आपका सटीक स्थान निर्धारित करने देती है."</string>
     <string name="permlab_accessCoarseLocation" msgid="7422827215441638984">"अनुमानित (नेटवर्क-आधारित) स्‍थान"</string>
     <string name="permdesc_accessCoarseLocation" msgid="5383798877137640762">"उपलब्‍ध नेटवर्क स्रोतों जैसे सेल टॉवर और WI- Fi का उपयोग करते हुए स्‍थान प्रदाताओं से अनुमानित स्थान तक पहुचें. जब ये स्थान सेवाएं उपलब्ध और चालू हों, तो यह अनुमति एप्लिकेशन को आपका अनुमानित स्थान निर्धारित करते देती है."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"SurfaceFlinger में पहुंचें"</string>
@@ -526,7 +526,7 @@
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"एप्लिकेशन को उपयोगकर्ता डिक्शनरी में नए शब्द लिखने देता है."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"संरक्ष‍ित संग्रहण पर पहुंच का परीक्षण करें"</string>
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"संरक्ष‍ित संग्रहण पर पहुंच का परीक्षण करें"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"एप्लि. को USB संग्रहण हेतु अनुमति का परीक्षण करने देता है जो भविष्‍य के उपकरणों में उपलब्‍ध होगा."</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"एप्लि. को USB संग्रहण अनुमति जांचने देता है जो भावी उपकरणों में उपलब्‍ध होगा."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"एप्लिकेशन को SD कार्ड के लिए किसी अनुमति का परीक्षण करने देता है जो भविष्‍य के उपकरणों में उपलब्‍ध होगा."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"अपने USB संग्रहण की सामग्री संशोधित करें या हटाएं"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"अपने SD कार्ड की सामग्री संशोधित करें या हटाएं"</string>
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"हटाएं"</string>
     <string name="inputMethod" msgid="1653630062304567879">"इनपुट विधि"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"पाठ क्रियाएं"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"ठीक"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"डॉक स्‍पीकर"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ऑडियो"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"सिस्‍टम"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"पूर्ण"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index dbe54ea..967e3e1 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ponestaje prostora za pohranu"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Neke sistemske funkcije možda neće raditi"</string>
     <string name="ok" msgid="5970060430562524910">"U redu"</string>
     <string name="cancel" msgid="6442560571259935130">"Odustani"</string>
     <string name="yes" msgid="5362982303337969312">"U redu"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvučnici postolja"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sustav"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 79e3119..a6ab456 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"törlés"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Beviteli mód"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kevés a szabad terület"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Előfordulhat, hogy néhány rendszerfunkció nem működik."</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Mégse"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkolóegység hangszórója"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audió"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Rendszer"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 28cc099..d8ec0c9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"hapus"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Metode masukan"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang penyimpanan hampir habis"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak dapat bekerja"</string>
     <string name="ok" msgid="5970060430562524910">"Oke"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="yes" msgid="5362982303337969312">"Oke"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pengeras suara dok"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index bf7a168..dfa1133 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1288,5 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altoparlanti dock"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
     <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fine"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 880cc9d..6e83f63 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"מחק"</string>
     <string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"אישור"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של מעגן"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"אודיו HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"מערכת"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"סיום"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index eb3d96f..f58fe5d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -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アプリがアカウントと同期しているかどうかをアプリから特定できるようになります。"</string>
+    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"アカウントの同期設定の読み取りをアプリに許可します。たとえば、連絡帳アプリがアカウントと同期しているかどうかをアプリから特定できるようになります。"</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"同期のON/OFFの切り替え"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"アカウントの同期設定の変更をアプリに許可します。たとえば、Peopleアプリとアカウントの同期を有効にするために使用できます。"</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>
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"削除"</string>
     <string name="inputMethod" msgid="1653630062304567879">"入力方法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"テキスト操作"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ホルダーのスピーカー"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMIオーディオ"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"システム"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完了"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index d345c91..b1dd2d9 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"삭제"</string>
     <string name="inputMethod" msgid="1653630062304567879">"입력 방법"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"확인"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"도크 스피커"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 오디오"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"시스템"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"완료"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 319aca7..b6a4b23 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"ištrinti"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Įvesties būdas"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Mažėja laisvos saugyklos vietos"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Kai kurios sistemos funkcijos gali neveikti"</string>
     <string name="ok" msgid="5970060430562524910">"Gerai"</string>
     <string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
     <string name="yes" msgid="5362982303337969312">"Gerai"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doko garsiakalbiai"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI garsas"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"„Bluetooth“ garsas"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Atlikta"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8839657..f497083 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -934,10 +934,8 @@
     <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>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Brīvās krātuves apjoms samazinās"</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>
     <string name="yes" msgid="5362982303337969312">"Labi"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Doka skaļruņi"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistēma"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gatavs"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 41f8521..426da6b 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"padam"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Kaedah input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Ruang storan semakin berkurangan"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Beberapa fungsi sistem mungkin tidak berfungsi"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Batal"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pembesar suara dok"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 24d8497..16e054d 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"slett"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Inndatametode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lite ledig lagringsplass"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Enkelte systemfunksjoner fungerer muligens ikke slik de skal"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkhøyttalere"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-lyd"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fb5e365..d840532 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"verwijderen"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Opslagruimte is bijna vol"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bepaalde systeemfuncties werken mogelijk niet"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockluidsprekers"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systeem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8bd9b91..9b5c91c 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"usuń"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Sposób wprowadzania tekstu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Kończy się miejsce"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektóre funkcje systemu mogą nie działać"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Głośniki stacji dokującej"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Dźwięk przez HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Dźwięk Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotowe"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1e2687d..aaa57a3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acções de texto"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Está quase sem espaço de armazenamento"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema poderão não funcionar"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Altif. estação ancoragem"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 75840cc..27a9c7c 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"excluir"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Pouco espaço de armazenamento"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Algumas funções do sistema podem não funcionar"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Alto-falantes do dock"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Áudio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
 </resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index d5a4250..3a229f7 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -2024,6 +2024,8 @@
     <skip />
     <!-- no translation found for default_audio_route_category_name (3722811174003886946) -->
     <skip />
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+    <skip />
     <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ef732f8..a2afc72 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1290,6 +1290,8 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Difuz. dispozit. andocare"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Ieşire audio HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
+    <skip />
     <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 8c280cc..ed8cd7f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"удалить"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"ОК"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динамики док-станции"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-аудио"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 0ddf9ef..dc240b4 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"odstrániť"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Metóda vstupu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nedostatok ukladacieho priestoru"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Niektoré systémové funkcie nemusia fungovať"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Reproduktory doku"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvuk HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 102e6f2..4d543c7 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Način vnosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Prostor za shranjevanje bo pošel"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Nekatere sistemske funkcije morda ne delujejo"</string>
     <string name="ok" msgid="5970060430562524910">"V redu"</string>
     <string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
     <string name="yes" msgid="5362982303337969312">"V redu"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Zvočniki stojala"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Zvok HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7dd17fc..dfe26b5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"избриши"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метод уноса"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"Потврди"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Звучници базне станице"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI аудио"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Систем"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c673628..f94fe3f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"ta bort"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Indatametod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textåtgärder"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Lagringsutrymmet börjar ta slut"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Det kan hända att vissa systemfunktioner inte fungerar"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dockningsstationens högtalare"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI-ljud"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klar"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ef9d19d..cf0f69f 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -196,9 +196,9 @@
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"panga upya simu zinazotoka"</string>
     <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Inaruhusu programu kuchakata simu zinazotoka nje na kubadilisha nambari ya kupigwa. Idhini hii inaruhusu programu kuchunguza, kuelekeza upya, au kuzuia simu zinazotoka nje."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"pokea jumbe za maandishi (SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"pokea jumbe za maandishi (MMS)"</string>
-    <string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe wa MMS. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
+    <string name="permdesc_receiveMms" msgid="533019437263212260">"Inaruhusu programu kupokea na kuchakata ujumbe medianwai (MMS). Hii inamaanisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwa kifaa chako bila ya kukuonyesha."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"Pokea matangazo ya dharura"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Inaruhusu programu kupokea na kuchakata jumbe za dharura. Ruhusa hii inapatikana tu kwa programu za mfumo."</string>
     <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"soma jumbe za matangazo ya simu"</string>
@@ -208,19 +208,19 @@
     <string name="permlab_sendSmsNoConfirmation" msgid="4781483105951730228">"Tuma ujumbe wa SMS bila ya thibitisho"</string>
     <string name="permdesc_sendSmsNoConfirmation" msgid="402569800862935907">"Inaruhusu programu kutuma ujumbe wa SMS. Hii inaweza ikasababisha malipo yasiyotarajiwa. Programu hasidi zinaweza kukugharimu pesa kwa kutuma ujumbe bila uthibitisho wako."</string>
     <string name="permlab_readSms" msgid="8745086572213270480">"soma jumbe zako za maandishi (SMS au MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye kompyuta yako ndogo au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye kompyuta kibao yako au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Inaruhusu programu kusoma ujumbe wa SMS uliohifadhiwa kwenye simu yako au SIM kadi. Hii inaruhusu programu kusoma ujumbe wote wa SMS, bila kujali maudhui au usiri."</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"Hariri jumbe zako za maandishi (SMS au MMS)"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Inaruhusu programu kuandikia jumbe za SMS zinazohifadhiwa kwenye kompyuta yako kibao au SIM kadi. Programu hasidi zinaweza kufuta jumbe zako."</string>
     <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Inaruhusu programu kuandika jumbe za SMS zinazohifadhiwa kwenye simu yako au SIM kadi. programu hasidi zinaweza kufuta ujumbe zako."</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"pokea jumbe za maandishi (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Inaruhusu programu kupokea na kuchakata ujumbe wa WAP. Idhini hii inajumulisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwako bila ya kukuonyesha."</string>
+    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Inaruhusu programu kupokea na kuchakata ujumbe wa WAP. Idhini hii inajumuisha uwezo wa kuchunguza na kufuta ujumbe uliotumwa kwako bila ya kukuonyesha."</string>
     <string name="permlab_getTasks" msgid="6466095396623933906">"rudisha programu zinazoendeshwa"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"Inaruhusu programu kurudisha taarifa kuhusu kazi zinazoendeshwa sasa na hivi karibuni. Hii inaweza kuruhusu programu kugundua taarifa kuhusu ni programu zipi zinazotumika kwenye kifaa."</string>
     <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"epua maelezo ya programu zinazoendeshwa"</string>
     <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Huruhusu programu kuepua maelezo tondoti kuhusu kazi za sasa na zinazoendelea hivi karibuni. Programu hasidi huenda zikagundua maelezo ya kibinafsi kuhusu programu zingine."</string>
     <string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string>
-    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na usuli. Programu inaweza kufanya haya bila ya maingizo yako."</string>
+    <string name="permdesc_reorderTasks" msgid="7734217754877439351">"Inaruhusu programu kusongesha kazi hadi kwenye mandhari-mbele na mandari nyuma. Programu inaweza kufanya haya bila ya maingizo yako."</string>
     <string name="permlab_removeTasks" msgid="6821513401870377403">"Komesha programu zinazoendeshwa"</string>
     <string name="permdesc_removeTasks" msgid="1394714352062635493">"Huruhusu programu kuondoa majukumu na kuua programu zao. Programu hasidi zinaweza kutatiza tabia ya programu zingine."</string>
     <string name="permlab_startAnyActivity" msgid="2918768238045206456">"anzisha shughuli yoyote"</string>
@@ -301,7 +301,7 @@
     <string name="permlab_signalPersistentProcesses" msgid="4539002991947376659">"Tuma ishara za Linux kwa programu"</string>
     <string name="permdesc_signalPersistentProcesses" msgid="4896992079182649141">"Inaruhusu programu kuomba ishara iliyotolewa kutumwa kwa michakato inyoendelea."</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"Fanya programu kuendeshwa kila mara"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Inaruhusu programu kuendelesha vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya kompyuta ndogo."</string>
+    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Inaruhusu programu kuendeleza vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya kompyuta ndogo."</string>
     <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Inaruhusu programu kuendelesha vijisehemu vyake kwenye kumbukumbu. Hii inaweza kupunguza kumbukumbu inayopatikana katika programu nyingine ikipunguza kasi ya simu."</string>
     <string name="permlab_deletePackages" msgid="184385129537705938">"futa programu"</string>
     <string name="permdesc_deletePackages" msgid="7411480275167205081">"Inaruhusu programu kufuta furushi za Android. Programu hasidi zinaweza kutumia hii kufuta programu muhimu."</string>
@@ -342,17 +342,17 @@
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Inaruhusu programu yenyewe kujianzisha baada ya mfumo kumaliza kuuanza upya. Hii inaweza kufanya ichukue muda mrefu kuanza kompyuta kibao na kuruhusu programu kupunguza kasi ya kompyuta kibao kijumla kwa kuendeshwa siku zote."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Inaruhusu programu kujianzisha yenyewe mfumo unapo maliza kuanza upya. Hii inaweza kuchukua muda mrefu simu kuanza na kuruhusu programu kupunguza kasi ya simu kwa jumla kwa kuendeshwa polepole kila wakati."</string>
     <string name="permlab_broadcastSticky" msgid="7919126372606881614">"tuma tangazo la kulanata"</string>
-    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya kompyuta ndogo kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
+    <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya kompyuta kibao kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Inaruhusu programu kutuma matangazo nata, ambayo hubakia baada ya matangazo kuisha. Matumizi zaidi yanaweza kufanya simu kufanya kazi polepole au kuifanya isiwe thabiti kwa kuisababisha itumie kumbukumbu kubwa zaidi."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"soma anwani zako"</string>
-    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ambayo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu maalum. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumulisha kasi ambayo umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu maalum. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
+    <string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
+    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Inaruhusu programu kusoma data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikiwa ni pamoja na mara ngapi umepiga simu, kutuma barua pepe au kuwasiliana kwa njia zingine na watu fulani. Idhini hii inaruhusu programu kuhifadhi data yako ya anwani, na programu hasidi zinaweza kushiriki data ya anwani bila ya kujua kwako."</string>
     <string name="permlab_writeContacts" msgid="5107492086416793544">"rekebisha anwani zako"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ya kupiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta yako ndogo, ikijumulisha kasi ya kupiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye kompyuta kibao yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
+    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Inaruhusu programu kurekebisha data kuhusu anwani zako zilizohifadhiwa kwenye simu yako, ikijumuisha ni mara ngapi umepiga simu, kutuma barua pepe, au kuwasiliana kwa njia nyingine na wawasiliani maalum. Idhini hii inaruhusu programu kufuta data ya anwani."</string>
     <string name="permlab_readCallLog" msgid="3478133184624102739">"soma rajisi ya simu"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Inaruhusu programu kusoma rajisi ya simu ya kompyuta yako ndogo, ikijumulisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Inaruhusu programu kusoma rajisi ya simu ya simu yako, ikijumulisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
+    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Inaruhusu programu kusoma rajisi ya simu ya kompyuta kibao yako, ikijumuisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
+    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Inaruhusu programu kusoma rajisi ya simu ya simu yako, ikijumuisha data kuhusu simu zinazoingia na zinazotoka. Idhini hii inaruhusu programu kuhifadhi data ya rajisi ya simu yako, na programu hasidi zinaweza kushiriki data ya rajisi ya simu bila ya kujua kwako."</string>
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"andika rajisi ya simu"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Huruhusu programu kurekebisha rajisi ya kompyuta kibao yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Huruhusu programu kurekebisha rajisi ya simu yako, ikiwa ni pamoja na simu zinazoingia na kutoka. Huenda programu hasidi zikatumia hii ili kufuta au kurekebisha rajisi ya simu yako."</string>
@@ -361,24 +361,24 @@
     <string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string>
-    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Inaruhusu programu kufikia na kupatanisha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao ya jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao ya jamii yote."</string>
+    <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Inaruhusu programu kufikia na kupatanisha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao ya jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"andika kwa mipasho yako wa kijamii"</string>
-    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yate ya kijamii."</string>
+    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Inaruhusu programu kuonyesha sasisho za kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii inaruhusu programu kutoa ujumbe unaoweza kuonekana kuwa unatoka kwa rafiki. Kumbuka: idhini hii huenda usitekelezwe kwenye mitandao yote ya kijamii."</string>
     <string name="permlab_readCalendar" msgid="5972727560257612398">"soma matukio ya kalenda pamoja na maelezo ya siri"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Inaruhusu programu kusoma matukio yote ya kalenda yaliohifadhiwa kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kaelnda, bila kujali usiri au unyeti."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifashi data yako ya kalenda, bila kujali usiri au umuhimu."</string>
+    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Inaruhusu programu kusoma matukio yote ya kalenda yaliohifadhiwa kwenye kompyuta kibao yako, yakijumuisha yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kaelnda, bila kujali usiri au unyeti."</string>
+    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Inaruhusu programu kusoma matukio yote ya kalenda yaliyohifadhiwa kwenye simu yako, pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kushiriki au kuhifadhi data yako ya kalenda, bila kujali usiri au umuhimu."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"ongeza au rekebisha matukio ya kalenda na utume barua pepe kwa wageni bila ufahamu wa mmiliki"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Inaruhusu programu kuongeza, kuondoa matukio ambayo unaweza kurekebisha kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe yanaonekana kuwa yanatoka kwa wamiliki wa kalenda, au kurekebisha matukio bila ya kujua kwa mmiliki."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Inaruhusu programu kuongeza, kuondoa matukio ambayo unaweza kurekebisha kwenye kompyuta yako ndogo, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe yanaonekana kuwa yanatoka kwa wamiliki wa kalenda, au kurekebisha matukio bila ya kujua kwa mmiliki."</string>
+    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye kompyuta kibao yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujua."</string>
+    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye simu yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujia."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"vyanzo vya jaribio la mahali kwa lengo la majaribio"</string>
-    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Unda vyanzo vya majaribio ya eneo vya kujaribu au sakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali inayorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
+    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Unda vyanzo vya majaribio ya eneo vya kujaribia au usakinishe mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali inayorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
     <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"fikia amri za ziada za mtoa huduma ya mahali"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Huruhusu programu kufikia amri za ziada za mtoaji huduma wa eneo. Hii inaweza kuruhusu programu kuhitilafiana na uendeshaji wa GPS au vyanzo vingine vya eneo."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"kibali ili kusakinisha mtoa huduma ya mahali"</string>
-    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Unda vyanzo vya eneo la majaribio vya kujaribu au kusakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/auhali zilizorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
+    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Unda vyanzo vya eneo la majaribio vya kujaribu au kusakinisha mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali zilizorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
     <string name="permlab_accessFineLocation" msgid="5885550969882561436">"eneo halisi la (GPS)"</string>
-    <string name="permdesc_accessFineLocation" product="tablet" msgid="8960597421469894181">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye kompyuta ndogo. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako sahihi."</string>
-    <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye simu. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako sahihi."</string>
+    <string name="permdesc_accessFineLocation" product="tablet" msgid="8960597421469894181">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye kompyuta ndogo. Wakati huduma za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako kamili."</string>
+    <string name="permdesc_accessFineLocation" product="default" msgid="239268765496141815">"Fikia vyanzo vya eneo sahihi kama vile Mfumo wa Global Positioning kwenye simu. Wakati huduma za eneo zinapatikana na zimewashwa, kibali hiki kinaruhusu programu kuthibitisha eneo lako kamili."</string>
     <string name="permlab_accessCoarseLocation" msgid="7422827215441638984">"eneo karibu  (linalotegemea mtandao)"</string>
     <string name="permdesc_accessCoarseLocation" msgid="5383798877137640762">"Fikia kadirio la eneo lako kutoka kwa watoaji huduma wa eneo kwa kutumia vyanzo vya mtandao kama vile mnara wa seli na Wi-Fi. Wakati huduma hizi za eneo zinapatikana na kuwashwa, kibali hiki kinaruhusu programu kuthibitisha kadirio la eneo lako."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"fikia SurfaceFlinger"</string>
@@ -388,7 +388,7 @@
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"badilisha mipangilio yako ya sauti"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Inaruhusu programu kurekebisha mipangilio ya sauti kila mahali kama vile sauti na ni kipaza sauti kipi ambacho kinatumika kwa kutoa."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"rekodi sauti"</string>
-    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Inaruhusu programu kurekodi sauti kwa kipokea sauti. Idhini hii inaruhusu programu kurekodi sauti wakati wowote bila ya uthibitisho wako."</string>
+    <string name="permdesc_recordAudio" msgid="4906839301087980680">"Inaruhusu programu kurekodi sauti kwa kinasa sauti. Idhini hii inaruhusu programu kurekodi sauti wakati wowote bila ya uthibitisho wako."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"chukua picha na video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Inaruhusu programu kupiga picha na video kwa kamera. Kibali hiki kinaruhusu programu kutumia kamera kwa wakati wowote bila uthibitisho wako."</string>
     <string name="permlab_brick" product="tablet" msgid="2961292205764488304">"lemaza kompyuta ndogo kabisa"</string>
@@ -426,7 +426,7 @@
     <string name="permlab_hardware_test" msgid="4148290860400659146">"jaribu maunzi"</string>
     <string name="permdesc_hardware_test" msgid="6597964191208016605">"Inaruhusu programu kudhibiti vifaa mbalimbali kwa lengo la kujaribia maunzi."</string>
     <string name="permlab_callPhone" msgid="3925836347681847954">"piga simu moja kwa moja kwa nambari za simu"</string>
-    <string name="permdesc_callPhone" msgid="3740797576113760827">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza sababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
+    <string name="permdesc_callPhone" msgid="3740797576113760827">"Inaruhusu programu kupiga nambari za simu bila ya wewe kuingilia kati. Hii inaweza kusababisha gharama zisizotarajiwa au simu. Kumbuka kuwa hii hairuhusu programu kupiga nambari za dharura. Programu hasidi zinaweza kukugharimu pesa kwa kupiga simu bila uthibitisho wako."</string>
     <string name="permlab_callPrivileged" msgid="4198349211108497879">"piga simu moja kwa moja kwa nambari zozote za simu"</string>
     <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Inaruhusu programu kupiga namba yoyote ya simu, ikiwa ni pamoja na namba za dharura, bila wewe kuingilia kati.Programu hasidi zinaweza piga simu zisizo za lazima na haramu kwa huduma za dharura."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"anzisha usanidi wa kompyuta ndogo ya CDMA moja kwa moja"</string>
@@ -441,7 +441,7 @@
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"badiliisha hali ya simu"</string>
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Inaruhusu programu kudhibiti vipengee vya kifaa. Programu iliyo na ruhusa hii inaweza badilisha mtandao, kuzima na kuwasha redio ya simu bila hata kukujulisha."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"soma hali ya simu na kitambulisho"</string>
-    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu tambulisho wa nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya kidhibiti mbali kuunganishwa kwa simu."</string>
+    <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Inaruhusu programu kuzuia kompyuta kibao  kwenda kulala."</string>
@@ -468,8 +468,8 @@
     <string name="permlab_accountManagerService" msgid="4829262349691386986">"tenda kama Huduma ya Meneja wa Akaunti"</string>
     <string name="permdesc_accountManagerService" msgid="1948455552333615954">"Huruhusu programu kupiga simu kwa Wathibitishaji Akaunti."</string>
     <string name="permlab_getAccounts" msgid="1086795467760122114">"pata akaunti kwenye kifaa"</string>
-    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa kompyuta ndogo. Hii inaweza kujumlisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa simu. Hii inaweza kujumlisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
+    <string name="permdesc_getAccounts" product="tablet" msgid="2741496534769660027">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa kompyuta kibao. Hii inaweza kujumuisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
+    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Inaruhusu programu kupata orodha ya akaunti zinazojulikana kwa simu. Hii inaweza kujumuisha akaunti zozote zilizoundwa na programu ambazo umesakinisha."</string>
     <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"unda akaunti na weka manenosiri"</string>
     <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Inaruhusu programu kutumia uwezo wa uthibitishaji akaunti wa KidhibitiAkaunti, pamoja na kuunda akaunti na kupata na kuweka nywila zao."</string>
     <string name="permlab_manageAccounts" msgid="4983126304757177305">"ongeza au uondoe akaunti"</string>
@@ -491,31 +491,31 @@
     <string name="permlab_accessWifiState" msgid="5202012949247040011">"ona miunganisho ya Wi-Fi"</string>
     <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Inaruhusu programu kuona taarifa kuhusu mtandao wa Wi-Fi, kama vile ikiwa Wi-Fi imewezeshwa mna jina la vifaa vya Wi-Fi vilivyounganishwa."</string>
     <string name="permlab_changeWifiState" msgid="6550641188749128035">"unganisha na utenganishe kutoka kwa Wi-Fi"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Inaruhusu programu kuunganisha kwenye au kuachanisha kutoka pointi za ufikivu wa Wi-Fi na kufanya mabadiliko kwenye usanidi wa kifaa cha mitandao ya Wi-Fi."</string>
+    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Inaruhusu programu kuunganisha kwenye au kukata kutoka pointi za ufikivu wa Wi-Fi na kufanya mabadiliko kwenye usanidi wa kifaa cha mitandao ya Wi-Fi."</string>
     <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ruhusu upokeaji wa Wi-Fi Multicast"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu kompyuta yako ndogo. Inatumia nguvu zaidi kuliko modi ya upeperushaji usiyo anuwai."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu simu yako. Inatumia nguvu zaidi kuliko modi ya upeperushaji usiyo anuwai."</string>
+    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu kompyuta yako kibao. Inatumia nguvu zaidi kuliko mfumo wa upeperushaji usio anuwai."</string>
+    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Inaruhusu programu kupokea pakiti zilizotumwa katika vifaa vyote kwenye mtandao wa Wi-Fi kwa kutumia anwani za upeperushaji anuwai, sio tu simu yako. Inatumia nguvu zaidi kuliko mfumo wa upeperushaji usio anuwai."</string>
     <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"fikia mipangilio ya Bluetooth"</string>
     <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Inaruhusu programu kusanidi kompyuta kibao ya karibu ya Bluetooth na kutambua na kuoanisha na vifaa vya kudhibiti."</string>
     <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Inaruhusu programu kusanidi simu ya karibu ya Bluetooth, na kutambua na kuoanisha na vifaa vya mbali."</string>
     <string name="permlab_accessWimaxState" msgid="7436749103151096452">"Ona miunganisho ya WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Inaruhusu programu kuthibitisha ikiwa WiMAX imewezeshwa na taarifa kuhusu mitandao yoyote ya WiMAX ambayo imeunganishwa."</string>
     <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Badilisha hali ya WiMAX"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Inaruhusu programu kuunganisha kompyuta ndogo kwenye na kuachanisha kompyuta ndogo kutoka mitandao ya WiMAX."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Inaruhusu programu kuunganisha simu kwenye na kuachanisha simu kutoka mitandao ya WiMAX."</string>
+    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Inaruhusu programu kuunganisha kompyuta kibao,  na kukata kompyuta kibao kutoka mitandao ya WiMAX."</string>
+    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Inaruhusu programu kuunganisha simu kwenye, na kukata simu kutoka mitandao ya WiMAX."</string>
     <string name="permlab_bluetooth" msgid="6127769336339276828">"oanisha na vifaa vya Bluetooth"</string>
-    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta ndogo, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
+    <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta kibao, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Inaruhusu programu kuona usanidi wa Bluetooth kwenye simu, na kuunda na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"dhibiti Mawasiliano Karibu na Uga"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Inaruhusu programu kuwasiliana na lebo, kadi na wasomaji wa Near Field Communication (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"lemaza kufuli la skrini yako"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine husiani wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string>
+    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Inaruhusu programu kulemaza ufunguo wa vitufe na usalama mwingine ambata wa nenosiri. Kwa mfano, simu inalemaza ufunguo wa viitufe inapopokea simu inayoingia, kisha inawezesha upya ufunguo wa vitufe wakati simu inapokamilika."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"soma mipangilio ya usawazishaji"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Inaruhusu programu kusoma mipangilio ya upatanishi wa akaunti. Kwa mfano, huku kunaweza kuamua kama programu ya Watu imepatanishwa na akaunti."</string>
     <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"washa na zima ulandanishi"</string>
-    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Inaruhusu programu kurekebisha mipangalio ya upatanishi wa akaunti. Kwa mfano, hii inaweza kuwesha programu ya upatanishi wa Watu na akaunti."</string>
+    <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Inaruhusu programu kurekebisha mipangalio ya upatanishi wa akaunti. Kwa mfano, hii inaweza kuwezesha programu ya upatanishi wa Watu na akaunti."</string>
     <string name="permlab_readSyncStats" msgid="7396577451360202448">"soma takwimu za usawazishaji"</string>
-    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Inaruhusu programu kusoma takwimu za upatanishi za akaunti, zikijumulisha historia ya matukio ya upatanishi na kiasi kipi cha data kimepatanishwa."</string>
+    <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Inaruhusu programu kusoma takwimu za upatanishi za akaunti, ikiwa ni pamoja na historia ya matukio ya upatanishi na kiasi cha data kimepatanishwa."</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"soma milisho ya kujiunga"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"Inaruhusu programu kupata maelezo kuhusu mlisho iliyolandanishwa kwa sasa."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"andika milisho ya kujiunga"</string>
@@ -524,8 +524,8 @@
     <string name="permdesc_readDictionary" msgid="659614600338904243">"Inaruhusu programu kusoma maneno, majina na misemo yote ambayo mtumiaji alihifadhi katika kamusi ya mtumiaji."</string>
     <string name="permlab_writeDictionary" msgid="2296383164914812772">"andika kwa kamusi iliyobainishwa na mtumiaji"</string>
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Inaruhusu programu kuandika maneno mapya katika kamusi ya mtumiaji."</string>
-    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"jaribu ufikiaji wa hifadhi iliyolindwa"</string>
-    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"jaribu ufikiaji wa hifadhi iliyolindwa"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"jaribu mfikio kwa hifadhi iliyolindwa"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"jaribu mfikio kwa hifadhi iliyolindwa"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Inaruhusu programu kujaribu idhini ya hifadhi ya USB itakayokuwa kwenye vifaa vya baadaye."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Inaruhusu programu kujaribu idhini ya kadi ya SD itakayokuwa kwenye vifaa vya baadaye."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"rekebisha au ufute maudhui ya hifadhi yako ya USB"</string>
@@ -784,9 +784,9 @@
     <string name="autofill_area" msgid="3547409050889952423">"Eneo"</string>
     <string name="autofill_emirate" msgid="2893880978835698818">"Emirate"</string>
     <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"soma alamisho na historia ya Wavuti wako"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Inaruhusu programu kusoma historia ya URL zote ambazo zimetembelewa na Kivinjari, na alamisho zote za Kivinjari. Kumbuka: idhini hii haiwezi kutekelezwa wavinjari wengine au programu zingine zenye uwezo wa kuvinjari."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Inaruhusu programu kusoma historia ya URL zote ambazo zimetembelewa na Kivinjari, na alamisho zote za Kivinjari. Kumbuka: idhini hii haiwezi kutekelezwa vivinjari vya vingine au programu zingine zenye uwezo wa kuvinjari."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"andika alamisho na historia ya wavuti"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa kwenye kompyuta yako ndogo. Hii inaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na kivinjari kingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Inaruhusu programu kurekebisha historia ya Kivinjari au alamisho zilizohifadhiwa kwenye kompyuta kibao yako. Hii inaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na kivinjari kingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
     <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Inaruhusu programu kurekebisha historia ya Kivinjari au vialamisho vilivyohifadhiwa kwenye simu yako. Hii huenda ikaruhusu programu kufuta au kurekebisha data ya Kivinjari. Kumbuka: huenda idhini hii isitekelezwe na vivinjari vingine au programu nyingine zenye uwezo wa kuvinjari wavuti."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"weka kengele"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Inaruhusu programu kuweka kengele katika programu iliyosakinishwa ya kengele. Programu zingine za kengele zinawezakosa kutekeleza kipengee hiki."</string>
@@ -821,9 +821,9 @@
     <string name="searchview_description_clear" msgid="1330281990951833033">"Futa swali"</string>
     <string name="searchview_description_submit" msgid="2688450133297983542">"Wasilisha hoja"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Utafutaji wa sauti"</string>
-    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Wezesha Kuchunguza kwa Kugusa?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya ni nini kilichochini ya kidole chako au kufanya ishara za kuingiliana na kumpyuta ndogo."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya ni nini kilichochini ya kidole chako au kufanya ishara za kuingiliana na simu."</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Unataka kuwezesha Kuchunguza kwa Kugusa?"</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya kilicho chini ya kidole chako au kutumia ishara ili kuingiliana na kompyuta kibao."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> inataka kuwezesha Kuchunguza kwa Kugusa. Wakati Kuchunguza kwa Kugusa kumewezeshwa, unaweza kusikia au kuona maelezo ya kilicho chini ya kidole chako au kutumia ishara ili kuingiliana na simu."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Mwezi 1 uliopita"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Kabla ya mwezi 1 uliopita"</string>
   <plurals name="num_seconds_ago">
@@ -1088,7 +1088,7 @@
     <string name="use_physical_keyboard" msgid="6203112478095117625">"Kibodi halisi"</string>
     <string name="hardware" msgid="7517821086888990278">"Maunzi"</string>
     <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Teua mpangilio wa kibodi"</string>
-    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Gusa kuchagua mpangilio wa kibodi."</string>
+    <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Gusa ili kuchagua mpangilio wa kibodi."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"wagombeaji"</u></string>
@@ -1284,12 +1284,13 @@
     <string name="SetupCallDefault" msgid="5834948469253758575">"Kubali simu?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Kila mara"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Mara moja tu"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Vipaza sauti vya kompyuta ndogo"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Vipaza sauti vya kompyuta kibao"</string>
     <string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Kipaza sauti cha simu"</string>
-    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Vipokea sauti"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Vipasa sauti vya gati"</string>
+    <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Vipokeasauti"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Vipasa sauti vya kituo"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Sauti ya HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Mfumo"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string>
     <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
     <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c4b31d5..008ceb5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"ลบ"</string>
     <string name="inputMethod" msgid="1653630062304567879">"วิธีป้อนข้อมูล"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"การทำงานของข้อความ"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"ตกลง"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"ลำโพงแท่นชาร์จ"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"เสียง HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"ระบบ"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"เสร็จสิ้น"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4ea1dbc..615d013 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"tanggalin"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Pamamaraan ng pag-input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Nauubusan na ang puwang ng storage"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Maaaring hindi gumana nang tama ang ilang paggana ng system"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Mga speaker ng dock"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI audio"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 182e2cd..7bafbe2 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -185,7 +185,7 @@
     <string name="permgrouplab_developmentTools" msgid="3446164584710596513">"Geliştirme araçları"</string>
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Yalnızca uygulama geliştiriciler için gerekli özellikler."</string>
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Depolama"</string>
-    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Payl depolama birimine erişin."</string>
+    <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USB belleğe erişin."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SD karta erişin."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"durum çubuğunu devre dışı bırak veya değiştir"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Uygulamaya, durum çubuğunu devre dışı bırakma ve sistem simgelerini ekleyip kaldırma izni verir."</string>
@@ -399,10 +399,10 @@
     <string name="permlab_reboot" product="default" msgid="2898560872462638242">"telefonu yeniden başlamaya zorla"</string>
     <string name="permdesc_reboot" product="tablet" msgid="8172056180063700741">"Uygulamaya, tableti yeniden açılmaya zorlama izni verir."</string>
     <string name="permdesc_reboot" product="default" msgid="5326008124289989969">"Uygulamaya, telefonu yeniden başlatmaya zorlama izni verir."</string>
-    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB deplm dosya sistemine eriş"</string>
+    <string name="permlab_mount_unmount_filesystems" product="nosdcard" msgid="2927361537942591841">"USB bellek dosya sistemine eriş"</string>
     <string name="permlab_mount_unmount_filesystems" product="default" msgid="4402305049890953810">"SD Kartın dosya sistemine eriş"</string>
     <string name="permdesc_mount_unmount_filesystems" msgid="1829290701658992347">"Uygulamaya, çıkarılabilir depolama için dosya sistemlerini ekleme veya bağlantısını kesme izni verir."</string>
-    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB depolamayı sil"</string>
+    <string name="permlab_mount_format_filesystems" product="nosdcard" msgid="6227819582624904972">"USB belleği sil"</string>
     <string name="permlab_mount_format_filesystems" product="default" msgid="262582698639274056">"SD Kartı sil"</string>
     <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Uygulamaya, çıkarılabilir depolama birimini biçimlendirme izni verir."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"dahili depolama birimi hakkında bilgi al"</string>
@@ -526,11 +526,11 @@
     <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Uygulamaya, kullanıcı sözlüğüne yeni kelimeler yazma izni verir."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="8235341515605559677">"korumalı depolama birimine erişimi test et"</string>
     <string name="permlab_sdcardRead" product="default" msgid="8235341515605559677">"korumalı depolama birimine erişimi test et"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Uygulamaya gelecekteki cihazlarda kullanılabilecek USB depolama birimine ilişkin bir izni test etme izni verir."</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="5791957130190763289">"Uygulamaya gelecekteki cihazlarda kullanılabilecek USB belleğe ilişkin bir izni test etme izni verir."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="5914402684685848828">"Uygulamaya gelecekteki cihazlarda kullanılabilecek SD karta ilişkin bir izni test etme olanağı verir."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB depolamamın içeriğini değiştir veya sil"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB belleğimin içeriğini değiştir veya sil"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD kartın içeriğini değiştir veya sil"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Uygulamaya USB depolama birimine yazma izni verir."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Uygulamaya USB belleğe yazma izni verir."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Uygulamaya, SD karta yazma izni verir."</string>
     <string name="permlab_mediaStorageWrite" product="default" msgid="6859839199706879015">"dahili medya depolama birimi içeriğini değiştir/sil"</string>
     <string name="permdesc_mediaStorageWrite" product="default" msgid="8189160597698529185">"Uygulamaya, dahili medya depolama içeriğini değiştirme izni verir."</string>
@@ -822,8 +822,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"Sorguyu gönder"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"Sesli arama"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Dokunarak Keşfet etkinleştirilsin mi?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda, parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da tabletle etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>, Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da telefonla etkileşimde bulunmak için ilgili hareketleri yapabilirsiniz."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda, parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da tabletle etkileşimde bulunmak için birtakım hareketler yapabilirsiniz."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>, Dokunarak Keşfet özelliğini etkinleştirmek istiyor. Dokunarak Keşfet açık olduğunda parmağınızın altındaki öğelere ait açıklamaları duyabilir veya görebilir ya da telefonla etkileşimde bulunmak için birtakım hareketler yapabilirsiniz."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay önce"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay önce"</string>
   <plurals name="num_seconds_ago">
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"sil"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Giriş yöntemi"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Metin eylemleri"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Depolama alanı bitiyor"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Bazı sistem işlevleri çalışmayabilir"</string>
     <string name="ok" msgid="5970060430562524910">"Tamam"</string>
     <string name="cancel" msgid="6442560571259935130">"İptal"</string>
     <string name="yes" msgid="5362982303337969312">"Tamam"</string>
@@ -1051,24 +1049,24 @@
     <string name="perms_show_all" msgid="2671791163933091180"><b>"Tümünü göster"</b></string>
     <string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"YENİ: "</font></string>
     <string name="perms_description_app" msgid="5139836143293299417">"Sağlayan: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB yığın depolama"</string>
+    <string name="usb_storage_activity_title" msgid="4465055157209648641">"USB yığın belleği"</string>
     <string name="usb_storage_title" msgid="5901459041398751495">"USB bağlandı"</string>
-    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB depolama birimi arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
+    <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin USB belleği arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
     <string name="usb_storage_message" product="default" msgid="805351000446037811">"Cihazınızı USB ile bilgisayarınıza bağladınız. Bilgisayarınız ile Android\'inizin SD kartı arasında dosya kopyalamak istiyorsanız aşağıdaki düğmeye dokunun."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB depolama birimini aç"</string>
-    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB depolama biriminizi USB yığın depolama amaçlı kullanmayla ilgili bir sorun var."</string>
-    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB yığın depolama birimi olarak kullanmada sorun var."</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"USB belleği aç"</string>
+    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"USB belleğinizi USB yığın belleği amaçlı kullanmayla ilgili bir sorun var."</string>
+    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"SD kartınızı USB yığın belleği olarak kullanmada sorun var."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB bağlandı"</string>
     <string name="usb_storage_notification_message" msgid="939822783828183763">"Bilgisayarınıza/bilgisayarınızdan dosya kopyalamak için dokunun."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB depolama birimini kapat"</string>
-    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB depolama birimini kapatmak için dokunun."</string>
-    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB depolama birimi kullanılıyor"</string>
-    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB depolama birimini kapatmadan önce Android\'inizin USB depolama biriminin bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB depolama birimini kapatmadan önce Android\'inizin SD kartının bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB depolama birimini kapat"</string>
-    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB depolama birimini kapatırken bir sorun oluştu. USB birimini kaldırdığınızdan emin olun ve daha sonra tekrar deneyin."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB depolama birimini aç"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB depolama birimini açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB depolama birimi kapatılıncaya kadar kullanılamayabilir."</string>
+    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"USB belleği kapat"</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"USB belleği kapatmak için dokunun."</string>
+    <string name="usb_storage_stop_title" msgid="660129851708775853">"USB bellek kullanılıyor"</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"USB belleği kapatmadan önce Android\'inizin USB belleğin bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"USB belleği kapatmadan önce Android\'inizin SD kartının bilgisayarınızla olan bağlantısını kesin (\"çıkarın\")."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"USB belleği kapat"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"USB belleği kapatırken bir sorun oluştu. USB birimini kaldırdığınızdan emin olun ve daha sonra tekrar deneyin."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"USB belleği aç"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB belleği açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB bellek kapatılıncaya kadar kullanılamayabilir."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USB işlemi başarısız oldu"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"Tamam"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Medya cihazı olarak bağlandı"</string>
@@ -1076,9 +1074,9 @@
     <string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Yükleyici olarak bağlandı"</string>
     <string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
     <string name="usb_notification_message" msgid="2290859399983720271">"Diğer USB seçenekleri için dokunun."</string>
-    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB dp br biçimlendirilsin mi?"</string>
+    <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB bellek biçimlendirilsin mi?"</string>
     <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD kart biçimlendirilsin mi?"</string>
-    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB depolama biriminizdeki tüm dosyalar silinecek. Bu işlem geri alınamaz!"</string>
+    <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB belleğinizdeki tüm dosyalar silinecek. Bu işlem geri alınamaz!"</string>
     <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kartınızdaki tüm veriler kaybolacak."</string>
     <string name="extmedia_format_button_format" msgid="4131064560127478695">"Biçimlendir"</string>
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
@@ -1092,28 +1090,28 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
-    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB depolm birimi hazırlanıyor"</string>
+    <string name="ext_media_checking_notification_title" product="nosdcard" msgid="3449816005351468560">"USB bellek hazırlanıyor"</string>
     <string name="ext_media_checking_notification_title" product="default" msgid="5457603418970994050">"SD kart hazırlanıyor"</string>
-    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Hatalar denetleniyor."</string>
-    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB depolama birimi"</string>
+    <string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Hata kontrolü yapılıyor"</string>
+    <string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Boş USB bellek"</string>
     <string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Boş SD kart"</string>
-    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB depolama birimi boş veya desteklenmeyen bir dosya sistemine sahip."</string>
+    <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="7840121067427269500">"USB bellek boş veya desteklenmeyen bir dosya sistemine sahip."</string>
     <string name="ext_media_nofs_notification_message" product="default" msgid="8641065641786923604">"SD kart boş veya desteklenmeyen dosya sistemi içeriyor."</string>
-    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"USB depolm birimi zarar görmüş"</string>
+    <string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"USB bellek zarar görmüş"</string>
     <string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Hasarlı SD kart"</string>
-    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB depolama birimi bozuk. Yeniden biçimlendirmeyi deneyin."</string>
+    <string name="ext_media_unmountable_notification_message" product="nosdcard" msgid="1795917578395333280">"USB bellek bozuk. Yeniden biçimlendirmeyi deneyin."</string>
     <string name="ext_media_unmountable_notification_message" product="default" msgid="1753898567525568253">"SD kart bozuk. Yeniden biçimlendirmeyi deneyin."</string>
-    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB dep br bklnmd şekl çıkarld"</string>
+    <string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"USB bellek bklnmd şekl çıkarld"</string>
     <string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"SD kart beklenmedik biçimde çıkarıldı"</string>
-    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Veri kaybı olmaması için çıkarmadan önce USB depolama biriminin bağlantısını kesin."</string>
+    <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Veri kaybı olmaması için çıkarmadan önce USB belleğin bağlantısını kesin."</string>
     <string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Veri kaybından kaçınmak için SD kartı çıkarmadan önce bağlantısını kesin."</string>
-    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB depl birm güvenle çıkrlblr"</string>
+    <string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"USB bellek güvenle çıkarılablr"</string>
     <string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"SD kart güvenle çıkarılabilir"</string>
-    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB depolama birimini güvenli bir şekilde çıkarabilirsiniz."</string>
+    <string name="ext_media_safe_unmount_notification_message" product="nosdcard" msgid="6142195361606493530">"USB belleği güvenli bir şekilde çıkarabilirsiniz."</string>
     <string name="ext_media_safe_unmount_notification_message" product="default" msgid="568841278138377604">"SD kartı güvenle kaldırabilirsiniz."</string>
-    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB depolama birimi çıkarıldı"</string>
+    <string name="ext_media_nomedia_notification_title" product="nosdcard" msgid="4486377230140227651">"USB bellek çıkarıldı"</string>
     <string name="ext_media_nomedia_notification_title" product="default" msgid="8902518030404381318">"SD kart çıkarılmış"</string>
-    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB depolama birimi çıkarıldı. Yeni medyayı takın."</string>
+    <string name="ext_media_nomedia_notification_message" product="nosdcard" msgid="6921126162580574143">"USB bellek çıkarıldı. Yeni medyayı takın."</string>
     <string name="ext_media_nomedia_notification_message" product="default" msgid="3870120652983659641">"SD kart çıkarıldı. Yeni bir SD kart takın."</string>
     <string name="activity_list_empty" msgid="1675388330786841066">"Eşleşen hiçbir etkinlik bulunamadı."</string>
     <string name="permlab_pkgUsageStats" msgid="8787352074326748892">"bileşen kullanım istatistiklerini güncelle"</string>
@@ -1171,17 +1169,17 @@
     <item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> / <xliff:g id="TOTAL">%d</xliff:g>"</item>
   </plurals>
     <string name="action_mode_done" msgid="7217581640461922289">"Bitti"</string>
-    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB depolama biriminin bağlantısı kesiliyor…"</string>
+    <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"USB belleğin bağlantısı kesiliyor…"</string>
     <string name="progress_unmounting" product="default" msgid="1327894998409537190">"SD kartın bağlantısı kesiliyor…"</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB depolama birimi siliniyor…"</string>
+    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"USB bellek siliniyor…"</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"SD kart siliniyor…"</string>
-    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB depolama birimi silinemedi."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"USB bellek silinemedi."</string>
     <string name="format_error" product="default" msgid="7315248696644510935">"SD kart silinemedi."</string>
     <string name="media_bad_removal" msgid="7960864061016603281">"SD kart, bağlantısı kesilmeden çıkarıldı."</string>
-    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB depolama birimi şu anda denetleniyor."</string>
+    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB bellek şu anda denetleniyor."</string>
     <string name="media_checking" product="default" msgid="7334762503904827481">"SD kart şu anda denetleniyor."</string>
     <string name="media_removed" msgid="7001526905057952097">"SD kart çıkarıldı."</string>
-    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB depolama birimi, şu anda bir bilgisayar tarafından kullanılıyor."</string>
+    <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"USB bellek şu anda bir bilgisayar tarafından kullanılıyor."</string>
     <string name="media_shared" product="default" msgid="5706130568133540435">"SD kart şu anda bir bilgisayar tarafından kullanılıyor."</string>
     <string name="media_unknown_state" msgid="729192782197290385">"Harici medyanın durumu bilinmiyor."</string>
     <string name="share" msgid="1778686618230011964">"Paylaş"</string>
@@ -1244,7 +1242,7 @@
     <string name="action_menu_overflow_description" msgid="2295659037509008453">"Diğer seçenekler"</string>
     <string name="storage_internal" msgid="4891916833657929263">"Dahili depolama birimi"</string>
     <string name="storage_sd_card" msgid="3282948861378286745">"SD kart"</string>
-    <string name="storage_usb" msgid="3017954059538517278">"USB depolama birimi"</string>
+    <string name="storage_usb" msgid="3017954059538517278">"USB bellek"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"Düzenle"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Veri kullanım uyarısı"</string>
     <string name="data_usage_warning_body" msgid="2814673551471969954">"Kullanımı ve ayarları görmek için dokunun."</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Yuva hoparlörleri"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI ses"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d861415..9dd7c73 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"видалити"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Метод введення"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,6 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Динаміки док-станції"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Аудіовихід HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Аудіо Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index e80ac6a..a9a8a93 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -810,7 +810,7 @@
     <string name="save_password_never" msgid="8274330296785855105">"Chưa bao giờ"</string>
     <string name="open_permission_deny" msgid="7374036708316629800">"Bạn không được phép mở trang này."</string>
     <string name="text_copied" msgid="4985729524670131385">"Đã sao chép văn bản vào khay nhớ tạm thời."</string>
-    <string name="more_item_label" msgid="4650918923083320495">"Khác"</string>
+    <string name="more_item_label" msgid="4650918923083320495">"Thêm"</string>
     <string name="prepend_shortcut_label" msgid="2572214461676015642">"Trình đơn+"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"dấu cách"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"nhập"</string>
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"xóa"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Phương thức nhập"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tác vụ văn bản"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Sắp hết dung lượng lưu trữ"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Một số chức năng hệ thống có thể không hoạt động"</string>
     <string name="ok" msgid="5970060430562524910">"OK"</string>
     <string name="cancel" msgid="6442560571259935130">"Hủy"</string>
     <string name="yes" msgid="5362982303337969312">"OK"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Loa đế"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Âm thanh HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Hệ thống"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Xong"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6b1bfa6..aa0fb65 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"删除"</string>
     <string name="inputMethod" msgid="1653630062304567879">"输入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"确定"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"基座扬声器"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音频"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"系统"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9decfa9..345a149 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"刪除"</string>
     <string name="inputMethod" msgid="1653630062304567879">"輸入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <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>
     <string name="yes" msgid="5362982303337969312">"確定"</string>
@@ -1290,6 +1288,7 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"座架喇叭"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"HDMI 音訊"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"系統"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
+    <!-- no translation found for bluetooth_a2dp_audio_route_name (8575624030406771015) -->
     <skip />
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 48a7a8a..6f16ab5 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -934,10 +934,8 @@
     <string name="deleteText" msgid="7070985395199629156">"susa"</string>
     <string name="inputMethod" msgid="1653630062304567879">"Indlela yokufakwayo"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
-    <!-- no translation found for low_internal_storage_view_title (5576272496365684834) -->
-    <skip />
-    <!-- no translation found for low_internal_storage_view_text (6640505817617414371) -->
-    <skip />
+    <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Isikhala sokulondoloza siyaphela"</string>
+    <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Eminye imisebenzi yohlelo ingahle ingasebenzi"</string>
     <string name="ok" msgid="5970060430562524910">"KULUNGILE"</string>
     <string name="cancel" msgid="6442560571259935130">"Khansela"</string>
     <string name="yes" msgid="5362982303337969312">"KULUNGILE"</string>
@@ -1284,12 +1282,12 @@
     <string name="SetupCallDefault" msgid="5834948469253758575">"Amukela ucingo?"</string>
     <string name="activity_resolver_use_always" msgid="8017770747801494933">"Njalo"</string>
     <string name="activity_resolver_use_once" msgid="2404644797149173758">"Kanye nje"</string>
-    <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Izipika zethebhulethi"</string>
-    <string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Isipika sefoni"</string>
+    <string name="default_audio_route_name" product="tablet" msgid="6890731863195399186">"Izipikha zethebhulethi"</string>
+    <string name="default_audio_route_name" product="default" msgid="4551396562363128432">"Isipikha sefoni"</string>
     <string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Ama-headphone"</string>
-    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Izipika ze-Dock"</string>
+    <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Izipikha ze-Dock"</string>
     <string name="default_audio_route_name_hdmi" msgid="7986404173839007682">"Umsindo we-HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Isistimu"</string>
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Umsindo we-Bluetooth"</string>
+    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Qedile"</string>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8ba0ccb..244aec8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1168,6 +1168,9 @@
   <java-symbol type="attr" name="externalRouteEnabledDrawable" />
   <java-symbol type="id" name="extended_settings" />
   <java-symbol type="id" name="check" />
+  <java-symbol type="id" name="volume_slider" />
+  <java-symbol type="id" name="volume_icon" />
+  <java-symbol type="drawable" name="ic_media_route_on_holo_dark" />
   <java-symbol type="layout" name="media_route_chooser_layout" />
   <java-symbol type="layout" name="media_route_list_item_top_header" />
   <java-symbol type="layout" name="media_route_list_item_section_header" />
diff --git a/data/sounds/ringtones/ogg/Themos.ogg b/data/sounds/ringtones/ogg/Themos.ogg
index bc850b8..4ddc71c 100644
--- a/data/sounds/ringtones/ogg/Themos.ogg
+++ b/data/sounds/ringtones/ogg/Themos.ogg
Binary files differ
diff --git a/data/sounds/ringtones/wav/Themos.wav b/data/sounds/ringtones/wav/Themos.wav
index d4d5c6e..fa3178f 100644
--- a/data/sounds/ringtones/wav/Themos.wav
+++ b/data/sounds/ringtones/wav/Themos.wav
Binary files differ
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6b9522b..e88c535 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1271,42 +1271,25 @@
     }
 
     /**
-     * Allow or disallow use of Bluetooth A2DP for media.
-     * <p>The default behavior of the system is to use A2DP for media playback whenever an A2DP sink
-     * is connected. Applications can use this method to override this behavior.
-     * Note that the request will not persist after a wired headset or an A2DP sink is connected or
-     * disconnected:
-     * - Connection of an A2DP sink automatically enables use of A2DP.
-     * - Connection of a wired headset automatically disables use of A2DP.
-     * - Disconnection of a wired headset automatically enables use of A2DP if an A2DP sink is
-     * connected.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
-     * @param on set <var>true</var> to allow use of A2DP for media (default).
-     *               <var>false</var> to disallow use of A2DP for media.
+     * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
+     *           headset; <var>false</var> disable A2DP audio
      * @deprecated Do not use.
      */
     @Deprecated public void setBluetoothA2dpOn(boolean on){
-        IAudioService service = getService();
-        try {
-            service.setBluetoothA2dpOn(on);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in setBluetoothA2dpOn", e);
-        }
     }
 
     /**
-     * Checks whether use of A2DP sinks is enabled for media.
+     * Checks whether A2DP audio routing to the Bluetooth headset is on or off.
      *
-     * @return true if use of A2DP is enabled for media, false otherwise.
+     * @return true if A2DP audio is being routed to/from Bluetooth headset;
+     *         false if otherwise
      */
     public boolean isBluetoothA2dpOn() {
-        IAudioService service = getService();
-        try {
-            return service.isBluetoothA2dpOn();
-        } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in isBluetoothA2dpOn", e);
+        if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
+            == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
             return false;
+        } else {
+            return true;
         }
     }
 
diff --git a/media/java/android/media/AudioRoutesInfo.aidl b/media/java/android/media/AudioRoutesInfo.aidl
new file mode 100644
index 0000000..d665851
--- /dev/null
+++ b/media/java/android/media/AudioRoutesInfo.aidl
@@ -0,0 +1,18 @@
+/* Copyright 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;
+
+parcelable AudioRoutesInfo;
diff --git a/media/java/android/media/AudioRoutesInfo.java b/media/java/android/media/AudioRoutesInfo.java
new file mode 100644
index 0000000..df9fc06
--- /dev/null
+++ b/media/java/android/media/AudioRoutesInfo.java
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Information available from AudioService about the current routes.
+ * @hide
+ */
+public class AudioRoutesInfo implements Parcelable {
+    static final int MAIN_SPEAKER = 0;
+    static final int MAIN_HEADSET = 1<<0;
+    static final int MAIN_HEADPHONES = 1<<1;
+    static final int MAIN_DOCK_SPEAKERS = 1<<2;
+    static final int MAIN_HDMI = 1<<3;
+
+    CharSequence mBluetoothName;
+    int mMainType = MAIN_SPEAKER;
+
+    public AudioRoutesInfo() {
+    }
+
+    public AudioRoutesInfo(AudioRoutesInfo o) {
+        mBluetoothName = o.mBluetoothName;
+        mMainType = o.mMainType;
+    }
+
+    AudioRoutesInfo(Parcel src) {
+        mBluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+        mMainType = src.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        TextUtils.writeToParcel(mBluetoothName, dest, flags);
+        dest.writeInt(mMainType);
+    }
+
+    public static final Parcelable.Creator<AudioRoutesInfo> CREATOR
+            = new Parcelable.Creator<AudioRoutesInfo>() {
+        public AudioRoutesInfo createFromParcel(Parcel in) {
+            return new AudioRoutesInfo(in);
+        }
+
+        public AudioRoutesInfo[] newArray(int size) {
+            return new AudioRoutesInfo[size];
+        }
+    };
+}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a69912d..ddb7e6b 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -53,6 +53,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
@@ -62,6 +63,7 @@
 import android.speech.RecognizerIntent;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.VolumePanel;
@@ -135,10 +137,11 @@
     private static final int MSG_RCDISPLAY_UPDATE = 13;
     private static final int MSG_SET_ALL_VOLUMES = 14;
     private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
+    private static final int MSG_REPORT_NEW_ROUTES = 16;
     // messages handled under wakelock, 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 = 16;
-    private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
+    private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 17;
+    private static final int MSG_SET_A2DP_CONNECTION_STATE = 18;
 
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -397,6 +400,11 @@
     private boolean mBluetoothA2dpEnabled;
     private final Object mBluetoothA2dpEnabledLock = new Object();
 
+    // Monitoring of audio routes.  Protected by mCurAudioRoutes.
+    final AudioRoutesInfo mCurAudioRoutes = new AudioRoutesInfo();
+    final RemoteCallbackList<IAudioRoutesObserver> mRoutesObservers
+            = new RemoteCallbackList<IAudioRoutesObserver>();
+
     ///////////////////////////////////////////////////////////////////////////
     // Construction
     ///////////////////////////////////////////////////////////////////////////
@@ -3011,6 +3019,26 @@
                     onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
                     mMediaEventWakeLock.release();
                     break;
+
+                case MSG_REPORT_NEW_ROUTES: {
+                    int N = mRoutesObservers.beginBroadcast();
+                    if (N > 0) {
+                        AudioRoutesInfo routes;
+                        synchronized (mCurAudioRoutes) {
+                            routes = new AudioRoutesInfo(mCurAudioRoutes);
+                        }
+                        while (N > 0) {
+                            N--;
+                            IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(N);
+                            try {
+                                obs.dispatchAudioRoutesChanged(routes);
+                            } catch (RemoteException e) {
+                            }
+                        }
+                    }
+                    mRoutesObservers.finishBroadcast();
+                    break;
+                }
             }
         }
     }
@@ -3127,6 +3155,13 @@
                 } else {
                     makeA2dpDeviceUnavailableNow(address);
                 }
+                synchronized (mCurAudioRoutes) {
+                    if (mCurAudioRoutes.mBluetoothName != null) {
+                        mCurAudioRoutes.mBluetoothName = null;
+                        sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                                SENDMSG_NOOP, 0, 0, null, 0);
+                    }
+                }
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                 if (btDevice.isBluetoothDock()) {
                     // this could be a reconnection after a transient disconnection
@@ -3141,6 +3176,14 @@
                     }
                 }
                 makeA2dpDeviceAvailable(address);
+                synchronized (mCurAudioRoutes) {
+                    String name = btDevice.getAliasName();
+                    if (!TextUtils.equals(mCurAudioRoutes.mBluetoothName, name)) {
+                        mCurAudioRoutes.mBluetoothName = name;
+                        sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                                SENDMSG_NOOP, 0, 0, null, 0);
+                    }
+                }
             }
         }
     }
@@ -3204,20 +3247,43 @@
         intent.putExtra("name", name);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 
+        int connType = 0;
+
         if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+            connType = AudioRoutesInfo.MAIN_HEADSET;
             intent.setAction(Intent.ACTION_HEADSET_PLUG);
             intent.putExtra("microphone", 1);
         } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
+            connType = AudioRoutesInfo.MAIN_HEADPHONES;
             intent.setAction(Intent.ACTION_HEADSET_PLUG);
             intent.putExtra("microphone", 0);
         } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
+            connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
             intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
         } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
+            connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS;
             intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
         } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
+            connType = AudioRoutesInfo.MAIN_HDMI;
             intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
         }
 
+        synchronized (mCurAudioRoutes) {
+            if (connType != 0) {
+                int newConn = mCurAudioRoutes.mMainType;
+                if (state != 0) {
+                    newConn |= connType;
+                } else {
+                    newConn &= ~connType;
+                }
+                if (newConn != mCurAudioRoutes.mMainType) {
+                    mCurAudioRoutes.mMainType = newConn;
+                    sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                            SENDMSG_NOOP, 0, 0, null, 0);
+                }
+            }
+        }
+
         ActivityManagerNative.broadcastStickyIntent(intent, null);
     }
 
@@ -4796,6 +4862,15 @@
     }
 
     @Override
+    public AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
+        synchronized (mCurAudioRoutes) {
+            AudioRoutesInfo routes = new AudioRoutesInfo(mCurAudioRoutes);
+            mRoutesObservers.register(observer);
+            return routes;
+        }
+    }
+
+    @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
 
@@ -4803,5 +4878,8 @@
         dumpFocusStack(pw);
         dumpRCStack(pw);
         dumpStreamStates(pw);
+        pw.println("\nAudio routes:");
+        pw.print("  mMainType=0x"); pw.println(Integer.toHexString(mCurAudioRoutes.mMainType));
+        pw.print("  mBluetoothName="); pw.println(mCurAudioRoutes.mBluetoothName);
     }
 }
diff --git a/media/java/android/media/IAudioRoutesObserver.aidl b/media/java/android/media/IAudioRoutesObserver.aidl
new file mode 100644
index 0000000..c269b83
--- /dev/null
+++ b/media/java/android/media/IAudioRoutesObserver.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+import android.media.AudioRoutesInfo;
+
+/**
+ * AIDL for the AudioService to report changes in available audio routes.
+ * @hide
+ */
+oneway interface IAudioRoutesObserver {
+    void dispatchAudioRoutesChanged(in AudioRoutesInfo newRoutes);
+}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 70fc623..fc5b8f1 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -19,7 +19,9 @@
 import android.app.PendingIntent;
 import android.bluetooth.BluetoothDevice;
 import android.content.ComponentName;
+import android.media.AudioRoutesInfo;
 import android.media.IAudioFocusDispatcher;
+import android.media.IAudioRoutesObserver;
 import android.media.IRemoteControlClient;
 import android.media.IRemoteControlDisplay;
 import android.media.IRingtonePlayer;
@@ -137,4 +139,6 @@
 
     void setWiredDeviceConnectionState(int device, int state, String name);
     int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
+
+    AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
 }
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 8488cd2..6f9cc62 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -16,19 +16,20 @@
 
 package android.media;
 
-import android.bluetooth.BluetoothA2dp;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * MediaRouter allows applications to control the routing of media channels
@@ -46,47 +47,98 @@
 
     static class Static {
         final Resources mResources;
-        final AudioManager mAudioManager;
+        final IAudioService mAudioService;
         final Handler mHandler;
-        final ArrayList<CallbackInfo> mCallbacks = new ArrayList<CallbackInfo>();
+        final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
+                new CopyOnWriteArrayList<CallbackInfo>();
 
         final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
         final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();
 
         final RouteCategory mSystemCategory;
-        final HeadphoneChangedBroadcastReceiver mHeadphoneChangedReceiver;
+
+        final AudioRoutesInfo mCurRoutesInfo = new AudioRoutesInfo();
 
         RouteInfo mDefaultAudio;
         RouteInfo mBluetoothA2dpRoute;
 
         RouteInfo mSelectedRoute;
 
+        final IAudioRoutesObserver.Stub mRoutesObserver = new IAudioRoutesObserver.Stub() {
+            public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+                mHandler.post(new Runnable() {
+                    @Override public void run() {
+                        updateRoutes(newRoutes);
+                    }
+                });
+            }
+        };
+
         Static(Context appContext) {
             mResources = Resources.getSystem();
             mHandler = new Handler(appContext.getMainLooper());
 
-            mAudioManager = (AudioManager)appContext.getSystemService(Context.AUDIO_SERVICE);
+            IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+            mAudioService = IAudioService.Stub.asInterface(b);
 
             // XXX this doesn't deal with locale changes!
             mSystemCategory = new RouteCategory(mResources.getText(
                     com.android.internal.R.string.default_audio_route_category_name),
                     ROUTE_TYPE_LIVE_AUDIO, false);
-
-            final IntentFilter speakerFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
-            speakerFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
-            speakerFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
-            speakerFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
-            mHeadphoneChangedReceiver = new HeadphoneChangedBroadcastReceiver();
-            appContext.registerReceiver(mHeadphoneChangedReceiver, speakerFilter);
         }
 
         // Called after sStatic is initialized
-        void initDefaultRoutes() {
+        void startMonitoringRoutes() {
             mDefaultAudio = new RouteInfo(mSystemCategory);
-            mDefaultAudio.mName = mResources.getText(
-                    com.android.internal.R.string.default_audio_route_name);
+            mDefaultAudio.mNameResId = com.android.internal.R.string.default_audio_route_name;
             mDefaultAudio.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
             addRoute(mDefaultAudio);
+
+            AudioRoutesInfo newRoutes = null;
+            try {
+                newRoutes = mAudioService.startWatchingRoutes(mRoutesObserver);
+            } catch (RemoteException e) {
+            }
+            if (newRoutes != null) {
+                updateRoutes(newRoutes);
+            }
+        }
+
+        void updateRoutes(AudioRoutesInfo newRoutes) {
+            if (newRoutes.mMainType != mCurRoutesInfo.mMainType) {
+                mCurRoutesInfo.mMainType = newRoutes.mMainType;
+                int name;
+                if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0
+                        || (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_headphones;
+                } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
+                } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_hdmi;
+                } else {
+                    name = com.android.internal.R.string.default_audio_route_name;
+                }
+                sStatic.mDefaultAudio.mNameResId = name;
+                dispatchRouteChanged(sStatic.mDefaultAudio);
+            }
+            if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) {
+                mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName;
+                if (mCurRoutesInfo.mBluetoothName != null) {
+                    if (sStatic.mBluetoothA2dpRoute == null) {
+                        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
+                        info.mName = mCurRoutesInfo.mBluetoothName;
+                        info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
+                        sStatic.mBluetoothA2dpRoute = info;
+                        addRoute(sStatic.mBluetoothA2dpRoute);
+                    } else {
+                        sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName;
+                        dispatchRouteChanged(sStatic.mBluetoothA2dpRoute);
+                    }
+                } else if (sStatic.mBluetoothA2dpRoute != null) {
+                    removeRoute(sStatic.mBluetoothA2dpRoute);
+                    sStatic.mBluetoothA2dpRoute = null;
+                }
+            }
         }
     }
 
@@ -133,7 +185,7 @@
         synchronized (Static.class) {
             if (sStatic == null) {
                 sStatic = new Static(context.getApplicationContext());
-                sStatic.initDefaultRoutes();
+                sStatic.startMonitoringRoutes();
             }
         }
     }
@@ -146,6 +198,13 @@
     }
 
     /**
+     * @hide for use by framework routing UI
+     */
+    public RouteCategory getSystemAudioCategory() {
+        return sStatic.mSystemCategory;
+    }
+
+    /**
      * Return the currently selected route for the given types
      *
      * @param type route types
@@ -155,14 +214,6 @@
         return sStatic.mSelectedRoute;
     }
 
-    static void onHeadphonesPlugged(boolean headphonesPresent, String headphonesName) {
-        sStatic.mDefaultAudio.mName = headphonesPresent
-                ? headphonesName
-                : sStatic.mResources.getText(
-                        com.android.internal.R.string.default_audio_route_name);
-        dispatchRouteChanged(sStatic.mDefaultAudio);
-    }
-
     /**
      * Add a callback to listen to events about specific kinds of media routes.
      * If the specified callback is already registered, its registration will be updated for any
@@ -207,11 +258,26 @@
      * @param route Route to select
      */
     public void selectRoute(int types, RouteInfo route) {
+        // Applications shouldn't programmatically change anything but user routes.
+        types &= ROUTE_TYPE_USER;
+        selectRouteStatic(types, route);
+    }
+    
+    /**
+     * @hide internal use
+     */
+    public void selectRouteInt(int types, RouteInfo route) {
         selectRouteStatic(types, route);
     }
 
     static void selectRouteStatic(int types, RouteInfo route) {
         if (sStatic.mSelectedRoute == route) return;
+        if ((route.getSupportedTypes() & types) == 0) {
+            Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
+                    typesToString(route.getSupportedTypes()) + " into route types " +
+                    typesToString(types));
+            return;
+        }
 
         if (sStatic.mSelectedRoute != null) {
             // TODO filter types properly
@@ -253,9 +319,9 @@
         if (cat.isGroupable() && !(info instanceof RouteGroup)) {
             // Enforce that any added route in a groupable category must be in a group.
             final RouteGroup group = new RouteGroup(info.getCategory());
-            group.addRoute(info);
             sStatic.mRoutes.add(group);
             dispatchRouteAdded(group);
+            group.addRoute(info);
 
             info = group;
         } else {
@@ -424,15 +490,24 @@
     public RouteCategory createRouteCategory(CharSequence name, boolean isGroupable) {
         return new RouteCategory(name, ROUTE_TYPE_USER, isGroupable);
     }
+    
+    /**
+     * Create a new route category. Each route must belong to a category.
+     *
+     * @param nameResId Resource ID of the name of the new category
+     * @param isGroupable true if routes in this category may be grouped with one another
+     * @return the new RouteCategory
+     */
+    public RouteCategory createRouteCategory(int nameResId, boolean isGroupable) {
+        return new RouteCategory(nameResId, ROUTE_TYPE_USER, isGroupable);
+    }
 
     static void updateRoute(final RouteInfo info) {
         dispatchRouteChanged(info);
     }
 
     static void dispatchRouteSelected(int type, RouteInfo info) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & type) != 0) {
                 cbi.cb.onRouteSelected(cbi.router, type, info);
             }
@@ -440,9 +515,7 @@
     }
 
     static void dispatchRouteUnselected(int type, RouteInfo info) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & type) != 0) {
                 cbi.cb.onRouteUnselected(cbi.router, type, info);
             }
@@ -450,9 +523,7 @@
     }
 
     static void dispatchRouteChanged(RouteInfo info) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & info.mSupportedTypes) != 0) {
                 cbi.cb.onRouteChanged(cbi.router, info);
             }
@@ -460,9 +531,7 @@
     }
 
     static void dispatchRouteAdded(RouteInfo info) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & info.mSupportedTypes) != 0) {
                 cbi.cb.onRouteAdded(cbi.router, info);
             }
@@ -470,9 +539,7 @@
     }
 
     static void dispatchRouteRemoved(RouteInfo info) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & info.mSupportedTypes) != 0) {
                 cbi.cb.onRouteRemoved(cbi.router, info);
             }
@@ -480,9 +547,7 @@
     }
 
     static void dispatchRouteGrouped(RouteInfo info, RouteGroup group, int index) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & group.mSupportedTypes) != 0) {
                 cbi.cb.onRouteGrouped(cbi.router, info, group, index);
             }
@@ -490,39 +555,27 @@
     }
 
     static void dispatchRouteUngrouped(RouteInfo info, RouteGroup group) {
-        final int count = sStatic.mCallbacks.size();
-        for (int i = 0; i < count; i++) {
-            final CallbackInfo cbi = sStatic.mCallbacks.get(i);
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
             if ((cbi.type & group.mSupportedTypes) != 0) {
                 cbi.cb.onRouteUngrouped(cbi.router, info, group);
             }
         }
     }
 
-    static void onA2dpDeviceConnected() {
-        final RouteInfo info = new RouteInfo(sStatic.mSystemCategory);
-        info.mName = sStatic.mResources.getString(
-                com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
-        sStatic.mBluetoothA2dpRoute = info;
-        addRoute(sStatic.mBluetoothA2dpRoute);
-    }
-
-    static void onA2dpDeviceDisconnected() {
-        removeRoute(sStatic.mBluetoothA2dpRoute);
-        sStatic.mBluetoothA2dpRoute = null;
-    }
-
     /**
      * Information about a media route.
      */
     public static class RouteInfo {
         CharSequence mName;
+        int mNameResId;
         private CharSequence mStatus;
         int mSupportedTypes;
         RouteGroup mGroup;
         final RouteCategory mCategory;
         Drawable mIcon;
 
+        private Object mTag;
+
         RouteInfo(RouteCategory category) {
             mCategory = category;
         }
@@ -532,6 +585,24 @@
          * to users who may select this as the active route.
          */
         public CharSequence getName() {
+            return getName(sStatic.mResources);
+        }
+        
+        /**
+         * Return the properly localized/resource selected name of this route.
+         * 
+         * @param context Context used to resolve the correct configuration to load
+         * @return The user-friendly name of the media route. This is the string presented
+         * to users who may select this as the active route.
+         */
+        public CharSequence getName(Context context) {
+            return getName(context.getResources());
+        }
+        
+        CharSequence getName(Resources res) {
+            if (mNameResId != 0) {
+                return mName = res.getText(mNameResId);
+            }
             return mName;
         }
 
@@ -574,10 +645,33 @@
             return mIcon;
         }
 
+        /**
+         * Set an application-specific tag object for this route.
+         * The application may use this to store arbitrary data associated with the
+         * route for internal tracking.
+         *
+         * <p>Note that the lifespan of a route may be well past the lifespan of
+         * an Activity or other Context; take care that objects you store here
+         * will not keep more data in memory alive than you intend.</p>
+         *
+         * @param tag Arbitrary, app-specific data for this route to hold for later use
+         */
+        public void setTag(Object tag) {
+            mTag = tag;
+            routeUpdated();
+        }
+
+        /**
+         * @return The tag object previously set by the application
+         * @see #setTag(Object)
+         */
+        public Object getTag() {
+            return mTag;
+        }
+
         void setStatusInt(CharSequence status) {
             if (!status.equals(mStatus)) {
                 mStatus = status;
-                routeUpdated();
                 if (mGroup != null) {
                     mGroup.memberStatusChanged(this, status);
                 }
@@ -605,7 +699,6 @@
      */
     public static class UserRouteInfo extends RouteInfo {
         RemoteControlClient mRcc;
-        private Object mTag;
 
         UserRouteInfo(RouteCategory category) {
             super(category);
@@ -620,6 +713,16 @@
             mName = name;
             routeUpdated();
         }
+        
+        /**
+         * Set the user-visible name of this route.
+         * @param resId Resource ID of the name to display to the user to describe this route
+         */
+        public void setName(int resId) {
+            mNameResId = resId;
+            mName = null;
+            routeUpdated();
+        }
 
         /**
          * Set the current user-visible status for this route.
@@ -645,6 +748,16 @@
         }
 
         /**
+         * Retrieve the RemoteControlClient associated with this route, if one has been set.
+         *
+         * @return the RemoteControlClient associated with this route
+         * @see #setRemoteControlClient(RemoteControlClient)
+         */
+        public RemoteControlClient getRemoteControlClient() {
+            return mRcc;
+        }
+
+        /**
          * Set an icon that will be used to represent this route.
          * The system may use this icon in picker UIs or similar.
          *
@@ -663,29 +776,6 @@
         public void setIconResource(int resId) {
             setIconDrawable(sStatic.mResources.getDrawable(resId));
         }
-
-        /**
-         * Set an application-specific tag object for this route.
-         * The application may use this to store arbitrary data associated with the
-         * route for internal tracking.
-         *
-         * <p>Note that the lifespan of a route may be well past the lifespan of
-         * an Activity or other Context; take care that objects you store here
-         * will not keep more data in memory alive than you intend.</p>
-         *
-         * @param tag Arbitrary, app-specific data for this route to hold for later use
-         */
-        public void setTag(Object tag) {
-            mTag = tag;
-        }
-
-        /**
-         * @return The tag object previously set by the application
-         * @see #setTag(Object)
-         */
-        public Object getTag() {
-            return mTag;
-        }
     }
 
     /**
@@ -700,9 +790,9 @@
             mGroup = this;
         }
 
-        public CharSequence getName() {
+        CharSequence getName(Resources res) {
             if (mUpdateName) updateName();
-            return super.getName();
+            return super.getName(res);
         }
 
         /**
@@ -831,6 +921,12 @@
         void routeUpdated() {
             int types = 0;
             final int count = mRoutes.size();
+            if (count == 0) {
+                // Don't keep empty groups in the router.
+                MediaRouter.removeRoute(this);
+                return;
+            }
+
             for (int i = 0; i < count; i++) {
                 types |= mRoutes.get(i).mSupportedTypes;
             }
@@ -844,6 +940,7 @@
             final int count = mRoutes.size();
             for (int i = 0; i < count; i++) {
                 final RouteInfo info = mRoutes.get(i);
+                // TODO: There's probably a much more correct way to localize this.
                 if (i > 0) sb.append(", ");
                 sb.append(info.mName);
             }
@@ -870,6 +967,7 @@
      */
     public static class RouteCategory {
         CharSequence mName;
+        int mNameResId;
         int mTypes;
         final boolean mGroupable;
 
@@ -879,10 +977,33 @@
             mGroupable = groupable;
         }
 
+        RouteCategory(int nameResId, int types, boolean groupable) {
+            mNameResId = nameResId;
+            mTypes = types;
+            mGroupable = groupable;
+        }
+
         /**
          * @return the name of this route category
          */
         public CharSequence getName() {
+            return getName(sStatic.mResources);
+        }
+        
+        /**
+         * Return the properly localized/configuration dependent name of this RouteCategory.
+         * 
+         * @param context Context to resolve name resources
+         * @return the name of this route category
+         */
+        public CharSequence getName(Context context) {
+            return getName(context.getResources());
+        }
+        
+        CharSequence getName(Resources res) {
+            if (mNameResId != 0) {
+                return res.getText(mNameResId);
+            }
             return mName;
         }
 
@@ -963,7 +1084,7 @@
      * @see MediaRouter#addCallback(int, Callback)
      * @see MediaRouter#removeCallback(Callback)
      */
-    public interface Callback {
+    public static abstract class Callback {
         /**
          * Called when the supplied route becomes selected as the active route
          * for the given route type.
@@ -972,7 +1093,7 @@
          * @param type Type flag set indicating the routes that have been selected
          * @param info Route that has been selected for the given route types
          */
-        public void onRouteSelected(MediaRouter router, int type, RouteInfo info);
+        public abstract void onRouteSelected(MediaRouter router, int type, RouteInfo info);
 
         /**
          * Called when the supplied route becomes unselected as the active route
@@ -982,7 +1103,7 @@
          * @param type Type flag set indicating the routes that have been unselected
          * @param info Route that has been unselected for the given route types
          */
-        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info);
+        public abstract void onRouteUnselected(MediaRouter router, int type, RouteInfo info);
 
         /**
          * Called when a route for the specified type was added.
@@ -990,7 +1111,7 @@
          * @param router the MediaRouter reporting the event
          * @param info Route that has become available for use
          */
-        public void onRouteAdded(MediaRouter router, RouteInfo info);
+        public abstract void onRouteAdded(MediaRouter router, RouteInfo info);
 
         /**
          * Called when a route for the specified type was removed.
@@ -998,7 +1119,7 @@
          * @param router the MediaRouter reporting the event
          * @param info Route that has been removed from availability
          */
-        public void onRouteRemoved(MediaRouter router, RouteInfo info);
+        public abstract void onRouteRemoved(MediaRouter router, RouteInfo info);
 
         /**
          * Called when an aspect of the indicated route has changed.
@@ -1009,7 +1130,7 @@
          * @param router the MediaRouter reporting the event
          * @param info The route that was changed
          */
-        public void onRouteChanged(MediaRouter router, RouteInfo info);
+        public abstract void onRouteChanged(MediaRouter router, RouteInfo info);
 
         /**
          * Called when a route is added to a group.
@@ -1019,7 +1140,8 @@
          * @param group The group the route was added to
          * @param index The route index within group that info was added at
          */
-        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, int index);
+        public abstract void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
+                int index);
 
         /**
          * Called when a route is removed from a group.
@@ -1028,15 +1150,15 @@
          * @param info The route that was removed
          * @param group The group the route was removed from
          */
-        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group);
+        public abstract void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group);
     }
 
     /**
-     * Stub implementation of the {@link MediaRouter.Callback} interface.
-     * Each interface method is defined as a no-op. Override just the ones
+     * Stub implementation of {@link MediaRouter.Callback}.
+     * Each abstract method is defined as a no-op. Override just the ones
      * you need.
      */
-    public static class SimpleCallback implements Callback {
+    public static class SimpleCallback extends Callback {
 
         @Override
         public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
@@ -1068,44 +1190,4 @@
         }
 
     }
-
-    class BtChangedBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
-                final int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
-                if (state == BluetoothA2dp.STATE_CONNECTED) {
-                    onA2dpDeviceConnected();
-                } else if (state == BluetoothA2dp.STATE_DISCONNECTING ||
-                        state == BluetoothA2dp.STATE_DISCONNECTED) {
-                    onA2dpDeviceDisconnected();
-                }
-            }
-        }
-    }
-
-    static class HeadphoneChangedBroadcastReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
-                final boolean plugged = intent.getIntExtra("state", 0) != 0;
-                final String name = sStatic.mResources.getString(
-                        com.android.internal.R.string.default_audio_route_name_headphones);
-                onHeadphonesPlugged(plugged, name);
-            } else if (Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG.equals(action) ||
-                    Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG.equals(action)) {
-                final boolean plugged = intent.getIntExtra("state", 0) != 0;
-                final String name = sStatic.mResources.getString(
-                        com.android.internal.R.string.default_audio_route_name_dock_speakers);
-                onHeadphonesPlugged(plugged, name);
-            } else if (Intent.ACTION_HDMI_AUDIO_PLUG.equals(action)) {
-                final boolean plugged = intent.getIntExtra("state", 0) != 0;
-                final String name = sStatic.mResources.getString(
-                        com.android.internal.R.string.default_audio_route_name_hdmi);
-                onHeadphonesPlugged(plugged, name);
-            }
-        }
-    }
 }
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index aa4e97a..afbceff 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -47,7 +47,7 @@
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Notificaciones"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth anclado"</string>
-    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de introducción"</string>
+    <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Configurar métodos de entrada"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Teclado físico"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al dispositivo USB?"</string>
     <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"¿Permitir que la aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> acceda al accesorio USB?"</string>
@@ -77,7 +77,7 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Inicio"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaciones recientes"</string>
-    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de introducción"</string>
+    <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
     <string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Bluetooth conectado"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6a96c6b..6c40461 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -68,7 +68,7 @@
     <dimen name="status_bar_icon_drawing_size">18dip</dimen>
 
     <!-- opacity at which Notification icons will be drawn in the status bar -->
-    <item type="dimen" name="status_bar_icon_drawing_alpha">55%</item>
+    <item type="dimen" name="status_bar_icon_drawing_alpha">65%</item>
 
     <!-- gap on either side of status bar notification icons -->
     <dimen name="status_bar_icon_padding">0dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1eb353f..f18e33e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -117,7 +117,7 @@
     </string>
 
     <!-- Separator for PLMN and SPN in network name. -->
-    <string name="status_bar_network_name_separator" translatable="false">"\n"</string>
+    <string name="status_bar_network_name_separator" translatable="false">|</string>
 
     <!-- Network connection string for Bluetooth Reverse Tethering -->
     <string name="bluetooth_tethered">Bluetooth tethered</string>
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 48efbc7..5dd15c3 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -22,15 +22,13 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.util.Log;
+import android.util.Slog;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
-import android.widget.ScrollView;
-import android.widget.FrameLayout;
 
 public class ExpandHelper implements Gefingerpoken, OnClickListener {
     public interface Callback {
@@ -41,7 +39,7 @@
     }
 
     private static final String TAG = "ExpandHelper";
-    protected static final boolean DEBUG = true;
+    protected static final boolean DEBUG = false;
     private static final long EXPAND_DURATION = 250;
     private static final long GLOW_DURATION = 150;
 
@@ -95,7 +93,7 @@
             mView = v;
         }
         public void setHeight(float h) {
-            if (DEBUG) Log.v(TAG, "SetHeight: setting to " + h);
+            if (DEBUG) Slog.v(TAG, "SetHeight: setting to " + h);
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
             lp.height = (int)h;
             mView.setLayoutParams(lp);
@@ -110,7 +108,7 @@
         }
         public int getNaturalHeight(int maximum) {
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
-            if (DEBUG) Log.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
+            if (DEBUG) Slog.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
             int oldHeight = lp.height;
             lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
             mView.setLayoutParams(lp);
@@ -176,7 +174,7 @@
                                          new ScaleGestureDetector.SimpleOnScaleGestureListener() {
             @Override
             public boolean onScaleBegin(ScaleGestureDetector detector) {
-                if (DEBUG) Log.v(TAG, "onscalebegin()");
+                if (DEBUG) Slog.v(TAG, "onscalebegin()");
                 float x = detector.getFocusX();
                 float y = detector.getFocusY();
 
@@ -194,7 +192,7 @@
                 // your fingers have to be somewhat close to the bounds of the view in question
                 mInitialTouchFocusY = detector.getFocusY();
                 mInitialTouchSpan = Math.abs(detector.getCurrentSpan());
-                if (DEBUG) Log.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
+                if (DEBUG) Slog.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
 
                 mStretching = initScale(v);
                 return mStretching;
@@ -202,7 +200,7 @@
 
             @Override
             public boolean onScale(ScaleGestureDetector detector) {
-                if (DEBUG) Log.v(TAG, "onscale() on " + mCurrView);
+                if (DEBUG) Slog.v(TAG, "onscale() on " + mCurrView);
 
                 // are we scaling or dragging?
                 float span = Math.abs(detector.getCurrentSpan()) - mInitialTouchSpan;
@@ -212,28 +210,28 @@
                 drag *= mGravity == Gravity.BOTTOM ? -1f : 1f;
                 float pull = Math.abs(drag) + Math.abs(span) + 1f;
                 float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
-                if (DEBUG) Log.d(TAG, "current span handle is: " + hand);
+                if (DEBUG) Slog.d(TAG, "current span handle is: " + hand);
                 hand = hand + mOldHeight;
                 float target = hand;
-                if (DEBUG) Log.d(TAG, "target is: " + target);
+                if (DEBUG) Slog.d(TAG, "target is: " + target);
                 hand = hand < mSmallSize ? mSmallSize : (hand > mLargeSize ? mLargeSize : hand);
                 hand = hand > mNaturalHeight ? mNaturalHeight : hand;
-                if (DEBUG) Log.d(TAG, "scale continues: hand =" + hand);
+                if (DEBUG) Slog.d(TAG, "scale continues: hand =" + hand);
                 mScaler.setHeight(hand);
 
                 // glow if overscale
                 float stretch = (float) Math.abs((target - hand) / mMaximumStretch);
                 float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
-                if (DEBUG) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
+                if (DEBUG) Slog.d(TAG, "stretch: " + stretch + " strength: " + strength);
                 setGlow(GLOW_BASE + strength * (1f - GLOW_BASE));
                 return true;
             }
 
             @Override
             public void onScaleEnd(ScaleGestureDetector detector) {
-                if (DEBUG) Log.v(TAG, "onscaleend()");
+                if (DEBUG) Slog.v(TAG, "onscaleend()");
                 // I guess we're alone now
-                if (DEBUG) Log.d(TAG, "scale end");
+                if (DEBUG) Slog.d(TAG, "scale end");
                 finishScale(false);
             }
         });
@@ -279,7 +277,7 @@
     }
 
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DEBUG) Log.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
+        if (DEBUG) Slog.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
                          " stretching=" + mStretching);
         mDetector.onTouchEvent(ev);
         return mStretching;
@@ -287,15 +285,15 @@
 
     public boolean onTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
-        if (DEBUG) Log.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
+        if (DEBUG) Slog.d(TAG, "touch: act=" + (action) + " stretching=" + mStretching);
         if (mStretching) {
-            if (DEBUG) Log.d(TAG, "detector ontouch");
+            if (DEBUG) Slog.d(TAG, "detector ontouch");
             mDetector.onTouchEvent(ev);
         }
         switch (action) {
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
-                if (DEBUG) Log.d(TAG, "cancel");
+                if (DEBUG) Slog.d(TAG, "cancel");
                 mStretching = false;
                 clearView();
                 break;
@@ -304,20 +302,20 @@
     }
     private boolean initScale(View v) {
         if (v != null) {
-            if (DEBUG) Log.d(TAG, "scale begins on view: " + v);
+            if (DEBUG) Slog.d(TAG, "scale begins on view: " + v);
             mStretching = true;
             setView(v);
             setGlow(GLOW_BASE);
             mScaler.setView(v);
             mOldHeight = mScaler.getHeight();
             if (mCallback.canChildBeExpanded(v)) {
-                if (DEBUG) Log.d(TAG, "working on an expandable child");
+                if (DEBUG) Slog.d(TAG, "working on an expandable child");
                 mNaturalHeight = mScaler.getNaturalHeight(mLargeSize);
             } else {
-                if (DEBUG) Log.d(TAG, "working on a non-expandable child");
+                if (DEBUG) Slog.d(TAG, "working on a non-expandable child");
                 mNaturalHeight = mOldHeight;
             }
-            if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight +
+            if (DEBUG) Slog.d(TAG, "got mOldHeight: " + mOldHeight +
                         " mNaturalHeight: " + mNaturalHeight);
             v.getParent().requestDisallowInterceptTouchEvent(true);
         }
@@ -342,7 +340,7 @@
         mStretching = false;
         setGlow(0f);
         mCallback.setUserExpandedChild(mCurrView, h == mNaturalHeight);
-        if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
+        if (DEBUG) Slog.d(TAG, "scale was finished on view: " + mCurrView);
         clearView();
     }
 
@@ -362,7 +360,7 @@
                 String debugLog = "Looking for glows: " + 
                         (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
                         (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
-                Log.v(TAG,  debugLog);
+                Slog.v(TAG,  debugLog);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index bec9aa2..0bdf84a 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -790,7 +790,7 @@
             if (DEBUG) Log.v(TAG, "Starting activity " + intent);
             context.startActivity(intent, opts.toBundle());
         }
-        if (!usingDrawingCache) {
+        if (usingDrawingCache) {
             holder.thumbnailViewImage.setDrawingCacheEnabled(false);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index baf86f3..3c19ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -462,11 +462,12 @@
         signalCluster.setNetworkController(mNetworkController);
 
         if (SHOW_CARRIER_LABEL) {
-            // for wifi-only devices, we show SSID; otherwise, we show PLMN
+            // for mobile devices, we always show mobile connection info here (SPN/PLMN)
+            // for other devices, we show whatever network is connected
             if (mNetworkController.hasMobileDataFeature()) {
                 mNetworkController.addMobileLabelView(mCarrierLabel);
             } else {
-                mNetworkController.addWifiLabelView(mCarrierLabel);
+                mNetworkController.addCombinedLabelView(mCarrierLabel);
             }
         }
 
@@ -820,6 +821,23 @@
             R.integer.config_show_search_delay);
     }
 
+    // Q: What kinds of notifications should show during setup?
+    // A: Almost none! Only things coming from the system (package is "android") that also 
+    // have special "kind" tags marking them as relevant for setup (see below).
+    private boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
+        if ("android".equals(sbn.pkg)) {
+            if (sbn.notification.kind != null) {
+                for (String aKind : sbn.notification.kind) {
+                    // IME switcher, created by InputMethodManagerService
+                    if ("android.system.imeswitcher".equals(aKind)) return true;
+                    // OTA availability & errors, created by SystemUpdateService
+                    if ("android.system.update".equals(aKind)) return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private void loadNotificationShade() {
         if (mPile == null) return;
 
@@ -831,7 +849,7 @@
         // If the device hasn't been through Setup, we only show system notifications
         for (int i=0; i<N; i++) {
             Entry ent = mNotificationData.get(N-i-1);
-            if (provisioned || "android".equals(ent.notification.pkg)) {
+            if (provisioned || showNotificationEvenIfUnprovisioned(ent.notification)) {
                 toShow.add(ent.row);
             }
         }
@@ -886,7 +904,7 @@
         for (int i=0; i<N; i++) {
             Entry ent = mNotificationData.get(N-i-1);
             if ((provisioned && ent.notification.score >= HIDE_ICONS_BELOW_SCORE)
-                    || "android".equals(ent.notification.pkg)) {
+                    || showNotificationEvenIfUnprovisioned(ent.notification)) {
                 toShow.add(ent.icon);
             }
         }
@@ -1376,12 +1394,59 @@
         if (!mTracking)
             return;
         mTracking = false;
-        mPile.setLayerType(View.LAYER_TYPE_NONE, null);
+        setPileLayers(View.LAYER_TYPE_NONE);
         mVelocityTracker.recycle();
         mVelocityTracker = null;
         mCloseView.setPressed(false);
     }
 
+    /**
+     * Enables or disables layers on the children of the notifications pile.
+     * 
+     * When layers are enabled, this method attempts to enable layers for the minimal
+     * number of children. Only children visible when the notification area is fully
+     * expanded will receive a layer. The technique used in this method might cause
+     * more children than necessary to get a layer (at most one extra child with the
+     * current UI.)
+     * 
+     * @param layerType {@link View#LAYER_TYPE_NONE} or {@link View#LAYER_TYPE_HARDWARE}
+     */
+    private void setPileLayers(int layerType) {
+        final int count = mPile.getChildCount();
+
+        switch (layerType) {
+            case View.LAYER_TYPE_NONE:
+                for (int i = 0; i < count; i++) {
+                    mPile.getChildAt(i).setLayerType(layerType, null);
+                }
+                break;
+            case View.LAYER_TYPE_HARDWARE:
+                final int[] location = new int[2]; 
+                mNotificationPanel.getLocationInWindow(location);
+
+                final int left = location[0];
+                final int top = location[1];
+                final int right = left + mNotificationPanel.getWidth();
+                final int bottom = top + getExpandedViewMaxHeight();
+
+                final Rect childBounds = new Rect();
+
+                for (int i = 0; i < count; i++) {
+                    final View view = mPile.getChildAt(i);
+                    view.getLocationInWindow(location);
+
+                    childBounds.set(location[0], location[1],
+                            location[0] + view.getWidth(), location[1] + view.getHeight());
+
+                    if (childBounds.intersects(left, top, right, bottom)) {
+                        view.setLayerType(layerType, null);
+                    }
+                }
+
+                break;
+        }
+    }
+
     void incrementAnim(long frameTimeNanos) {
         final long deltaNanos = Math.max(frameTimeNanos - mAnimLastTimeNanos, 0);
         final float t = deltaNanos * 0.000000001f;                  // ns -> s
@@ -1421,7 +1486,7 @@
         mCloseView.setPressed(true);
 
         mTracking = true;
-        mPile.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        setPileLayers(View.LAYER_TYPE_HARDWARE);
         mVelocityTracker = VelocityTracker.obtain();
         if (opening) {
             makeExpandedVisible(true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index bb0ce16..82d6a99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -46,7 +46,7 @@
     private static final String TAG = "StatusBar.KeyButtonView";
 
     final float GLOW_MAX_SCALE_FACTOR = 1.8f;
-    final float BUTTON_QUIESCENT_ALPHA = 0.6f;
+    final float BUTTON_QUIESCENT_ALPHA = 0.70f;
 
     long mDownTime;
     int mCode;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index b8f6054..1068267 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -121,8 +121,12 @@
     private int mWimaxSignal = 0;
     private int mWimaxState = 0;
     private int mWimaxExtraState = 0;
+
     // data connectivity (regardless of state, can we access the internet?)
     // state of inet connection - 0 not connected, 100 connected
+    private boolean mConnected = false;
+    private int mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
+    private String mConnectedNetworkTypeName;
     private int mInetCondition = 0;
     private static final int INET_CONDITION_THRESHOLD = 50;
 
@@ -868,6 +872,16 @@
                 .getSystemService(Context.CONNECTIVITY_SERVICE);
         final NetworkInfo info = connManager.getActiveNetworkInfo();
 
+        // Are we connected at all, by any interface?
+        mConnected = info != null && info.isConnected();
+        if (mConnected) {
+            mConnectedNetworkType = info.getType();
+            mConnectedNetworkTypeName = info.getTypeName();
+        } else {
+            mConnectedNetworkType = ConnectivityManager.TYPE_NONE;
+            mConnectedNetworkTypeName = null;
+        }
+
         int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0);
 
         if (CHATTY) {
@@ -912,12 +926,13 @@
             //   - We are connected to mobile data, or
             //   - We are not connected to mobile data, as long as the *reason* packets are not
             //     being routed over that link is that we have better connectivity via wifi.
-            // If data is disconnected for some other reason but wifi is connected, we show nothing.
+            // If data is disconnected for some other reason but wifi (or ethernet/bluetooth) 
+            // is connected, we show nothing.
             // Otherwise (nothing connected) we show "No internet connection".
 
             if (mDataConnected) {
                 mobileLabel = mNetworkName;
-            } else if (mWifiConnected) {
+            } else if (mConnected) {
                 if (hasService()) {
                     mobileLabel = mNetworkName;
                 } else {
@@ -997,6 +1012,12 @@
                     R.string.accessibility_bluetooth_tether);
         }
 
+        final boolean ethernetConnected = (mConnectedNetworkType == ConnectivityManager.TYPE_ETHERNET);
+        if (ethernetConnected) {
+            // TODO: icons and strings for Ethernet connectivity
+            combinedLabel = mConnectedNetworkTypeName;
+        }
+
         if (mAirplaneMode &&
                 (mServiceState == null || (!hasService() && !mServiceState.isEmergencyOnly()))) {
             // Only display the flight-mode icon if not in "emergency calls only" mode.
@@ -1023,7 +1044,7 @@
                 combinedSignalIconId = mDataSignalIconId;
             }
         }
-        else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected) {
+        else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected && !ethernetConnected) {
             // pretty much totally disconnected
 
             combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
@@ -1224,6 +1245,9 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("NetworkController state:");
+        pw.println(String.format("  %s network type %d (%s)", 
+                mConnected?"CONNECTED":"DISCONNECTED",
+                mConnectedNetworkType, mConnectedNetworkTypeName));
         pw.println("  - telephony ------");
         pw.print("  hasService()=");
         pw.println(hasService());
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 87ec16b..dfe9134 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -105,6 +105,8 @@
     protected static final int MSG_DPM_STATE_CHANGED = 309;
     protected static final int MSG_USER_CHANGED = 310;
 
+    protected static final boolean DEBUG_SIM_STATES = DEBUG || false;
+
     /**
      * When we receive a
      * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
@@ -292,6 +294,10 @@
                             MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
                     mHandler.sendMessage(msg);
                 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
+                    if (DEBUG_SIM_STATES) {
+                        Log.v(TAG, "action " + action + " state" +
+                            intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE));
+                    }
                     mHandler.sendMessage(mHandler.obtainMessage(
                             MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
                 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
@@ -407,6 +413,7 @@
         }
 
         if (state != IccCard.State.UNKNOWN && state != mSimState) {
+            if (DEBUG_SIM_STATES) Log.v(TAG, "dispatching state: " + state);
             mSimState = state;
             for (int i = 0; i < mSimStateCallbacks.size(); i++) {
                 mSimStateCallbacks.get(i).onSimStateChanged(state);
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 518d8e9..35e7820 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -202,8 +202,21 @@
 
     private Runnable mRecreateRunnable = new Runnable() {
         public void run() {
-            updateScreen(mMode, true);
+            Mode mode = mMode;
+            // If we were previously in a locked state but now it's Unknown, it means the phone
+            // was previously locked because of SIM state and has since been resolved. This
+            // bit of code checks this condition and dismisses keyguard.
+            boolean dismissAfterCreation = false;
+            if (mode == Mode.UnlockScreen && getUnlockMode() == UnlockMode.Unknown) {
+                if (DEBUG) Log.v(TAG, "Switch to Mode.LockScreen because SIM unlocked");
+                mode = Mode.LockScreen;
+                dismissAfterCreation = true;
+            }
+            updateScreen(mode, true);
             restoreWidgetState();
+            if (dismissAfterCreation) {
+                mKeyguardScreenCallback.keyguardDone(false);
+            }
         }
     };
 
@@ -307,6 +320,7 @@
         }
 
         public void recreateMe(Configuration config) {
+            if (DEBUG) Log.v(TAG, "recreateMe()");
             removeCallbacks(mRecreateRunnable);
             post(mRecreateRunnable);
         }
@@ -524,6 +538,7 @@
     public void reset() {
         mIsVerifyUnlockOnly = false;
         mForgotPattern = false;
+        if (DEBUG) Log.v(TAG, "reset()");
         post(mRecreateRunnable);
     }
 
@@ -673,6 +688,7 @@
         if (DEBUG_CONFIGURATION) Log.v(TAG, "**** re-creating lock screen since config changed");
         saveWidgetState();
         removeCallbacks(mRecreateRunnable);
+        if (DEBUG) Log.v(TAG, "recreating lockscreen because config changed");
         post(mRecreateRunnable);
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a5190f1..35f71ec 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -143,7 +143,6 @@
 import android.view.animation.AnimationUtils;
 
 import java.io.File;
-import java.io.FileDescriptor;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -2968,7 +2967,7 @@
     }
 
     public boolean allowAppAnimationsLw() {
-        if (mKeyguard != null && mKeyguard.isVisibleLw()) {
+        if (mKeyguard != null && mKeyguard.isVisibleLw() && !mKeyguard.isAnimatingLw()) {
             // If keyguard is currently visible, no reason to animate
             // behind it.
             return false;
@@ -4371,7 +4370,7 @@
         mLastInputMethodTargetWindow = target;
     }
 
-    public void dump(String prefix, FileDescriptor fd, PrintWriter pw, String[] args) {
+    public void dump(String prefix, PrintWriter pw, String[] args) {
         pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
                 pw.print(" mSystemReady="); pw.print(mSystemReady);
                 pw.print(" mSystemBooted="); pw.println(mSystemBooted);
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 7e1a80c..e63da05 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -53,6 +53,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <limits.h>
+#include <time.h>
 
 #define INDENT "  "
 #define INDENT2 "    "
@@ -1073,7 +1074,7 @@
             injectionResult, timeSpentWaitingForApplication);
 #if DEBUG_FOCUS
     ALOGD("findFocusedWindow finished: injectionResult=%d, "
-            "timeSpendWaitingForApplication=%0.1fms",
+            "timeSpentWaitingForApplication=%0.1fms",
             injectionResult, timeSpentWaitingForApplication / 1000000.0);
 #endif
     return injectionResult;
@@ -3100,7 +3101,7 @@
         for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
             dump.append(INDENT2);
             entry->appendDescription(dump);
-            dump.appendFormat(", age=%01.1fms\n",
+            dump.appendFormat(", age=%0.1fms\n",
                     (currentTime - entry->eventTime) * 0.000001f);
         }
     } else {
@@ -3124,7 +3125,7 @@
                         entry = entry->next) {
                     dump.append(INDENT4);
                     entry->eventEntry->appendDescription(dump);
-                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%01.1fms\n",
+                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
                             entry->targetFlags, entry->resolvedAction,
                             (currentTime - entry->eventEntry->eventTime) * 0.000001f);
                 }
@@ -3140,7 +3141,7 @@
                     dump.append(INDENT4);
                     entry->eventEntry->appendDescription(dump);
                     dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
-                            "age=%01.1fms, wait=%01.1fms\n",
+                            "age=%0.1fms, wait=%0.1fms\n",
                             entry->targetFlags, entry->resolvedAction,
                             (currentTime - entry->eventEntry->eventTime) * 0.000001f,
                             (currentTime - entry->deliveryTime) * 0.000001f);
@@ -3154,11 +3155,17 @@
     }
 
     if (isAppSwitchPendingLocked()) {
-        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
+        dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
                 (mAppSwitchDueTime - now()) / 1000000.0);
     } else {
         dump.append(INDENT "AppSwitch: not pending\n");
     }
+
+    dump.append(INDENT "Configuration:\n");
+    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
+            mConfig.keyRepeatDelay * 0.000001f);
+    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
+            mConfig.keyRepeatTimeout * 0.000001f);
 }
 
 status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
@@ -3285,11 +3292,28 @@
         nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
         const sp<InputWindowHandle>& windowHandle,
         nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
+    float dispatchLatency = (currentTime - eventTime) * 0.000001f;
+    float waitDuration = (currentTime - waitStartTime) * 0.000001f;
     ALOGI("Application is not responding: %s.  "
-            "It has been %01.1fms since event, %01.1fms since wait started.  Reason: %s",
+            "It has been %0.1fms since event, %0.1fms since wait started.  Reason: %s",
             getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
-            (currentTime - eventTime) / 1000000.0,
-            (currentTime - waitStartTime) / 1000000.0, reason);
+            dispatchLatency, waitDuration, reason);
+
+    // Capture a record of the InputDispatcher state at the time of the ANR.
+    time_t t = time(NULL);
+    struct tm tm;
+    localtime_r(&t, &tm);
+    char timestr[64];
+    strftime(timestr, sizeof(timestr), "%F %T", &tm);
+    mLastANRState.clear();
+    mLastANRState.append(INDENT "ANR:\n");
+    mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
+    mLastANRState.appendFormat(INDENT2 "Window: %s\n",
+            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
+    mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
+    mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
+    mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
+    dumpDispatchStateLocked(mLastANRState);
 
     CommandEntry* commandEntry = postCommandLocked(
             & InputDispatcher::doNotifyANRLockedInterruptible);
@@ -3371,7 +3395,7 @@
         nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
         if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
             String8 msg;
-            msg.appendFormat("Window '%s' spent %01.1fms processing the last input event: ",
+            msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
                     connection->getWindowName(), eventDuration * 0.000001f);
             dispatchEntry->eventEntry->appendDescription(msg);
             ALOGI("%s", msg.string());
@@ -3634,9 +3658,10 @@
     dump.append("Input Dispatcher State:\n");
     dumpDispatchStateLocked(dump);
 
-    dump.append(INDENT "Configuration:\n");
-    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
-    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
+    if (!mLastANRState.isEmpty()) {
+        dump.append("\nInput Dispatcher State at time of last ANR:\n");
+        dump.append(mLastANRState);
+    }
 }
 
 void InputDispatcher::monitor() {
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index c5b8cd7..d0824fc 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -948,6 +948,9 @@
     // Focused application.
     sp<InputApplicationHandle> mFocusedApplicationHandle;
 
+    // Dispatcher state at time of last ANR.
+    String8 mLastANRState;
+
     // Dispatch inbound events.
     bool dispatchConfigurationChangedLocked(
             nsecs_t currentTime, ConfigurationChangedEntry* entry);
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index eb33060..0f5ad66 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -112,6 +112,8 @@
     int mPasswordOwner = -1;
     Handler mHandler = new Handler();
 
+    long mLastMaximumTimeToLock = -1;
+
     final HashMap<ComponentName, ActiveAdmin> mAdminMap
             = new HashMap<ComponentName, ActiveAdmin>();
     final ArrayList<ActiveAdmin> mAdminList
@@ -595,7 +597,7 @@
                     new BroadcastReceiver() {
                         @Override
                         public void onReceive(Context context, Intent intent) {
-                            synchronized (this) {
+                            synchronized (DevicePolicyManagerService.this) {
                                 boolean doProxyCleanup = admin.info.usesPolicy(
                                         DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
                                 mAdminList.remove(admin);
@@ -603,9 +605,10 @@
                                 validatePasswordOwnerLocked();
                                 syncDeviceCapabilitiesLocked();
                                 if (doProxyCleanup) {
-                                    resetGlobalProxy();
+                                    resetGlobalProxyLocked();
                                 }
                                 saveSettingsLocked();
+                                updateMaximumTimeToLockLocked();
                             }
                         }
             });
@@ -826,16 +829,7 @@
 
         validatePasswordOwnerLocked();
         syncDeviceCapabilitiesLocked();
-
-        long timeMs = getMaximumTimeToLock(null);
-        if (timeMs <= 0) {
-            timeMs = Integer.MAX_VALUE;
-        }
-        try {
-            getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
-        } catch (RemoteException e) {
-            Slog.w(TAG, "Failure talking with power manager", e);
-        }
+        updateMaximumTimeToLockLocked();
     }
 
     static void validateQualityConstant(int quality) {
@@ -1606,28 +1600,41 @@
                     DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
             if (ap.maximumTimeToUnlock != timeMs) {
                 ap.maximumTimeToUnlock = timeMs;
-
-                long ident = Binder.clearCallingIdentity();
-                try {
-                    saveSettingsLocked();
-
-                    timeMs = getMaximumTimeToLock(null);
-                    if (timeMs <= 0) {
-                        timeMs = Integer.MAX_VALUE;
-                    }
-
-                    try {
-                        getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "Failure talking with power manager", e);
-                    }
-                } finally {
-                    Binder.restoreCallingIdentity(ident);
-                }
+                saveSettingsLocked();
+                updateMaximumTimeToLockLocked();
             }
         }
     }
 
+    void updateMaximumTimeToLockLocked() {
+        long timeMs = getMaximumTimeToLock(null);
+        if (mLastMaximumTimeToLock == timeMs) {
+            return;
+        }
+
+        long ident = Binder.clearCallingIdentity();
+        try {
+            if (timeMs <= 0) {
+                timeMs = Integer.MAX_VALUE;
+            } else {
+                // Make sure KEEP_SCREEN_ON is disabled, since that
+                // would allow bypassing of the maximum time to lock.
+                Settings.System.putInt(mContext.getContentResolver(),
+                        Settings.System.STAY_ON_WHILE_PLUGGED_IN, 0);
+            }
+
+            mLastMaximumTimeToLock = timeMs;
+
+            try {
+                getIPowerManager().setMaximumScreenOffTimeount((int)timeMs);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failure talking with power manager", e);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     public long getMaximumTimeToLock(ComponentName who) {
         synchronized (this) {
             long time = 0;
@@ -1868,7 +1875,7 @@
             // Reset the global proxy accordingly
             // Do this using system permissions, as apps cannot write to secure settings
             long origId = Binder.clearCallingIdentity();
-            resetGlobalProxy();
+            resetGlobalProxyLocked();
             Binder.restoreCallingIdentity(origId);
             return null;
         }
@@ -1892,20 +1899,20 @@
         return null;
     }
 
-    private void resetGlobalProxy() {
+    private void resetGlobalProxyLocked() {
         final int N = mAdminList.size();
         for (int i = 0; i < N; i++) {
             ActiveAdmin ap = mAdminList.get(i);
             if (ap.specifiesGlobalProxy) {
-                saveGlobalProxy(ap.globalProxySpec, ap.globalProxyExclusionList);
+                saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
                 return;
             }
         }
         // No device admins defining global proxies - reset global proxy settings to none
-        saveGlobalProxy(null, null);
+        saveGlobalProxyLocked(null, null);
     }
 
-    private void saveGlobalProxy(String proxySpec, String exclusionList) {
+    private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
         if (exclusionList == null) {
             exclusionList = "";
         }
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 48219a4..2d41f43 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -586,6 +586,10 @@
         mImeSwitcherNotification.defaults = 0; // please be quiet
         mImeSwitcherNotification.sound = null;
         mImeSwitcherNotification.vibrate = null;
+
+        // Tag this notification specially so SystemUI knows it's important
+        mImeSwitcherNotification.kind = new String[] { "android.system.imeswitcher" };
+
         Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
         mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
 
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 6695cb9..fbdd7aa 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -477,6 +477,11 @@
         }
     }
 
+    int getStayOnConditionsLocked() {
+        return mMaximumScreenOffTimeout <= 0 || mMaximumScreenOffTimeout == Integer.MAX_VALUE
+                ? mStayOnConditions : 0;
+    }
+
     private class SettingsObserver implements Observer {
         private int getInt(String name, int defValue) {
             ContentValues values = mSettings.getValues(name);
@@ -618,9 +623,11 @@
                                 PowerManager.PARTIAL_WAKE_LOCK, "Proximity Partial", false);
 
         mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
-        mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mScreenOnIntent.addFlags(
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
         mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
-        mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        mScreenOffIntent.addFlags(
+                Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
 
         Resources resources = mContext.getResources();
 
@@ -758,7 +765,8 @@
     }
 
     private void updateWakeLockLocked() {
-        if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+        final int stayOnConditions = getStayOnConditionsLocked();
+        if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
             // keep the device on if we're plugged in and mStayOnWhilePluggedIn is set.
             mStayOnWhilePluggedInScreenDimLock.acquire();
             mStayOnWhilePluggedInPartialLock.acquire();
@@ -2095,7 +2103,8 @@
                         // was dim
                         steps = (int)(ANIM_STEPS*ratio);
                     }
-                    if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+                    final int stayOnConditions = getStayOnConditionsLocked();
+                    if (stayOnConditions != 0 && mBatteryService.isPowered(stayOnConditions)) {
                         // If the "stay on while plugged in" option is
                         // turned on, then the screen will often not
                         // automatically turn off while plugged in.  To
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 26c5c3d..17957d2 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -164,6 +164,9 @@
         if (pendingResults != null) {
             pw.print(prefix); pw.print("pendingResults="); pw.println(pendingResults);
         }
+        if (pendingOptions != null) {
+            pw.print(prefix); pw.print("pendingOptions="); pw.println(pendingOptions);
+        }
         if (uriPermissions != null) {
             if (uriPermissions.readUriPermissions != null) {
                 pw.print(prefix); pw.print("readUriPermissions=");
@@ -202,7 +205,7 @@
         if (lastVisibleTime != 0 || waitingVisible || nowVisible) {
             pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible);
                     pw.print(" nowVisible="); pw.print(nowVisible);
-                    pw.print("lastVisibleTime=");
+                    pw.print(" lastVisibleTime=");
                     TimeUtils.formatDuration(lastVisibleTime, pw); pw.println("");
         }
         if (configDestroy || configChangeFlags != 0) {
@@ -453,6 +456,7 @@
             if (task != null && !finishing) {
                 task.numActivities--;
             }
+            clearOptionsLocked();
         }
     }
 
@@ -466,6 +470,9 @@
             if (task != null && inHistory) {
                 task.numActivities--;
             }
+            if (stopped) {
+                clearOptionsLocked();
+            }
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 8a86fe7..e2d6d98 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1055,7 +1055,9 @@
             mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
             r.stopped = true;
             r.state = ActivityState.STOPPED;
-            if (!r.finishing) {
+            if (r.finishing) {
+                r.clearOptionsLocked();
+            } else {
                 if (r.configDestroy) {
                     destroyActivityLocked(r, true, false, "stop-config");
                     resumeTopActivityLocked(null);
@@ -1474,6 +1476,21 @@
             return true;
         }
 
+        // If the most recent activity was noHistory but was only stopped rather
+        // than stopped+finished because the device went to sleep, we need to make
+        // sure to finish it as we're making a new activity topmost.
+        final ActivityRecord last = mLastPausedActivity;
+        if (mService.mSleeping && last != null && !last.finishing) {
+            if ((last.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
+                    || (last.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
+                if (DEBUG_STATES) {
+                    Slog.d(TAG, "no-history finish of " + last + " on new resume");
+                }
+                requestFinishActivityLocked(last.appToken, Activity.RESULT_CANCELED, null,
+                "no-history");
+            }
+        }
+
         if (prev != null && prev != next) {
             if (!prev.waitingVisible && next != null && !next.nowVisible) {
                 prev.waitingVisible = true;
@@ -3279,8 +3296,16 @@
         if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
             if (!r.finishing) {
-                requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
-                        "no-history");
+                if (!mService.mSleeping) {
+                    if (DEBUG_STATES) {
+                        Slog.d(TAG, "no-history finish of " + r);
+                    }
+                    requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
+                            "no-history");
+                } else {
+                    if (DEBUG_STATES) Slog.d(TAG, "Not finishing noHistory " + r
+                            + " on stop because we're just sleeping");
+                }
             }
         }
 
@@ -3526,9 +3551,10 @@
     final boolean requestFinishActivityLocked(IBinder token, int resultCode,
             Intent resultData, String reason) {
         int index = indexOfTokenLocked(token);
-        if (DEBUG_RESULTS) Slog.v(
+        if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(
                 TAG, "Finishing activity @" + index + ": token=" + token
-                + ", result=" + resultCode + ", data=" + resultData);
+                + ", result=" + resultCode + ", data=" + resultData
+                + ", reason=" + reason);
         if (index < 0) {
             return false;
         }
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index c4bb519..47cd34a 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -94,6 +94,7 @@
                     Slog.i(WindowManagerService.TAG, "Input event dispatching timed out sending to "
                             + windowState.mAttrs.getTitle());
                     appWindowToken = windowState.mAppToken;
+                    mService.saveANRStateLocked(appWindowToken, windowState);
                 }
             }
         }
@@ -104,6 +105,7 @@
                 Slog.i(WindowManagerService.TAG,
                         "Input event dispatching timed out sending to application "
                                 + appWindowToken.stringName);
+                mService.saveANRStateLocked(appWindowToken, null);
             }
         }
 
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 267bf82..758b6e7 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -279,7 +279,7 @@
                         }
                         mService.mFocusMayChange = true;
                     }
-                    if (win.isReadyForDisplay()) {
+                    if (win.isReadyForDisplay() && !winAnimator.isAnimating()) {
                         mForceHiding = true;
                     }
                     if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 6d5ae71..0d7b06c 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -143,7 +143,9 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.net.Socket;
+import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -458,6 +460,8 @@
     boolean mForceDisplayEnabled = false;
     boolean mShowingBootMessages = false;
 
+    String mLastANRState;
+
     // This protects the following display size properties, so that
     // getDisplaySize() doesn't need to acquire the global lock.  This is
     // needed because the window manager sometimes needs to use ActivityThread
@@ -885,8 +889,8 @@
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
-        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
-                "KEEP_SCREEN_ON_FLAG");
+        mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
+                | PowerManager.ON_AFTER_RELEASE, "KEEP_SCREEN_ON_FLAG");
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
         mInputManager = new InputManagerService(context, mInputMonitor);
@@ -3237,7 +3241,7 @@
             if (delayed) {
                 a = new AlphaAnimation(1, 0);
                 a.setStartOffset(0);
-                a.setDuration(delayDuration - 50);
+                a.setDuration(delayDuration - 120);
                 a.setBackgroundColor(0xFF000000);
             } else {
                 a = createExitAnimationLocked(transit, duration);
@@ -9429,12 +9433,12 @@
         mPolicy.lockNow();
     }
 
-    void dumpPolicyLocked(FileDescriptor fd, PrintWriter pw, String[] args, boolean dumpAll) {
+    void dumpPolicyLocked(PrintWriter pw, String[] args, boolean dumpAll) {
         pw.println("WINDOW MANAGER POLICY STATE (dumpsys window policy)");
-        mPolicy.dump("    ", fd, pw, args);
+        mPolicy.dump("    ", pw, args);
     }
 
-    void dumpTokensLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
+    void dumpTokensLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER TOKENS (dumpsys window tokens)");
         if (mTokenMap.size() > 0) {
             pw.println("  All tokens:");
@@ -9542,7 +9546,7 @@
         }
     }
 
-    void dumpSessionsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
+    void dumpSessionsLocked(PrintWriter pw, boolean dumpAll) {
         pw.println("WINDOW MANAGER SESSIONS (dumpsys window sessions)");
         if (mSessions.size() > 0) {
             Iterator<Session> it = mSessions.iterator();
@@ -9554,9 +9558,14 @@
         }
     }
 
-    void dumpWindowsLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+    void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
             ArrayList<WindowState> windows) {
         pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
+        dumpWindowsNoHeaderLocked(pw, dumpAll, windows);
+    }
+
+    void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
+            ArrayList<WindowState> windows) {
         for (int i=mWindows.size()-1; i>=0; i--) {
             WindowState w = mWindows.get(i);
             if (windows == null || windows.contains(w)) {
@@ -9793,7 +9802,7 @@
         }
     }
 
-    boolean dumpWindows(FileDescriptor fd, PrintWriter pw, String name, String[] args,
+    boolean dumpWindows(PrintWriter pw, String name, String[] args,
             int opti, boolean dumpAll) {
         ArrayList<WindowState> windows = new ArrayList<WindowState>();
         if ("visible".equals(name)) {
@@ -9832,11 +9841,42 @@
         }
 
         synchronized(mWindowMap) {
-            dumpWindowsLocked(fd, pw, dumpAll, windows);
+            dumpWindowsLocked(pw, dumpAll, windows);
         }
         return true;
     }
 
+    void dumpLastANRLocked(PrintWriter pw) {
+        pw.println("WINDOW MANAGER LAST ANR (dumpsys window lastanr)");
+        if (mLastANRState == null) {
+            pw.println("  <no ANR has occurred since boot>");
+        } else {
+            pw.println(mLastANRState);
+        }
+    }
+
+    /**
+     * Saves information about the state of the window manager at
+     * the time an ANR occurred before anything else in the system changes
+     * in response.
+     *
+     * @param appWindowToken The application that ANR'd, never null.
+     * @param windowState The window that ANR'd, may be null.
+     */
+    public void saveANRStateLocked(AppWindowToken appWindowToken, WindowState windowState) {
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        pw.println("  ANR time: " + DateFormat.getInstance().format(new Date()));
+        pw.println("  Application at fault: " + appWindowToken.stringName);
+        if (windowState != null) {
+            pw.println("  Window at fault: " + windowState.mAttrs.getTitle());
+        }
+        pw.println();
+        dumpWindowsNoHeaderLocked(pw, true, null);
+        pw.close();
+        mLastANRState = sw.toString();
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -9862,6 +9902,7 @@
                 pw.println("Window manager dump options:");
                 pw.println("  [-a] [-h] [cmd] ...");
                 pw.println("  cmd may be one of:");
+                pw.println("    l[astanr]: last ANR information");
                 pw.println("    p[policy]: policy state");
                 pw.println("    s[essions]: active sessions");
                 pw.println("    t[okens]: token list");
@@ -9882,34 +9923,39 @@
         if (opti < args.length) {
             String cmd = args[opti];
             opti++;
-            if ("policy".equals(cmd) || "p".equals(cmd)) {
+            if ("lastanr".equals(cmd) || "l".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    dumpPolicyLocked(fd, pw, args, true);
+                    dumpLastANRLocked(pw);
+                }
+                return;
+            } else if ("policy".equals(cmd) || "p".equals(cmd)) {
+                synchronized(mWindowMap) {
+                    dumpPolicyLocked(pw, args, true);
                 }
                 return;
             } else if ("sessions".equals(cmd) || "s".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    dumpSessionsLocked(fd, pw, true);
+                    dumpSessionsLocked(pw, true);
                 }
                 return;
             } else if ("tokens".equals(cmd) || "t".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    dumpTokensLocked(fd, pw, true);
+                    dumpTokensLocked(pw, true);
                 }
                 return;
             } else if ("windows".equals(cmd) || "w".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    dumpWindowsLocked(fd, pw, true, null);
+                    dumpWindowsLocked(pw, true, null);
                 }
                 return;
             } else if ("all".equals(cmd) || "a".equals(cmd)) {
                 synchronized(mWindowMap) {
-                    dumpWindowsLocked(fd, pw, true, null);
+                    dumpWindowsLocked(pw, true, null);
                 }
                 return;
             } else {
                 // Dumping a single name?
-                if (!dumpWindows(fd, pw, cmd, args, opti, dumpAll)) {
+                if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {
                     pw.println("Bad window command, or no windows match: " + cmd);
                     pw.println("Use -h for help.");
                 }
@@ -9921,22 +9967,27 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpPolicyLocked(fd, pw, args, dumpAll);
+            dumpPolicyLocked(pw, args, dumpAll);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpSessionsLocked(fd, pw, dumpAll);
+            dumpSessionsLocked(pw, dumpAll);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpTokensLocked(fd, pw, dumpAll);
+            dumpTokensLocked(pw, dumpAll);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpWindowsLocked(fd, pw, dumpAll, null);
+            dumpWindowsLocked(pw, dumpAll, null);
+            pw.println();
+            if (dumpAll) {
+                pw.println("-------------------------------------------------------------------------------");
+            }
+            dumpLastANRLocked(pw);
         }
     }