am 904fb9d7: Merge "Notify people of empty proxies too." into ics-factoryrom

* commit '904fb9d79cc72879e4c6767c219ec78feda8e62b':
  Notify people of empty proxies too.
diff --git a/Android.mk b/Android.mk
index 91850d5..be8c25b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -381,7 +381,7 @@
     -since ./frameworks/base/api/11.xml 11 \
     -since ./frameworks/base/api/12.xml 12 \
     -since ./frameworks/base/api/13.xml 13 \
-    -since ./frameworks/base/api/current.txt ICS \
+    -since ./frameworks/base/api/14.txt 14 \
 		-werror -hide 113 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
@@ -473,7 +473,7 @@
 
 ## SDK version identifiers used in the published docs
   # major[.minor] version for current SDK. (full releases only)
-framework_docs_SDK_VERSION:=3.2
+framework_docs_SDK_VERSION:=4.0
   # release version (ie "Release x")  (full releases only)
 framework_docs_SDK_REL_ID:=1
 
diff --git a/build/phone-xhdpi-1024-dalvik-heap.mk b/build/phone-xhdpi-1024-dalvik-heap.mk
new file mode 100644
index 0000000..f76535a
--- /dev/null
+++ b/build/phone-xhdpi-1024-dalvik-heap.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Provides overrides to configure the Dalvik heap for a standard tablet device.
+
+PRODUCT_PROPERTY_OVERRIDES += \
+    dalvik.vm.heapstartsize=8m \
+    dalvik.vm.heapgrowthlimit=64m \
+    dalvik.vm.heapsize=256m
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2c2a493..0776e10 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -153,6 +153,7 @@
     final HashMap<IBinder, Service> mServices
             = new HashMap<IBinder, Service>();
     AppBindData mBoundApplication;
+    Profiler mProfiler;
     Configuration mConfiguration;
     Configuration mCompatConfiguration;
     Configuration mResConfiguration;
@@ -364,10 +365,6 @@
         ApplicationInfo appInfo;
         List<ProviderInfo> providers;
         ComponentName instrumentationName;
-        String profileFile;
-        ParcelFileDescriptor profileFd;
-        boolean autoStopProfiler;
-        boolean profiling;
         Bundle instrumentationArgs;
         IInstrumentationWatcher instrumentationWatcher;
         int debugMode;
@@ -375,10 +372,23 @@
         boolean persistent;
         Configuration config;
         CompatibilityInfo compatInfo;
-        boolean handlingProfiling;
+
+        /** Initial values for {@link Profiler}. */
+        String initProfileFile;
+        ParcelFileDescriptor initProfileFd;
+        boolean initAutoStopProfiler;
+
         public String toString() {
             return "AppBindData{appInfo=" + appInfo + "}";
         }
+    }
+
+    static final class Profiler {
+        String profileFile;
+        ParcelFileDescriptor profileFd;
+        boolean autoStopProfiler;
+        boolean profiling;
+        boolean handlingProfiling;
         public void setProfiler(String file, ParcelFileDescriptor fd) {
             if (profiling) {
                 if (fd != null) {
@@ -661,8 +671,6 @@
             data.appInfo = appInfo;
             data.providers = providers;
             data.instrumentationName = instrumentationName;
-            data.setProfiler(profileFile, profileFd);
-            data.autoStopProfiler = false;
             data.instrumentationArgs = instrumentationArgs;
             data.instrumentationWatcher = instrumentationWatcher;
             data.debugMode = debugMode;
@@ -670,6 +678,9 @@
             data.persistent = persistent;
             data.config = config;
             data.compatInfo = compatInfo;
+            data.initProfileFile = profileFile;
+            data.initProfileFd = profileFd;
+            data.initAutoStopProfiler = false;
             queueOrSendMessage(H.BIND_APPLICATION, data);
         }
 
@@ -1293,8 +1304,8 @@
         public final boolean queueIdle() {
             ActivityClientRecord a = mNewActivities;
             boolean stopProfiling = false;
-            if (mBoundApplication != null && mBoundApplication.profileFd != null
-                    && mBoundApplication.autoStopProfiler) {
+            if (mBoundApplication != null && mProfiler.profileFd != null
+                    && mProfiler.autoStopProfiler) {
                 stopProfiling = true;
             }
             if (a != null) {
@@ -1320,7 +1331,7 @@
                 } while (a != null);
             }
             if (stopProfiling) {
-                mBoundApplication.stopProfiling();
+                mProfiler.stopProfiling();
             }
             ensureJitEnabled();
             return false;
@@ -1635,12 +1646,12 @@
     }
 
     public boolean isProfiling() {
-        return mBoundApplication != null && mBoundApplication.profileFile != null
-                && mBoundApplication.profileFd == null;
+        return mProfiler != null && mProfiler.profileFile != null
+                && mProfiler.profileFd == null;
     }
 
     public String getProfileFilePath() {
-        return mBoundApplication.profileFile;
+        return mProfiler.profileFile;
     }
 
     public Looper getLooper() {
@@ -1679,6 +1690,9 @@
             ContextImpl context = getSystemContext();
             context.init(new LoadedApk(this, "android", context, info,
                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
+
+            // give ourselves a default profiler
+            mProfiler = new Profiler();
         }
     }
 
@@ -1947,9 +1961,9 @@
         unscheduleGcIdler();
 
         if (r.profileFd != null) {
-            mBoundApplication.setProfiler(r.profileFile, r.profileFd);
-            mBoundApplication.startProfiling();
-            mBoundApplication.autoStopProfiler = r.autoStopProfiler;
+            mProfiler.setProfiler(r.profileFile, r.profileFd);
+            mProfiler.startProfiling();
+            mProfiler.autoStopProfiler = r.autoStopProfiler;
         }
 
         if (localLOGV) Slog.v(
@@ -3570,10 +3584,10 @@
                     case 1:
                         ViewDebug.startLooperProfiling(pcd.path, pcd.fd.getFileDescriptor());
                         break;
-                    default:
-                        mBoundApplication.setProfiler(pcd.path, pcd.fd);
-                        mBoundApplication.autoStopProfiler = false;
-                        mBoundApplication.startProfiling();
+                    default:                        
+                        mProfiler.setProfiler(pcd.path, pcd.fd);
+                        mProfiler.autoStopProfiler = false;
+                        mProfiler.startProfiling();
                         break;
                 }
             } catch (RuntimeException e) {
@@ -3592,7 +3606,7 @@
                     ViewDebug.stopLooperProfiling();
                     break;
                 default:
-                    mBoundApplication.stopProfiling();
+                    mProfiler.stopProfiling();
                     break;
             }
         }
@@ -3685,6 +3699,11 @@
         mConfiguration = new Configuration(data.config);
         mCompatConfiguration = new Configuration(data.config);
 
+        mProfiler = new Profiler();
+        mProfiler.profileFile = data.initProfileFile;
+        mProfiler.profileFd = data.initProfileFd;
+        mProfiler.autoStopProfiler = data.initAutoStopProfiler;
+
         // send up app name; do this *before* waiting for debugger
         Process.setArgV0(data.processName);
         android.ddm.DdmHandleAppName.setAppName(data.processName);
@@ -3699,8 +3718,8 @@
             }
         }
 
-        if (data.profileFd != null) {
-            data.startProfiling();
+        if (mProfiler.profileFd != null) {
+            mProfiler.startProfiling();
         }
 
         // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
@@ -3841,10 +3860,10 @@
             mInstrumentation.init(this, instrContext, appContext,
                     new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
 
-            if (data.profileFile != null && !ii.handleProfiling
-                    && data.profileFd == null) {
-                data.handlingProfiling = true;
-                File file = new File(data.profileFile);
+            if (mProfiler.profileFile != null && !ii.handleProfiling
+                    && mProfiler.profileFd == null) {
+                mProfiler.handlingProfiling = true;
+                File file = new File(mProfiler.profileFile);
                 file.getParentFile().mkdirs();
                 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
             }
@@ -3896,8 +3915,8 @@
 
     /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
         IActivityManager am = ActivityManagerNative.getDefault();
-        if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling
-                && mBoundApplication.profileFd == null) {
+        if (mProfiler.profileFile != null && mProfiler.handlingProfiling
+                && mProfiler.profileFd == null) {
             Debug.stopMethodTracing();
         }
         //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 5c4cc87..3290b9d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -338,7 +338,7 @@
 
     /**
      * Column name for suggestions cursor. <i>Optional.</i> This column may be
-     * used to specify the time in (@link System#currentTimeMillis
+     * used to specify the time in {@link System#currentTimeMillis
      * System.currentTImeMillis()} (wall time in UTC) when an item was last
      * accessed within the results-providing application. If set, this may be
      * used to show more-recently-used items first.
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index 10386f8..4fe54c0 100644
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -144,6 +144,8 @@
     /** Number of key widths from current touch point to search for nearest keys. */
     private static float SEARCH_DISTANCE = 1.8f;
 
+    private ArrayList<Row> rows = new ArrayList<Row>();
+
     /**
      * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. 
      * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
@@ -164,6 +166,9 @@
         public int defaultHorizontalGap;
         /** Vertical gap following this row. */
         public int verticalGap;
+
+        ArrayList<Key> mKeys = new ArrayList<Key>();
+
         /**
          * Edge flags for this row of keys. Possible values that can be assigned are
          * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM}  
@@ -256,7 +261,7 @@
         public CharSequence text;
         /** Popup characters */
         public CharSequence popupCharacters;
-        
+
         /** 
          * Flags that specify the anchoring to edges of the keyboard for detecting touch events
          * that are just out of the boundary of the key. This is a bit mask of 
@@ -596,11 +601,44 @@
             column++;
             x += key.width + key.gap;
             mKeys.add(key);
+            row.mKeys.add(key);
             if (x > mTotalWidth) {
                 mTotalWidth = x;
             }
         }
-        mTotalHeight = y + mDefaultHeight; 
+        mTotalHeight = y + mDefaultHeight;
+        rows.add(row);
+    }
+
+    final void resize(int newWidth, int newHeight) {
+        int numRows = rows.size();
+        for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
+            Row row = rows.get(rowIndex);
+            int numKeys = row.mKeys.size();
+            int totalGap = 0;
+            int totalWidth = 0;
+            for (int keyIndex = 0; keyIndex < numKeys; ++keyIndex) {
+                Key key = row.mKeys.get(keyIndex);
+                if (keyIndex > 0) {
+                    totalGap += key.gap;
+                }
+                totalWidth += key.width;
+            }
+            if (totalGap + totalWidth > newWidth) {
+                int x = 0;
+                float scaleFactor = (float)(newWidth - totalGap) / totalWidth;
+                for (int keyIndex = 0; keyIndex < numKeys; ++keyIndex) {
+                    Key key = row.mKeys.get(keyIndex);
+                    key.width *= scaleFactor;
+                    key.x = x;
+                    x += key.width + key.gap;
+                }
+            }
+        }
+        mTotalWidth = newWidth;
+        // TODO: This does not adjust the vertical placement according to the new size.
+        // The main problem in the previous code was horizontal placement/size, but we should
+        // also recalculate the vertical sizes/positions when we get this resize call.
     }
     
     public List<Key> getKeys() {
@@ -749,7 +787,7 @@
         Row currentRow = null;
         Resources res = context.getResources();
         boolean skipRow = false;
-        
+
         try {
             int event;
             while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) {
@@ -759,6 +797,7 @@
                         inRow = true;
                         x = 0;
                         currentRow = createRowFromXml(res, parser);
+                        rows.add(currentRow);
                         skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode;
                         if (skipRow) {
                             skipToEndOfRow(parser);
@@ -781,6 +820,7 @@
                         } else if (key.codes[0] == KEYCODE_ALT) {
                             mModifierKeys.add(key);
                         }
+                        currentRow.mKeys.add(key);
                     } else if (TAG_KEYBOARD.equals(tag)) {
                         parseKeyboardAttributes(res, parser);
                     }
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 05444f6..1119c1e 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -376,6 +376,7 @@
         initGestureDetector();
     }
 
+
     private void initGestureDetector() {
         mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
             @Override
@@ -615,6 +616,9 @@
     @Override
     public void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
+        if (mKeyboard != null) {
+            mKeyboard.resize(w, h);
+        }
         // Release the buffer, if any and it will be reallocated on the next draw
         mBuffer = null;
     }
diff --git a/core/java/android/net/DhcpInfoInternal.java b/core/java/android/net/DhcpInfoInternal.java
index 9b0a2d7..fa77bc5 100644
--- a/core/java/android/net/DhcpInfoInternal.java
+++ b/core/java/android/net/DhcpInfoInternal.java
@@ -24,6 +24,7 @@
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
@@ -41,14 +42,18 @@
     public String serverAddress;
     public int leaseDuration;
 
-    private Collection<RouteInfo> routes;
+    private Collection<RouteInfo> mRoutes;
 
     public DhcpInfoInternal() {
-        routes = new ArrayList<RouteInfo>();
+        mRoutes = new ArrayList<RouteInfo>();
     }
 
     public void addRoute(RouteInfo routeInfo) {
-        routes.add(routeInfo);
+        mRoutes.add(routeInfo);
+    }
+
+    public Collection<RouteInfo> getRoutes() {
+        return Collections.unmodifiableCollection(mRoutes);
     }
 
     private int convertToInt(String addr) {
@@ -66,7 +71,7 @@
     public DhcpInfo makeDhcpInfo() {
         DhcpInfo info = new DhcpInfo();
         info.ipAddress = convertToInt(ipAddress);
-        for (RouteInfo route : routes) {
+        for (RouteInfo route : mRoutes) {
             if (route.isDefaultRoute()) {
                 info.gateway = convertToInt(route.getGateway().getHostAddress());
                 break;
@@ -94,14 +99,14 @@
     public LinkProperties makeLinkProperties() {
         LinkProperties p = new LinkProperties();
         p.addLinkAddress(makeLinkAddress());
-        for (RouteInfo route : routes) {
+        for (RouteInfo route : mRoutes) {
             p.addRoute(route);
         }
+        //if empty, connectivity configures default DNS
         if (TextUtils.isEmpty(dns1) == false) {
             p.addDns(NetworkUtils.numericToInetAddress(dns1));
         } else {
-            p.addDns(NetworkUtils.numericToInetAddress(serverAddress));
-            Log.d(TAG, "empty dns1, use dhcp server as dns1!");
+            Log.d(TAG, "makeLinkProperties with empty dns1!");
         }
         if (TextUtils.isEmpty(dns2) == false) {
             p.addDns(NetworkUtils.numericToInetAddress(dns2));
@@ -111,11 +116,33 @@
         return p;
     }
 
+    /* Updates the DHCP fields that need to be retained from
+     * original DHCP request if the DHCP renewal shows them as
+     * being empty
+     */
+    public void updateFromDhcpRequest(DhcpInfoInternal orig) {
+        if (orig == null) return;
+
+        if (TextUtils.isEmpty(dns1)) {
+            dns1 = orig.dns1;
+        }
+
+        if (TextUtils.isEmpty(dns2)) {
+            dns2 = orig.dns2;
+        }
+
+        if (mRoutes.size() == 0) {
+            for (RouteInfo route : orig.getRoutes()) {
+                addRoute(route);
+            }
+        }
+    }
+
     public String toString() {
         String routeString = "";
-        for (RouteInfo route : routes) routeString += route.toString() + " | ";
+        for (RouteInfo route : mRoutes) routeString += route.toString() + " | ";
         return "addr: " + ipAddress + "/" + prefixLength +
-                " routes: " + routeString +
+                " mRoutes: " + routeString +
                 " dns: " + dns1 + "," + dns2 +
                 " dhcpServer: " + serverAddress +
                 " leaseDuration: " + leaseDuration;
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 445b2f7..79c9395 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -63,6 +63,9 @@
     private PowerManager.WakeLock mDhcpRenewWakeLock;
     private static final String WAKELOCK_TAG = "DHCP";
 
+    //Remember DHCP configuration from first request
+    private DhcpInfoInternal mDhcpInfo;
+
     private static final int DHCP_RENEW = 0;
     private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
 
@@ -335,9 +338,11 @@
         if (dhcpAction == DhcpAction.START) {
             Log.d(TAG, "DHCP request on " + mInterfaceName);
             success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
+            mDhcpInfo = dhcpInfoInternal;
         } else if (dhcpAction == DhcpAction.RENEW) {
             Log.d(TAG, "DHCP renewal on " + mInterfaceName);
             success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
+            dhcpInfoInternal.updateFromDhcpRequest(mDhcpInfo);
         }
 
         if (success) {
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 5da3114..5f111eb 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -283,6 +283,17 @@
          */
         public static final String IS_DRM = "is_drm";
 
+        /**
+         * The width of the image/video in pixels.
+         * @hide
+         */
+        public static final String WIDTH = "width";
+
+        /**
+         * The height of the image/video in pixels.
+         * @hide
+         */
+        public static final String HEIGHT = "height";
      }
 
     /**
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index 3f9b945..106a801 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -35,44 +35,39 @@
      * Y position.
      */
     public static void scrollTo(TextView widget, Layout layout, int x, int y) {
-        int padding = widget.getTotalPaddingTop() +
-                      widget.getTotalPaddingBottom();
-        int top = layout.getLineForVertical(y);
-        int bottom = layout.getLineForVertical(y + widget.getHeight() -
-                                               padding);
+        final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
+        final int top = layout.getLineForVertical(y);
+        final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding);
 
         int left = Integer.MAX_VALUE;
         int right = 0;
-        Alignment a = null;
-        boolean ltr = true;
+        Alignment a = layout.getParagraphAlignment(top);
+        boolean ltr = layout.getParagraphDirection(top) > 0;
 
         for (int i = top; i <= bottom; i++) {
             left = (int) Math.min(left, layout.getLineLeft(i));
             right = (int) Math.max(right, layout.getLineRight(i));
-
-            if (a == null) {
-                a = layout.getParagraphAlignment(i);
-                ltr = layout.getParagraphDirection(i) > 0;
-            }
         }
 
-        padding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight();
-        int width = widget.getWidth();
-        int diff = 0;
+        final int hoizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight();
+        final int availableWidth = widget.getWidth() - hoizontalPadding;
+        final int actualWidth = right - left;
 
-        // align_opposite does NOT mean align_right, we need the paragraph
-        // direction to resolve it to left or right
-        if (right - left < width - padding) {
+        if (actualWidth < availableWidth) {
             if (a == Alignment.ALIGN_CENTER) {
-                diff = (width - padding - (right - left)) / 2;
-            } else if (ltr == (a == Alignment.ALIGN_OPPOSITE)) {
-                diff = width - padding - (right - left);
+                x = left - ((availableWidth - actualWidth) / 2);
+            } else if ((ltr && (a == Alignment.ALIGN_OPPOSITE)) || (a == Alignment.ALIGN_RIGHT)) {
+                // align_opposite does NOT mean align_right, we need the paragraph
+                // direction to resolve it to left or right
+                x = left - (availableWidth - actualWidth);
+            } else {
+                x = left;
             }
+        } else {
+            x = Math.min(x, right - availableWidth);
+            x = Math.max(x, left);
         }
 
-        x = Math.min(x, right - (width - padding) - diff);
-        x = Math.max(x, left - diff);
-
         widget.scrollTo(x, y);
     }
 
diff --git a/core/java/android/view/ActionProvider.java b/core/java/android/view/ActionProvider.java
index 5601dc5..ed976ab 100644
--- a/core/java/android/view/ActionProvider.java
+++ b/core/java/android/view/ActionProvider.java
@@ -58,6 +58,7 @@
  * @see MenuItem#getActionProvider()
  */
 public abstract class ActionProvider {
+    private SubUiVisibilityListener mSubUiVisibilityListener;
 
     /**
      * Creates a new instance.
@@ -138,4 +139,31 @@
      */
     public void onPrepareSubMenu(SubMenu subMenu) {
     }
+
+    /**
+     * Notify the system that the visibility of an action view's sub-UI such as
+     * an anchored popup has changed. This will affect how other system
+     * visibility notifications occur.
+     *
+     * @hide Pending future API approval
+     */
+    public void subUiVisibilityChanged(boolean isVisible) {
+        if (mSubUiVisibilityListener != null) {
+            mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible);
+        }
+    }
+
+    /**
+     * @hide Internal use only
+     */
+    public void setSubUiVisibilityListener(SubUiVisibilityListener listener) {
+        mSubUiVisibilityListener = listener;
+    }
+
+    /**
+     * @hide Internal use only
+     */
+    public interface SubUiVisibilityListener {
+        public void onSubUiVisibilityChanged(boolean isVisible);
+    }
 }
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0dc781f..55c821d 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -23,6 +23,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Point;
+import android.os.IRemoteCallback;
 import android.view.IApplicationToken;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -162,15 +163,13 @@
 
     // These can only be called with the SET_ORIENTATION permission.
     /**
-     * Change the current screen rotation, constants as per
-     * {@link android.view.Surface}.
-     * @param rotation the intended rotation.
+     * Update the current screen rotation based on the current state of
+     * the world.
      * @param alwaysSendConfiguration Flag to force a new configuration to
      * be evaluated.  This can be used when there are other parameters in
      * configuration that are changing.
-     * @param animFlags Animation flags as per {@link android.view.Surface}.
      */
-    void setRotation(int rotation, boolean alwaysSendConfiguration, int animFlags);
+    void updateRotation(boolean alwaysSendConfiguration);
 
     /**
      * Retrieve the current screen orientation, constants as per
@@ -220,7 +219,7 @@
     void setPointerSpeed(int speed);
 
     /**
-     * Block until all windows the window manager knows about have been drawn.
+     * Block until the given window has been drawn to the screen.
      */
-    void waitForAllDrawn();
+    void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
 }
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 3880bc45..64d3d31 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -207,9 +207,6 @@
 
     /** Enable dithering when compositing this surface @hide */
     public static final int SURFACE_DITHER    = 0x04;
-    
-    /** Disable the orientation animation @hide */
-    public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;
 
     // The mSurfaceControl will only be present for Surfaces used by the window
     // server or system processes. When this class is parceled we defer to the
@@ -393,7 +390,7 @@
      * set the orientation of the given display.
      * @param display
      * @param orientation
-     * @param flags
+     * @param flags Currently unused, set to 0.
      * @hide
      */
     public static native   void setOrientation(int display, int orientation, int flags);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c7b59b8..b678c7d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -290,6 +290,13 @@
     private static final int FLAG_SPLIT_MOTION_EVENTS = 0x200000;
 
     /**
+     * When set, this ViewGroup will not dispatch onAttachedToWindow calls
+     * to children when adding new views. This is used to prevent multiple
+     * onAttached calls when a ViewGroup adds children in its own onAttached method.
+     */
+    private static final int FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW = 0x400000;
+
+    /**
      * Indicates which types of drawing caches are to be kept in memory.
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
@@ -2154,8 +2161,12 @@
      */
     @Override
     void dispatchAttachedToWindow(AttachInfo info, int visibility) {
+        mGroupFlags |= FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW;
         super.dispatchAttachedToWindow(info, visibility);
+        mGroupFlags &= ~FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW;
+
         visibility |= mViewFlags & VISIBILITY_MASK;
+
         final int count = mChildrenCount;
         final View[] children = mChildren;
         for (int i = 0; i < count; i++) {
@@ -3321,7 +3332,7 @@
         }
 
         AttachInfo ai = mAttachInfo;
-        if (ai != null) {
+        if (ai != null && (mGroupFlags & FLAG_PREVENT_DISPATCH_ATTACHED_TO_WINDOW) == 0) {
             boolean lastKeepOn = ai.mKeepScreenOn;
             ai.mKeepScreenOn = false;
             child.dispatchAttachedToWindow(mAttachInfo, (mViewFlags&VISIBILITY_MASK));
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4611984..9cb4e5e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1054,7 +1054,6 @@
                     || attachInfo.mSystemUiVisibility != oldVis
                     || attachInfo.mHasSystemUiListeners) {
                 params = lp;
-                windowAttributesChanges |= WindowManager.LayoutParams.BUFFER_CHANGED;
             }
         }
 
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index fb87e23..122865e 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -34,10 +34,12 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
+import android.os.RemoteException;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
 import android.util.Log;
+import android.view.WindowManager.LayoutParams;
 import android.widget.ImageView;
 import android.widget.SeekBar;
 import android.widget.SeekBar.OnSeekBarChangeListener;
@@ -175,20 +177,8 @@
         View view = mView = inflater.inflate(R.layout.volume_adjust, null);
         mView.setOnTouchListener(new View.OnTouchListener() {
             public boolean onTouch(View v, MotionEvent event) {
-                // Dismiss the dialog if the user touches outside the visible area. This is not
-                // handled by the usual dialog dismissing code because there is a region above
-                // the panel (marginTop) that is still within the dialog.
-                if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                    int x = (int) event.getX();
-                    int y = (int) event.getY();
-                    if (x < mPanel.getLeft() || x > mPanel.getRight() || y < mPanel.getTop()
-                            || y > mPanel.getBottom()) {
-                        forceTimeout();
-                        return true;
-                    }
-                }
                 resetTimeout();
-                return true;
+                return false;
             }
         });
         mPanel = (ViewGroup) mView.findViewById(R.id.visible_panel);
@@ -196,7 +186,15 @@
         mMoreButton = (ImageView) mView.findViewById(R.id.expand_button);
         mDivider = (ImageView) mView.findViewById(R.id.expand_button_divider);
 
-        mDialog = new Dialog(context, R.style.Theme_Panel_Volume);
+        mDialog = new Dialog(context, R.style.Theme_Panel_Volume) {
+            public boolean onTouchEvent(MotionEvent event) {
+                if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                    forceTimeout();
+                    return true;
+                }
+                return false;
+            }
+        };
         mDialog.setTitle("Volume control"); // No need to localize
         mDialog.setContentView(mView);
         mDialog.setOnDismissListener(new OnDismissListener() {
@@ -208,11 +206,17 @@
         // Change some window properties
         Window window = mDialog.getWindow();
         window.setGravity(Gravity.TOP);
-        WindowManager.LayoutParams lp = window.getAttributes();
+        LayoutParams lp = window.getAttributes();
         lp.token = null;
-        lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+        // Offset from the top
+        lp.y = mContext.getResources().getDimensionPixelOffset(
+                com.android.internal.R.dimen.volume_panel_top);
+        lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
+        lp.width = LayoutParams.WRAP_CONTENT;
+        lp.height = LayoutParams.WRAP_CONTENT;
         window.setAttributes(lp);
-        window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+        window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
 
         mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
         mVibrator = new Vibrator();
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 980e454..1dbb083 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -375,12 +375,6 @@
     /** Screen turned off because of proximity sensor */
     public final int OFF_BECAUSE_OF_PROX_SENSOR = 4;
 
-    /**
-     * Magic constant to {@link IWindowManager#setRotation} to not actually
-     * modify the rotation.
-     */
-    public final int USE_LAST_ROTATION = -1000;
-
     /** When not otherwise specified by the activity's screenOrientation, rotation should be
      * determined by the system (that is, using sensors). */
     public final int USER_ROTATION_FREE = 0;
@@ -772,15 +766,26 @@
      */
     public void screenTurnedOff(int why);
 
-    /**
-     * Called after the screen turns on.
-     */
-    public void screenTurnedOn();
+    public interface ScreenOnListener {
+        void onScreenOn();
+    };
 
     /**
-     * Return whether the screen is currently on.
+     * Called when the power manager would like to turn the screen on.
+     * Must call back on the listener to tell it when the higher-level system
+     * is ready for the screen to go on (i.e. the lock screen is shown).
      */
-    public boolean isScreenOn();
+    public void screenTurningOn(ScreenOnListener screenOnListener);
+
+    /**
+     * Return whether the screen is about to turn on or is currently on.
+     */
+    public boolean isScreenOnEarly();
+
+    /**
+     * Return whether the screen is fully turned on.
+     */
+    public boolean isScreenOnFully();
 
     /**
      * Tell the policy that the lid switch has changed state.
@@ -845,22 +850,30 @@
     public boolean inKeyguardRestrictedKeyInputMode();
 
     /**
-     * Given an orientation constant
-     * ({@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE
-     * ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE} or
-     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_PORTRAIT
-     * ActivityInfo.SCREEN_ORIENTATION_PORTRAIT}), return a surface
-     * rotation.
+     * Given an orientation constant, returns the appropriate surface rotation,
+     * taking into account sensors, docking mode, rotation lock, and other factors.
+     *
+     * @param orientation An orientation constant, such as
+     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+     * @param lastRotation The most recently used rotation.
+     * @return The surface rotation to use.
      */
-    public int rotationForOrientationLw(int orientation, int lastRotation,
-            boolean displayEnabled);
-    
+    public int rotationForOrientationLw(int orientation, int lastRotation);
+
     /**
-     * Return the currently locked screen rotation, if any.  Return
-     * Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_180, or
-     * Surface.ROTATION_270 if locked; return -1 if not locked.
+     * Given an orientation constant and a rotation, returns true if the rotation
+     * has compatible metrics to the requested orientation.  For example, if
+     * the application requested landscape and got seascape, then the rotation
+     * has compatible metrics; if the application requested portrait and got landscape,
+     * then the rotation has incompatible metrics; if the application did not specify
+     * a preference, then anything goes.
+     *
+     * @param orientation An orientation constant, such as
+     * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+     * @param rotation The rotation to check.
+     * @return True if the rotation is compatible with the requested orientation.
      */
-    public int getLockedRotationLw();
+    public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation);
 
     /**
      * Called when the system is mostly done booting to determine whether
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 76b47ca..726bf4a 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -118,14 +118,13 @@
 
     /**
      * Gets the current orientation.
-     * @param lastRotation
-     * @return
+     * @return The current rotation, or -1 if unknown.
      */
-    public int getCurrentRotation(int lastRotation) {
+    public int getCurrentRotation() {
         if (mEnabled) {
-            return mSensorEventListener.getCurrentRotation(lastRotation);
+            return mSensorEventListener.getCurrentRotation();
         }
-        return lastRotation;
+        return -1;
     }
 
     /**
@@ -342,8 +341,8 @@
             mOrientationListener = orientationListener;
         }
 
-        public int getCurrentRotation(int lastRotation) {
-            return mRotation != ROTATION_UNKNOWN ? mRotation : lastRotation;
+        public int getCurrentRotation() {
+            return mRotation; // may be -1, if unknown
         }
 
         @Override
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index 01587aa..b06c112 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -223,7 +223,7 @@
         try {
             sService.setSpellCheckerEnabled(enabled);
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in setSpellCheckerSubtype:" + e);
+            Log.e(TAG, "Error in setSpellCheckerEnabled:" + e);
         }
     }
 
@@ -234,7 +234,7 @@
         try {
             return sService.isSpellCheckerEnabled();
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in setSpellCheckerSubtype:" + e);
+            Log.e(TAG, "Error in isSpellCheckerEnabled:" + e);
             return false;
         }
     }
diff --git a/core/java/android/webkit/CookieSyncManager.java b/core/java/android/webkit/CookieSyncManager.java
index 313f755..a699800 100644
--- a/core/java/android/webkit/CookieSyncManager.java
+++ b/core/java/android/webkit/CookieSyncManager.java
@@ -88,6 +88,10 @@
      */
     public static synchronized CookieSyncManager createInstance(
             Context context) {
+        if (context == null) {
+            throw new IllegalArgumentException("Invalid context argument");
+        }
+
         JniUtil.setContext(context);
         Context appContext = context.getApplicationContext();
         if (sRef == null) {
diff --git a/core/java/android/webkit/JniUtil.java b/core/java/android/webkit/JniUtil.java
index ef1641d..7759ff3 100644
--- a/core/java/android/webkit/JniUtil.java
+++ b/core/java/android/webkit/JniUtil.java
@@ -39,25 +39,21 @@
     private static Boolean sUseChromiumHttpStack;
     private static Context sContext;
 
-    private static boolean initialized = false;
-
     private static void checkInitialized() {
-        if (!initialized) {
+        if (sContext == null) {
             throw new IllegalStateException("Call CookieSyncManager::createInstance() or create a webview before using this class");
         }
     }
 
     protected static synchronized void setContext(Context context) {
-        if (initialized)
+        if (sContext != null) {
             return;
+        }
 
         sContext = context.getApplicationContext();
-        initialized = true;
     }
 
     protected static synchronized Context getContext() {
-        if (!initialized)
-            return null;
         return sContext;
     }
 
@@ -68,8 +64,9 @@
     private static synchronized String getDatabaseDirectory() {
         checkInitialized();
 
-        if (sDatabaseDirectory == null)
+        if (sDatabaseDirectory == null) {
             sDatabaseDirectory = sContext.getDatabasePath("dummy").getParent();
+        }
 
         return sDatabaseDirectory;
     }
@@ -81,8 +78,9 @@
     private static synchronized String getCacheDirectory() {
         checkInitialized();
 
-        if (sCacheDirectory == null)
+        if (sCacheDirectory == null) {
             sCacheDirectory = sContext.getCacheDir().getAbsolutePath();
+        }
 
         return sCacheDirectory;
     }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 600c899..47629c4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -644,7 +644,7 @@
     private Drawable mSelectHandleLeft;
     private Drawable mSelectHandleRight;
 
-    static final boolean USE_WEBKIT_RINGS = true;
+    static final boolean USE_WEBKIT_RINGS = false;
     // the color used to highlight the touch rectangles
     private static final int HIGHLIGHT_COLOR = 0x6633b5e5;
     // the round corner for the highlight path
@@ -730,6 +730,7 @@
     static final int SELECT_AT                          = 135;
     static final int SCREEN_ON                          = 136;
     static final int ENTER_FULLSCREEN_VIDEO             = 137;
+    static final int UPDATE_SELECTION                   = 138;
 
     private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
     private static final int LAST_PACKAGE_MSG_ID = SET_TOUCH_HIGHLIGHT_RECTS;
@@ -1054,6 +1055,10 @@
         super(context, attrs, defStyle);
         checkThread();
 
+        if (context == null) {
+            throw new IllegalArgumentException("Invalid context argument");
+        }
+
         // Used by the chrome stack to find application paths
         JniUtil.setContext(context);
 
@@ -4062,8 +4067,11 @@
         // state.
         // If mNativeClass is 0, we should not reach here, so we do not
         // need to check it again.
+        boolean pressed = (mTouchMode == TOUCH_SHORTPRESS_START_MODE
+                || mTouchMode == TOUCH_INIT_MODE
+                || mTouchMode == TOUCH_SHORTPRESS_MODE);
         nativeRecordButtons(hasFocus() && hasWindowFocus(),
-                (mTouchMode == TOUCH_SHORTPRESS_START_MODE && !USE_WEBKIT_RINGS)
+                (pressed && !USE_WEBKIT_RINGS)
                 || mTrackballDown || mGotCenterDown, false);
         drawCoreAndCursorRing(canvas, mBackgroundColor,
                 mDrawCursorRing && drawRings);
@@ -4280,7 +4288,6 @@
         }
         nativeSetExtendSelection();
         mDrawSelectionPointer = false;
-        mSelectionStarted = true;
         mTouchMode = TOUCH_DRAG_MODE;
         return true;
     }
@@ -6532,6 +6539,8 @@
         mLastTouchTime = eventTime;
         mVelocityTracker = VelocityTracker.obtain();
         mSnapScrollMode = SNAP_NONE;
+        mPrivateHandler.sendEmptyMessageDelayed(UPDATE_SELECTION,
+                ViewConfiguration.getTapTimeout());
     }
 
     private void startDrag() {
@@ -7161,6 +7170,14 @@
     }
 
     /**
+     * Return the overview scale of the WebView
+     * @return The overview scale.
+     */
+    float getZoomOverviewScale() {
+        return mZoomManager.getZoomOverviewScale();
+    }
+
+    /**
      * @return TRUE if the WebView can be zoomed in.
      */
     public boolean canZoomIn() {
@@ -7194,10 +7211,15 @@
         return mZoomManager.zoomOut();
     }
 
+    /**
+     * This selects the best clickable target at mLastTouchX and mLastTouchY
+     * and calls showCursorTimed on the native side
+     */
     private void updateSelection() {
         if (mNativeClass == 0) {
             return;
         }
+        mPrivateHandler.removeMessages(UPDATE_SELECTION);
         // mLastTouchX and mLastTouchY are the point in the current viewport
         int contentX = viewToContentX(mLastTouchX + mScrollX);
         int contentY = viewToContentY(mLastTouchY + mScrollY);
@@ -7297,6 +7319,7 @@
             return;
         }
         mTouchMode = TOUCH_DONE_MODE;
+        updateSelection();
         switchOutDrawHistory();
         // mLastTouchX and mLastTouchY are the point in the current viewport
         int contentX = viewToContentX(mLastTouchX + mScrollX);
@@ -8187,6 +8210,14 @@
                             SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
                     break;
                 }
+                case UPDATE_SELECTION: {
+                    if (mTouchMode == TOUCH_INIT_MODE
+                            || mTouchMode == TOUCH_SHORTPRESS_MODE
+                            || mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
+                        updateSelection();
+                    }
+                    break;
+                }
                 case SWITCH_TO_SHORTPRESS: {
                     mInitialHitTestResult = null; // set by updateSelection()
                     if (mTouchMode == TOUCH_INIT_MODE) {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 48359d44..470e843 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2512,10 +2512,13 @@
     // called by JNI
     private void restoreScale(float scale, float textWrapScale) {
         if (mBrowserFrame.firstLayoutDone() == false) {
-            final float defaultScale = mWebView.getDefaultZoomScale();
-            mRestoredScale = (scale <= 0.0) ? defaultScale : scale;
+            // If restored scale and textWrapScale are 0, set them to
+            // overview and reading level scale respectively.
+            mRestoredScale = (scale <= 0.0)
+                ? mWebView.getZoomOverviewScale() : scale;
             if (mSettings.getUseWideViewPort()) {
-                mRestoredTextWrapScale = (textWrapScale <= 0.0) ? defaultScale : textWrapScale;
+                mRestoredTextWrapScale = (textWrapScale <= 0.0)
+                    ? mWebView.getReadingLevelScale() : textWrapScale;
             }
         }
     }
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 7ca6aeb..7f526e7 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -1128,12 +1128,6 @@
                     mTextWrapScale = Math.max(mTextWrapScale, overviewScale);
                 }
                 reflowText = exceedsMinScaleIncrement(mTextWrapScale, scale);
-            } else {
-                // In case of restored scale, treat defaultScale as overview since
-                // it usually means the previous scale is not saved.
-                if (scale == mDefaultScale && settings.getLoadWithOverviewMode()) {
-                    scale = overviewScale;
-                }
             }
             mInitialZoomOverview = settings.getLoadWithOverviewMode() &&
                     !exceedsMinScaleIncrement(scale, overviewScale);
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 312303d..5841283 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -23,19 +25,16 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
-import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.view.ActionProvider;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.widget.ActivityChooserModel.ActivityChooserModelClient;
 
-import com.android.internal.R;
-
 /**
  * This class is a view for choosing an activity for handling a given {@link Intent}.
  * <p>
@@ -107,6 +106,11 @@
     private final int mListPopupMaxWidth;
 
     /**
+     * The ActionProvider hosting this view, if applicable.
+     */
+    ActionProvider mProvider;
+
+    /**
      * Observer for the model data.
      */
     private final DataSetObserver mModelDataSetOberver = new DataSetObserver() {
@@ -131,6 +135,9 @@
                     getListPopupWindow().dismiss();
                 } else {
                     getListPopupWindow().show();
+                    if (mProvider != null) {
+                        mProvider.subUiVisibilityChanged(true);
+                    }
                 }
             }
         }
@@ -262,6 +269,14 @@
     }
 
     /**
+     * Set the provider hosting this view, if applicable.
+     * @hide Internal use only
+     */
+    public void setProvider(ActionProvider provider) {
+        mProvider = provider;
+    }
+
+    /**
      * Shows the popup window with activities.
      *
      * @return True if the popup was shown, false if already showing.
@@ -299,14 +314,19 @@
 
         ListPopupWindow popupWindow = getListPopupWindow();
         if (!popupWindow.isShowing()) {
-            if (mIsSelectingDefaultActivity) {
-                mAdapter.setShowDefaultActivity(true);
+            final boolean defaultActivityButtonShown =
+                mDefaultActivityButton.getVisibility() == VISIBLE;
+            if (mIsSelectingDefaultActivity || !defaultActivityButtonShown) {
+                mAdapter.setShowDefaultActivity(true, defaultActivityButtonShown);
             } else {
-                mAdapter.setShowDefaultActivity(false);
+                mAdapter.setShowDefaultActivity(false, false);
             }
             final int contentWidth = Math.min(mAdapter.measureContentWidth(), mListPopupMaxWidth);
             popupWindow.setContentWidth(contentWidth);
             popupWindow.show();
+            if (mProvider != null) {
+                mProvider.subUiVisibilityChanged(true);
+            }
         }
     }
 
@@ -476,8 +496,10 @@
                             mAdapter.getDataModel().setDefaultActivity(position);
                         }
                     } else {
-                        // The first item in the model is default action => adjust index
-                        Intent launchIntent  = mAdapter.getDataModel().chooseActivity(position + 1);
+                        // If the default target is not shown in the list, the first
+                        // item in the model is default action => adjust index
+                        position = mAdapter.getShowDefaultActivity() ? position : position + 1;
+                        Intent launchIntent = mAdapter.getDataModel().chooseActivity(position);
                         if (launchIntent != null) {
                             mContext.startActivity(launchIntent);
                         }
@@ -523,6 +545,9 @@
         // PopUpWindow.OnDismissListener#onDismiss
         public void onDismiss() {
             notifyOnDismissListener();
+            if (mProvider != null) {
+                mProvider.subUiVisibilityChanged(false);
+            }
         }
 
         private void notifyOnDismissListener() {
@@ -553,6 +578,8 @@
 
         private boolean mShowDefaultActivity;
 
+        private boolean mHighlightDefaultActivity;
+
         private boolean mShowFooterView;
 
         public void setDataModel(ActivityChooserModel dataModel) {
@@ -640,7 +667,7 @@
                     TextView titleView = (TextView) convertView.findViewById(R.id.title);
                     titleView.setText(activity.loadLabel(packageManager));
                     // Highlight the default.
-                    if (mShowDefaultActivity && position == 0) {
+                    if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
                         convertView.setActivated(true);
                     } else {
                         convertView.setActivated(false);
@@ -709,11 +736,18 @@
             return mDataModel;
         }
 
-        public void setShowDefaultActivity(boolean showDefaultActivity) {
-            if (mShowDefaultActivity != showDefaultActivity) {
+        public void setShowDefaultActivity(boolean showDefaultActivity,
+                boolean highlightDefaultActivity) {
+            if (mShowDefaultActivity != showDefaultActivity
+                    || mHighlightDefaultActivity != highlightDefaultActivity) {
                 mShowDefaultActivity = showDefaultActivity;
+                mHighlightDefaultActivity = highlightDefaultActivity;
                 notifyDataSetChanged();
             }
         }
+
+        public boolean getShowDefaultActivity() {
+            return mShowDefaultActivity;
+        }
     }
 }
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 72db8e8..5392c2e 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -277,10 +277,11 @@
      *         called, false otherwise is returned.
      */
     public boolean performItemClick(View view, int position, long id) {
-        view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-
         if (mOnItemClickListener != null) {
             playSoundEffect(SoundEffectConstants.CLICK);
+            if (view != null) {
+                view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+            }
             mOnItemClickListener.onItemClick(this, view, position, id);
             return true;
         }
@@ -338,8 +339,10 @@
      */
     public interface OnItemSelectedListener {
         /**
-         * Callback method to be invoked when an item in this view has been
-         * selected.
+         * <p>Callback method to be invoked when an item in this view has been
+         * selected. This callback is invoked only when the newly selected
+         * position is different from the previously selected position or if
+         * there was no selected item.</p>
          *
          * Impelmenters can call getItemAtPosition(position) if they need to access the
          * data associated with the selected item.
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 27610b9f..07523e3 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,8 +16,6 @@
 
 package android.widget;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
@@ -38,6 +36,8 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
+import com.android.internal.R;
+
 
 /**
  * <p>An editable text view that shows completion suggestions automatically
@@ -744,7 +744,6 @@
             if (mFilter != null) {
                 mPopupCanBeUpdated = true;
                 performFiltering(getText(), mLastKeyCode);
-                buildImeCompletions();
             }
         } else {
             // drop down is automatically dismissed when enough characters
@@ -837,10 +836,6 @@
     @Override
     public void onCommitCompletion(CompletionInfo completion) {
         if (isPopupShowing()) {
-            mBlockCompletion = true;
-            replaceText(completion.getText());
-            mBlockCompletion = false;
-
             mPopup.performItemClick(completion.getPosition());
         }
     }
@@ -938,7 +933,8 @@
          */
 
         final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
-        if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
+        final boolean enoughToFilter = enoughToFilter();
+        if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter) {
             if (hasFocus() && hasWindowFocus() && mPopupCanBeUpdated) {
                 showDropDown();
             }
@@ -1049,6 +1045,8 @@
      * <p>Displays the drop down on screen.</p>
      */
     public void showDropDown() {
+        buildImeCompletions();
+
         if (mPopup.getAnchorView() == null) {
             if (mDropDownAnchorId != View.NO_ID) {
                 mPopup.setAnchorView(getRootView().findViewById(mDropDownAnchorId));
@@ -1064,7 +1062,7 @@
         mPopup.show();
         mPopup.getListView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
     }
-    
+
     /**
      * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is
      * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we
@@ -1075,7 +1073,7 @@
     public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
         mPopup.setForceIgnoreOutsideTouch(forceIgnoreOutsideTouch);
     }
-    
+
     private void buildImeCompletions() {
         final ListAdapter adapter = mAdapter;
         if (adapter != null) {
@@ -1090,8 +1088,7 @@
                         realCount++;
                         Object item = adapter.getItem(i);
                         long id = adapter.getItemId(i);
-                        completions[i] = new CompletionInfo(id, i,
-                                convertSelectionToString(item));
+                        completions[i] = new CompletionInfo(id, i, convertSelectionToString(item));
                     }
                 }
                 
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index 1b713c3..9cbe8db 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -339,10 +339,8 @@
         // initialization based on locale
         setCurrentLocale(Locale.getDefault());
 
-        TypedValue calendarViewStyle = new TypedValue();
-        context.getTheme().resolveAttribute(R.attr.calendarViewStyle, calendarViewStyle, true);
-        TypedArray attributesArray = context.obtainStyledAttributes(calendarViewStyle.resourceId,
-                R.styleable.CalendarView);
+        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.CalendarView,
+                R.attr.calendarViewStyle, 0);
         mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
                 DEFAULT_SHOW_WEEK_NUMBER);
         mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
@@ -355,6 +353,9 @@
         if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
             parseDate(DEFAULT_MAX_DATE, mMaxDate);
         }
+        if (mMaxDate.before(mMinDate)) {
+            throw new IllegalArgumentException("Max date cannot be before min date.");
+        }
         mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
                 DEFAULT_SHOWN_WEEK_COUNT);
         mSelectedWeekBackgroundColor = attributesArray.getColor(
@@ -407,9 +408,16 @@
         setUpListView();
         setUpAdapter();
 
-        // go to today now
+        // go to today or whichever is close to today min or max date
         mTempDate.setTimeInMillis(System.currentTimeMillis());
-        goTo(mTempDate, false, true, true);
+        if (mTempDate.before(mMinDate)) {
+            goTo(mMinDate, false, true, true);
+        } else if (mMaxDate.before(mTempDate)) {
+            goTo(mMaxDate, false, true, true);
+        } else {
+            goTo(mTempDate, false, true, true);
+        }
+
         invalidate();
     }
 
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 390002b..ba69288 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -87,19 +87,26 @@
  * layout parameters. When the
  * {@link GridLayout#setUseDefaultMargins(boolean) useDefaultMargins}
  * property is set, default margins around children are automatically
- * allocated based on the child's visual characteristics. Each of the
- * margins so defined may be independently overridden by an assignment
+ * allocated based on the prevailing UI style guide for the platform.
+ * Each of the margins so defined may be independently overridden by an assignment
  * to the appropriate layout parameter.
+ * Default values will generally produce a reasonable spacing between components
+ * but values may change between different releases of the platform.
  *
  * <h4>Excess Space Distribution</h4>
  *
+ * GridLayout's distribution of excess space is based on <em>priority</em>
+ * rather than <em>weight</em>.
+ * <p>
  * A child's ability to stretch is inferred from the alignment properties of
  * its row and column groups (which are typically set by setting the
  * {@link LayoutParams#setGravity(int) gravity} property of the child's layout parameters).
  * If alignment was defined along a given axis then the component
- * is taken as flexible in along that axis. If no alignment was set,
- * the component is instead assumed to be inflexible. Multiple components in
- * the same row or column group are considered to act in <em>parallel</em>. Such a
+ * is taken as <em>flexible</em> in that direction. If no alignment was set,
+ * the component is instead assumed to be <em>inflexible</em>.
+ * <p>
+ * Multiple components in the same row or column group are
+ * considered to act in <em>parallel</em>. Such a
  * group is flexible only if <em>all</em> of the components
  * within it are flexible. Row and column groups that sit either side of a common boundary
  * are instead considered to act in <em>series</em>. The composite group made of these two
@@ -109,6 +116,23 @@
  * gravity. To prevent a column from stretching, ensure that one of the components
  * in the column does not define a gravity.
  * <p>
+ * When the principle of flexibility does not provide complete disambiguation,
+ * GridLayout's algorithms favour rows and columns that are closer to its <em>right</em>
+ * and <em>bottom</em> edges.
+ *
+ * <h5>Limitations</h5>
+ *
+ * GridLayout does not provide support for the principle of <em>weight</em>, as defined in
+ * {@link LinearLayout.LayoutParams#weight}. In general, it is not therefore possible
+ * to configure a GridLayout to distribute excess space in non-trivial proportions between
+ * multiple rows or columns.
+ * <p>
+ * Some common use-cases may nevertheless be accommodated as follows.
+ * To place equal amounts of space around a component in a cell group;
+ * use {@link #CENTER} alignment (or {@link LayoutParams#setGravity(int) gravity}).
+ * For complete control over excess space distribution in a row or column;
+ * use a {@link LinearLayout} subview to hold the components in the associated cell group.
+ * When using either of these techniques, bear in mind that cell groups may be defined to overlap.
  * <p>
  * See {@link GridLayout.LayoutParams} for a full description of the
  * layout parameters used by GridLayout.
@@ -180,9 +204,11 @@
 
     // Misc constants
 
-    private static final String TAG = GridLayout.class.getName();
-    private static boolean DEBUG = false;
-    private static final int PRF = 1;
+    static final String TAG = GridLayout.class.getName();
+    static final boolean DEBUG = false;
+    static final int PRF = 1;
+    static final int MAX_SIZE = 100000;
+    static final int DEFAULT_CONTAINER_MARGIN = 0;
 
     // Defaults
 
@@ -191,8 +217,6 @@
     private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false;
     private static final boolean DEFAULT_ORDER_PRESERVED = true;
     private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
-    private static final int DEFAULT_CONTAINER_MARGIN = 0;
-    private static final int MAX_SIZE = 100000;
 
     // TypedArray indices
 
@@ -206,13 +230,13 @@
 
     // Instance variables
 
-    private final Axis mHorizontalAxis = new Axis(true);
-    private final Axis mVerticalAxis = new Axis(false);
-    private boolean mLayoutParamsValid = false;
-    private int mOrientation = DEFAULT_ORIENTATION;
-    private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
-    private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE;
-    private int mDefaultGap;
+    final Axis horizontalAxis = new Axis(true);
+    final Axis verticalAxis = new Axis(false);
+    boolean layoutParamsValid = false;
+    int orientation = DEFAULT_ORIENTATION;
+    boolean useDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
+    int alignmentMode = DEFAULT_ALIGNMENT_MODE;
+    int defaultGap;
 
     // Constructors
 
@@ -224,7 +248,7 @@
         if (DEBUG) {
             setWillNotDraw(false);
         }
-        mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
+        defaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
@@ -266,13 +290,12 @@
      * @attr ref android.R.styleable#GridLayout_orientation
      */
     public int getOrientation() {
-        return mOrientation;
+        return orientation;
     }
 
     /**
-     * The orientation property does not affect layout. Orientation is used
-     * only to generate default row/column indices when they are not specified
-     * by a component's layout parameters.
+     * Orientation is used only to generate default row/column indices when
+     * they are not specified by a component's layout parameters.
      * <p>
      * The default value of this property is {@link #HORIZONTAL}.
      *
@@ -283,8 +306,9 @@
      * @attr ref android.R.styleable#GridLayout_orientation
      */
     public void setOrientation(int orientation) {
-        if (mOrientation != orientation) {
-            mOrientation = orientation;
+        if (this.orientation != orientation) {
+            this.orientation = orientation;
+            invalidateStructure();
             requestLayout();
         }
     }
@@ -302,13 +326,12 @@
      * @attr ref android.R.styleable#GridLayout_rowCount
      */
     public int getRowCount() {
-        return mVerticalAxis.getCount();
+        return verticalAxis.getCount();
     }
 
     /**
-     * The rowCount property does not affect layout. RowCount is used
-     * only to generate default row/column indices when they are not specified
-     * by a component's layout parameters.
+     * RowCount is used only to generate default row/column indices when
+     * they are not specified by a component's layout parameters.
      *
      * @param rowCount the number of rows
      *
@@ -318,7 +341,9 @@
      * @attr ref android.R.styleable#GridLayout_rowCount
      */
     public void setRowCount(int rowCount) {
-        mVerticalAxis.setCount(rowCount);
+        verticalAxis.setCount(rowCount);
+        invalidateStructure();
+        requestLayout();
     }
 
     /**
@@ -334,13 +359,12 @@
      * @attr ref android.R.styleable#GridLayout_columnCount
      */
     public int getColumnCount() {
-        return mHorizontalAxis.getCount();
+        return horizontalAxis.getCount();
     }
 
     /**
-     * The columnCount property does not affect layout. ColumnCount is used
-     * only to generate default column/column indices when they are not specified
-     * by a component's layout parameters.
+     * ColumnCount is used only to generate default column/column indices when
+     * they are not specified by a component's layout parameters.
      *
      * @param columnCount the number of columns.
      *
@@ -350,7 +374,9 @@
      * @attr ref android.R.styleable#GridLayout_columnCount
      */
     public void setColumnCount(int columnCount) {
-        mHorizontalAxis.setCount(columnCount);
+        horizontalAxis.setCount(columnCount);
+        invalidateStructure();
+        requestLayout();
     }
 
     /**
@@ -364,7 +390,7 @@
      * @attr ref android.R.styleable#GridLayout_useDefaultMargins
      */
     public boolean getUseDefaultMargins() {
-        return mUseDefaultMargins;
+        return useDefaultMargins;
     }
 
     /**
@@ -394,7 +420,7 @@
      * @attr ref android.R.styleable#GridLayout_useDefaultMargins
      */
     public void setUseDefaultMargins(boolean useDefaultMargins) {
-        mUseDefaultMargins = useDefaultMargins;
+        this.useDefaultMargins = useDefaultMargins;
         requestLayout();
     }
 
@@ -411,7 +437,7 @@
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
     public int getAlignmentMode() {
-        return mAlignmentMode;
+        return alignmentMode;
     }
 
     /**
@@ -430,7 +456,7 @@
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
     public void setAlignmentMode(int alignmentMode) {
-        mAlignmentMode = alignmentMode;
+        this.alignmentMode = alignmentMode;
         requestLayout();
     }
 
@@ -445,7 +471,7 @@
      * @attr ref android.R.styleable#GridLayout_rowOrderPreserved
      */
     public boolean isRowOrderPreserved() {
-        return mVerticalAxis.isOrderPreserved();
+        return verticalAxis.isOrderPreserved();
     }
 
     /**
@@ -465,7 +491,7 @@
      * @attr ref android.R.styleable#GridLayout_rowOrderPreserved
      */
     public void setRowOrderPreserved(boolean rowOrderPreserved) {
-        mVerticalAxis.setOrderPreserved(rowOrderPreserved);
+        verticalAxis.setOrderPreserved(rowOrderPreserved);
         invalidateStructure();
         requestLayout();
     }
@@ -481,7 +507,7 @@
      * @attr ref android.R.styleable#GridLayout_columnOrderPreserved
      */
     public boolean isColumnOrderPreserved() {
-        return mHorizontalAxis.isOrderPreserved();
+        return horizontalAxis.isOrderPreserved();
     }
 
     /**
@@ -501,14 +527,14 @@
      * @attr ref android.R.styleable#GridLayout_columnOrderPreserved
      */
     public void setColumnOrderPreserved(boolean columnOrderPreserved) {
-        mHorizontalAxis.setOrderPreserved(columnOrderPreserved);
+        horizontalAxis.setOrderPreserved(columnOrderPreserved);
         invalidateStructure();
         requestLayout();
     }
 
     // Static utility methods
 
-    private static int max2(int[] a, int valueIfEmpty) {
+    static int max2(int[] a, int valueIfEmpty) {
         int result = valueIfEmpty;
         for (int i = 0, N = a.length; i < N; i++) {
             result = Math.max(result, a[i]);
@@ -517,14 +543,14 @@
     }
 
     @SuppressWarnings("unchecked")
-    private static <T> T[] append(T[] a, T[] b) {
+    static <T> T[] append(T[] a, T[] b) {
         T[] result = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
         System.arraycopy(a, 0, result, 0, a.length);
         System.arraycopy(b, 0, result, a.length, b.length);
         return result;
     }
 
-    private static Alignment getAlignment(int gravity, boolean horizontal) {
+    static Alignment getAlignment(int gravity, boolean horizontal) {
         int mask = horizontal ? HORIZONTAL_GRAVITY_MASK : VERTICAL_GRAVITY_MASK;
         int shift = horizontal ? AXIS_X_SHIFT : AXIS_Y_SHIFT;
         int flags = (gravity & mask) >> shift;
@@ -547,7 +573,7 @@
         if (c.getClass() == Space.class) {
             return 0;
         }
-        return mDefaultGap / 2;
+        return defaultGap / 2;
     }
 
     private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
@@ -555,18 +581,18 @@
     }
 
     private int getDefaultMarginValue(View c, LayoutParams p, boolean horizontal, boolean leading) {
-        if (!mUseDefaultMargins) {
+        if (!useDefaultMargins) {
             return 0;
         }
         Spec spec = horizontal ? p.columnSpec : p.rowSpec;
-        Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
+        Axis axis = horizontal ? horizontalAxis : verticalAxis;
         Interval span = spec.span;
         boolean isAtEdge = leading ? (span.min == 0) : (span.max == axis.getCount());
 
         return getDefaultMargin(c, isAtEdge, horizontal, leading);
     }
 
-    private int getMargin1(View view, boolean horizontal, boolean leading) {
+    int getMargin1(View view, boolean horizontal, boolean leading) {
         LayoutParams lp = getLayoutParams(view);
         int margin = horizontal ?
                 (leading ? lp.leftMargin : lp.rightMargin) :
@@ -575,10 +601,10 @@
     }
 
     private int getMargin(View view, boolean horizontal, boolean leading) {
-        if (mAlignmentMode == ALIGN_MARGINS) {
+        if (alignmentMode == ALIGN_MARGINS) {
             return getMargin1(view, horizontal, leading);
         } else {
-            Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
+            Axis axis = horizontal ? horizontalAxis : verticalAxis;
             int[] margins = leading ? axis.getLeadingMargins() : axis.getTrailingMargins();
             LayoutParams lp = getLayoutParams(view);
             Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
@@ -591,10 +617,6 @@
         return getMargin(child, horizontal, true) + getMargin(child, horizontal, false);
     }
 
-    private static int valueIfDefined(int value, int defaultValue) {
-        return (value != UNDEFINED) ? value : defaultValue;
-    }
-
     private static boolean fits(int[] a, int value, int start, int end) {
         if (end > a.length) {
             return false;
@@ -629,9 +651,9 @@
 
     // install default indices for cells that don't define them
     private void validateLayoutParams() {
-        final boolean horizontal = (mOrientation == HORIZONTAL);
-        final int axisCount = horizontal ? mHorizontalAxis.count : mVerticalAxis.count;
-        final int count = valueIfDefined(axisCount, 0);
+        final boolean horizontal = (orientation == HORIZONTAL);
+        final Axis axis = horizontal ? horizontalAxis : verticalAxis;
+        final int count = (axis.definedCount != UNDEFINED) ? axis.definedCount : 0;
 
         int major = 0;
         int minor = 0;
@@ -640,15 +662,17 @@
         for (int i = 0, N = getChildCount(); i < N; i++) {
             LayoutParams lp = getLayoutParams1(getChildAt(i));
 
-            final Interval majorRange = (horizontal ? lp.rowSpec : lp.columnSpec).span;
-            final boolean majorWasDefined = (majorRange.min != UNDEFINED);
+            final Spec majorSpec = horizontal ? lp.rowSpec : lp.columnSpec;
+            final Interval majorRange = majorSpec.span;
+            final boolean majorWasDefined = majorSpec.startDefined;
             final int majorSpan = majorRange.size();
             if (majorWasDefined) {
                 major = majorRange.min;
             }
 
-            final Interval minorRange = (horizontal ? lp.columnSpec : lp.rowSpec).span;
-            final boolean minorWasDefined = (minorRange.min != UNDEFINED);
+            final Spec minorSpec = horizontal ? lp.columnSpec : lp.rowSpec;
+            final Interval minorRange = minorSpec.span;
+            final boolean minorWasDefined = minorSpec.startDefined;
             final int minorSpan = clip(minorRange, minorWasDefined, count);
             if (minorWasDefined) {
                 minor = minorRange.min;
@@ -685,9 +709,9 @@
     }
 
     private void invalidateStructure() {
-        mLayoutParamsValid = false;
-        mHorizontalAxis.invalidateStructure();
-        mVerticalAxis.invalidateStructure();
+        layoutParamsValid = false;
+        horizontalAxis.invalidateStructure();
+        verticalAxis.invalidateStructure();
         // This can end up being done twice. Better twice than not at all.
         invalidateValues();
     }
@@ -695,9 +719,9 @@
     private void invalidateValues() {
         // Need null check because requestLayout() is called in View's initializer,
         // before we are set up.
-        if (mHorizontalAxis != null && mVerticalAxis != null) {
-            mHorizontalAxis.invalidateValues();
-            mVerticalAxis.invalidateValues();
+        if (horizontalAxis != null && verticalAxis != null) {
+            horizontalAxis.invalidateValues();
+            verticalAxis.invalidateValues();
         }
     }
 
@@ -705,10 +729,10 @@
         return (LayoutParams) c.getLayoutParams();
     }
 
-    private LayoutParams getLayoutParams(View c) {
-        if (!mLayoutParamsValid) {
+    final LayoutParams getLayoutParams(View c) {
+        if (!layoutParamsValid) {
             validateLayoutParams();
-            mLayoutParamsValid = true;
+            layoutParamsValid = true;
         }
         return getLayoutParams1(c);
     }
@@ -752,7 +776,7 @@
             paint.setStyle(Paint.Style.STROKE);
             paint.setColor(Color.argb(50, 255, 255, 255));
 
-            int[] xs = mHorizontalAxis.locations;
+            int[] xs = horizontalAxis.locations;
             if (xs != null) {
                 for (int i = 0, length = xs.length; i < length; i++) {
                     int x = xs[i];
@@ -760,7 +784,7 @@
                 }
             }
 
-            int[] ys = mVerticalAxis.locations;
+            int[] ys = verticalAxis.locations;
             if (ys != null) {
                 for (int i = 0, length = ys.length; i < length; i++) {
                     int y = ys[i];
@@ -822,7 +846,7 @@
 
     // Measurement
 
-    private boolean isGone(View c) {
+    final boolean isGone(View c) {
         return c.getVisibility() == View.GONE;
     }
 
@@ -847,8 +871,8 @@
     protected void onMeasure(int widthSpec, int heightSpec) {
         measureChildrenWithMargins(widthSpec, heightSpec);
 
-        int width = getPaddingLeft() + mHorizontalAxis.getMeasure(widthSpec) + getPaddingRight();
-        int height = getPaddingTop() + mVerticalAxis.getMeasure(heightSpec) + getPaddingBottom();
+        int width = getPaddingLeft() + horizontalAxis.getMeasure(widthSpec) + getPaddingRight();
+        int height = getPaddingTop() + verticalAxis.getMeasure(heightSpec) + getPaddingBottom();
 
         int measuredWidth = Math.max(width, getSuggestedMinimumWidth());
         int measuredHeight = Math.max(height, getSuggestedMinimumHeight());
@@ -866,7 +890,7 @@
         return horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
     }
 
-    private int getMeasurementIncludingMargin(View c, boolean horizontal) {
+    final int getMeasurementIncludingMargin(View c, boolean horizontal) {
         if (isGone(c)) {
             return 0;
         }
@@ -879,7 +903,7 @@
         invalidateValues();
     }
 
-    private Alignment getAlignment(Alignment alignment, boolean horizontal) {
+    final Alignment getAlignment(Alignment alignment, boolean horizontal) {
         return (alignment != UNDEFINED_ALIGNMENT) ? alignment :
                 (horizontal ? LEFT : BASELINE);
     }
@@ -908,11 +932,11 @@
         int paddingRight = getPaddingRight();
         int paddingBottom = getPaddingBottom();
 
-        mHorizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
-        mVerticalAxis.layout(targetHeight - paddingTop - paddingBottom);
+        horizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
+        verticalAxis.layout(targetHeight - paddingTop - paddingBottom);
 
-        int[] hLocations = mHorizontalAxis.getLocations();
-        int[] vLocations = mVerticalAxis.getLocations();
+        int[] hLocations = horizontalAxis.getLocations();
+        int[] vLocations = verticalAxis.getLocations();
 
         for (int i = 0, N = getChildCount(); i < N; i++) {
             View c = getChildAt(i);
@@ -941,8 +965,8 @@
 
             int dx, dy;
 
-            Bounds colBounds = mHorizontalAxis.getGroupBounds().getValue(i);
-            Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i);
+            Bounds colBounds = horizontalAxis.getGroupBounds().getValue(i);
+            Bounds rowBounds = verticalAxis.getGroupBounds().getValue(i);
 
             // Gravity offsets: the location of the alignment group relative to its cell group.
             //noinspection NullableProblems
@@ -990,7 +1014,7 @@
      distinguished by the "horizontal" flag which is true for the horizontal axis and false
      for the vertical one.
      */
-    private class Axis {
+    final class Axis {
         private static final int MIN_VALUE = -1000000;
 
         private static final int NEW = 0;
@@ -999,9 +1023,8 @@
 
         public final boolean horizontal;
 
-        public int count = UNDEFINED;
-        public boolean countValid = false;
-        public boolean countWasExplicitySet = false;
+        public int definedCount = UNDEFINED;
+        private int inferredCount = UNDEFINED;
 
         PackedMap<Spec, Bounds> groupBounds;
         public boolean groupBoundsValid = false;
@@ -1024,7 +1047,7 @@
         public int[] locations;
         public boolean locationsValid = false;
 
-        private boolean mOrderPreserved = DEFAULT_ORDER_PRESERVED;
+        boolean orderPreserved = DEFAULT_ORDER_PRESERVED;
 
         private MutableInt parentMin = new MutableInt(0);
         private MutableInt parentMax = new MutableInt(-MAX_SIZE);
@@ -1046,25 +1069,27 @@
             return count == -1 ? UNDEFINED : count;
         }
 
-        public int getCount() {
-            if (!countValid) {
-                count = max(0, maxIndex()); // if there are no cells, the count is zero
-                countValid = true;
+        private int getInferredCount() {
+            if (inferredCount == UNDEFINED) {
+                inferredCount = max(0, maxIndex()); // if there are no cells, actual count is zero
             }
-            return count;
+            return inferredCount;
+        }
+
+        public int getCount() {
+            return max(definedCount, getInferredCount());
         }
 
         public void setCount(int count) {
-            this.count = count;
-            this.countWasExplicitySet = count != UNDEFINED;
+            this.definedCount = count;
         }
 
         public boolean isOrderPreserved() {
-            return mOrderPreserved;
+            return orderPreserved;
         }
 
         public void setOrderPreserved(boolean orderPreserved) {
-            mOrderPreserved = orderPreserved;
+            this.orderPreserved = orderPreserved;
             invalidateStructure();
         }
 
@@ -1093,7 +1118,7 @@
             }
         }
 
-        private PackedMap<Spec, Bounds> getGroupBounds() {
+        public PackedMap<Spec, Bounds> getGroupBounds() {
             if (groupBounds == null) {
                 groupBounds = createGroupBounds();
             }
@@ -1183,7 +1208,7 @@
 
         // Group arcs by their first vertex, returning an array of arrays.
         // This is linear in the number of arcs.
-        private Arc[][] groupArcsByFirstVertex(Arc[] arcs) {
+        Arc[][] groupArcsByFirstVertex(Arc[] arcs) {
             int N = getCount() + 1; // the number of vertices
             Arc[][] result = new Arc[N][];
             int[] sizes = new int[N];
@@ -1262,7 +1287,7 @@
             addComponentSizes(maxs, getBackwardLinks());
 
             // Add ordering constraints to prevent row/col sizes from going negative
-            if (mOrderPreserved) {
+            if (orderPreserved) {
                 // Add a constraint for every row/col
                 for (int i = 0; i < getCount(); i++) {
                     include(mins, new Interval(i, i + 1), new MutableInt(0));
@@ -1315,6 +1340,48 @@
             return false;
         }
 
+        private void init(int[] locations) {
+            Arrays.fill(locations, MIN_VALUE);
+            locations[0] = 0;
+        }
+
+        private String arcsToString(List<Arc> arcs) {
+            String var = horizontal ? "c" : "r";
+            StringBuilder result = new StringBuilder();
+            boolean first = false;
+            for(Arc arc : arcs) {
+                if (!first) {
+                    first = true;
+                } else {
+                    result =result.append(", ");
+                }
+                int src = arc.span.min;
+                int dst = arc.span.max;
+                int value = arc.value.value;
+                result.append((src < dst) ?
+                        var + dst + " - " + var + src + " > " + value :
+                        var + src + " - " + var + dst + " < " + -value);
+
+            }
+            return result.toString();
+        }
+
+        private void logError(String axisName, Arc[] arcs, boolean[] culprits0) {
+            List<Arc> culprits = new ArrayList<Arc>();
+            List<Arc> removed = new ArrayList<Arc>();
+            for (int c = 0; c < arcs.length; c++) {
+                Arc arc = arcs[c];
+                if (culprits0[c]) {
+                    culprits.add(arc);
+                }
+                if (!arc.valid) {
+                    removed.add(arc);
+                }
+            }
+            Log.d(TAG, axisName + " constraints: " + arcsToString(culprits) + " are inconsistent; "
+                    + "permanently removing: " + arcsToString(removed) + ". ");
+        }
+
         /*
         Bellman-Ford variant - modified to reduce typical running time from O(N^2) to O(N)
 
@@ -1350,51 +1417,54 @@
         completes in O(N) steps with very low constants.
         */
         private void solve(Arc[] arcs, int[] locations) {
-            String axis = horizontal ? "horizontal" : "vertical";
+            String axisName = horizontal ? "horizontal" : "vertical";
             int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1.
+            boolean[] originalCulprits = null;
 
-            // We take one extra pass over traditional Bellman-Ford (and omit their final step)
-            for (int i = 0; i < N; i++) {
-                boolean changed = false;
-                for (int j = 0, length = arcs.length; j < length; j++) {
-                    changed |= relax(locations, arcs[j]);
-                }
-                if (!changed) {
-                    if (DEBUG) {
-                        Log.v(TAG, axis + " iteration completed in " + (1 + i) + " steps of " + N);
+            for (int p = 0; p < arcs.length; p++) {
+                init(locations);
+
+                // We take one extra pass over traditional Bellman-Ford (and omit their final step)
+                for (int i = 0; i < N; i++) {
+                    boolean changed = false;
+                    for (int j = 0, length = arcs.length; j < length; j++) {
+                        changed |= relax(locations, arcs[j]);
                     }
-                    return;
-                }
-            }
-
-            Log.d(TAG, "The " + axis + " constraints contained a contradiction. Resolving... ");
-            Log.d(TAG, Arrays.toString(arcs));
-
-            boolean[] culprits = new boolean[arcs.length];
-            for (int i = 0; i < N; i++) {
-                for (int j = 0, length = arcs.length; j < length; j++) {
-                    culprits[j] |= relax(locations, arcs[j]);
-                }
-            }
-            for (int i = 0; i < culprits.length; i++) {
-                if (culprits[i]) {
-                    Arc arc = arcs[i];
-                    // Only remove max values, min values alone cannot be inconsistent
-                    if (arc.span.min < arc.span.max) {
-                        continue;
+                    if (!changed) {
+                        if (originalCulprits != null) {
+                            logError(axisName, arcs, originalCulprits);
+                        }
+                        if (DEBUG) {
+                            Log.v(TAG, axisName + " iteration completed in " +
+                                    (1 + i) + " steps of " + N);
+                        }
+                        return;
                     }
-                    Log.d(TAG, "Removing: " + arc);
-                    arc.valid = false;
-                    break;
+                }
+
+                boolean[] culprits = new boolean[arcs.length];
+                for (int i = 0; i < N; i++) {
+                    for (int j = 0, length = arcs.length; j < length; j++) {
+                        culprits[j] |= relax(locations, arcs[j]);
+                    }
+                }
+
+                if (p == 0) {
+                    originalCulprits = culprits;
+                }
+
+                for (int i = 0; i < arcs.length; i++) {
+                    if (culprits[i]) {
+                        Arc arc = arcs[i];
+                        // Only remove max values, min values alone cannot be inconsistent
+                        if (arc.span.min < arc.span.max) {
+                            continue;
+                        }
+                        arc.valid = false;
+                        break;
+                    }
                 }
             }
-            solve1(arcs, locations);
-        }
-
-        private void solve1(Arc[] arcs, int[] a) {
-            Arrays.fill(a, MIN_VALUE);
-            a[0] = 0;
-            solve(arcs, a);
         }
 
         private void computeMargins(boolean leading) {
@@ -1410,7 +1480,9 @@
             }
         }
 
-        private int[] getLeadingMargins() {
+        // External entry points
+
+        public int[] getLeadingMargins() {
             if (leadingMargins == null) {
                 leadingMargins = new int[getCount() + 1];
             }
@@ -1421,7 +1493,7 @@
             return leadingMargins;
         }
 
-        private int[] getTrailingMargins() {
+        public int[] getTrailingMargins() {
             if (trailingMargins == null) {
                 trailingMargins = new int[getCount() + 1];
             }
@@ -1433,10 +1505,10 @@
         }
 
         private void computeLocations(int[] a) {
-            solve1(getArcs(), a);
+            solve(getArcs(), a);
         }
 
-        private int[] getLocations() {
+        public int[] getLocations() {
             if (locations == null) {
                 int N = getCount() + 1;
                 locations = new int[N];
@@ -1448,8 +1520,6 @@
             return locations;
         }
 
-        // External entry points
-
         private int size(int[] locations) {
             return max2(locations, 0) - locations[0];
         }
@@ -1465,7 +1535,7 @@
             return size(getLocations());
         }
 
-        private int getMeasure(int measureSpec) {
+        public int getMeasure(int measureSpec) {
             int mode = MeasureSpec.getMode(measureSpec);
             int size = MeasureSpec.getSize(measureSpec);
             switch (mode) {
@@ -1485,13 +1555,13 @@
             }
         }
 
-        private void layout(int size) {
+        public void layout(int size) {
             setParentConstraints(size, size);
             getLocations();
         }
 
-        private void invalidateStructure() {
-            countValid = false;
+        public void invalidateStructure() {
+            inferredCount = UNDEFINED;
 
             groupBounds = null;
             forwardLinks = null;
@@ -1506,7 +1576,7 @@
             invalidateValues();
         }
 
-        private void invalidateValues() {
+        public void invalidateValues() {
             groupBoundsValid = false;
             forwardLinksValid = false;
             backwardLinksValid = false;
@@ -1536,9 +1606,22 @@
      * both aspects of alignment within the cell group. It is also possible to specify a child's
      * alignment within its cell group by using the {@link GridLayout.LayoutParams#setGravity(int)}
      * method.
-     * <p>
-     * See {@link GridLayout} for a description of the conventions used by GridLayout
-     * in reference to grid indices.
+     *
+     * <h4>WRAP_CONTENT and MATCH_PARENT</h4>
+     *
+     * Because the default values of the {@link #width} and {@link #height}
+     * properties are both {@link #WRAP_CONTENT}, this value never needs to be explicitly
+     * declared in the layout parameters of GridLayout's children. In addition,
+     * GridLayout does not distinguish the special size value {@link #MATCH_PARENT} from
+     * {@link #WRAP_CONTENT}. A component's ability to expand to the size of the parent is
+     * instead controlled by the principle of <em>flexibility</em>,
+     * as discussed in {@link GridLayout}.
+     *
+     * <h4>Summary</h4>
+     *
+     * You should not need to use either of the special size values:
+     * {@code WRAP_CONTENT} or {@code MATCH_PARENT} when configuring the children of
+     * a GridLayout.
      *
      * <h4>Default values</h4>
      *
@@ -1561,12 +1644,17 @@
      *          {@link GridLayout#setUseDefaultMargins(boolean) useDefaultMargins} is
      *          {@code false}; otherwise {@link #UNDEFINED}, to
      *          indicate that a default value should be computed on demand. </li>
-     *     <li>{@link #rowSpec}{@code .span} = {@code [0, 1]} </li>
-     *     <li>{@link #rowSpec}{@code .alignment} = {@link #BASELINE} </li>
-     *     <li>{@link #columnSpec}{@code .span} = {@code [0, 1]} </li>
-     *     <li>{@link #columnSpec}{@code .alignment} = {@link #LEFT} </li>
+     *     <li>{@link #rowSpec}<code>.row</code> = {@link #UNDEFINED} </li>
+     *     <li>{@link #rowSpec}<code>.rowSpan</code> = 1 </li>
+     *     <li>{@link #rowSpec}<code>.alignment</code> = {@link #BASELINE} </li>
+     *     <li>{@link #columnSpec}<code>.column</code> = {@link #UNDEFINED} </li>
+     *     <li>{@link #columnSpec}<code>.columnSpan</code> = 1 </li>
+     *     <li>{@link #columnSpec}<code>.alignment</code> = {@link #LEFT} </li>
      * </ul>
      *
+     * See {@link GridLayout} for a more complete description of the conventions
+     * used by GridLayout in the interpretation of the properties of this class.
+     *
      * @attr ref android.R.styleable#GridLayout_Layout_layout_row
      * @attr ref android.R.styleable#GridLayout_Layout_layout_rowSpan
      * @attr ref android.R.styleable#GridLayout_Layout_layout_column
@@ -1606,15 +1694,16 @@
         // Instance variables
 
         /**
-         * The spec that specifies the vertical characteristics of the cell group
+         * The spec that defines the vertical characteristics of the cell group
          * described by these layout parameters.
          */
-        public Spec rowSpec;
+        public Spec rowSpec = Spec.UNDEFINED;
+
         /**
-         * The spec that specifies the horizontal characteristics of the cell group
+         * The spec that defines the horizontal characteristics of the cell group
          * described by these layout parameters.
          */
-        public Spec columnSpec;
+        public Spec columnSpec = Spec.UNDEFINED;
 
         // Constructors
 
@@ -1646,7 +1735,7 @@
          * Constructs a new LayoutParams with default values as defined in {@link LayoutParams}.
          */
         public LayoutParams() {
-            this(spec(UNDEFINED), spec(UNDEFINED));
+            this(Spec.UNDEFINED, Spec.UNDEFINED);
         }
 
         // Copying constructors
@@ -1670,8 +1759,8 @@
          */
         public LayoutParams(LayoutParams that) {
             super(that);
-            this.rowSpec = new Spec(that.rowSpec);
-            this.columnSpec = new Spec(that.columnSpec);
+            this.rowSpec = that.rowSpec;
+            this.columnSpec = that.columnSpec;
         }
 
         // AttributeSet constructors
@@ -1750,11 +1839,11 @@
             this.height = attributes.getLayoutDimension(heightAttr, DEFAULT_HEIGHT);
         }
 
-        private void setRowSpecSpan(Interval span) {
+        final void setRowSpecSpan(Interval span) {
             rowSpec = rowSpec.copyWriteSpan(span);
         }
 
-        private void setColumnSpecSpan(Interval span) {
+        final void setColumnSpecSpan(Interval span) {
             columnSpec = columnSpec.copyWriteSpan(span);
         }
     }
@@ -1763,7 +1852,7 @@
     In place of a HashMap from span to Int, use an array of key/value pairs - stored in Arcs.
     Add the mutables completesCycle flag to avoid creating another hash table for detecting cycles.
      */
-    private static class Arc {
+    final static class Arc {
         public final Interval span;
         public final MutableInt value;
         public boolean valid = true;
@@ -1781,18 +1870,18 @@
 
     // A mutable Integer - used to avoid heap allocation during the layout operation
 
-    private static class MutableInt {
+    final static class MutableInt {
         public int value;
 
-        private MutableInt() {
+        public MutableInt() {
             reset();
         }
 
-        private MutableInt(int value) {
+        public MutableInt(int value) {
             this.value = value;
         }
 
-        private void reset() {
+        public void reset() {
             value = Integer.MIN_VALUE;
         }
 
@@ -1802,7 +1891,7 @@
         }
     }
 
-    private static class Assoc<K, V> extends ArrayList<Pair<K, V>> {
+    final static class Assoc<K, V> extends ArrayList<Pair<K, V>> {
         private final Class<K> keyType;
         private final Class<V> valueType;
 
@@ -1811,7 +1900,7 @@
             this.valueType = valueType;
         }
 
-        private static <K, V> Assoc<K, V> of(Class<K> keyType, Class<V> valueType) {
+        public static <K, V> Assoc<K, V> of(Class<K> keyType, Class<V> valueType) {
             return new Assoc<K, V>(keyType, valueType);
         }
 
@@ -1847,7 +1936,7 @@
     rather than using (and storing) an implementation of Map<Key, ?>.
      */
     @SuppressWarnings(value = "unchecked")
-    private static class PackedMap<K, V> {
+    final static class PackedMap<K, V> {
         public final int[] index;
         public final K[] keys;
         public final V[] values;
@@ -1859,7 +1948,7 @@
             this.values = compact(values, index);
         }
 
-        private V getValue(int i) {
+        public V getValue(int i) {
             return values[index[i]];
         }
 
@@ -1907,7 +1996,7 @@
     group to Bounds and to loop through all Views in the group taking the maximum
     of the values for each View.
     */
-    private static class Bounds {
+    static class Bounds {
         public int before;
         public int after;
         public int flexibility; // we're flexible iff all included specs are flexible
@@ -1969,7 +2058,7 @@
      * Intervals are often written as {@code [min, max]} and represent the set of values
      * {@code x} such that {@code min <= x < max}.
      */
-    static class Interval {
+    final static class Interval {
         /**
          * The minimum value.
          */
@@ -1995,11 +2084,11 @@
             this.max = max;
         }
 
-        private int size() {
+        int size() {
             return max - min;
         }
 
-        private Interval inverse() {
+        Interval inverse() {
             return new Interval(max, min);
         }
 
@@ -2062,32 +2151,31 @@
      * For column groups, this specifies the horizontal alignment.
      */
     public static class Spec {
+        static final Spec UNDEFINED = spec(GridLayout.UNDEFINED);
+
+        final boolean startDefined;
         final Interval span;
         final Alignment alignment;
 
-        private Spec(Interval span, Alignment alignment) {
+        private Spec(boolean startDefined, Interval span, Alignment alignment) {
+            this.startDefined = startDefined;
             this.span = span;
             this.alignment = alignment;
         }
 
-        /* Copying constructor */
-        private Spec(Spec that) {
-            this(that.span, that.alignment);
+        private Spec(boolean startDefined, int start, int size, Alignment alignment) {
+            this(startDefined, new Interval(start, start + size), alignment);
         }
 
-        private Spec(int start, int size, Alignment alignment) {
-            this(new Interval(start, start + size), alignment);
+        final Spec copyWriteSpan(Interval span) {
+            return new Spec(startDefined, span, alignment);
         }
 
-        private Spec copyWriteSpan(Interval span) {
-            return new Spec(span, alignment);
+        final Spec copyWriteAlignment(Alignment alignment) {
+            return new Spec(startDefined, span, alignment);
         }
 
-        private Spec copyWriteAlignment(Alignment alignment) {
-            return new Spec(span, alignment);
-        }
-
-        int getFlexibility() {
+        final int getFlexibility() {
             return (alignment == UNDEFINED_ALIGNMENT) ? INFLEXIBLE : CAN_STRETCH;
         }
 
@@ -2143,7 +2231,7 @@
      * @param alignment the alignment
      */
     public static Spec spec(int start, int size, Alignment alignment) {
-        return new Spec(start, size, alignment);
+        return new Spec(start != UNDEFINED, start, size, alignment);
     }
 
     /**
@@ -2246,7 +2334,7 @@
         }
     }
 
-    private static final Alignment UNDEFINED_ALIGNMENT = new Alignment() {
+    static final Alignment UNDEFINED_ALIGNMENT = new Alignment() {
         public int getAlignmentValue(View view, int viewSize) {
             return UNDEFINED;
         }
@@ -2367,7 +2455,7 @@
         }
     };
 
-    private static boolean canStretch(int flexibility) {
+    static boolean canStretch(int flexibility) {
         return (flexibility & CAN_STRETCH) != 0;
     }
 
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 690164c..a63b8c8 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -299,6 +299,7 @@
             p.format = PixelFormat.TRANSLUCENT;
             p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
             p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                     | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
             p.token = null;
             p.windowAnimations = 0; // android.R.style.DropDownAnimationDown;
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index e571998..6aee5a0 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -584,10 +584,10 @@
         // A device specific coefficient adjusted to physical values.
         private static float PHYSICAL_COEF;
 
-        private static float DECELERATION_RATE = (float) (Math.log(0.75) / Math.log(0.9));
-        private static final float INFLEXION = 0.4f; // Tension lines cross at (INFLEXION, 1)
-        private static final float START_TENSION = 1.0f;
-        private static final float END_TENSION = 0.6666f;
+        private static float DECELERATION_RATE = (float) (Math.log(0.78) / Math.log(0.9));
+        private static final float INFLEXION = 0.35f; // Tension lines cross at (INFLEXION, 1)
+        private static final float START_TENSION = 0.5f;
+        private static final float END_TENSION = 1.0f;
         private static final float P1 = START_TENSION * INFLEXION;
         private static final float P2 = 1.0f - END_TENSION * (1.0f - INFLEXION);
 
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index 17512d8..6a6d767 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -157,6 +157,8 @@
      * @hide
      */
     public boolean onOpenSubMenu(MenuBuilder subMenu) {
+        if (subMenu == null) return false;
+
         if (!subMenu.hasVisibleItems()) {
             return true;
         }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 4d45c2f..aac20c4 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -796,6 +796,21 @@
      * @param y the popup's y location offset
      */
     public void showAtLocation(View parent, int gravity, int x, int y) {
+        showAtLocation(parent.getWindowToken(), gravity, x, y);
+    }
+
+    /**
+     * Display the content view in a popup window at the specified location.
+     *
+     * @param token Window token to use for creating the new window
+     * @param gravity the gravity which controls the placement of the popup window
+     * @param x the popup's x location offset
+     * @param y the popup's y location offset
+     *
+     * @hide Internal use only. Applications should use
+     *       {@link #showAtLocation(View, int, int, int)} instead.
+     */
+    public void showAtLocation(IBinder token, int gravity, int x, int y) {
         if (isShowing() || mContentView == null) {
             return;
         }
@@ -805,7 +820,7 @@
         mIsShowing = true;
         mIsDropdown = false;
 
-        WindowManager.LayoutParams p = createPopupLayout(parent.getWindowToken());
+        WindowManager.LayoutParams p = createPopupLayout(token);
         p.windowAnimations = computeAnimationResource();
        
         preparePopup(p);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 6edfd59..12a93ac 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -212,6 +212,11 @@
      * Describes how the child views are positioned. Defaults to
      * <code>Gravity.LEFT | Gravity.TOP</code>.
      *
+     * <p>Note that since RelativeLayout considers the positioning of each child
+     * relative to one another to be significant, setting gravity will affect
+     * the positioning of all children as a single unit within the parent.
+     * This happens after children have been relatively positioned.</p>
+     *
      * @param gravity See {@link android.view.Gravity}
      *
      * @see #setHorizontalGravity(int)
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 6e29024..3627890 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -169,6 +169,7 @@
         mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
         Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
         activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
+        activityChooserView.setProvider(this);
 
         return activityChooserView;
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index d680f36..8db6592 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8944,13 +8944,7 @@
 
         final boolean isPassword = hasPasswordTransformationMethod();
         if (!isPassword) {
-            CharSequence text = getText();
-            if (TextUtils.isEmpty(text)) {
-                text = getHint();
-            }
-            if (TextUtils.isEmpty(text)) {
-                text = getContentDescription();
-            }
+            CharSequence text = getTextForAccessibility();
             if (!TextUtils.isEmpty(text)) {
                 event.getText().add(text);
             }
@@ -8977,7 +8971,7 @@
 
         final boolean isPassword = hasPasswordTransformationMethod();
         if (!isPassword) {
-            info.setText(getText());
+            info.setText(getTextForAccessibility());
         }
         info.setPassword(isPassword);
     }
@@ -8993,6 +8987,20 @@
         super.sendAccessibilityEvent(eventType);
     }
 
+    /**
+     * Gets the text reported for accessibility purposes. It is the
+     * text if not empty or the hint.
+     *
+     * @return The accessibility text.
+     */
+    private CharSequence getTextForAccessibility() {
+        CharSequence text = getText();
+        if (TextUtils.isEmpty(text)) {
+            text = getHint();
+        }
+        return text;
+    }
+
     void sendAccessibilityEventTypeViewTextChanged(CharSequence beforeText,
             int fromIndex, int removedCount, int addedCount) {
         AccessibilityEvent event =
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index fba6a5a..0db1ccc 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -24,6 +24,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.SparseBooleanArray;
+import android.view.ActionProvider;
 import android.view.MenuItem;
 import android.view.SoundEffectConstants;
 import android.view.View;
@@ -40,7 +41,8 @@
 /**
  * MenuPresenter for building action menus as seen in the action bar and action modes.
  */
-public class ActionMenuPresenter extends BaseMenuPresenter {
+public class ActionMenuPresenter extends BaseMenuPresenter
+        implements ActionProvider.SubUiVisibilityListener {
     private static final String TAG = "ActionMenuPresenter";
 
     private View mOverflowButton;
@@ -187,6 +189,17 @@
     public void updateMenuView(boolean cleared) {
         super.updateMenuView(cleared);
 
+        if (mMenu != null) {
+            final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
+            final int count = actionItems.size();
+            for (int i = 0; i < count; i++) {
+                final ActionProvider provider = actionItems.get(i).getActionProvider();
+                if (provider != null) {
+                    provider.setSubUiVisibilityListener(this);
+                }
+            }
+        }
+
         final boolean hasOverflow = mReserveOverflow && mMenu != null &&
                 mMenu.getNonActionItems().size() > 0;
         if (hasOverflow) {
@@ -483,6 +496,16 @@
         }
     }
 
+    @Override
+    public void onSubUiVisibilityChanged(boolean isVisible) {
+        if (isVisible) {
+            // Not a submenu, but treat it like one.
+            super.onSubMenuSelected(null);
+        } else {
+            mMenu.close(false);
+        }
+    }
+
     private static class SavedState implements Parcelable {
         public int openSubMenuId;
 
@@ -590,7 +613,6 @@
         @Override
         public void onDismiss() {
             super.onDismiss();
-            mSubMenu.close();
             mActionButtonPopup = null;
             mOpenSubMenuId = 0;
         }
@@ -600,12 +622,17 @@
 
         @Override
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
+            if (subMenu == null) return false;
+
             mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
             return false;
         }
 
         @Override
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+            if (menu instanceof SubMenuBuilder) {
+                ((SubMenuBuilder) menu).getRootMenu().close(false);
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/view/menu/IconMenuPresenter.java b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
index d1b1dae..24ddad6 100644
--- a/core/java/com/android/internal/view/menu/IconMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/IconMenuPresenter.java
@@ -187,7 +187,9 @@
 
         @Override
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
-            mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
+            if (subMenu != null) {
+                mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
+            }
             return false;
         }
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 4d828c4..76550cf 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -756,24 +756,36 @@
     }
 
     /**
-     * @return Whether the lock password is enabled.
+     * @return Whether the lock password is enabled, or if it is set as a backup for biometric weak
      */
     public boolean isLockPasswordEnabled() {
         long mode = getLong(PASSWORD_TYPE_KEY, 0);
-        return savedPasswordExists() &&
-                (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
-                        || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
-                        || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
-                        || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
+        long backupMode = getLong(PASSWORD_TYPE_ALTERNATE_KEY, 0);
+        final boolean passwordEnabled = mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+                || mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+        final boolean backupEnabled = backupMode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+                || backupMode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                || backupMode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+                || backupMode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+
+        return savedPasswordExists() && (passwordEnabled ||
+                (isBiometricEnabled() && backupEnabled));
     }
 
     /**
-     * @return Whether the lock pattern is enabled.
+     * @return Whether the lock pattern is enabled, or if it is set as a backup for biometric weak
      */
     public boolean isLockPatternEnabled() {
+        final boolean backupEnabled =
+                getLong(PASSWORD_TYPE_ALTERNATE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
+                == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+
         return getBoolean(Settings.Secure.LOCK_PATTERN_ENABLED)
-                && getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
-                        == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+                && (getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING)
+                        == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING ||
+                        (isBiometricEnabled() && backupEnabled));
     }
 
     /**
@@ -923,8 +935,7 @@
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
                 || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
         final boolean secure = isPattern && isLockPatternEnabled() && savedPatternExists()
-                || isPassword && savedPasswordExists()
-                || usingBiometricWeak() && isBiometricEnabled();
+                || isPassword && savedPasswordExists();
         return secure;
     }
 
diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java
index 9f6ab31..8445ad1 100644
--- a/core/java/com/android/server/NetworkManagementSocketTagger.java
+++ b/core/java/com/android/server/NetworkManagementSocketTagger.java
@@ -75,30 +75,20 @@
             Log.d(TAG, "tagSocket(" + fd.getInt$() + ") with statsTag=0x"
                     + Integer.toHexString(options.statsTag) + ", statsUid=" + options.statsUid);
         }
-        try {
-            // TODO: skip tagging when options would be no-op
-            tagSocketFd(fd, options.statsTag, options.statsUid);
-        } catch (IOException e) {
-            throw new SocketException("Problem tagging socket", e);
-        }
+        // TODO: skip tagging when options would be no-op
+        tagSocketFd(fd, options.statsTag, options.statsUid);
     }
 
-    private void tagSocketFd(FileDescriptor fd, int tag, int uid) throws IOException {
-        final int fdNum = fd.getInt$();
-        if (fdNum == -1 || (tag == -1 && uid == -1)) return;
+    private void tagSocketFd(FileDescriptor fd, int tag, int uid) {
+        int errno;
+        if (tag == -1 && uid == -1) return;
 
-        String cmd = "t " + fdNum;
-        if (tag == -1) {
-            // Case where just the uid needs adjusting. But probably the caller
-            // will want to track his own name here, just in case.
-            cmd += " 0";
-        } else {
-            cmd += " " + tagToKernel(tag);
+        errno = native_tagSocketFd(fd, tag, uid);
+        if (errno < 0) {
+            Log.i(TAG, "tagSocketFd(" + fd.getInt$() + ", "
+                  + tag + ", " +
+                  + uid + ") failed with errno" + errno);
         }
-        if (uid != -1) {
-            cmd += " " + uid;
-        }
-        internalModuleCtrl(cmd);
     }
 
     @Override
@@ -106,19 +96,18 @@
         if (LOGD) {
             Log.i(TAG, "untagSocket(" + fd.getInt$() + ")");
         }
-        try {
-            unTagSocketFd(fd);
-        } catch (IOException e) {
-            throw new SocketException("Problem untagging socket", e);
-        }
+        unTagSocketFd(fd);
     }
 
-    private void unTagSocketFd(FileDescriptor fd) throws IOException {
-        int fdNum = fd.getInt$();
+    private void unTagSocketFd(FileDescriptor fd) {
         final SocketTags options = threadSocketTags.get();
-        if (fdNum == -1 || (options.statsTag == -1 && options.statsUid == -1)) return;
-        String cmd = "u " + fdNum;
-        internalModuleCtrl(cmd);
+        int errno;
+        if (options.statsTag == -1 && options.statsUid == -1) return;
+
+        errno = native_untagSocketFd(fd);
+        if (errno < 0) {
+            Log.w(TAG, "untagSocket(" + fd.getInt$() + ") failed with errno " + errno);
+        }
     }
 
     public static class SocketTags {
@@ -127,69 +116,20 @@
     }
 
     public static void setKernelCounterSet(int uid, int counterSet) {
-        final StringBuilder command = new StringBuilder();
-        command.append("s ").append(counterSet).append(" ").append(uid);
-        try {
-            internalModuleCtrl(command.toString());
-        } catch (IOException e) {
-            Slog.w(TAG, "problem changing counter set for uid " + uid + " : " + e);
+        int errno = native_setCounterSet(counterSet, uid);
+        if (errno < 0) {
+            Log.w(TAG, "setKernelCountSet(" + uid + ", " + counterSet + ") failed with errno " + errno);
         }
     }
 
     public static void resetKernelUidStats(int uid) {
-        final StringBuilder command = new StringBuilder();
-        command.append("d 0 ").append(uid);
-        try {
-            internalModuleCtrl(command.toString());
-        } catch (IOException e) {
-            Slog.w(TAG, "problem clearing counters for uid " + uid + " : " + e);
+        int errno = native_deleteTagData(0, uid);
+        if (errno < 0) {
+            Slog.w(TAG, "problem clearing counters for uid " + uid + " : errno " + errno);
         }
     }
 
     /**
-     * Sends commands to the kernel netfilter module.
-     *
-     * @param cmd command string for the qtaguid netfilter module. May not be null.
-     *   <p>Supports:
-     *     <ul><li>tag a socket:<br>
-     *        <code>t <i>sock_fd</i> <i>acct_tag</i> [<i>uid_in_case_caller_is_acting_on_behalf_of</i>]</code><br>
-     *     <code>*_tag</code> defaults to default_policy_tag_from_uid(uid_of_caller)<br>
-     *     <code>acct_tag</code> is either 0 or greater that 2^32.<br>
-     *     <code>uid_*</code> is only settable by privileged UIDs (DownloadManager,...)
-     *     </li>
-     *     <li>untag a socket, preserving counters:<br>
-     *       <code>u <i>sock_fd</i></code>
-     *     </li></ul>
-     *   <p>Notes:<br>
-     *   <ul><li><i>sock_fd</i> is withing the callers process space.</li>
-     *   <li><i>*_tag</i> are 64bit values</li></ul>
-     *
-     */
-    private static void internalModuleCtrl(String cmd) throws IOException {
-        if (!SystemProperties.getBoolean(PROP_QTAGUID_ENABLED, false)) return;
-
-        // TODO: migrate to native library for tagging commands
-        FileOutputStream procOut = null;
-        try {
-            procOut = new FileOutputStream("/proc/net/xt_qtaguid/ctrl");
-            procOut.write(cmd.getBytes(Charsets.US_ASCII));
-        } finally {
-            IoUtils.closeQuietly(procOut);
-        }
-    }
-
-    /**
-     * Convert {@link Integer} tag to {@code /proc/} format. Assumes unsigned
-     * base-10 format like {@code 2147483647}. Currently strips signed bit to
-     * avoid using {@link BigInteger}.
-     */
-    public static String tagToKernel(int tag) {
-        // TODO: eventually write in hex, since that's what proc exports
-        // TODO: migrate to direct integer instead of odd shifting
-        return Long.toString((((long) tag) << 32) & 0x7FFFFFFF00000000L);
-    }
-
-    /**
      * Convert {@code /proc/} tag format to {@link Integer}. Assumes incoming
      * format like {@code 0x7fffffff00000000}.
      */
@@ -197,4 +137,9 @@
         // TODO: migrate to direct integer instead of odd shifting
         return (int) (Long.decode(string) >> 32);
     }
+
+    private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid);
+    private static native int native_untagSocketFd(FileDescriptor fd);
+    private static native int native_setCounterSet(int uid, int counterSetNum);
+    private static native int native_deleteTagData(int tag, int uid);
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index aece5f0..59a03e7 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -143,6 +143,7 @@
 	android_server_BluetoothService.cpp \
 	android_server_BluetoothEventLoop.cpp \
 	android_server_BluetoothA2dpService.cpp \
+	android_server_NetworkManagementSocketTagger.cpp \
 	android_server_Watchdog.cpp \
 	android_ddm_DdmHandleNativeHeap.cpp \
 	com_android_internal_os_ZygoteInit.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index dd7dd86..12ec1b6 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -155,6 +155,7 @@
 extern int register_android_server_BluetoothService(JNIEnv* env);
 extern int register_android_server_BluetoothEventLoop(JNIEnv *env);
 extern int register_android_server_BluetoothA2dpService(JNIEnv* env);
+extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
 extern int register_android_server_Watchdog(JNIEnv* env);
 extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
 extern int register_com_android_internal_os_ZygoteInit(JNIEnv* env);
@@ -1178,6 +1179,7 @@
     REG_JNI(register_android_server_BluetoothService),
     REG_JNI(register_android_server_BluetoothEventLoop),
     REG_JNI(register_android_server_BluetoothA2dpService),
+    REG_JNI(register_android_server_NetworkManagementSocketTagger),
     REG_JNI(register_android_server_Watchdog),
     REG_JNI(register_android_ddm_DdmHandleNativeHeap),
     REG_JNI(register_android_backup_BackupDataInput),
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index fa9a7b7..a2d6efb 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -271,19 +271,11 @@
     }
 }
 
-void TextLayout::getTextRunAdvancesHB(SkPaint* paint, const jchar* chars, jint start,
-                                    jint count, jint contextCount, jint dirFlags,
-                                    jfloat* resultAdvances, jfloat& resultTotalAdvance) {
-    // Compute advances and return them
-    TextLayoutCacheValue::computeValuesWithHarfbuzz(paint, chars, start, count, contextCount,
-            dirFlags, resultAdvances, &resultTotalAdvance, NULL, NULL);
-}
-
 void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start,
                                     jint count, jint contextCount, jint dirFlags,
                                     jfloat* resultAdvances, jfloat& resultTotalAdvance) {
     // Compute advances and return them
-    TextLayoutCacheValue::computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags,
+    computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags,
             resultAdvances, &resultTotalAdvance);
 }
 
@@ -321,4 +313,73 @@
     }
 }
 
+void TextLayout::computeAdvancesWithICU(SkPaint* paint, const UChar* chars,
+        size_t start, size_t count, size_t contextCount, int dirFlags,
+        jfloat* outAdvances, jfloat* outTotalAdvance) {
+    SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount);
+    jchar* buffer = tempBuffer.get();
+    SkScalar* scalarArray = (SkScalar*)outAdvances;
+
+    // this is where we'd call harfbuzz
+    // for now we just use ushape.c
+    size_t widths;
+    const jchar* text;
+    if (dirFlags & 0x1) { // rtl, call arabic shaping in case
+        UErrorCode status = U_ZERO_ERROR;
+        // Use fixed length since we need to keep start and count valid
+        u_shapeArabic(chars, contextCount, buffer, contextCount,
+                U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
+                U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE |
+                U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
+        // we shouldn't fail unless there's an out of memory condition,
+        // in which case we're hosed anyway
+        for (int i = start, e = i + count; i < e; ++i) {
+            if (buffer[i] == UNICODE_NOT_A_CHAR) {
+                buffer[i] = UNICODE_ZWSP; // zero-width-space for skia
+            }
+        }
+        text = buffer + start;
+        widths = paint->getTextWidths(text, count << 1, scalarArray);
+    } else {
+        text = chars + start;
+        widths = paint->getTextWidths(text, count << 1, scalarArray);
+    }
+
+    jfloat totalAdvance = 0;
+    if (widths < count) {
+#if DEBUG_ADVANCES
+    LOGD("ICU -- count=%d", widths);
+#endif
+        // Skia operates on code points, not code units, so surrogate pairs return only
+        // one value. Expand the result so we have one value per UTF-16 code unit.
+
+        // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
+        // leaving the remaining widths zero.  Not nice.
+        for (size_t i = 0, p = 0; i < widths; ++i) {
+            totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]);
+            if (p < count &&
+                    text[p] >= UNICODE_FIRST_LOW_SURROGATE &&
+                    text[p] < UNICODE_FIRST_PRIVATE_USE &&
+                    text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE &&
+                    text[p-1] < UNICODE_FIRST_LOW_SURROGATE) {
+                outAdvances[p++] = 0;
+            }
+#if DEBUG_ADVANCES
+            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
+#endif
+        }
+    } else {
+#if DEBUG_ADVANCES
+    LOGD("ICU -- count=%d", count);
+#endif
+        for (size_t i = 0; i < count; i++) {
+            totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]);
+#if DEBUG_ADVANCES
+            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
+#endif
+        }
+    }
+    *outTotalAdvance = totalAdvance;
+}
+
 }
diff --git a/core/jni/android/graphics/TextLayout.h b/core/jni/android/graphics/TextLayout.h
index 0a29d78..9d8913c 100644
--- a/core/jni/android/graphics/TextLayout.h
+++ b/core/jni/android/graphics/TextLayout.h
@@ -77,10 +77,6 @@
                                    jint count, jint contextCount, jint dirFlags,
                                    jfloat* resultAdvances, jfloat& resultTotalAdvance);
 
-    static void getTextRunAdvancesHB(SkPaint* paint, const jchar* chars, jint start,
-                                   jint count, jint contextCount, jint dirFlags,
-                                   jfloat* resultAdvances, jfloat& resultTotalAdvance);
-
     static void drawText(SkPaint* paint, const jchar* text, jsize len,
                          jint bidiFlags, jfloat x, jfloat y, SkCanvas* canvas);
 
@@ -106,5 +102,9 @@
                            UErrorCode &status);
     static void handleText(SkPaint* paint, const jchar* text, jsize len,
                            int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas, SkPath* path);
+
+    static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars,
+            size_t start, size_t count, size_t contextCount, int dirFlags,
+            jfloat* outAdvances, jfloat* outTotalAdvance);
 };
 } // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index d04e059..e4eeec8 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -52,13 +52,7 @@
     mCacheStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
     if (mDebugEnabled) {
-        LOGD("Start time: %lld", mCacheStartTime);
-#if RTL_USE_HARFBUZZ
-        LOGD("Using HARFBUZZ");
-#else
-        LOGD("Using ICU");
-#endif
-        LOGD("Initialization is done");
+        LOGD("Initialization is done - Start time: %lld", mCacheStartTime);
     }
 
     mInitialized = true;
@@ -242,6 +236,24 @@
     hinting = paint->getHinting();
 }
 
+TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
+        text(NULL),
+        textCopy(other.textCopy),
+        start(other.start),
+        count(other.count),
+        contextCount(other.contextCount),
+        dirFlags(other.dirFlags),
+        typeface(other.typeface),
+        textSize(other.textSize),
+        textSkewX(other.textSkewX),
+        textScaleX(other.textScaleX),
+        flags(other.flags),
+        hinting(other.hinting) {
+    if (other.text) {
+        textCopy.setTo(other.text);
+    }
+}
+
 bool TextLayoutCacheKey::operator<(const TextLayoutCacheKey& rhs) const {
     LTE_INT(count) {
         LTE_INT(contextCount) {
@@ -253,7 +265,7 @@
                                 LTE_INT(flags) {
                                     LTE_INT(hinting) {
                                         LTE_INT(dirFlags) {
-                                            return strncmp16(text, rhs.text, contextCount) < 0;
+                                            return strncmp16(getText(), rhs.getText(), contextCount) < 0;
                                         }
                                     }
                                 }
@@ -269,7 +281,7 @@
 
 void TextLayoutCacheKey::internalTextCopy() {
     textCopy.setTo(text, contextCount);
-    text = textCopy.string();
+    text = NULL;
 }
 
 size_t TextLayoutCacheKey::getSize() {
@@ -280,13 +292,7 @@
  * TextLayoutCacheValue
  */
 TextLayoutCacheValue::TextLayoutCacheValue() :
-        mAdvances(NULL), mTotalAdvance(0), mAdvancesCount(0),
-        mGlyphs(NULL), mGlyphsCount(0), mElapsedTime(0) {
-}
-
-TextLayoutCacheValue::~TextLayoutCacheValue() {
-    delete[] mAdvances;
-    delete[] mGlyphs;
+        mTotalAdvance(0), mElapsedTime(0) {
 }
 
 void TextLayoutCacheValue::setElapsedTime(uint32_t time) {
@@ -299,16 +305,11 @@
 
 void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars, size_t start,
         size_t count, size_t contextCount, int dirFlags) {
-    mAdvancesCount = count;
-    mAdvances = new float[count];
-
-#if RTL_USE_HARFBUZZ
+    // Give a hint for advances and glyphs vectors size
+    mAdvances.setCapacity(count);
+    mGlyphs.setCapacity(count);
     computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
-            mAdvances, &mTotalAdvance, &mGlyphs, &mGlyphsCount);
-#else
-    computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags,
-            mAdvances, &mTotalAdvance);
-#endif
+            &mAdvances, &mTotalAdvance, &mGlyphs);
 #if DEBUG_ADVANCES
     LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - "
             "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, mTotalAdvance,
@@ -317,8 +318,8 @@
 }
 
 size_t TextLayoutCacheValue::getSize() {
-    return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvancesCount +
-            sizeof(jchar) * mGlyphsCount;
+    return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() +
+            sizeof(jchar) * mGlyphs.capacity();
 }
 
 void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
@@ -389,27 +390,10 @@
     }
 }
 
-struct GlyphRun {
-    inline GlyphRun() {}
-    inline GlyphRun(jchar* glyphs, size_t glyphsCount, bool isRTL) :
-            glyphs(glyphs), glyphsCount(glyphsCount), isRTL(isRTL) { }
-    jchar* glyphs;
-    size_t glyphsCount;
-    int isRTL;
-};
-
-void static reverseGlyphArray(jchar* glyphs, size_t count) {
-    for (size_t i = 0; i < count / 2; i++) {
-        jchar temp = glyphs[i];
-        glyphs[i] = glyphs[count - 1 - i];
-        glyphs[count - 1 - i] = temp;
-    }
-}
-
 void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, int dirFlags,
-        jfloat* outAdvances, jfloat* outTotalAdvance,
-        jchar** outGlyphs, size_t* outGlyphsCount) {
+        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+        Vector<jchar>* const outGlyphs) {
 
         UBiDiLevel bidiReq = 0;
         bool forceLTR = false;
@@ -430,11 +414,7 @@
                             forceLTR, forceRTL);
 #endif
             computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, forceRTL,
-                    outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
-
-            if (forceRTL && *outGlyphsCount > 1) {
-                reverseGlyphArray(*outGlyphs, *outGlyphsCount);
-            }
+                    outAdvances, outTotalAdvance, outGlyphs);
         } else {
             UBiDi* bidi = ubidi_open();
             if (bidi) {
@@ -456,15 +436,8 @@
                                 "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
 #endif
                         computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount,
-                                isRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
-
-                        if (isRTL && *outGlyphsCount > 1) {
-                            reverseGlyphArray(*outGlyphs, *outGlyphsCount);
-                        }
+                                isRTL, outAdvances, outTotalAdvance, outGlyphs);
                     } else {
-                        Vector<GlyphRun> glyphRuns;
-                        jchar* runGlyphs;
-                        size_t runGlyphsCount = 0;
                         int32_t end = start + count;
                         for (size_t i = 0; i < rc; ++i) {
                             int32_t startRun;
@@ -498,34 +471,9 @@
                             computeRunValuesWithHarfbuzz(paint, chars, startRun,
                                     lengthRun, contextCount, isRTL,
                                     outAdvances, &runTotalAdvance,
-                                    &runGlyphs, &runGlyphsCount);
+                                    outGlyphs);
 
-                            outAdvances += lengthRun;
                             *outTotalAdvance += runTotalAdvance;
-                            *outGlyphsCount += runGlyphsCount;
-#if DEBUG_GLYPHS
-                            LOGD("computeValuesWithHarfbuzz -- run=%d run-glyphs-count=%d",
-                                    i, runGlyphsCount);
-                            for (size_t j = 0; j < runGlyphsCount; j++) {
-                                LOGD("                          -- glyphs[%d]=%d", j, runGlyphs[j]);
-                            }
-#endif
-                            glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, isRTL));
-                        }
-                        *outGlyphs = new jchar[*outGlyphsCount];
-
-                        jchar* glyphs = *outGlyphs;
-                        for (size_t i = 0; i < glyphRuns.size(); i++) {
-                            const GlyphRun& glyphRun = glyphRuns.itemAt(i);
-                            if (glyphRun.isRTL) {
-                                for (size_t n = 0; n < glyphRun.glyphsCount; n++) {
-                                    glyphs[glyphRun.glyphsCount - n - 1] = glyphRun.glyphs[n];
-                                }
-                            } else {
-                                memcpy(glyphs, glyphRun.glyphs, glyphRun.glyphsCount * sizeof(jchar));
-                            }
-                            glyphs += glyphRun.glyphsCount;
-                            delete[] glyphRun.glyphs;
                         }
                     }
                 }
@@ -538,22 +486,18 @@
                         "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
 #endif
                 computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, isRTL,
-                        outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
-
-                if (isRTL && *outGlyphsCount > 1) {
-                    reverseGlyphArray(*outGlyphs, *outGlyphsCount);
-                }
+                        outAdvances, outTotalAdvance, outGlyphs);
             }
         }
 #if DEBUG_GLYPHS
-        LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", *outGlyphsCount);
+        LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", outGlyphs->size());
 #endif
 }
 
 static void logGlyphs(HB_ShaperItem shaperItem) {
     LOGD("Got glyphs - count=%d", shaperItem.num_glyphs);
     for (size_t i = 0; i < shaperItem.num_glyphs; i++) {
-        LOGD("      glyphs[%d]=%d - offset.x=%f offset.y=%f", i, shaperItem.glyphs[i],
+        LOGD("      glyph[%d]=%d - offset.x=%f offset.y=%f", i, shaperItem.glyphs[i],
                 HBFixedToFloat(shaperItem.offsets[i].x),
                 HBFixedToFloat(shaperItem.offsets[i].y));
     }
@@ -561,12 +505,13 @@
 
 void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
         size_t start, size_t count, size_t contextCount, bool isRTL,
-        jfloat* outAdvances, jfloat* outTotalAdvance,
-        jchar** outGlyphs, size_t* outGlyphsCount) {
+        Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+        Vector<jchar>* const outGlyphs) {
 
     HB_ShaperItem shaperItem;
     HB_FontRec font;
     FontData fontData;
+
     shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
             contextCount, isRTL);
 
@@ -583,30 +528,28 @@
 #if DEBUG_GLYPHS
     LOGD("HARFBUZZ -- advances array is empty or num_glypth = 0");
 #endif
-        for (size_t i = 0; i < count; i++) {
-            outAdvances[i] = 0;
-        }
+        outAdvances->insertAt(0, outAdvances->size(), count);
         *outTotalAdvance = 0;
 
-        if (outGlyphs) {
-            *outGlyphsCount = 0;
-            *outGlyphs = new jchar[0];
-        }
-
         // Cleaning
         deleteGlyphArrays(&shaperItem);
         HB_FreeFace(shaperItem.face);
         return;
     }
+
     // Get Advances and their total
-    jfloat totalAdvance = outAdvances[0] = HBFixedToFloat(shaperItem.advances[shaperItem.log_clusters[0]]);
+    jfloat currentAdvance = HBFixedToFloat(shaperItem.advances[shaperItem.log_clusters[0]]);
+    jfloat totalAdvance = currentAdvance;
+    outAdvances->add(currentAdvance);
     for (size_t i = 1; i < count; i++) {
         size_t clusterPrevious = shaperItem.log_clusters[i - 1];
         size_t cluster = shaperItem.log_clusters[i];
         if (cluster == clusterPrevious) {
-            outAdvances[i] = 0;
+            outAdvances->add(0);
         } else {
-            totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[shaperItem.log_clusters[i]]);
+            currentAdvance = HBFixedToFloat(shaperItem.advances[shaperItem.log_clusters[i]]);
+            totalAdvance += currentAdvance;
+            outAdvances->add(currentAdvance);
         }
     }
     *outTotalAdvance = totalAdvance;
@@ -618,12 +561,15 @@
     }
 #endif
 
-    // Get Glyphs
+    // Get Glyphs and reverse them in place if RTL
     if (outGlyphs) {
-        *outGlyphsCount = shaperItem.num_glyphs;
-        *outGlyphs = new jchar[shaperItem.num_glyphs];
-        for (size_t i = 0; i < shaperItem.num_glyphs; i++) {
-            (*outGlyphs)[i] = (jchar) shaperItem.glyphs[i];
+        size_t count = shaperItem.num_glyphs;
+        for (size_t i = 0; i < count; i++) {
+            jchar glyph = (jchar) shaperItem.glyphs[(!isRTL) ? i : count - 1 - i];
+#if DEBUG_GLYPHS
+            LOGD("HARFBUZZ  -- glyph[%d]=%d", i, glyph);
+#endif
+            outGlyphs->add(glyph);
         }
     }
 
@@ -632,75 +578,6 @@
     HB_FreeFace(shaperItem.face);
 }
 
-void TextLayoutCacheValue::computeAdvancesWithICU(SkPaint* paint, const UChar* chars,
-        size_t start, size_t count, size_t contextCount, int dirFlags,
-        jfloat* outAdvances, jfloat* outTotalAdvance) {
-    SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount);
-    jchar* buffer = tempBuffer.get();
-    SkScalar* scalarArray = (SkScalar*)outAdvances;
-
-    // this is where we'd call harfbuzz
-    // for now we just use ushape.c
-    size_t widths;
-    const jchar* text;
-    if (dirFlags & 0x1) { // rtl, call arabic shaping in case
-        UErrorCode status = U_ZERO_ERROR;
-        // Use fixed length since we need to keep start and count valid
-        u_shapeArabic(chars, contextCount, buffer, contextCount,
-                U_SHAPE_LENGTH_FIXED_SPACES_NEAR |
-                U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE |
-                U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status);
-        // we shouldn't fail unless there's an out of memory condition,
-        // in which case we're hosed anyway
-        for (int i = start, e = i + count; i < e; ++i) {
-            if (buffer[i] == UNICODE_NOT_A_CHAR) {
-                buffer[i] = UNICODE_ZWSP; // zero-width-space for skia
-            }
-        }
-        text = buffer + start;
-        widths = paint->getTextWidths(text, count << 1, scalarArray);
-    } else {
-        text = chars + start;
-        widths = paint->getTextWidths(text, count << 1, scalarArray);
-    }
-
-    jfloat totalAdvance = 0;
-    if (widths < count) {
-#if DEBUG_ADVANCES
-    LOGD("ICU -- count=%d", widths);
-#endif
-        // Skia operates on code points, not code units, so surrogate pairs return only
-        // one value. Expand the result so we have one value per UTF-16 code unit.
-
-        // Note, skia's getTextWidth gets confused if it encounters a surrogate pair,
-        // leaving the remaining widths zero.  Not nice.
-        for (size_t i = 0, p = 0; i < widths; ++i) {
-            totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]);
-            if (p < count &&
-                    text[p] >= UNICODE_FIRST_LOW_SURROGATE &&
-                    text[p] < UNICODE_FIRST_PRIVATE_USE &&
-                    text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE &&
-                    text[p-1] < UNICODE_FIRST_LOW_SURROGATE) {
-                outAdvances[p++] = 0;
-            }
-#if DEBUG_ADVANCES
-            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
-#endif
-        }
-    } else {
-#if DEBUG_ADVANCES
-    LOGD("ICU -- count=%d", count);
-#endif
-        for (size_t i = 0; i < count; i++) {
-            totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]);
-#if DEBUG_ADVANCES
-            LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance);
-#endif
-        }
-    }
-    *outTotalAdvance = totalAdvance;
-}
-
 void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) {
     delete[] shaperItem->glyphs;
     delete[] shaperItem->attributes;
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 0d8d71f..1f08bda 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -72,6 +72,8 @@
             const UChar* text, size_t start, size_t count,
             size_t contextCount, int dirFlags);
 
+    TextLayoutCacheKey(const TextLayoutCacheKey& other);
+
     bool operator<(const TextLayoutCacheKey& rhs) const;
 
     /**
@@ -86,7 +88,7 @@
     size_t getSize();
 
 private:
-    const UChar* text;
+    const UChar* text; // if text is NULL, use textCopy
     String16 textCopy;
     size_t start;
     size_t count;
@@ -98,15 +100,16 @@
     SkScalar textScaleX;
     uint32_t flags;
     SkPaint::Hinting hinting;
+
+    inline const UChar* getText() const {
+        return text ? text : textCopy.string();
+    }
 }; // TextLayoutCacheKey
 
 /*
  * TextLayoutCacheValue is the Cache value
  */
 class TextLayoutCacheValue : public RefBase {
-protected:
-    ~TextLayoutCacheValue();
-
 public:
     TextLayoutCacheValue();
 
@@ -116,11 +119,11 @@
     void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count,
             size_t contextCount, int dirFlags);
 
-    inline const jfloat* getAdvances() const { return mAdvances; }
-    inline size_t getAdvancesCount() const { return mAdvancesCount; }
+    inline const jfloat* getAdvances() const { return mAdvances.array(); }
+    inline size_t getAdvancesCount() const { return mAdvances.size(); }
     inline jfloat getTotalAdvance() const { return mTotalAdvance; }
-    inline const jchar* getGlyphs() const { return mGlyphs; }
-    inline size_t getGlyphsCount() const { return mGlyphsCount; }
+    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
+    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
 
     /**
      * Get the size of the Cache entry
@@ -137,8 +140,8 @@
 
     static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, int dirFlags,
-            jfloat* outAdvances, jfloat* outTotalAdvance,
-            jchar** outGlyphs, size_t* outGlyphsCount);
+            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+            Vector<jchar>* const outGlyphs);
 
     static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, int dirFlags,
@@ -146,9 +149,9 @@
 
 private:
     /**
-     * Advances array
+     * Advances vector
      */
-    jfloat* mAdvances;
+    Vector<jfloat> mAdvances;
 
     /**
      * Total number of advances
@@ -156,19 +159,9 @@
     jfloat mTotalAdvance;
 
     /**
-     * Allocated size for advances array
+     * Glyphs vector
      */
-    size_t mAdvancesCount;
-
-    /**
-     * Glyphs array
-     */
-    jchar* mGlyphs;
-
-    /**
-     * Total number of glyphs
-     */
-    size_t mGlyphsCount;
+    Vector<jchar> mGlyphs;
 
     /**
      * Time for computing the values (in milliseconds)
@@ -181,8 +174,8 @@
 
     static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, bool isRTL,
-            jfloat* outAdvances, jfloat* outTotalAdvance,
-            jchar** outGlyphs, size_t* outGlyphsCount);
+            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+            Vector<jchar>* const outGlyphs);
 }; // TextLayoutCacheValue
 
 /**
diff --git a/core/jni/android_server_NetworkManagementSocketTagger.cpp b/core/jni/android_server_NetworkManagementSocketTagger.cpp
new file mode 100644
index 0000000..c279ced
--- /dev/null
+++ b/core/jni/android_server_NetworkManagementSocketTagger.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NMST_QTagUidNative"
+#include <utils/Log.h>
+
+#include "JNIHelp.h"
+
+#include "jni.h"
+#include <utils/misc.h>
+#include <cutils/qtaguid.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+namespace android {
+
+static jint QTagUid_tagSocketFd(JNIEnv* env, jclass,
+                                jobject fileDescriptor,
+                                jint tagNum, jint uid) {
+  int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+  if (env->ExceptionOccurred() != NULL) {
+    LOGE("Can't get FileDescriptor num");
+    return (jint)-1;
+  }
+
+  int res = qtaguid_tagSocket(userFd, tagNum, uid);
+  if (res < 0) {
+    return (jint)-errno;
+  }
+  return (jint)res;
+}
+
+static int QTagUid_untagSocketFd(JNIEnv* env, jclass,
+                                 jobject fileDescriptor) {
+  int userFd = jniGetFDFromFileDescriptor(env, fileDescriptor);
+
+  if (env->ExceptionOccurred() != NULL) {
+    LOGE("Can't get FileDescriptor num");
+    return (jint)-1;
+  }
+
+  int res = qtaguid_untagSocket(userFd);
+  if (res < 0) {
+    return (jint)-errno;
+  }
+  return (jint)res;
+}
+
+static jint QTagUid_setCounterSet(JNIEnv* env, jclass,
+                                  jint setNum, jint uid) {
+
+  int res = qtaguid_setCounterSet(setNum, uid);
+  if (res < 0) {
+    return (jint)-errno;
+  }
+  return (jint)res;
+}
+
+static jint QTagUid_deleteTagData(JNIEnv* env, jclass,
+                                  jint tagNum, jint uid) {
+
+  int res = qtaguid_deleteTagData(tagNum, uid);
+  if (res < 0) {
+    return (jint)-errno;
+  }
+  return (jint)res;
+}
+
+static JNINativeMethod gQTagUidMethods[] = {
+  { "native_tagSocketFd", "(Ljava/io/FileDescriptor;II)I", (void*)QTagUid_tagSocketFd},
+  { "native_untagSocketFd", "(Ljava/io/FileDescriptor;)I", (void*)QTagUid_untagSocketFd},
+  { "native_setCounterSet", "(II)I", (void*)QTagUid_setCounterSet},
+  { "native_deleteTagData", "(II)I", (void*)QTagUid_deleteTagData},
+};
+
+int register_android_server_NetworkManagementSocketTagger(JNIEnv* env) {
+  return jniRegisterNativeMethods(env, "com/android/server/NetworkManagementSocketTagger", gQTagUidMethods, NELEM(gQTagUidMethods));
+}
+
+};
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png
index 1d33e47..bf3cabb 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png
index 81fe085..c4f00be 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png
index cf864d2..935e44f 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png
index 583e0c9..03ae28b 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png
index 357b660..b68981f 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png
index 0add340..678b772 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png
index e1a8a63..0aeb0a6 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png
index 934d6d1..1bd7312 100644
--- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png
+++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png
index 4cab1a1..1e5d956 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png
index 2692bd1..d0c0200 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png
index d83cad9..bfdc5ea 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png
index 4ef84a1..1440bc8 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png
index f661b11..4f645fa8 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png
index 69df8e0..21966fd 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png
index c34f0a5..7ca15ed 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png
index 2258b20..369d0ac 100644
--- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png
+++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
index f96a4a6..ca24502 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
index 3a6554f..5653118 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
index 30bd7ad..438b1b5 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
index 209036b..efe3fed 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
index 830820b..cb7931c 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
index 39eb204..8ff7ee9 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
index a2d4dc2..ce07298 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
index 1772aea..87e9d8f 100644
--- a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
+++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png
Binary files differ
diff --git a/core/res/res/drawable/btn_cab_done_holo_dark.xml b/core/res/res/drawable/btn_cab_done_holo_dark.xml
index 2cdb605..65d3496 100644
--- a/core/res/res/drawable/btn_cab_done_holo_dark.xml
+++ b/core/res/res/drawable/btn_cab_done_holo_dark.xml
@@ -14,9 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="true"
-        android:drawable="@drawable/btn_cab_done_default_holo_dark" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
     <item android:state_pressed="true"
         android:drawable="@drawable/btn_cab_done_pressed_holo_dark" />
     <item android:state_focused="true" android:state_enabled="true"
diff --git a/core/res/res/drawable/btn_cab_done_holo_light.xml b/core/res/res/drawable/btn_cab_done_holo_light.xml
index 81add4c..f6a63f4 100644
--- a/core/res/res/drawable/btn_cab_done_holo_light.xml
+++ b/core/res/res/drawable/btn_cab_done_holo_light.xml
@@ -14,9 +14,8 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_window_focused="false" android:state_enabled="true"
-        android:drawable="@drawable/btn_cab_done_default_holo_light" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+          android:exitFadeDuration="@android:integer/config_mediumAnimTime">
     <item android:state_pressed="true"
         android:drawable="@drawable/btn_cab_done_pressed_holo_light" />
     <item android:state_focused="true" android:state_enabled="true"
diff --git a/core/res/res/drawable/item_background_holo_dark.xml b/core/res/res/drawable/item_background_holo_dark.xml
index 2d4f20a..f188df7 100644
--- a/core/res/res/drawable/item_background_holo_dark.xml
+++ b/core/res/res/drawable/item_background_holo_dark.xml
@@ -17,8 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
           android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_window_focused="false" android:drawable="@color/transparent" />
-
     <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
     <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" />
     <item android:state_focused="true"  android:state_enabled="false"                              android:drawable="@drawable/list_selector_disabled_holo_dark" />
diff --git a/core/res/res/drawable/item_background_holo_light.xml b/core/res/res/drawable/item_background_holo_light.xml
index c616d86..ee3f4d8 100644
--- a/core/res/res/drawable/item_background_holo_light.xml
+++ b/core/res/res/drawable/item_background_holo_light.xml
@@ -17,8 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
           android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_window_focused="false" android:drawable="@color/transparent" />
-
     <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
     <item android:state_focused="true"  android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" />
     <item android:state_focused="true"  android:state_enabled="false"                              android:drawable="@drawable/list_selector_disabled_holo_light" />
diff --git a/core/res/res/layout/keyguard_screen_glogin_unlock.xml b/core/res/res/layout/keyguard_screen_glogin_unlock.xml
index 0e5fe78..35d113c 100644
--- a/core/res/res/layout/keyguard_screen_glogin_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_glogin_unlock.xml
@@ -119,7 +119,7 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:drawableLeft="@drawable/ic_emergency"
-        android:drawablePadding="8dip"
+        android:drawablePadding="4dip"
         android:text="@android:string/lockscreen_emergency_call"
         />
 
diff --git a/core/res/res/layout/keyguard_screen_lock.xml b/core/res/res/layout/keyguard_screen_lock.xml
index 6e4fa7d..43867f4 100644
--- a/core/res/res/layout/keyguard_screen_lock.xml
+++ b/core/res/res/layout/keyguard_screen_lock.xml
@@ -211,7 +211,7 @@
             android:layout_marginTop="5dip"
             android:layout_gravity="center_horizontal"
             android:drawableLeft="@drawable/ic_emergency"
-            android:drawablePadding="8dip"
+            android:drawablePadding="4dip"
             android:text="@android:string/lockscreen_emergency_call"
            />
 
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 694db50..3343d8b 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -170,6 +170,7 @@
     <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
         android:layout_width="270dip"
         android:layout_height="wrap_content"
+        android:layout_marginLeft="4dip"
         android:layout_marginRight="4dip"
         android:background="#40000000"
         android:layout_marginTop="5dip"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index cf3bd42..2a66d7d 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -132,7 +132,7 @@
     <!-- Numeric keyboard -->
     <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:layout_marginLeft="4dip"
         android:layout_marginRight="4dip"
         android:paddingTop="4dip"
         android:paddingBottom="4dip"
@@ -178,4 +178,17 @@
         android:layout_height="0dip"
         />
 
+    <!-- Area to overlay FaceLock -->
+    <TextView android:id="@+id/faceLockAreaView"
+        android:visibility="gone"
+        android:layout_row="3"
+        android:layout_column="0"
+        android:layout_rowSpan="2"
+        android:layout_columnSpan="1"
+        android:layout_gravity="fill"
+        android:layout_width="0dip"
+        android:layout_height="0dip"
+        android:background="@color/facelock_color_background"
+    />
+
 </GridLayout>
diff --git a/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml b/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
index dff2a3f..59065e1 100644
--- a/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_sim_pin_landscape.xml
@@ -113,7 +113,7 @@
             android:layout_marginLeft="8dip"
             android:textSize="18sp"
             android:drawableLeft="@drawable/ic_emergency"
-            android:drawablePadding="8dip"
+            android:drawablePadding="4dip"
         />
     </LinearLayout>
 
diff --git a/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml b/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
index d8bea56..6e8a645 100644
--- a/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
@@ -111,7 +111,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:drawableLeft="@android:drawable/ic_emergency"
-            android:drawablePadding="8dip"
+            android:drawablePadding="4dip"
             android:text="@android:string/lockscreen_emergency_call"
         />
     </LinearLayout>
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
index 11a6e12..b662e82 100644
--- a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
@@ -175,7 +175,7 @@
             android:layout_marginLeft="8dip"
             android:textSize="18sp"
             android:drawableLeft="@drawable/ic_emergency"
-            android:drawablePadding="8dip"
+            android:drawablePadding="4dip"
         />
     </LinearLayout>
 
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml b/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml
index e5e0459..0f2ae0c 100644
--- a/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml
@@ -177,7 +177,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:drawableLeft="@android:drawable/ic_emergency"
-            android:drawablePadding="8dip"
+            android:drawablePadding="4dip"
             android:text="@android:string/lockscreen_emergency_call"
         />
     </LinearLayout>
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 0368530..4349c5b 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -29,7 +29,8 @@
     android:gravity="center_horizontal">
 
     <com.android.internal.widget.DigitalClock android:id="@+id/time"
-        android:layout_marginBottom="18dip"
+        android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin"
+        android:layout_marginBottom="12dip"
         android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin"
         android:layout_gravity="right">
 
@@ -149,7 +150,7 @@
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_alignParentBottom="true"
-            android:layout_marginBottom="8dip"
+            android:layout_marginBottom="12dip"
             android:gravity="center_horizontal"
             android:singleLine="true"
             android:ellipsize="marquee"
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 2849376..294f91e 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -104,6 +104,7 @@
         android:id="@+id/carrier"
         android:layout_width="0dip"
         android:layout_gravity="fill_horizontal"
+        android:layout_marginBottom="12dip"
         android:gravity="right"
         android:singleLine="true"
         android:ellipsize="marquee"
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 64c479f..03fc79e 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -28,7 +28,8 @@
     android:gravity="center_horizontal">
 
     <com.android.internal.widget.DigitalClock android:id="@+id/time"
-        android:layout_marginBottom="18dip"
+        android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin"
+        android:layout_marginBottom="12dip"
         android:layout_marginRight="@dimen/keyguard_lockscreen_status_line_font_right_margin"
         android:layout_gravity="right">
 
@@ -171,4 +172,19 @@
         android:layout_height="0dip"
         />
 
+    <!-- Area to overlay FaceLock -->
+    <TextView android:id="@+id/faceLockAreaView"
+        android:visibility="gone"
+        android:layout_row="4"
+        android:layout_column="0"
+        android:layout_rowSpan="1"
+        android:layout_columnSpan="1"
+        android:layout_gravity="fill"
+        android:layout_marginTop="8dip"
+        android:layout_marginBottom="8dip"
+        android:layout_width="0dip"
+        android:layout_height="0dip"
+        android:background="@color/facelock_color_background"
+    />
+
 </GridLayout>
diff --git a/core/res/res/layout/volume_adjust.xml b/core/res/res/layout/volume_adjust.xml
index ea4e1f9..c16a12c 100644
--- a/core/res/res/layout/volume_adjust.xml
+++ b/core/res/res/layout/volume_adjust.xml
@@ -21,7 +21,6 @@
         android:id="@+id/visible_panel"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginTop="80dp"
         android:background="@android:drawable/dialog_full_holo_dark"
         android:orientation="horizontal"
         >
diff --git a/core/res/res/layout/webview_find.xml b/core/res/res/layout/webview_find.xml
index 4cf2df5..a628ac8 100644
--- a/core/res/res/layout/webview_find.xml
+++ b/core/res/res/layout/webview_find.xml
@@ -26,7 +26,7 @@
         android:scrollHorizontally="true"
         android:inputType="text"
         android:hint="@string/find_on_page"
-        android:imeOptions="actionDone"
+        android:imeOptions="actionDone|flagNoExtractUi|flagNoFullscreen"
         android:layout_marginRight="10dip"
         />
     <TextView android:id="@+id/matches"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index c2ff20b..ddb1baf 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"የURL ቅጂ"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"ፅሁፍ ምረጥ"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"የፅሁፍ ምርጫ"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"ወደ መዝገበ ቃላት አክል"</string>
-    <string name="deleteText" msgid="7070985395199629156">"ሰርዝ"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"ግቤት ሜተድ"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"የፅሁፍ እርምጃዎች"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"ቦታ አንሷል"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"የUSB  ማከማቻ"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"አርትእ..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"የውሂብ አጠቃቀም ማስጠንቀቂየ"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"ቅንብሮችን እና አጠቃቀምን ለማየት ንካ"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G ውሂብ ቦዝኗል"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G ውሂብ ቦዝኗል"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"የተንቀሳቃሽ ውሂብ ቦዝኗል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 49cd387..0386ab4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"نسخ عنوان URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"تحديد نص..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"تحديد النص"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"إضافة إلى القاموس"</string>
-    <string name="deleteText" msgid="7070985395199629156">"حذف"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"طريقة الإرسال"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"إجراءات النص"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"المساحة منخفضة"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"وحدة تخزين USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"تعديل..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"تحذير استخدام البيانات"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"المس لعرض الاستخدام والإعدادات"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"تم تعطيل بيانات شبكات الجيل الثاني والجيل الثالث"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"تم تعطيل بيانات الجوال"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 4470d47..c55322b 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Копиране на URL адреса"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Избиране на текст..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Избиране на текст"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"добавяне към речника"</string>
-    <string name="deleteText" msgid="7070985395199629156">"изтриване"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Метод на въвеждане"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Действия с текста"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Мястото не достига"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB хранилище"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Редактиране..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Предупрежд. за ползване на данни"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Ползване и настройки: Докоснете"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G данните са деактивирани"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G данните са деактивирани"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобилните данни са деактивирани"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index f9dd816..2190b7e 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopírovat adresu URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Vybrat text..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Výběr textu"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"přidat do slovníku"</string>
-    <string name="deleteText" msgid="7070985395199629156">"smazat"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Metoda zadávání dat"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operace s textem"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Málo paměti"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Úložiště USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Upravit..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Upozornění na využití dat"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Dotykem zobraz. využití a nast."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datové přenosy 2G a 3G zakázány"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datové přenosy 4G jsou zakázány"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilní data jsou zakázána"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index f942642..f5a9846 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopier webadresse"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Marker tekst..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstmarkering"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"føj til ordbog"</string>
-    <string name="deleteText" msgid="7070985395199629156">"slet"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Inputmetode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Der er ikke så meget plads tilbage"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-lager"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Rediger..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Advarsel om dataforbrug"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Tryk for at få vist brug og indstillinger"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G-data er deaktiveret"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-data er deaktiveret"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata er deaktiveret"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index ababfee..d376fd9 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"URL kopieren"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Text auswählen..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Textauswahl"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"Zum Wörterbuch hinzufügen"</string>
-    <string name="deleteText" msgid="7070985395199629156">"Löschen"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Eingabemethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textaktionen"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Geringer Speicher"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-Speicher"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Bearbeiten..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Warnung zu Datennutzung"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Zur Anzeige der Nutzung/Einstellungen berühren"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-/3G-Daten deaktiviert"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-Daten deaktiviert"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobile Daten deaktiviert"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 41c32de..601a054 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Αντιγραφή διεύθυνσης URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Επιλογή κειμένου..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Επιλογή κειμένου"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"προσθήκη στο λεξικό"</string>
-    <string name="deleteText" msgid="7070985395199629156">"διαγραφή"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Μέθοδος εισόδου"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ενέργειες κειμένου"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Απομένει λίγος ελεύθερος χώρος"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Χώρος αποθήκευσης USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Επεξεργασία..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Προειδοποίηση χρήσης δεδομένων"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Αγγ.για προβ.της χρ.και των ρυθ."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Τα δεδ. 2G-3G απενεργοποιήθηκαν"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Τα δεδομένα 4G απενεργοποιήθηκαν"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Τα δεδομ. κιν. τηλεφ. απενεργοπ."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index cd701a6..721b0c7 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selección de texto"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"Agregar al diccionario"</string>
-    <string name="deleteText" msgid="7070985395199629156">"Eliminar"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio de almacenamiento"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Almacenamiento USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Advertencia de uso de datos"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Toca para ver uso y config."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datos de 2 GB - 3 GB desactivados"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datos de 4 GB desactivados"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datos móviles desactivados"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f511d02..dc3a630 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selección de texto"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"añadir al diccionario"</string>
-    <string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Método de introducción de texto"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acciones de texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Poco espacio"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Almacenamiento USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Advertencia de uso de datos"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Tocar para ver el uso y ajustes"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datos 2G-3G inhabilitados"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datos 4G inhabilitados"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datos móviles inhabilitados"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 6fce5ee..1462df4 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopioi URL-osoite"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Tekstin valinta..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstin valinta"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"lisää sanakirjaan"</string>
-    <string name="deleteText" msgid="7070985395199629156">"poista"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Syöttötapa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstitoiminnot"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Tila vähissä"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-tallennustila"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Muokkaa..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Tiedonsiirtovaroitus"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Näytä käyttö ja asetukset"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G-tiedonsiirto pois käytöstä"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-tiedonsiirto pois käytöstä"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiilitiedonsiirto pois käytöstä"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 81e3ca1..c5e692b 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copier l\'URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Sélect. le texte..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Sélection de texte"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"ajouter au dictionnaire"</string>
-    <string name="deleteText" msgid="7070985395199629156">"supprimer"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Actions sur le texte"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Espace disponible faible"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Mémoire de stockage USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Modifier..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Avertissement utilisation données"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Appuyez pour utilisation/param."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Données 2G-3G désactivées"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Données 4G désactivées"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Données mobiles désactivées"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index dc26670..ab6eb93 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopiraj URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Odabir teksta..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Odabir teksta"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"dodaj u rječnik"</string>
-    <string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Radnje s tekstom"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Prostora ima sve manje"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB pohrana"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Uređivanje..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Upozorenje o upotrebi podataka"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Dodirnite za pregled upotrebe i postavki"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G podaci su onemogućeni"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G podaci su onemogućeni"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilni podaci su onemogućeni"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index a805686..3e2ae7f 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"URL másolása"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Szöveg kijelölése..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Szöveg kijelölése"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"hozzáadás a szótárhoz"</string>
-    <string name="deleteText" msgid="7070985395199629156">"törlés"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Beviteli mód"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Műveletek szöveggel"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Kevés a hely"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-tár"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Szerkesztés..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Adathasználati figyelmeztetés"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Haszn. és beállítás: érintse meg"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G adatforgalom letiltva"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G adatforgalom letiltva"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobil adatforgalom letiltva"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 785acef..aea1a4c 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Salin URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Pilih teks..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"tambahkan ke kamus"</string>
-    <string name="deleteText" msgid="7070985395199629156">"hapus"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Metode masukan"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tindakan teks"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Ruang penyimpanan tinggal sedikit"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Penyimpanan USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Edit..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Peringatan penggunaan data"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Sentuh utk mlht pnggnaan dan stln"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Data 2G-3G dinonaktifkan"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data 4G dinonaktifkan"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Data seluler dinonaktifkan"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 181910c..c0c1695 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"העתק כתובת אתר"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"בחר טקסט..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"בחירת טקסט"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"הוסף למילון"</string>
-    <string name="deleteText" msgid="7070985395199629156">"מחק"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"פעולות טקסט"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"חסר שטח"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"אמצעי אחסון מסוג USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"ערוך..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"אזהרת שימוש בנתונים"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"גע כדי להציג נתוני שימוש והגדרות"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"נתוני 2G-3G מושבתים"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"נתוני 4G מושבתים"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"נתונים לנייד מושבתים"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1d4de64..42a6e37 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"URL 복사"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"텍스트 선택..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"텍스트 선택"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"사전에 추가"</string>
-    <string name="deleteText" msgid="7070985395199629156">"삭제"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"입력 방법"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"텍스트 작업"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"저장공간 부족"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB 저장소"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"수정..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"데이터 사용 경고"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"사용 및 설정을 보려면 터치하세요."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G 데이터 사용중지됨"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 데이터 사용중지됨"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"모바일 데이터 사용중지됨"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bb7e3ca..3a30114 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopijuoti URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Pasirinkti tekstą..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Teksto pasirinkimas"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"pridėti prie žodyno"</string>
-    <string name="deleteText" msgid="7070985395199629156">"ištrinti"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Įvesties būdas"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksto veiksmai"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Mažai vietos"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB atmintis"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Redaguoti..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Įspėjimas dėl duomenų naudojimo"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Paliesk., kad žr. naud. ir nust."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G–3G duomenys neleidžiami"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G duomenys neleidžiami"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilieji duomenys neleidžiami"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 8af324f..e9a01e9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopēt URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Atlasīt tekstu..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Teksta atlase"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"pievienot vārdnīcai"</string>
-    <string name="deleteText" msgid="7070985395199629156">"dzēst"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Ievades metode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksta darbības"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Maz brīvas vietas"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB atmiņa"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Rediģēt..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Datu izmantošanas brīdinājums"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Piesk., lai sk. lietoš. un iest."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G–3G dati ir atspējoti"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G dati ir atspējoti"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilie dati ir atspējoti"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 90ae2c1..e879f9b 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopier URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Marker tekst"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Merket tekst"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"legg til i ordliste"</string>
-    <string name="deleteText" msgid="7070985395199629156">"slett"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Inndatametode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Teksthandlinger"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Lite plass"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-lagring"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Rediger"</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Advarsel for høyt dataforbruk"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Berør for å se bruk og innst."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G–3G-data er deaktivert"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-data er deaktivert"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata er deaktivert"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 464d2e9..5d22f64 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"URL kopiëren"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Tekst selecteren..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Tekstselectie"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"toevoegen aan woordenboek"</string>
-    <string name="deleteText" msgid="7070985395199629156">"verwijderen"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Invoermethode"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Tekstacties"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Weinig ruimte"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-opslag"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Bewerken..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Waarschuwing v. gegevensgebruik"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Aanraken: gebruik/inst. bekijken"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-/3G-gegevens uitgeschakeld"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G-gegevens uitgeschakeld"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobiele gegevens uitgeschakeld"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7ed8220..56553cd 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopiuj adres URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Zaznacz tekst"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Zaznaczanie tekstu"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"dodaj do słownika"</string>
-    <string name="deleteText" msgid="7070985395199629156">"usuń"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Sposób wprowadzania tekstu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Działania na tekście"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Mało miejsca"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Nośnik USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Edytuj..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Ostrzeżenie o transmisji danych"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Kliknij i zobacz użycie i ustaw."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Wyłączono transmisję danych 2G/3G"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Wyłączono transmisję danych 4G"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Wyłączono komórkową transm. danych"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 565bfd0..e60a3c87 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Seleccionar texto..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selecção de texto"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"adicionar ao dicionário"</string>
-    <string name="deleteText" msgid="7070985395199629156">"eliminar"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acções de texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Pouco espaço livre"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Aviso de utilização de dados"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Toque para ver a utilização e as definições"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Os dados 2G-3G estão desativados"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Os dados 4G estão desativados"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Os dados móveis estão desativados"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index dc9a9f5..de8266b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiar URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Selecionar texto..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Seleção de texto"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"adicionar ao dicionário"</string>
-    <string name="deleteText" msgid="7070985395199629156">"excluir"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Ações de texto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Pouco espaço"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Armazenamento USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Editar..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Aviso sobre uso de dados"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Tocar p/ ver uso e configurações"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Dados 2G e 3G desativados"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dados 4G desativados"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dados móveis desativados"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index ff0f310..c538450 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Copiaţi adresa URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Selectaţi text..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Selectare text"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"adăugaţi în dicţionar"</string>
-    <string name="deleteText" msgid="7070985395199629156">"ştergeţi"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Metodă de intrare"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Acţiuni pentru text"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Spaţiu de stocare redus"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Dsipozitiv de stocare USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Editaţi..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Avertisment de utiliz. a datelor"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Ating. pt. afiş. utiliz./setări"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Datele 2G-3G au fost dezactivate"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Datele 4G au fost dezactivate"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Datele mobile au fost dezactiv."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 7d464ca..2ca256f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Копировать URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Выбрать текст..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Выбор текста"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"добавить в словарь"</string>
-    <string name="deleteText" msgid="7070985395199629156">"удалить"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Способ ввода"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Операции с текстом"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Недостаточно места"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-накопитель"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Изменить..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Осталось мало трафика"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Посмотрите трафик и настройки"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Передача данных 2G/3G отключена"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Передача данных 4G отключена"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобильный Интернет отключен"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 376c714..9cf846f 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Skopírovať adresu URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Vybrať text..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Výber textu"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"pridať do slovníka"</string>
-    <string name="deleteText" msgid="7070985395199629156">"odstrániť"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Metóda vstupu"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Operácie s textom"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Nedostatok pamäte"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Ukladací priestor USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Upraviť..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Upozornenie o využití dát"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Zobr. využívania dát a nastavení"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Dátové prenosy 2G a 3G zakázané"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Dátové prenosy 4G zakázané"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilné dátové prenosy zakázané"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index cfe2054..5aa1448 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopiraj URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Izbiranje besedila ..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Izbrano besedilo"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"dodaj v slovar"</string>
-    <string name="deleteText" msgid="7070985395199629156">"izbriši"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Način vnosa"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Besedilna dejanja"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Zmanjkuje pomnilnika"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Pomnilnik USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Urejanje ..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Opozorilo o uporabi podatkov"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Dotik za prikaz uporabe in nast."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Podatki 2G-3G so onemogočeni"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Podatki 4G so onemogočeni"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobilni podatki so onemogočeni"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e22cc0a..f60e212 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Копирај URL адресу"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Изабери текст..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Избор текста"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"додај у речник"</string>
-    <string name="deleteText" msgid="7070985395199629156">"избриши"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Метод уноса"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Радње у вези са текстом"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Мало простора"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB меморија"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Измени..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Упозорење о потрошњи података"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Додир за коришћење и подешавања"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G подаци су онемогућени"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G подаци су онемогућени"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Подаци мобилне мреже су онемогућени"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 93dce56..9a42ff3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopiera webbadress"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Markera text..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Textmarkering"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"lägg till i ordlista"</string>
-    <string name="deleteText" msgid="7070985395199629156">"ta bort"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Indatametod"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Textåtgärder"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Dåligt med utrymme"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB-lagring"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Redigera..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Varning angående dataanvändning"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Tryck om du vill visa användning och inställningar"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Data via 2G-3G har inaktiverats"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Data via 4G har inaktiverats"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Mobildata har inaktiverats"</string>
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index 13bbac6..7fa7658 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -32,5 +32,8 @@
     <!-- see comment in values/config.xml -->
     <dimen name="config_prefDialogWidth">580dp</dimen>
     
+    <!-- If true, the screen can be rotated via the accelerometer in all 4
+         rotations as the default behavior. -->
+    <bool name="config_allowAllRotations">true</bool>
 </resources>
 
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index d6ca340..f535cae 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"คัดลอก URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"เลือกข้อความ..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"การเลือกข้อความ"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"เพิ่มลงในพจนานุกรม"</string>
-    <string name="deleteText" msgid="7070985395199629156">"ลบ"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"วิธีป้อนข้อมูล"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"การทำงานของข้อความ"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"เหลือที่ว่างน้อย"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"ที่เก็บข้อมูล USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"แก้ไข..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"คำเตือนการใช้ข้อมูล"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"แตะเพื่อดูการใช้งานและการตั้งค่า"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"ปิดใช้งานข้อมูล 2G-3G"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"ปิดใช้งานข้อมูล 4G"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"ปิดใช้งานข้อมูลมือถือ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 71e3062..3803181 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopyahin ang URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Pumili ng teksto..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Pagpili ng teksto"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"idagdag sa diksyunaryo"</string>
-    <string name="deleteText" msgid="7070985395199629156">"tanggalin"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Pamamaraan ng pag-input"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Pagkilos ng teksto"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Mababa sa espasyo"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB storage"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"I-edit..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Babala sa paggamit ng data"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Pindutin upang tingnan ang paggamit at mga setting"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Di pinagana ang data ng 2G-3G"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Di pinagana ang data ng 4G"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Di pinagana ang data ng mobile"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6e5eb53..1eb5ed0 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Копіюв. URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Вибрати текст..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Вибір тексту"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"додати в словник"</string>
-    <string name="deleteText" msgid="7070985395199629156">"видалити"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Метод введення"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Дії з текстом"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Недост. місця"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Носій USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Редагувати..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Застереження про використ. даних"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Торкн.для перегл.викор.і налашт."</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Дані 2G–3G вимкнено"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Дані 4G вимкнено"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Мобільне передав. даних вимкнено"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index a446d2d..e4d3423 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Sao chép URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Chọn văn bản..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Lựa chọn văn bản"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"thêm vào từ điển"</string>
-    <string name="deleteText" msgid="7070985395199629156">"xóa"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <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>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Còn ít dung lượng"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Bộ lưu trữ USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Chỉnh sửa..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Cảnh báo sử dụng dữ liệu"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Chạm để xem việc sử dụng và cài đặt"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Đã tắt dữ liệu 2G-3G"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G dữ liệu bị vô hiệu hóa"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Dữ liệu di động bị vô hiệu hóa"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index fb14242..a306d67 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"复制网址"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"选择文字..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"文字选择"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"添加到词典"</string>
-    <string name="deleteText" msgid="7070985395199629156">"删除"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"输入法"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字操作"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"存储空间不足"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB 存储器"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"编辑..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"数据使用情况警告"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"触摸可查看使用情况和设置"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"2G-3G 数据已停用"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据已停用"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据已停用"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 7d6e38c..6b13a95 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"複製網址"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"選取文字..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"選取文字"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"新增至字典"</string>
-    <string name="deleteText" msgid="7070985395199629156">"刪除"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"輸入方式"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"文字動作"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"儲存空間即將不足"</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"USB 儲存裝置"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"編輯..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"資料用量警告"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"輕觸即可查看使用量和設定"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"已停用 2G-3G 數據"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"已停用 4G 數據"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"已停用行動數據"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 46c1065..f7dde4f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -21,11 +21,11 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="8340973892742019101">"B"</string>
-    <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string>
-    <string name="megabyteShort" msgid="6355851576770428922">"MB"</string>
-    <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string>
-    <string name="terabyteShort" msgid="231613018159186962">"TB"</string>
-    <string name="petabyteShort" msgid="5637816680144990219">"PB"</string>
+    <string name="kilobyteShort" msgid="5973789783504771878">"I-KB"</string>
+    <string name="megabyteShort" msgid="6355851576770428922">"I-MB"</string>
+    <string name="gigabyteShort" msgid="3259882455212193214">"I-GB"</string>
+    <string name="terabyteShort" msgid="231613018159186962">"I-TB"</string>
+    <string name="petabyteShort" msgid="5637816680144990219">"I-PB"</string>
     <string name="fileSizeSuffix" msgid="7670819340156489359">"<xliff:g id="NUMBER">%1$s</xliff:g><xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="6071602020171759109">"&lt;untitled&gt;"</string>
     <string name="ellipsis" msgid="7899829516048813237">"..."</string>
@@ -80,11 +80,11 @@
     <string name="serviceClassVoice" msgid="1258393812335258019">"Izwi"</string>
     <string name="serviceClassData" msgid="872456782077937893">"Idatha"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"Ifeksi"</string>
-    <string name="serviceClassSMS" msgid="2015460373701527489">"SMS"</string>
+    <string name="serviceClassSMS" msgid="2015460373701527489">"I-SMS"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"Vumelanisa"</string>
     <string name="serviceClassDataSync" msgid="7530000519646054776">"Vumelanisa"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"Iphakethe"</string>
-    <string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
+    <string name="serviceClassPAD" msgid="3235259085648271037">"I-PAD"</string>
     <string name="roamingText0" msgid="7170335472198694945">"Isikhombisi Sokuzulazula Sivuliwe"</string>
     <string name="roamingText1" msgid="5314861519752538922">"Isibonisi Sokuzulazula Sivaliwe"</string>
     <string name="roamingText2" msgid="8969929049081268115">"Isikhombisi Sokuzulazula Siyafulesha"</string>
@@ -285,7 +285,7 @@
     <string name="permlab_deletePackages" msgid="3343439331576348805">"susa izinhlelo zokusebenza"</string>
     <string name="permdesc_deletePackages" msgid="3634943677518723314">"Ivumela izinhlelo zokusebenza ukususa amaphakheji e-Android. Izinhlelo zokusebenza ezinonya zingase zisebenzise lokhu ukususa izinhlelo zokusebenza ezibalulekile."</string>
     <string name="permlab_clearAppUserData" msgid="2192134353540277878">"susa enye idatha yezinhlelo zokusebenza"</string>
-    <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Ivumela uhlelo lokusebenza ukuthi lisule idatha yomsebenzisi."</string>
+    <string name="permdesc_clearAppUserData" msgid="7546345080434325456">"Ivumela uhlelo lokusebenza ukuba lisule idatha yomsebenzisi."</string>
     <string name="permlab_deleteCacheFiles" msgid="1518556602634276725">"susa ezinye izilondolozi zesikhashana zezinhlelo zokusebenza"</string>
     <string name="permdesc_deleteCacheFiles" msgid="2283074077168165971">"Ivumela uhlelo lokusebenza ukususa amafayela okulondoloza okwesikhashana."</string>
     <string name="permlab_getPackageSize" msgid="4799785352306641460">"linganisa isikhala sokugcina uhlelo lokusebenza"</string>
@@ -336,7 +336,7 @@
     <string name="permdesc_writeCalendar" msgid="5368129321997977226">"Ivumela uhlelo lokusebenza ukuthumela izimemo njengomnikazi wekhalenda futhi ufake, ukhiphe, ushintshe izenzakalo ongakwazi ukuziguqula kwidivaysi yakho, kuhlanganise lezo zabangani noma osebenza nabo. Uhlelo lokusebenza olu-malicious olunalemvume lungase luthumele ama-imeyili angafuneki ukuba aphume kubanikazi bekhalenda, luguqule izenzakalo ngaphandle kolwazi lomnikazi, noma lufake izenzakalo mbumbulu ezintsha."</string>
     <string name="permlab_accessMockLocation" msgid="8688334974036823330">"lungisela imithombo yendawo ukuhlolwa"</string>
     <string name="permdesc_accessMockLocation" msgid="7648286063459727252">"Yenza imithombo yendawo ukuhlola. Izinhlelo ezinonya zingase zisebenzise lokhu ukukhipha indawo futhi/noma isimo esibuyiswe imithombo yendawo yangempela njengabahlinzeki be-GPS noma Inethiwekhi."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"finyelela kweminye imiyalo yokunikeza indawo"</string>
+    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"finyelela eminye imiyalo yokunikeza indawo"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="1948144701382451721">"Finyelela kweminye imiyalo yendawo eyengeziwe. Izinhlelo ezinonya zingase zisebenzise lokhu ukuphazamaisa ukusebenza kwe-GPS noma eminye imithombo yezinye izindawo."</string>
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"imvume yokufaka umhlinzeki wendawo"</string>
     <string name="permdesc_installLocationProvider" msgid="5449175116732002106">"Yenza imithombo yokudlala ukuhlola. Izinhlelo ezinonya zingase zisebenzise lokhu ukukhipha indawo futhi/noma isimo esibuyiswe imithombo yendawo yangempela njenge-GPS noma abahlinzeki Benethiwekhi noma zigade futhi zibike indawo yakho njengomthombo wangaphandle."</string>
@@ -397,7 +397,7 @@
     <string name="permdesc_performCdmaProvisioning" msgid="6457447676108355905">"Ivumela uhlelo lokusebenza ukuqalisa amalungiselelo e-CDMA. Izinhlelo ezinonya ngokungadingekile zingaqalisa amalungiselelo e-CDMA."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"lawula izaziso zokubuyekeza indawo"</string>
     <string name="permdesc_locationUpdates" msgid="2300018303720930256">"Ivumela ukuvula/ukuvimbela izaziso zesibuyekezo sendawo kusuka emsakazweni. Akumele isebenziswe izinhlelo zokusebenza ezivamile."</string>
-    <string name="permlab_checkinProperties" msgid="7855259461268734914">"finyelela kwizakhiwo zokuhlola"</string>
+    <string name="permlab_checkinProperties" msgid="7855259461268734914">"finyelela izakhiwo zokuhlola"</string>
     <string name="permdesc_checkinProperties" msgid="7150307006141883832">"Ivumela ukufinyelela kokufunda/ukubhalela ezicini ezilayishwe insizakalo zokuhlola. Akuyona eyokusebenziswa izinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"khetha izinqunjwana"</string>
     <string name="permdesc_bindGadget" msgid="2098697834497452046">"Ivumela uhlelo lokusebenza ukutshela isistimu ukuthi yimaphi amawijethi angasebenziswa yiziphi izinhlelo zokusebenza. Ngalemvume, izinhlelo zokusebenza zinganikeza ukufinyelela idatha yomuntu siqu kwezinye izinhlelo zokusebenza. Ayisebenziswa izinhlelo zokusebenza ezivamile."</string>
@@ -678,7 +678,7 @@
     <string name="lockscreen_too_many_failed_attempts_countdown" msgid="6251480343394389665">"Zama futhi emizuzwini  engu <xliff:g id="NUMBER">%d</xliff:g>."</string>
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Ukhohlwe iphethini?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Ukuvulwa kwe-akhawunti"</string>
-    <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Kunemizamo eminingi kakhulu yephathini!"</string>
+    <string name="lockscreen_glogin_too_many_attempts" msgid="2446246026221678244">"Kunemizama eminingi kakhulu yephathini!"</string>
     <string name="lockscreen_glogin_instructions" msgid="1816635201812207709">"Ukuvula, ngena ngemvumekwi-akhawunti ye-Google"</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Igama lomsebenzisi (i-imeyli)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"I-password"</string>
@@ -859,8 +859,12 @@
     <string name="copyUrl" msgid="2538211579596067402">"Kopisha i-URL"</string>
     <string name="selectTextMode" msgid="6738556348861347240">"Khetha umbhalo..."</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"Inketho yombhalo"</string>
-    <string name="addToDictionary" msgid="9090375111134433012">"Faka esichazinimazwi"</string>
-    <string name="deleteText" msgid="7070985395199629156">"susa"</string>
+    <!-- unknown placeholder WORD in addToDictionary -->
+    <skip />
+    <!-- no translation found for addToDictionary (9090375111134433012) -->
+    <skip />
+    <!-- no translation found for deleteText (7070985395199629156) -->
+    <skip />
     <string name="inputMethod" msgid="1653630062304567879">"Indlela yokufakwayo"</string>
     <string name="editTextMenuTitle" msgid="4909135564941815494">"Izenzo zombhalo"</string>
     <string name="low_internal_storage_view_title" msgid="1399732408701697546">"Isikhala sincane"</string>
@@ -876,9 +880,9 @@
     <string name="capital_off" msgid="6815870386972805832">"VALIWE"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Qedela isenzo usebenzisa"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Sebenzisa ngokuzenzakalelayo kulesenzo."</string>
-    <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Sula okuzenzakalelayo Emalungiselelweni Asekhaya; Uhlelo Lokusebenza; Phatha izinhlelo zokusebenza"</string>
+    <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Sula okuzenzakalelayo Emalungiselelweni Asekhaya &gt; Uhlelo Lokusebenza &gt; Phatha izinhlelo zokusebenza"</string>
     <string name="chooseActivity" msgid="1009246475582238425">"Khetha isenzo"</string>
-    <string name="chooseUsbActivity" msgid="7892597146032121735">"Khethela idivayisi ye-USB uhlelo lokusebenza"</string>
+    <string name="chooseUsbActivity" msgid="7892597146032121735">"Khethela idivayisi ye-USB uhlelolokusebenza"</string>
     <string name="noApplications" msgid="1691104391758345586">"Azikho izinhlelo zokusebenza ezingenza lesi sinyathelo."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"Ngeshwa, <xliff:g id="APPLICATION">%1$s</xliff:g> kumile."</string>
@@ -1116,7 +1120,7 @@
     <!-- no translation found for add_account_button_label (3611982894853435874) -->
     <skip />
     <string name="number_picker_increment_button" msgid="4830170763103463443">"Nciphisa"</string>
-    <string name="number_picker_decrement_button" msgid="2576606679160067262">"Decrement"</string>
+    <string name="number_picker_decrement_button" msgid="2576606679160067262">"i-Descrement"</string>
     <string name="number_picker_increment_scroll_mode" msgid="1343063395404990189">"<xliff:g id="VALUE">%s</xliff:g> chofoza bese ucindezela."</string>
     <string name="number_picker_increment_scroll_action" msgid="4628981789985093179">"Shishilizisa kwenyuke kuye ekwenyusweni kwehle kuye ekwehlisweni."</string>
     <string name="time_picker_increment_minute_button" msgid="2843066823236250329">"Umzuzu wokwenyusa."</string>
@@ -1164,7 +1168,10 @@
     <string name="storage_usb" msgid="3017954059538517278">"Isitoreji se-USB"</string>
     <string name="extract_edit_menu_button" msgid="302060189057163906">"Hlela..."</string>
     <string name="data_usage_warning_title" msgid="1955638862122232342">"Isexwayiso sokusetshenziswa kwedatha"</string>
-    <string name="data_usage_warning_body" msgid="7217480745540055170">"Thinta ze ubone ukusebenza kanye nezisetho"</string>
+    <!-- unknown placeholder SIZE in data_usage_warning_body -->
+    <skip />
+    <!-- no translation found for data_usage_warning_body (7217480745540055170) -->
+    <skip />
     <string name="data_usage_3g_limit_title" msgid="7093334419518706686">"Idatha ye-2G-3G ikhubasekisiwe"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"Idatha ye-4G ikhubazekisiwe"</string>
     <string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"Idatha yeselula ikhubazekile"</string>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index ddb9942..f0c6d09 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -112,6 +112,9 @@
     <color name="lockscreen_clock_am_pm">#ff9a9a9a</color>
     <color name="lockscreen_owner_info">#ff9a9a9a</color>
 
+    <!-- FaceLock -->
+    <color name="facelock_color_background">#000000</color>
+
     <!-- For holo theme -->
       <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
       <drawable name="screen_background_holo_dark">#ff000000</drawable>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8fea35f..5eb3e5a 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -231,7 +231,7 @@
 
     <!-- If true, the screen can be rotated via the accelerometer in all 4
          rotations as the default behavior. -->
-    <bool name="config_allowAllRotations">true</bool>
+    <bool name="config_allowAllRotations">false</bool>
 
     <!-- If true, the direction rotation is applied to get to an application's requested
          orientation is reversed.  Normally, the model is that landscape is
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f1fc42c..1cd3911 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -158,7 +158,10 @@
     <dimen name="keyguard_lockscreen_status_line_font_size">14sp</dimen>
 
     <!-- Size of right margin on Unsecure unlock LockScreen -->
-    <dimen name="keyguard_lockscreen_status_line_font_right_margin">45dip</dimen>
+    <dimen name="keyguard_lockscreen_status_line_font_right_margin">42dip</dimen>
+
+    <!-- Size of top margin on Clock font to edge on unlock LockScreen -->
+    <dimen name="keyguard_lockscreen_status_line_clockfont_top_margin">24dip</dimen>
 
     <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. -->
     <dimen name="activity_chooser_popup_min_width">200dip</dimen>
@@ -178,4 +181,6 @@
     <!-- Default width for a textview error popup -->
     <dimen name="textview_error_popup_default_width">240dip</dimen>
 
+    <!-- Volume panel y offset -->
+    <dimen name="volume_panel_top">80dp</dimen>
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 346a3d29..88b45fd 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -250,7 +250,7 @@
     </style>
 
     <style name="TextAppearance.EasyCorrectSuggestion" parent="TextAppearance.Suggestion">
-        <item name="android:textUnderlineColor">@color/holo_blue_dark</item>
+        <item name="android:textUnderlineColor">#ff888888</item>
     </style>
 
     <style name="TextAppearance.MisspelledSuggestion" parent="TextAppearance.Suggestion">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3378dc8..1987d99 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -94,7 +94,7 @@
 
         <item name="textAppearanceButton">@android:style/TextAppearance.Widget.Button</item>
         
-        <item name="editTextColor">?android:attr/textColorPrimaryInverse</item>
+        <item name="editTextColor">@android:color/primary_text_light</item>
         <item name="editTextBackground">@android:drawable/edit_text</item>
         
         <item name="candidatesTextStyleSpans">@android:string/candidates_style</item>
@@ -410,7 +410,7 @@
         <item name="textColorLink">@android:color/link_text_light</item>
         <item name="textColorLinkInverse">@android:color/link_text_dark</item>
         
-        <item name="editTextColor">?android:attr/textColorPrimary</item>
+        <item name="editTextColor">@android:color/primary_text_light</item>
         <item name="listChoiceBackgroundIndicator">@android:drawable/list_selector_background</item>
 
         <item name="activatedBackgroundIndicator">@android:drawable/activated_background_light</item>
diff --git a/core/tests/bandwidthtests/Android.mk b/core/tests/bandwidthtests/Android.mk
index 3d56141..6871efd 100644
--- a/core/tests/bandwidthtests/Android.mk
+++ b/core/tests/bandwidthtests/Android.mk
@@ -27,4 +27,4 @@
 
 include $(BUILD_PACKAGE)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index be740d3..9eee2f0 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -120,6 +120,42 @@
     }
 
     /**
+     * Ensure that downloading on wifi reports reasonable stats.
+     */
+    @LargeTest
+    public void testWifiUpload() {
+        assertTrue(setDeviceWifiAndAirplaneMode(mSsid));
+        // Download a file from the server.
+        String ts = Long.toString(System.currentTimeMillis());
+        String targetUrl = BandwidthTestUtil.buildDownloadUrl(
+                mTestServer, FILE_SIZE, mDeviceId, ts);
+        File tmpSaveFile = new File(BASE_DIR + File.separator + TMP_FILENAME);
+        assertTrue(BandwidthTestUtil.DownloadFromUrl(targetUrl, tmpSaveFile));
+
+        ts = Long.toString(System.currentTimeMillis());
+        NetworkStats pre_test_stats = fetchDataFromProc(mUid);
+        TrafficStats.startDataProfiling(mContext);
+        assertTrue(BandwidthTestUtil.postFileToServer(mTestServer, mDeviceId, ts, tmpSaveFile));
+        NetworkStats prof_stats = TrafficStats.stopDataProfiling(mContext);
+        Log.d(LOG_TAG, prof_stats.toString());
+        NetworkStats post_test_stats = fetchDataFromProc(mUid);
+        NetworkStats proc_stats = post_test_stats.subtract(pre_test_stats);
+
+        // Output measurements to instrumentation out, so that it can be compared to that of
+        // the server.
+        Bundle results = new Bundle();
+        results.putString("device_id", mDeviceId);
+        results.putString("timestamp", ts);
+        results.putInt("size", FILE_SIZE);
+        AddStatsToResults(PROF_LABEL, prof_stats, results);
+        AddStatsToResults(PROC_LABEL, proc_stats, results);
+        getInstrumentation().sendStatus(INSTRUMENTATION_IN_PROGRESS, results);
+
+        // Clean up.
+        assertTrue(cleanUpFile(tmpSaveFile));
+    }
+
+    /**
      * We want to make sure that if we use the Download Manager to download stuff,
      * accounting still goes to the app making the call and that the numbers still make sense.
      */
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
index d850169..577767c 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/BandwidthTestUtil.java
@@ -18,6 +18,15 @@
 
 import android.util.Log;
 
+import com.android.internal.http.multipart.FilePart;
+import com.android.internal.http.multipart.MultipartEntity;
+import com.android.internal.http.multipart.Part;
+import com.android.internal.http.multipart.StringPart;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.util.ByteArrayBuffer;
 
 import java.io.BufferedInputStream;
@@ -80,7 +89,7 @@
      * Download a given file from a target url to a given destination file.
      * @param targetUrl the url to download
      * @param file the {@link File} location where to save to
-     * @return true if it succeeded.
+     * @return true if it succeeded
      */
     public static boolean DownloadFromUrl(String targetUrl, File file) {
         try {
@@ -106,4 +115,39 @@
         return true;
     }
 
+    /**
+     * Post a given file for a given device and timestamp to the server.
+     * @param server {@link String} url of test server
+     * @param deviceId {@link String} device id that is uploading
+     * @param timestamp {@link String} timestamp
+     * @param file {@link File} to upload
+     * @return true if it succeeded
+     */
+    public static boolean postFileToServer(String server, String deviceId, String timestamp,
+            File file) {
+        try {
+            Log.d(LOG_TAG, "Uploading begining");
+            HttpClient httpClient = new DefaultHttpClient();
+            String uri = server;
+            if (!uri.endsWith("/")) {
+                uri += "/";
+            }
+            uri += "upload";
+            Log.d(LOG_TAG, "Upload url:" + uri);
+            HttpPost postRequest = new HttpPost(uri);
+            Part[] parts = {
+                    new StringPart("device_id", deviceId),
+                    new StringPart("timestamp", timestamp),
+                    new FilePart("file", file)
+            };
+            MultipartEntity reqEntity = new MultipartEntity(parts, postRequest.getParams());
+            postRequest.setEntity(reqEntity);
+            HttpResponse res = httpClient.execute(postRequest);
+            res.getEntity().getContent().close();
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Could not upload file with error: " + e);
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 9c3a0be..3716583 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -222,8 +222,7 @@
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/service-element.html">&lt;service&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-gl-texture-element.html">&lt;supports-gl-texture&gt;</a></li>
-          <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a>
-              <span class="new">updated</span></li>  <!-- ##api level 4## -->
+          <li><a href="<?cs var:toroot ?>guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></li><!-- ##api level 4## -->
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></li> <!-- ##api level 4## -->
           <li><a href="<?cs var:toroot ?>guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></li>
@@ -244,7 +243,7 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
                 <span class="en">3D with OpenGL</span>
-              </a><span class="new">updated</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
                 <span class="en">Property Animation</span>
               </a></li>
@@ -271,7 +270,7 @@
 
       <li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
             <span class="en">Media</span>
-          </a><span class="new">updated</span></li>
+          </a></li>
       <li>
         <a href="<?cs var:toroot ?>guide/topics/clipboard/copy-paste.html">
             <span class="en">Copy and Paste</span>
@@ -408,7 +407,6 @@
       </li>
       <li><a href="<?cs var:toroot ?>guide/market/publishing/multiple-apks.html">
           <span class="en">Multiple APK Support</span></a>
-          <span class="new">new!</span>
       </li>
     </ul>
   </li>
@@ -569,7 +567,7 @@
           </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>guide/developing/tools/adb.html">adb</a></li>
-          <li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT</a> <span class="new">new!</span></li>
+          <li><a href="<?cs var:toroot ?>guide/developing/tools/adt.html">ADT</a></li>
           <li><a href="<?cs var:toroot ?>guide/developing/tools/android.html">android</a></li>
           <li><a href="<?cs var:toroot ?>guide/developing/tools/bmgr.html">bmgr</a>
           <li><a href="<?cs var:toroot ?>guide/developing/tools/dmtracedump.html">dmtracedump</a></li>
@@ -672,14 +670,14 @@
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>guide/practices/screens_support.html">
           <span class="en">Supporting Multiple Screens</span>
-        </a> <span class="new">updated</span></div>
+        </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>guide/practices/screens-distribution.html">
             <span class="en">Distributing to Specific Screens</span>
           </a></li>
           <li><a href="<?cs var:toroot ?>guide/practices/screen-compat-mode.html">
             <span class="en">Screen Compatibility Mode</span>
-          </a> <span class="new">new!</span></li>
+          </a></li>
           <li><a href="<?cs var:toroot ?>guide/practices/screens-support-1.5.html">
             <span class="en">Strategies for Android 1.5</span>
           </a></li>
@@ -737,11 +735,11 @@
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>guide/practices/design/performance.html">
             <span class="en">Designing for Performance</span>
-          </a> <span class="new-child">new!</span></div>
+          </a></div>
         <ul>
           <li><a href="<?cs var:toroot ?>guide/practices/design/jni.html">
                 <span class="en">JNI Tips</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
         </ul>
       </li>
       <li><a href="<?cs var:toroot ?>guide/practices/design/responsiveness.html">
diff --git a/docs/html/guide/topics/resources/more-resources.jd b/docs/html/guide/topics/resources/more-resources.jd
index 5f4d5c2..972eab9 100644
--- a/docs/html/guide/topics/resources/more-resources.jd
+++ b/docs/html/guide/topics/resources/more-resources.jd
@@ -698,7 +698,7 @@
 TypedArray icons = res.{@link android.content.res.Resources#obtainTypedArray(int) obtainTypedArray}(R.array.icons);
 Drawable drawable = icons.{@link android.content.res.TypedArray#getDrawable(int) getDrawable}(0);
 
-TypedArray colors = res.{@link android.content.res.Resources#obtainTypedArray(int) obtainTypedArray}(R.array.icons);
+TypedArray colors = res.{@link android.content.res.Resources#obtainTypedArray(int) obtainTypedArray}(R.array.colors);
 int color = colors.{@link android.content.res.TypedArray#getColor(int,int) getColor}(0,0);
 </pre>
 </dd> <!-- end example -->
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 720e143..f799b0c 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -31,7 +31,8 @@
   },
   misc: {
     'external': 'External',
-    'new': 'New'
+    'new': 'New',
+    'updated': 'Updated'
   }
 };
 
@@ -377,7 +378,7 @@
 ///////////////////
  
   {
-    tags: ['sample', 'new'],
+    tags: ['sample'],
     path: 'samples/AccelerometerPlay/index.html',
     title: {
       en: 'Accelerometer Play'
@@ -387,7 +388,7 @@
     }
   },
   {
-    tags: ['sample', 'new', 'accessibility'],
+    tags: ['sample', 'accessibility'],
     path: 'samples/AccessibilityService/index.html',
     title: {
       en: 'Accessibility Service'
@@ -407,7 +408,7 @@
     }
   },
   {
-    tags: ['sample', 'layout', 'ui', 'fragment', 'loader', 'new'],
+    tags: ['sample', 'layout', 'ui', 'fragment', 'loader'],
     path: 'samples/Support4Demos/index.html',
     title: {
       en: 'API 4+ Support Demos'
@@ -417,7 +418,7 @@
     }
   },
   {
-    tags: ['sample', 'layout', 'ui', 'new'],
+    tags: ['sample', 'layout', 'ui'],
     path: 'samples/Support13Demos/index.html',
     title: {
       en: 'API 13+ Support Demos'
@@ -487,13 +488,13 @@
     }
   },
   {
-    tags: ['sample', 'new', 'newfeature', 'ui'],
+    tags: ['sample', 'updated', 'newfeature', 'ui'],
     path: 'samples/HoneycombGallery/index.html',
     title: {
       en: 'Honeycomb Gallery'
     },
     description: {
-      en: 'An image gallery application using APIs that are new in Android 3.0 (a.k.a. Honeycomb).'
+      en: 'An image gallery application that demonstrates a variety of new APIs in Android 3.0 (Honeycomb). In addition to providing a tablet-optimized design, it also supports handsets running Android 4.0 (Ice Cream Sandwich) and beyond, so is a good example of how to reuse Fragments to support different screen sizes.'
     }
   },
   {
@@ -547,7 +548,7 @@
     }
   },
   {
-    tags: ['sample', 'new', 'media' ],
+    tags: ['sample', 'media' ],
     path: 'samples/RandomMusicPlayer/index.html',
     title: {
       en: 'Random Music Player'
@@ -557,7 +558,7 @@
     }
   },
   {
-    tags: ['sample', 'new', 'newfeature', 'performance', 'gamedev', 'gl'],
+    tags: ['sample', 'newfeature', 'performance', 'gamedev', 'gl'],
     path: 'samples/RenderScript/index.html',
     title: {
       en: 'RenderScript'
@@ -637,7 +638,7 @@
     }
   },
   {
-    tags: ['sample', 'new', 'newfeature', 'widgets'],
+    tags: ['sample', 'newfeature', 'widgets'],
     path: 'samples/StackWidget/index.html',
     title: {
       en: 'StackView Widget'
@@ -667,7 +668,7 @@
     }
   },
   {
-    tags: ['sample', 'new', 'newfeature'],
+    tags: ['sample', 'newfeature'],
     path: 'samples/USB/index.html',
     title: {
       en: 'USB'
@@ -683,7 +684,7 @@
       en: 'Voicemail Provider Demo'
     },
     description: {
-      en: 'A sample application to demonstrate how to use voicemail content provider APIs.'
+      en: 'A sample application to demonstrate how to use voicemail content provider APIs in Android 4.0.'
     }
   },
   {
@@ -707,7 +708,7 @@
     }
   },
   {
-    tags: ['sample', 'widgets', 'newfeature', 'new'],
+    tags: ['sample', 'widgets', 'newfeature'],
     path: 'samples/WeatherListWidget/index.html',
     title: {
       en: 'Weather List Widget'
@@ -733,7 +734,7 @@
       en: 'Text To Speech Engine'
     },
     description: {
-      en: 'An example Text To Speech engine written using the android text to speech engine API.'
+      en: 'An example Text To Speech engine written using the Android text to speech engine API in Android 4.0.'
     }
   },
 
diff --git a/docs/html/sdk/android-3.2.jd b/docs/html/sdk/android-3.2.jd
index 5618eae..ea2b4ed 100644
--- a/docs/html/sdk/android-3.2.jd
+++ b/docs/html/sdk/android-3.2.jd
@@ -166,7 +166,7 @@
 reserved by the system.
 </li>
 
-<li>In constrast, a screen's <em>width</em> and <em>height</em> represent the
+<li>In contrast, a screen's <em>width</em> and <em>height</em> represent the
 current horizontal or vertical space available for application layout, measured
 in "dp" units, not including screen areas reserved by the system. The width and
 height of a screen change when the user switches orientation between landscape
@@ -313,7 +313,7 @@
 the system forces the application into screen compatibility mode, to ensure best
 display on the current screen.</li>
 
-<li><code>android:smallestWidthLimitDp="<em>numDp"</em></code> &mdash; This
+<li><code>android:requiresSmallestWidthDp="<em>numDp"</em></code> &mdash; This
 attribute lets you specify the minimum smallestWidth on which the application
 can run. If the current screen is smaller than the value specified, the system
 considers the application incompatible with the device, but does not prevent it
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index a00ca12..92b912d 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -77,7 +77,7 @@
     <ul>
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>sdk/android-3.2.html">
-        <span class="en">Android 3.2 Platform</span></a> <span class="new">new!</span></div>
+        <span class="en">Android 3.2 Platform</span></a></div>
         <ul>
           <!-- <li><a href="<?cs var:toroot ?>sdk/android-3.2-highlights.html">Platform Highlights</a></li> -->
           <li><a href="<?cs var:toroot ?>sdk/api_diff/13/changes.html">API Differences Report &raquo;</a></li>
@@ -142,11 +142,10 @@
       </li>
     </ul>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r12</a> <span
-class="new">new!</span></li>
+      <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r12</a></li>
       <li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
       <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Compatibility Package,
-r3</a> <span class="new">new!</span></li>
+r3</a></li>
     </ul>
   </li>
   <li>
@@ -169,7 +168,7 @@
       <span style="display:none" class="ja"></span>
       <span style="display:none" class="zh-CN"></span>
       <span style="display:none" class="zh-TW"></span></a>
-      <span class="new">new!</span></li>
+      </li>
     </ul>
   </li>
   <li>
@@ -183,8 +182,7 @@
       <span style="display:none" class="zh-TW"></span>
     </h2>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6b</a> 
-        <span class="new">new!</span>
+      <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r6b</a>
         </li>
       <li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li>
     </ul>
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 3e4fe8c..b2fa053 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -98,21 +98,27 @@
 }
 
 status_t DrmManager::loadPlugIns() {
+
+    String8 vendorPluginDirPath("/vendor/lib/drm");
+    loadPlugIns(vendorPluginDirPath);
+
     String8 pluginDirPath("/system/lib/drm");
-    return loadPlugIns(pluginDirPath);
+    loadPlugIns(pluginDirPath);
+    return DRM_NO_ERROR;
+
 }
 
 status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
-    if (mSupportInfoToPlugInIdMap.isEmpty()) {
-        mPlugInManager.loadPlugIns(plugInDirPath);
-        Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
-        for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
-            String8 plugInPath = plugInPathList[i];
-            DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
-            if (NULL != info) {
+    mPlugInManager.loadPlugIns(plugInDirPath);
+    Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
+    for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+        String8 plugInPath = plugInPathList[i];
+        DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
+        if (NULL != info) {
+            if (mSupportInfoToPlugInIdMap.indexOfKey(*info) < 0) {
                 mSupportInfoToPlugInIdMap.add(*info, plugInPath);
-                delete info;
             }
+            delete info;
         }
     }
     return DRM_NO_ERROR;
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 6b31ca4..e0f4cf9 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -88,11 +88,6 @@
         eElectronBeamAnimationOff = 0x10
     };
 
-    // flags for setOrientation
-    enum {
-        eOrientationAnimationDisable = 0x00000001
-    };
-
     /* create connection with surface flinger, requires
      * ACCESS_SURFACE_FLINGER permission
      */
@@ -112,7 +107,8 @@
     virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
     virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;
 
-    /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission */
+    /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission
+     * No flags are currently defined.  Set flags to 0. */
     virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags) = 0;
 
     /* signal that we're done booting.
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 4e65a2d..9e98bc5 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -27,7 +27,7 @@
 class Rect : public ARect
 {
 public:
-    typedef int32_t value_type;
+    typedef ARect::value_type value_type;
 
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
diff --git a/include/utils/threads.h b/include/utils/threads.h
index c685625..ab3e8cd 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -143,6 +143,10 @@
 // in either case errno is set.  Thread ID zero means current thread.
 extern int androidSetThreadPriority(pid_t tid, int prio);
 
+// Get the current priority of a particular thread. Returns one of the
+// ANDROID_PRIORITY constants or a negative result in case of error.
+extern int androidGetThreadPriority(pid_t tid);
+
 // Get the current scheduling group of a particular thread. Normally returns
 // one of the ANDROID_TGROUP constants other than ANDROID_TGROUP_DEFAULT.
 // Returns ANDROID_TGROUP_DEFAULT if no pthread support (e.g. on host) or if
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 79a01a3..f2bc81e 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -595,7 +595,7 @@
     Mutex::Autolock lock(mMutex);
 
     if (mAbandoned) {
-        LOGE("connect: SurfaceTexture has been abandoned!");
+        LOGE("disconnect: SurfaceTexture has been abandoned!");
         return NO_INIT;
     }
 
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index a398673..349b9e3 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -31,20 +31,16 @@
 // Rendering
 ///////////////////////////////////////////////////////////////////////////////
 
-Rect* gHackDontCorruptRegisters;
-
 void LayerRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) {
     LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo());
 
-    Rect dirty(left, top, right, bottom);
-    gHackDontCorruptRegisters = &dirty;
-
     glBindFramebuffer(GL_FRAMEBUFFER, mLayer->getFbo());
 
     const float width = mLayer->layer.getWidth();
     const float height = mLayer->layer.getHeight();
 
 #if RENDER_LAYERS_AS_REGIONS
+    Rect dirty(left, top, right, bottom);
     if (dirty.isEmpty() || (dirty.left <= 0 && dirty.top <= 0 &&
             dirty.right >= width && dirty.bottom >= height)) {
         mLayer->region.clear();
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 71951b7..edc90e1 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -28,7 +28,19 @@
 // Structs
 ///////////////////////////////////////////////////////////////////////////////
 
-struct Rect {
+class Rect {
+    static inline float min(float a, float b) { return (a<b) ? a : b; }
+    static inline float max(float a, float b) { return (a>b) ? a : b; }
+    Rect intersectWith(float l, float t, float r, float b) const {
+        Rect tmp;
+        tmp.left    = max(left, l);
+        tmp.top     = max(top, t);
+        tmp.right   = min(right, r);
+        tmp.bottom  = min(bottom, b);
+        return tmp;
+    }
+
+public:
     float left;
     float top;
     float right;
@@ -37,6 +49,9 @@
     // Used by Region
     typedef float value_type;
 
+    // we don't provide copy-ctor and operator= on purpose
+    // because we want the compiler generated versions
+
     inline Rect():
             left(0),
             top(0),
@@ -58,24 +73,6 @@
             bottom(height) {
     }
 
-    inline Rect(const Rect& r) {
-        set(r);
-    }
-
-    inline Rect(Rect& r) {
-        set(r);
-    }
-
-    Rect& operator=(const Rect& r) {
-        set(r);
-        return *this;
-    }
-
-    Rect& operator=(Rect& r) {
-        set(r);
-        return *this;
-    }
-
     friend int operator==(const Rect& a, const Rect& b) {
         return !memcmp(&a, &b, sizeof(a));
     }
@@ -89,7 +86,9 @@
     }
 
     inline bool isEmpty() const {
-        return left >= right || top >= bottom;
+        // this is written in such way this it'll handle NANs to return
+        // true (empty)
+        return !((left < right) && (top < bottom));
     }
 
     inline void setEmpty() {
@@ -115,27 +114,18 @@
         return bottom - top;
     }
 
-    bool intersects(float left, float top, float right, float bottom) const {
-        return left < right && top < bottom &&
-                this->left < this->right && this->top < this->bottom &&
-                this->left < right && left < this->right &&
-                this->top < bottom && top < this->bottom;
+    bool intersects(float l, float t, float r, float b) const {
+        return !intersectWith(l,t,r,b).isEmpty();
     }
 
     bool intersects(const Rect& r) const {
         return intersects(r.left, r.top, r.right, r.bottom);
     }
 
-    bool intersect(float left, float top, float right, float bottom) {
-        if (left < right && top < bottom && !this->isEmpty() &&
-                this->left < right && left < this->right &&
-                this->top < bottom && top < this->bottom) {
-
-            if (this->left < left) this->left = left;
-            if (this->top < top) this->top = top;
-            if (this->right > right) this->right = right;
-            if (this->bottom > bottom) this->bottom = bottom;
-
+    bool intersect(float l, float t, float r, float b) {
+        Rect tmp(intersectWith(l,t,r,b));
+        if (!tmp.isEmpty()) {
+            set(tmp);
             return true;
         }
         return false;
@@ -182,7 +172,7 @@
         LOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
     }
 
-}; // struct Rect
+}; // class Rect
 
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index a38fff77..f8107d9 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -219,7 +219,7 @@
 
 
     int cpu = sysconf(_SC_NPROCESSORS_ONLN);
-    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
+    LOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
     if (cpu < 2) cpu = 0;
 
     dc->mWorkers.mCount = (uint32_t)cpu;
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index c5b81db..98d9486 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -129,11 +129,8 @@
 
     dc->gl.shaderCache->cleanupAll();
     delete dc->gl.shaderCache;
-
     delete dc->gl.vertexArrayState;
 
-    LOGV("%p, deinitEGL", rsc);
-
     if (dc->gl.egl.context != EGL_NO_CONTEXT) {
         RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
                     EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
@@ -363,7 +360,7 @@
     dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
     dc->gl.currentFrameBuffer = NULL;
 
-    LOGV("initGLThread end %p", rsc);
+    LOGV("%p initGLThread end", rsc);
     rsc->setWatchdogGL(NULL, 0, NULL);
     return true;
 }
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 948d51c..53d4970 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -37,11 +37,10 @@
 
 bool Context::initGLThread() {
     pthread_mutex_lock(&gInitMutex);
-    LOGV("initGLThread start %p", this);
 
     if (!mHal.funcs.initGraphics(this)) {
         pthread_mutex_unlock(&gInitMutex);
-        LOGE("%p, initGraphics failed", this);
+        LOGE("%p initGraphics failed", this);
         return false;
     }
 
@@ -50,7 +49,6 @@
 }
 
 void Context::deinitEGL() {
-    LOGV("%p, deinitEGL", this);
     mHal.funcs.shutdownGraphics(this);
 }
 
@@ -284,7 +282,7 @@
         }
     }
 
-    LOGV("%p, RS Thread exiting", rsc);
+    LOGV("%p RS Thread exiting", rsc);
 
     if (rsc->mIsGraphicsContext) {
         pthread_mutex_lock(&gInitMutex);
@@ -292,7 +290,7 @@
         pthread_mutex_unlock(&gInitMutex);
     }
 
-    LOGV("%p, RS Thread exited", rsc);
+    LOGV("%p RS Thread exited", rsc);
     return NULL;
 }
 
@@ -426,7 +424,7 @@
 }
 
 Context::~Context() {
-    LOGV("Context::~Context");
+    LOGV("%p Context::~Context", this);
 
     if (!mIsContextLite) {
         mIO.coreFlush();
@@ -450,7 +448,7 @@
         }
         pthread_mutex_unlock(&gInitMutex);
     }
-    LOGV("Context::~Context done");
+    LOGV("%p Context::~Context done", this);
 }
 
 void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
@@ -667,10 +665,10 @@
 }
 
 void rsi_ContextDestroy(Context *rsc) {
-    LOGV("rsContextDestroy %p", rsc);
+    LOGV("%p rsContextDestroy", rsc);
     rsContextDestroyWorker(rsc);
     delete rsc;
-    LOGV("rsContextDestroy 2 %p", rsc);
+    LOGV("%p rsContextDestroy done", rsc);
 }
 
 
@@ -701,7 +699,7 @@
 
 RsContext rsContextCreate(RsDevice vdev, uint32_t version,
                           uint32_t sdkVersion) {
-    LOGV("rsContextCreate %p", vdev);
+    LOGV("rsContextCreate dev=%p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, NULL);
     if (rsc) {
@@ -713,14 +711,14 @@
 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
                             uint32_t sdkVersion, RsSurfaceConfig sc,
                             uint32_t dpi) {
-    LOGV("rsContextCreateGL %p", vdev);
+    LOGV("rsContextCreateGL dev=%p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, &sc);
     if (rsc) {
         rsc->setTargetSdkVersion(sdkVersion);
         rsc->setDPI(dpi);
     }
-    LOGV("rsContextCreateGL ret %p ", rsc);
+    LOGV("%p rsContextCreateGL ret", rsc);
     return rsc;
 }
 
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index a060a5f..8dab291 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -479,6 +479,11 @@
         const Region& lhs,
         const Rect& rhs, int dx, int dy)
 {
+    if (!rhs.isValid()) {
+        LOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}",
+                op, rhs.left, rhs.top, rhs.right, rhs.bottom);
+    }
+
 #if VALIDATE_WITH_CORECG || VALIDATE_REGIONS
     boolean_operation(op, dst, lhs, Region(rhs), dx, dy);
 #else
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 02c380b..5dbcb75 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -368,6 +368,14 @@
     return rc;
 }
 
+int androidGetThreadPriority(pid_t tid) {
+#if defined(HAVE_PTHREADS)
+    return getpriority(PRIO_PROCESS, tid);
+#else
+    return ANDROID_PRIORITY_NORMAL;
+#endif
+}
+
 int androidGetThreadSchedulingGroup(pid_t tid)
 {
     int ret = ANDROID_TGROUP_DEFAULT;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 65818a1..2d927ad 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -314,14 +314,14 @@
 
     // WARNING: Bulk inserts sounded like a great idea and gave us a good performance improvement,
     // but unfortunately it also introduced a number of bugs.  Many of those bugs were fixed,
-    // but (at least) two problems are still outstanding:
+    // but (at least) one problem is still outstanding:
     //
-    // 1) Bulk inserts broke the code that sets the default ringtones on first boot
-    // 2) Bulk inserts broke file based playlists in the case where the playlist is processed
-    //    at the same time the files in the playlist are inserted in the database
+    // - Bulk inserts broke the code that sets the default ringtones, notifications, and alarms
+    //   on first boot
     //
-    // These problems might be solvable by moving the logic to the media provider instead,
-    // but for now we are disabling bulk inserts until we have solid fixes for these problems.
+    // This problem might be solvable by moving the logic to the media provider or disabling bulk
+    // inserts only for those cases. For now, we are disabling bulk inserts until we have a solid
+    // fix for this problem.
     private static final boolean ENABLE_BULK_INSERTS = false;
 
     // used when scanning the image database so we know whether we have to prune
@@ -470,6 +470,8 @@
         private int mCompilation;
         private boolean mIsDrm;
         private boolean mNoMedia;   // flag to suppress file from appearing in media tables
+        private int mWidth;
+        private int mHeight;
 
         public FileCacheEntry beginFile(String path, String mimeType, long lastModified,
                 long fileSize, boolean isDirectory, boolean noMedia) {
@@ -545,6 +547,8 @@
             mWriter = null;
             mCompilation = 0;
             mIsDrm = false;
+            mWidth = 0;
+            mHeight = 0;
 
             return entry;
         }
@@ -583,6 +587,10 @@
                             processFile(path, mimeType, this);
                         }
 
+                        if (MediaFile.isImageFileType(mFileType)) {
+                            processImageFile(path);
+                        }
+
                         result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
                     }
                 }
@@ -697,6 +705,18 @@
             return genreTagValue;
         }
 
+        private void processImageFile(String path) {
+            try {
+                mBitmapOptions.outWidth = 0;
+                mBitmapOptions.outHeight = 0;
+                BitmapFactory.decodeFile(path, mBitmapOptions);
+                mWidth = mBitmapOptions.outWidth;
+                mHeight = mBitmapOptions.outHeight;
+            } catch (Throwable th) {
+                // ignore;
+            }
+        }
+
         public void setMimeType(String mimeType) {
             if ("audio/mp4".equals(mMimeType) &&
                     mimeType.startsWith("video")) {
@@ -725,6 +745,11 @@
             map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType);
             map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm);
 
+            if (mWidth > 0 && mHeight > 0) {
+                map.put(MediaStore.MediaColumns.WIDTH, mWidth);
+                map.put(MediaStore.MediaColumns.HEIGHT, mHeight);
+            }
+
             if (!mNoMedia) {
                 if (MediaFile.isVideoFileType(mFileType)) {
                     map.put(Video.Media.ARTIST, (mArtist != null && mArtist.length() > 0
@@ -1439,7 +1464,22 @@
         }
 
         try {
-        // OK, now we need to add this to the database
+            // check rowid is set. Rowid may be missing if it is inserted by bulkInsert().
+            if (bestMatch.mRowId == 0) {
+                Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION,
+                        MediaStore.Files.FileColumns.DATA + "=?",
+                        new String[] { bestMatch.mPath }, null);
+                if (c != null) {
+                    if (c.moveToNext()) {
+                        bestMatch.mRowId = c.getLong(0);
+                    }
+                    c.close();
+                }
+                if (bestMatch.mRowId == 0) {
+                    return false;
+                }
+            }
+            // OK, now we are ready to add this to the database
             values.clear();
             values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(index));
             values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, Long.valueOf(bestMatch.mRowId));
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 0ce3526..f2c1694 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -203,7 +203,22 @@
         mUri = uri;
         openMediaPlayer();
     }
-    
+
+    /** @hide */
+    public void setWakeMode(Context context, int mode) {
+        if (mAudio == null) {
+            try {
+                openMediaPlayer();
+            } catch (Exception ex) {
+                Log.e(TAG, "setWakeMode() caught ", ex);
+                mAudio = null;
+            }
+        }
+        if (mAudio != null) {
+            mAudio.setWakeMode(context, mode);
+        }
+    }
+
     /**
      * Plays the ringtone.
      */
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index ee77f47..7218faf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -34,17 +34,21 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/ACodec.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <surfaceflinger/Surface.h>
 #include <gui/ISurfaceTexture.h>
 
+#include "avc_utils.h"
+
 namespace android {
 
 ////////////////////////////////////////////////////////////////////////////////
 
 NuPlayer::NuPlayer()
     : mUIDValid(false),
+      mVideoIsAVC(false),
       mAudioEOS(false),
       mVideoEOS(false),
       mScanSourcesPending(false),
@@ -52,7 +56,12 @@
       mFlushingAudio(NONE),
       mFlushingVideo(NONE),
       mResetInProgress(false),
-      mResetPostponed(false) {
+      mResetPostponed(false),
+      mSkipRenderingAudioUntilMediaTimeUs(-1ll),
+      mSkipRenderingVideoUntilMediaTimeUs(-1ll),
+      mVideoLateByUs(0ll),
+      mNumFramesTotal(0ll),
+      mNumFramesDropped(0ll) {
 }
 
 NuPlayer::~NuPlayer() {
@@ -185,10 +194,14 @@
         {
             LOGV("kWhatStart");
 
+            mVideoIsAVC = false;
             mAudioEOS = false;
             mVideoEOS = false;
             mSkipRenderingAudioUntilMediaTimeUs = -1;
             mSkipRenderingVideoUntilMediaTimeUs = -1;
+            mVideoLateByUs = 0;
+            mNumFramesTotal = 0;
+            mNumFramesDropped = 0;
 
             mSource->start();
 
@@ -269,6 +282,8 @@
                 } else {
                     CHECK(IsFlushingState(mFlushingVideo, &needShutdown));
                     mFlushingVideo = FLUSHED;
+
+                    mVideoLateByUs = 0;
                 }
 
                 LOGV("decoder %s flush completed", audio ? "audio" : "video");
@@ -299,7 +314,12 @@
                          sampleRate, numChannels);
 
                     mAudioSink->close();
-                    CHECK_EQ(mAudioSink->open(sampleRate, numChannels), (status_t)OK);
+                    CHECK_EQ(mAudioSink->open(
+                                sampleRate,
+                                numChannels,
+                                AUDIO_FORMAT_PCM_16_BIT,
+                                8 /* bufferCount */),
+                             (status_t)OK);
                     mAudioSink->start();
 
                     mRenderer->signalAudioSinkChanged();
@@ -392,13 +412,18 @@
                 int64_t positionUs;
                 CHECK(msg->findInt64("positionUs", &positionUs));
 
+                CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
+
                 if (mDriver != NULL) {
                     sp<NuPlayerDriver> driver = mDriver.promote();
                     if (driver != NULL) {
                         driver->notifyPosition(positionUs);
+
+                        driver->notifyFrameStats(
+                                mNumFramesTotal, mNumFramesDropped);
                     }
                 }
-            } else {
+            } else if (what == Renderer::kWhatFlushComplete) {
                 CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
 
                 int32_t audio;
@@ -560,6 +585,12 @@
         return -EWOULDBLOCK;
     }
 
+    if (!audio) {
+        const char *mime;
+        CHECK(meta->findCString(kKeyMIMEType, &mime));
+        mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime);
+    }
+
     sp<AMessage> notify =
         new AMessage(audio ? kWhatAudioNotify : kWhatVideoNotify,
                      id());
@@ -593,53 +624,70 @@
     }
 
     sp<ABuffer> accessUnit;
-    status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
 
-    if (err == -EWOULDBLOCK) {
-        return err;
-    } else if (err != OK) {
-        if (err == INFO_DISCONTINUITY) {
-            int32_t type;
-            CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
+    bool dropAccessUnit;
+    do {
+        status_t err = mSource->dequeueAccessUnit(audio, &accessUnit);
 
-            bool formatChange =
-                type == ATSParser::DISCONTINUITY_FORMATCHANGE;
+        if (err == -EWOULDBLOCK) {
+            return err;
+        } else if (err != OK) {
+            if (err == INFO_DISCONTINUITY) {
+                int32_t type;
+                CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
 
-            LOGV("%s discontinuity (formatChange=%d)",
-                 audio ? "audio" : "video", formatChange);
+                bool formatChange =
+                    type == ATSParser::DISCONTINUITY_FORMATCHANGE;
 
-            if (audio) {
-                mSkipRenderingAudioUntilMediaTimeUs = -1;
-            } else {
-                mSkipRenderingVideoUntilMediaTimeUs = -1;
-            }
+                LOGV("%s discontinuity (formatChange=%d)",
+                     audio ? "audio" : "video", formatChange);
 
-            sp<AMessage> extra;
-            if (accessUnit->meta()->findMessage("extra", &extra)
-                    && extra != NULL) {
-                int64_t resumeAtMediaTimeUs;
-                if (extra->findInt64(
-                            "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
-                    LOGI("suppressing rendering of %s until %lld us",
-                            audio ? "audio" : "video", resumeAtMediaTimeUs);
+                if (audio) {
+                    mSkipRenderingAudioUntilMediaTimeUs = -1;
+                } else {
+                    mSkipRenderingVideoUntilMediaTimeUs = -1;
+                }
 
-                    if (audio) {
-                        mSkipRenderingAudioUntilMediaTimeUs =
-                            resumeAtMediaTimeUs;
-                    } else {
-                        mSkipRenderingVideoUntilMediaTimeUs =
-                            resumeAtMediaTimeUs;
+                sp<AMessage> extra;
+                if (accessUnit->meta()->findMessage("extra", &extra)
+                        && extra != NULL) {
+                    int64_t resumeAtMediaTimeUs;
+                    if (extra->findInt64(
+                                "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
+                        LOGI("suppressing rendering of %s until %lld us",
+                                audio ? "audio" : "video", resumeAtMediaTimeUs);
+
+                        if (audio) {
+                            mSkipRenderingAudioUntilMediaTimeUs =
+                                resumeAtMediaTimeUs;
+                        } else {
+                            mSkipRenderingVideoUntilMediaTimeUs =
+                                resumeAtMediaTimeUs;
+                        }
                     }
                 }
+
+                flushDecoder(audio, formatChange);
             }
 
-            flushDecoder(audio, formatChange);
+            reply->setInt32("err", err);
+            reply->post();
+            return OK;
         }
 
-        reply->setInt32("err", err);
-        reply->post();
-        return OK;
-    }
+        if (!audio) {
+            ++mNumFramesTotal;
+        }
+
+        dropAccessUnit = false;
+        if (!audio
+                && mVideoLateByUs > 100000ll
+                && mVideoIsAVC
+                && !IsAVCReferenceFrame(accessUnit)) {
+            dropAccessUnit = true;
+            ++mNumFramesDropped;
+        }
+    } while (dropAccessUnit);
 
     // LOGV("returned a valid buffer of %s data", audio ? "audio" : "video");
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index cf9185b..a5382b4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -70,19 +70,19 @@
     struct StreamingSource;
 
     enum {
-        kWhatSetDataSource,
-        kWhatSetVideoNativeWindow,
-        kWhatSetAudioSink,
-        kWhatMoreDataQueued,
-        kWhatStart,
-        kWhatScanSources,
-        kWhatVideoNotify,
-        kWhatAudioNotify,
-        kWhatRendererNotify,
-        kWhatReset,
-        kWhatSeek,
-        kWhatPause,
-        kWhatResume,
+        kWhatSetDataSource              = '=DaS',
+        kWhatSetVideoNativeWindow       = '=NaW',
+        kWhatSetAudioSink               = '=AuS',
+        kWhatMoreDataQueued             = 'more',
+        kWhatStart                      = 'strt',
+        kWhatScanSources                = 'scan',
+        kWhatVideoNotify                = 'vidN',
+        kWhatAudioNotify                = 'audN',
+        kWhatRendererNotify             = 'renN',
+        kWhatReset                      = 'rset',
+        kWhatSeek                       = 'seek',
+        kWhatPause                      = 'paus',
+        kWhatResume                     = 'rsme',
     };
 
     wp<NuPlayerDriver> mDriver;
@@ -92,6 +92,7 @@
     sp<NativeWindowWrapper> mNativeWindow;
     sp<MediaPlayerBase::AudioSink> mAudioSink;
     sp<Decoder> mVideoDecoder;
+    bool mVideoIsAVC;
     sp<Decoder> mAudioDecoder;
     sp<Renderer> mRenderer;
 
@@ -119,6 +120,9 @@
     int64_t mSkipRenderingAudioUntilMediaTimeUs;
     int64_t mSkipRenderingVideoUntilMediaTimeUs;
 
+    int64_t mVideoLateByUs;
+    int64_t mNumFramesTotal, mNumFramesDropped;
+
     status_t instantiateDecoder(bool audio, sp<Decoder> *decoder);
 
     status_t feedDecoderInputData(bool audio, const sp<AMessage> &msg);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 81b41ef..56c2773 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -59,8 +59,21 @@
         format->setObject("native-window", mNativeWindow);
     }
 
+    // Current video decoders do not return from OMX_FillThisBuffer
+    // quickly, violating the OpenMAX specs, until that is remedied
+    // we need to invest in an extra looper to free the main event
+    // queue.
+    bool needDedicatedLooper = !strncasecmp(mime, "video/", 6);
+
     mCodec = new ACodec;
-    looper()->registerHandler(mCodec);
+
+    if (needDedicatedLooper && mCodecLooper == NULL) {
+        mCodecLooper = new ALooper;
+        mCodecLooper->setName("NuPlayerDecoder");
+        mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
+    }
+
+    (needDedicatedLooper ? mCodecLooper : looper())->registerHandler(mCodec);
 
     mCodec->setNotificationMessage(notifyMsg);
     mCodec->initiateSetup(format);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index fabc606..3ab1fcf 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -43,13 +43,14 @@
 
 private:
     enum {
-        kWhatCodecNotify,
+        kWhatCodecNotify        = 'cdcN',
     };
 
     sp<AMessage> mNotify;
     sp<NativeWindowWrapper> mNativeWindow;
 
     sp<ACodec> mCodec;
+    sp<ALooper> mCodecLooper;
 
     Vector<sp<ABuffer> > mCSD;
     size_t mCSDIndex;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index c6fca2c..b1e917d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -31,6 +31,8 @@
     : mResetInProgress(false),
       mDurationUs(-1),
       mPositionUs(-1),
+      mNumFramesTotal(0),
+      mNumFramesDropped(0),
       mLooper(new ALooper),
       mState(UNINITIALIZED),
       mStartupSeekTimeUs(-1) {
@@ -292,4 +294,30 @@
     sendEvent(MEDIA_SEEK_COMPLETE);
 }
 
+void NuPlayerDriver::notifyFrameStats(
+        int64_t numFramesTotal, int64_t numFramesDropped) {
+    Mutex::Autolock autoLock(mLock);
+    mNumFramesTotal = numFramesTotal;
+    mNumFramesDropped = numFramesDropped;
+}
+
+status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
+    Mutex::Autolock autoLock(mLock);
+
+    FILE *out = fdopen(dup(fd), "w");
+
+    fprintf(out, " NuPlayer\n");
+    fprintf(out, "  numFramesTotal(%lld), numFramesDropped(%lld), "
+                 "percentageDropped(%.2f)\n",
+                 mNumFramesTotal,
+                 mNumFramesDropped,
+                 mNumFramesTotal == 0
+                    ? 0.0 : (double)mNumFramesDropped / mNumFramesTotal);
+
+    fclose(out);
+    out = NULL;
+
+    return OK;
+}
+
 }  // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index 1bb7ca2..181c37d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -60,16 +60,19 @@
     virtual status_t getMetadata(
             const media::Metadata::Filter& ids, Parcel *records);
 
+    virtual status_t dump(int fd, const Vector<String16> &args) const;
+
     void notifyResetComplete();
     void notifyDuration(int64_t durationUs);
     void notifyPosition(int64_t positionUs);
     void notifySeekComplete();
+    void notifyFrameStats(int64_t numFramesTotal, int64_t numFramesDropped);
 
 protected:
     virtual ~NuPlayerDriver();
 
 private:
-    Mutex mLock;
+    mutable Mutex mLock;
     Condition mCondition;
 
     // The following are protected through "mLock"
@@ -77,6 +80,8 @@
     bool mResetInProgress;
     int64_t mDurationUs;
     int64_t mPositionUs;
+    int64_t mNumFramesTotal;
+    int64_t mNumFramesDropped;
     // <<<
 
     sp<ALooper> mLooper;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index bf83849..07e347e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -47,7 +47,8 @@
       mHasVideo(false),
       mSyncQueues(false),
       mPaused(false),
-      mLastPositionUpdateUs(-1ll) {
+      mLastPositionUpdateUs(-1ll),
+      mVideoLateByUs(0ll) {
 }
 
 NuPlayer::Renderer::~Renderer() {
@@ -118,9 +119,24 @@
 
             mDrainAudioQueuePending = false;
 
-            onDrainAudioQueue();
+            if (onDrainAudioQueue()) {
+                uint32_t numFramesPlayed;
+                CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
+                         (status_t)OK);
 
-            postDrainAudioQueue();
+                uint32_t numFramesPendingPlayout =
+                    mNumFramesWritten - numFramesPlayed;
+
+                // This is how long the audio sink will have data to
+                // play back.
+                int64_t delayUs =
+                    mAudioSink->msecsPerFrame()
+                        * numFramesPendingPlayout * 1000ll;
+
+                // Let's give it more data after about half that time
+                // has elapsed.
+                postDrainAudioQueue(delayUs / 2);
+            }
             break;
         }
 
@@ -182,7 +198,7 @@
     }
 }
 
-void NuPlayer::Renderer::postDrainAudioQueue() {
+void NuPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) {
     if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
         return;
     }
@@ -194,19 +210,33 @@
     mDrainAudioQueuePending = true;
     sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, id());
     msg->setInt32("generation", mAudioQueueGeneration);
-    msg->post();
+    msg->post(delayUs);
 }
 
 void NuPlayer::Renderer::signalAudioSinkChanged() {
     (new AMessage(kWhatAudioSinkChanged, id()))->post();
 }
 
-void NuPlayer::Renderer::onDrainAudioQueue() {
-    for (;;) {
-        if (mAudioQueue.empty()) {
-            break;
-        }
+bool NuPlayer::Renderer::onDrainAudioQueue() {
+    uint32_t numFramesPlayed;
+    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
 
+    ssize_t numFramesAvailableToWrite =
+        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
+
+#if 0
+    if (numFramesAvailableToWrite == mAudioSink->frameCount()) {
+        LOGI("audio sink underrun");
+    } else {
+        LOGV("audio queue has %d frames left to play",
+             mAudioSink->frameCount() - numFramesAvailableToWrite);
+    }
+#endif
+
+    size_t numBytesAvailableToWrite =
+        numFramesAvailableToWrite * mAudioSink->frameSize();
+
+    while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
         QueueEntry *entry = &*mAudioQueue.begin();
 
         if (entry->mBuffer == NULL) {
@@ -216,20 +246,7 @@
 
             mAudioQueue.erase(mAudioQueue.begin());
             entry = NULL;
-            return;
-        }
-
-        uint32_t numFramesPlayed;
-        CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
-
-        ssize_t numFramesAvailableToWrite =
-            mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
-
-        size_t numBytesAvailableToWrite =
-            numFramesAvailableToWrite * mAudioSink->frameSize();
-
-        if (numBytesAvailableToWrite == 0) {
-            break;
+            return false;
         }
 
         if (entry->mOffset == 0) {
@@ -274,10 +291,14 @@
             entry = NULL;
         }
 
-        mNumFramesWritten += copy / mAudioSink->frameSize();
+        numBytesAvailableToWrite -= copy;
+        size_t copiedFrames = copy / mAudioSink->frameSize();
+        mNumFramesWritten += copiedFrames;
     }
 
     notifyPosition();
+
+    return !mAudioQueue.empty();
 }
 
 void NuPlayer::Renderer::postDrainVideoQueue() {
@@ -337,15 +358,26 @@
 
         mVideoQueue.erase(mVideoQueue.begin());
         entry = NULL;
+
+        mVideoLateByUs = 0ll;
+
+        notifyPosition();
         return;
     }
 
-#if 0
     int64_t mediaTimeUs;
     CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
 
-    LOGI("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
-#endif
+    int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
+    mVideoLateByUs = ALooper::GetNowUs() - realTimeUs;
+
+    bool tooLate = (mVideoLateByUs > 40000);
+
+    if (tooLate) {
+        LOGV("video late by %lld us (%.2f secs)", lateByUs, lateByUs / 1E6);
+    } else {
+        LOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
+    }
 
     entry->mNotifyConsumed->setInt32("render", true);
     entry->mNotifyConsumed->post();
@@ -577,6 +609,7 @@
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("what", kWhatPosition);
     notify->setInt64("positionUs", positionUs);
+    notify->setInt64("videoLateByUs", mVideoLateByUs);
     notify->post();
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 3a641a2..268628b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -45,9 +45,9 @@
     void resume();
 
     enum {
-        kWhatEOS,
-        kWhatFlushComplete,
-        kWhatPosition,
+        kWhatEOS                = 'eos ',
+        kWhatFlushComplete      = 'fluC',
+        kWhatPosition           = 'posi',
     };
 
 protected:
@@ -57,14 +57,14 @@
 
 private:
     enum {
-        kWhatDrainAudioQueue,
-        kWhatDrainVideoQueue,
-        kWhatQueueBuffer,
-        kWhatQueueEOS,
-        kWhatFlush,
-        kWhatAudioSinkChanged,
-        kWhatPause,
-        kWhatResume,
+        kWhatDrainAudioQueue    = 'draA',
+        kWhatDrainVideoQueue    = 'draV',
+        kWhatQueueBuffer        = 'queB',
+        kWhatQueueEOS           = 'qEOS',
+        kWhatFlush              = 'flus',
+        kWhatAudioSinkChanged   = 'auSC',
+        kWhatPause              = 'paus',
+        kWhatResume             = 'resm',
     };
 
     struct QueueEntry {
@@ -101,9 +101,10 @@
     bool mPaused;
 
     int64_t mLastPositionUpdateUs;
+    int64_t mVideoLateByUs;
 
-    void onDrainAudioQueue();
-    void postDrainAudioQueue();
+    bool onDrainAudioQueue();
+    void postDrainAudioQueue(int64_t delayUs = 0);
 
     void onDrainVideoQueue();
     void postDrainVideoQueue();
@@ -118,6 +119,7 @@
     void notifyEOS(bool audio, status_t finalResult);
     void notifyFlushComplete(bool audio);
     void notifyPosition();
+    void notifyVideoLateBy(int64_t lateByUs);
 
     void flushQueue(List<QueueEntry> *queue);
     bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
index df0935d..1874d80 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.h
@@ -41,8 +41,8 @@
 
 private:
     enum {
-        kNumBuffers = 16,
-        kBufferSize = 188 * 20
+        kNumBuffers = 8,
+        kBufferSize = 188 * 10
     };
 
     struct QueueEntry {
diff --git a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
index a741987..7319e4c 100644
--- a/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/StreamingSource.cpp
@@ -52,7 +52,7 @@
         return false;
     }
 
-    for (int32_t i = 0; i < 10; ++i) {
+    for (int32_t i = 0; i < 50; ++i) {
         char buffer[188];
         sp<AMessage> extra;
         ssize_t n = mStreamListener->read(buffer, sizeof(buffer), &extra);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2ba2273..a2d9e59 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1377,8 +1377,13 @@
                     memcpy(info->mData->data(), buffer->data(), buffer->size());
                 }
 
-                LOGV("[%s] calling emptyBuffer %p",
-                     mCodec->mComponentName.c_str(), bufferID);
+                if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
+                    LOGV("[%s] calling emptyBuffer %p w/ codec specific data",
+                         mCodec->mComponentName.c_str(), bufferID);
+                } else {
+                    LOGV("[%s] calling emptyBuffer %p w/ time %lld us",
+                         mCodec->mComponentName.c_str(), bufferID, timeUs);
+                }
 
                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
                             mCodec->mNode,
@@ -1396,7 +1401,7 @@
                 LOGV("[%s] Signalling EOS on the input port",
                      mCodec->mComponentName.c_str());
 
-                LOGV("[%s] calling emptyBuffer %p",
+                LOGV("[%s] calling emptyBuffer %p signalling EOS",
                      mCodec->mComponentName.c_str(), bufferID);
 
                 CHECK_EQ(mCodec->mOMX->emptyBuffer(
@@ -1457,8 +1462,8 @@
         int64_t timeUs,
         void *platformPrivate,
         void *dataPtr) {
-    LOGV("[%s] onOMXFillBufferDone %p",
-         mCodec->mComponentName.c_str(), bufferID);
+    LOGV("[%s] onOMXFillBufferDone %p time %lld us",
+         mCodec->mComponentName.c_str(), bufferID, timeUs);
 
     ssize_t index;
     BufferInfo *info =
@@ -1686,7 +1691,11 @@
             ++matchIndex) {
         componentName = matchingCodecs.itemAt(matchIndex).string();
 
+        pid_t tid = androidGetTid();
+        int prevPriority = androidGetThreadPriority(tid);
+        androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
         status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
+        androidSetThreadPriority(tid, prevPriority);
 
         if (err == OK) {
             break;
diff --git a/media/libstagefright/AVIExtractor.cpp b/media/libstagefright/AVIExtractor.cpp
index 4e46414..d47e5d1 100644
--- a/media/libstagefright/AVIExtractor.cpp
+++ b/media/libstagefright/AVIExtractor.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "AVIExtractor"
 #include <utils/Log.h>
 
+#include "include/avc_utils.h"
 #include "include/AVIExtractor.h"
 
 #include <binder/ProcessState.h>
@@ -362,6 +363,13 @@
         case FOURCC('X', 'V', 'I', 'X'):
             return MEDIA_MIMETYPE_VIDEO_MPEG4;
 
+        // from http://wiki.multimedia.cx/index.php?title=H264
+        case FOURCC('a', 'v', 'c', '1'):
+        case FOURCC('d', 'a', 'v', 'c'):
+        case FOURCC('x', '2', '6', '4'):
+        case FOURCC('v', 's', 's', 'h'):
+            return MEDIA_MIMETYPE_VIDEO_AVC;
+
         default:
             return NULL;
     }
@@ -406,6 +414,14 @@
             return ERROR_MALFORMED;
         }
 
+        if (mime == NULL) {
+            LOGW("Unsupported video format '%c%c%c%c'",
+                 (char)(handler >> 24),
+                 (char)((handler >> 16) & 0xff),
+                 (char)((handler >> 8) & 0xff),
+                 (char)(handler & 0xff));
+        }
+
         kind = Track::VIDEO;
     } else if (type == FOURCC('a', 'u', 'd', 's')) {
         if (mime && strncasecmp(mime, "audio/", 6)) {
@@ -473,8 +489,11 @@
         track->mMeta->setInt32(kKeyHeight, height);
     } else {
         uint32_t format = U16LE_AT(data);
+
         if (format == 0x55) {
             track->mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+        } else {
+            LOGW("Unsupported audio format = 0x%04x", format);
         }
 
         uint32_t numChannels = U16LE_AT(&data[2]);
@@ -646,21 +665,26 @@
 
         AString mime = tmp;
 
-        if (!strncasecmp("video/", mime.c_str(), 6)
-                && track->mThumbnailSampleIndex >= 0) {
-            int64_t thumbnailTimeUs;
-            CHECK_EQ((status_t)OK,
-                     getSampleTime(i, track->mThumbnailSampleIndex,
-                                   &thumbnailTimeUs));
+        if (!strncasecmp("video/", mime.c_str(), 6)) {
+            if (track->mThumbnailSampleIndex >= 0) {
+                int64_t thumbnailTimeUs;
+                CHECK_EQ((status_t)OK,
+                         getSampleTime(i, track->mThumbnailSampleIndex,
+                                       &thumbnailTimeUs));
 
-            track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+                track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
+            }
+
+            status_t err = OK;
 
             if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_MPEG4)) {
-                status_t err = addMPEG4CodecSpecificData(i);
+                err = addMPEG4CodecSpecificData(i);
+            } else if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_VIDEO_AVC)) {
+                err = addH264CodecSpecificData(i);
+            }
 
-                if (err != OK) {
-                    return err;
-                }
+            if (err != OK) {
+                return err;
             }
         }
 
@@ -781,6 +805,63 @@
     return OK;
 }
 
+status_t AVIExtractor::addH264CodecSpecificData(size_t trackIndex) {
+    Track *track = &mTracks.editItemAt(trackIndex);
+
+    off64_t offset;
+    size_t size;
+    bool isKey;
+    int64_t timeUs;
+
+    // Extract codec specific data from the first non-empty sample.
+
+    size_t sampleIndex = 0;
+    for (;;) {
+        status_t err =
+            getSampleInfo(
+                    trackIndex, sampleIndex, &offset, &size, &isKey, &timeUs);
+
+        if (err != OK) {
+            return err;
+        }
+
+        if (size > 0) {
+            break;
+        }
+
+        ++sampleIndex;
+    }
+
+    sp<ABuffer> buffer = new ABuffer(size);
+    ssize_t n = mDataSource->readAt(offset, buffer->data(), buffer->size());
+
+    if (n < (ssize_t)size) {
+        return n < 0 ? (status_t)n : ERROR_MALFORMED;
+    }
+
+    sp<MetaData> meta = MakeAVCCodecSpecificData(buffer);
+
+    if (meta == NULL) {
+        LOGE("Unable to extract AVC codec specific data");
+        return ERROR_MALFORMED;
+    }
+
+    int32_t width, height;
+    CHECK(meta->findInt32(kKeyWidth, &width));
+    CHECK(meta->findInt32(kKeyHeight, &height));
+
+    uint32_t type;
+    const void *csd;
+    size_t csdSize;
+    CHECK(meta->findData(kKeyAVCC, &type, &csd, &csdSize));
+
+    track->mMeta->setInt32(kKeyWidth, width);
+    track->mMeta->setInt32(kKeyHeight, width);
+    track->mMeta->setData(kKeyAVCC, type, csd, csdSize);
+
+    return OK;
+}
+
 status_t AVIExtractor::getSampleInfo(
         size_t trackIndex, size_t sampleIndex,
         off64_t *offset, size_t *size, bool *isKey,
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 2b9d99b..ebad321 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -23,8 +23,8 @@
 
 #include <arpa/inet.h>
 
+#include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/DataSource.h>
-#include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/Utils.h>
 
 namespace android {
@@ -40,6 +40,71 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+struct SampleTable::CompositionDeltaLookup {
+    CompositionDeltaLookup();
+
+    void setEntries(
+            const uint32_t *deltaEntries, size_t numDeltaEntries);
+
+    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
+
+private:
+    Mutex mLock;
+
+    const uint32_t *mDeltaEntries;
+    size_t mNumDeltaEntries;
+
+    size_t mCurrentDeltaEntry;
+    size_t mCurrentEntrySampleIndex;
+
+    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
+};
+
+SampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
+    : mDeltaEntries(NULL),
+      mNumDeltaEntries(0),
+      mCurrentDeltaEntry(0),
+      mCurrentEntrySampleIndex(0) {
+}
+
+void SampleTable::CompositionDeltaLookup::setEntries(
+        const uint32_t *deltaEntries, size_t numDeltaEntries) {
+    Mutex::Autolock autolock(mLock);
+
+    mDeltaEntries = deltaEntries;
+    mNumDeltaEntries = numDeltaEntries;
+    mCurrentDeltaEntry = 0;
+    mCurrentEntrySampleIndex = 0;
+}
+
+uint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
+        uint32_t sampleIndex) {
+    Mutex::Autolock autolock(mLock);
+
+    if (mDeltaEntries == NULL) {
+        return 0;
+    }
+
+    if (sampleIndex < mCurrentEntrySampleIndex) {
+        mCurrentDeltaEntry = 0;
+        mCurrentEntrySampleIndex = 0;
+    }
+
+    while (mCurrentDeltaEntry < mNumDeltaEntries) {
+        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
+        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
+            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
+        }
+
+        mCurrentEntrySampleIndex += sampleCount;
+        ++mCurrentDeltaEntry;
+    }
+
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 SampleTable::SampleTable(const sp<DataSource> &source)
     : mDataSource(source),
       mChunkOffsetOffset(-1),
@@ -56,6 +121,7 @@
       mSampleTimeEntries(NULL),
       mCompositionTimeDeltaEntries(NULL),
       mNumCompositionTimeDeltaEntries(0),
+      mCompositionDeltaLookup(new CompositionDeltaLookup),
       mSyncSampleOffset(-1),
       mNumSyncSamples(0),
       mSyncSamples(NULL),
@@ -71,6 +137,9 @@
     delete[] mSyncSamples;
     mSyncSamples = NULL;
 
+    delete mCompositionDeltaLookup;
+    mCompositionDeltaLookup = NULL;
+
     delete[] mCompositionTimeDeltaEntries;
     mCompositionTimeDeltaEntries = NULL;
 
@@ -318,6 +387,9 @@
         mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
     }
 
+    mCompositionDeltaLookup->setEntries(
+            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
+
     return OK;
 }
 
@@ -430,8 +502,12 @@
 
                 mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
 
+                uint32_t compTimeDelta =
+                    mCompositionDeltaLookup->getCompositionTimeOffset(
+                            sampleIndex);
+
                 mSampleTimeEntries[sampleIndex].mCompositionTime =
-                    sampleTime + getCompositionTimeOffset(sampleIndex);
+                    sampleTime + compTimeDelta;
             }
 
             ++sampleIndex;
@@ -739,25 +815,8 @@
     return OK;
 }
 
-uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const {
-    if (mCompositionTimeDeltaEntries == NULL) {
-        return 0;
-    }
-
-    uint32_t curSample = 0;
-    for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) {
-        uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i];
-
-        if (sampleIndex < curSample + sampleCount) {
-            uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1];
-
-            return sampleDelta;
-        }
-
-        curSample += sampleCount;
-    }
-
-    return 0;
+uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
+    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index 8a42e8b..153ee33 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -297,7 +297,7 @@
     sp<MetaData> meta = new MetaData;
     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
 
-    meta->setData(kKeyAVCC, 0, csd->data(), csd->size());
+    meta->setData(kKeyAVCC, kTypeAVCC, csd->data(), csd->size());
     meta->setInt32(kKeyWidth, width);
     meta->setInt32(kKeyHeight, height);
 
@@ -329,6 +329,28 @@
     return foundIDR;
 }
 
+bool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit) {
+    const uint8_t *data = accessUnit->data();
+    size_t size = accessUnit->size();
+
+    const uint8_t *nalStart;
+    size_t nalSize;
+    while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
+        CHECK_GT(nalSize, 0u);
+
+        unsigned nalType = nalStart[0] & 0x1f;
+
+        if (nalType == 5) {
+            return true;
+        } else if (nalType == 1) {
+            unsigned nal_ref_idc = (nalStart[0] >> 5) & 3;
+            return nal_ref_idc != 0;
+        }
+    }
+
+    return true;
+}
+
 sp<MetaData> MakeAACCodecSpecificData(
         unsigned profile, unsigned sampling_freq_index,
         unsigned channel_configuration) {
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index de936c4..f15014e 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -74,10 +74,32 @@
     return false;
 }
 
+struct AutoPrioritySaver {
+    AutoPrioritySaver()
+        : mTID(androidGetTid()),
+          mPrevPriority(androidGetThreadPriority(mTID)) {
+        androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL);
+    }
+
+    ~AutoPrioritySaver() {
+        androidSetThreadPriority(mTID, mPrevPriority);
+    }
+
+private:
+    pid_t mTID;
+    int mPrevPriority;
+
+    DISALLOW_EVIL_CONSTRUCTORS(AutoPrioritySaver);
+};
 
 static void InitializeNetworkThreadIfNecessary() {
     Mutex::Autolock autoLock(gNetworkThreadLock);
+
     if (gNetworkThread == NULL) {
+        // Make sure any threads spawned by the chromium framework are
+        // running at normal priority instead of inheriting this thread's.
+        AutoPrioritySaver saver;
+
         gNetworkThread = new base::Thread("network");
         base::Thread::Options options;
         options.message_loop_type = MessageLoop::TYPE_IO;
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index 582bdba..f039bc1 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -385,6 +385,15 @@
                             item.u.refValue)->debugString(
                                 indent + strlen(item.mName) + 14).c_str());
                 break;
+            case kTypeRect:
+                tmp = StringPrintf(
+                        "Rect %s(%d, %d, %d, %d)",
+                        item.mName,
+                        item.u.rectValue.mLeft,
+                        item.u.rectValue.mTop,
+                        item.u.rectValue.mRight,
+                        item.u.rectValue.mBottom);
+                break;
             default:
                 TRESPASS();
         }
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
index b575347..75ce68d 100644
--- a/media/libstagefright/include/AVIExtractor.h
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -101,6 +101,7 @@
             size_t *sampleIndex) const;
 
     status_t addMPEG4CodecSpecificData(size_t trackIndex);
+    status_t addH264CodecSpecificData(size_t trackIndex);
 
     static bool IsCorrectChunkType(
         ssize_t trackIndex, Track::Kind kind, uint32_t chunkType);
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index a6a6524..847dff7 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -86,6 +86,8 @@
     ~SampleTable();
 
 private:
+    struct CompositionDeltaLookup;
+
     static const uint32_t kChunkOffsetType32;
     static const uint32_t kChunkOffsetType64;
     static const uint32_t kSampleSizeType32;
@@ -117,6 +119,7 @@
 
     uint32_t *mCompositionTimeDeltaEntries;
     size_t mNumCompositionTimeDeltaEntries;
+    CompositionDeltaLookup *mCompositionDeltaLookup;
 
     off64_t mSyncSampleOffset;
     uint32_t mNumSyncSamples;
@@ -135,8 +138,7 @@
     friend struct SampleIterator;
 
     status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
-
-    uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
+    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
 
     static int CompareIncreasingTime(const void *, const void *);
 
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index 15cd4d4..e418822 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -50,6 +50,7 @@
 sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit);
 
 bool IsIDR(const sp<ABuffer> &accessUnit);
+bool IsAVCReferenceFrame(const sp<ABuffer> &accessUnit);
 
 const char *AVCProfileToString(uint8_t profile);
 
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index bc24dbb..33d3f30 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -85,7 +85,7 @@
     : mOwner(owner),
       mDone(false) {
     mThread = new CallbackDispatcherThread(this);
-    mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_AUDIO);
+    mThread->run("OMXCallbackDisp", ANDROID_PRIORITY_FOREGROUND);
 }
 
 OMX::CallbackDispatcher::~CallbackDispatcher() {
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index f7330f3..b705d00 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -42,7 +42,7 @@
     mLooper->start(
             false, // runOnCallingThread
             false, // canCallJava
-            PRIORITY_AUDIO);
+            ANDROID_PRIORITY_FOREGROUND);
 }
 
 void SimpleSoftOMXComponent::prepareForDestruction() {
diff --git a/native/include/android/rect.h b/native/include/android/rect.h
index 3e81f53..64d487d 100644
--- a/native/include/android/rect.h
+++ b/native/include/android/rect.h
@@ -23,6 +23,9 @@
 #endif
 
 typedef struct ARect {
+#ifdef __cplusplus
+    typedef int32_t value_type;
+#endif
     int32_t left;
     int32_t top;
     int32_t right;
diff --git a/opengl/java/android/opengl/Matrix.java b/opengl/java/android/opengl/Matrix.java
index 6d80bc6..7c72ae4 100644
--- a/opengl/java/android/opengl/Matrix.java
+++ b/opengl/java/android/opengl/Matrix.java
@@ -39,6 +39,10 @@
  *
  */
 public class Matrix {
+
+    /** Temporary memory for operations that need temporary matrix data. */
+    private final static float[] sTemp = new float[32];
+
     /**
      * Multiply two 4x4 matrices together and store the result in a third 4x4
      * matrix. In matrix notation: result = lhs x rhs. Due to the way
@@ -125,95 +129,120 @@
             int mOffset) {
         // Invert a 4 x 4 matrix using Cramer's Rule
 
-        // array of transpose source matrix
-        float[] src = new float[16];
-
         // transpose matrix
-        transposeM(src, 0, m, mOffset);
+        final float src0  = m[mOffset +  0];
+        final float src4  = m[mOffset +  1];
+        final float src8  = m[mOffset +  2];
+        final float src12 = m[mOffset +  3];
 
-        // temp array for pairs
-        float[] tmp = new float[12];
+        final float src1  = m[mOffset +  4];
+        final float src5  = m[mOffset +  5];
+        final float src9  = m[mOffset +  6];
+        final float src13 = m[mOffset +  7];
+
+        final float src2  = m[mOffset +  8];
+        final float src6  = m[mOffset +  9];
+        final float src10 = m[mOffset + 10];
+        final float src14 = m[mOffset + 11];
+
+        final float src3  = m[mOffset + 12];
+        final float src7  = m[mOffset + 13];
+        final float src11 = m[mOffset + 14];
+        final float src15 = m[mOffset + 15];
 
         // calculate pairs for first 8 elements (cofactors)
-        tmp[0] = src[10] * src[15];
-        tmp[1] = src[11] * src[14];
-        tmp[2] = src[9] * src[15];
-        tmp[3] = src[11] * src[13];
-        tmp[4] = src[9] * src[14];
-        tmp[5] = src[10] * src[13];
-        tmp[6] = src[8] * src[15];
-        tmp[7] = src[11] * src[12];
-        tmp[8] = src[8] * src[14];
-        tmp[9] = src[10] * src[12];
-        tmp[10] = src[8] * src[13];
-        tmp[11] = src[9] * src[12];
-
-        // Holds the destination matrix while we're building it up.
-        float[] dst = new float[16];
+        final float atmp0  = src10 * src15;
+        final float atmp1  = src11 * src14;
+        final float atmp2  = src9  * src15;
+        final float atmp3  = src11 * src13;
+        final float atmp4  = src9  * src14;
+        final float atmp5  = src10 * src13;
+        final float atmp6  = src8  * src15;
+        final float atmp7  = src11 * src12;
+        final float atmp8  = src8  * src14;
+        final float atmp9  = src10 * src12;
+        final float atmp10 = src8  * src13;
+        final float atmp11 = src9  * src12;
 
         // calculate first 8 elements (cofactors)
-        dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
-        dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
-        dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
-        dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7];
-        dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7];
-        dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7];
-        dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6];
-        dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6];
-        dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3];
-        dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3];
-        dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3];
-        dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3];
-        dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3];
-        dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
-        dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
-        dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
+        final float dst0  = (atmp0 * src5 + atmp3 * src6 + atmp4  * src7)
+                          - (atmp1 * src5 + atmp2 * src6 + atmp5  * src7);
+        final float dst1  = (atmp1 * src4 + atmp6 * src6 + atmp9  * src7)
+                          - (atmp0 * src4 + atmp7 * src6 + atmp8  * src7);
+        final float dst2  = (atmp2 * src4 + atmp7 * src5 + atmp10 * src7)
+                          - (atmp3 * src4 + atmp6 * src5 + atmp11 * src7);
+        final float dst3  = (atmp5 * src4 + atmp8 * src5 + atmp11 * src6)
+                          - (atmp4 * src4 + atmp9 * src5 + atmp10 * src6);
+        final float dst4  = (atmp1 * src1 + atmp2 * src2 + atmp5  * src3)
+                          - (atmp0 * src1 + atmp3 * src2 + atmp4  * src3);
+        final float dst5  = (atmp0 * src0 + atmp7 * src2 + atmp8  * src3)
+                          - (atmp1 * src0 + atmp6 * src2 + atmp9  * src3);
+        final float dst6  = (atmp3 * src0 + atmp6 * src1 + atmp11 * src3)
+                          - (atmp2 * src0 + atmp7 * src1 + atmp10 * src3);
+        final float dst7  = (atmp4 * src0 + atmp9 * src1 + atmp10 * src2)
+                          - (atmp5 * src0 + atmp8 * src1 + atmp11 * src2);
 
         // calculate pairs for second 8 elements (cofactors)
-        tmp[0] = src[2] * src[7];
-        tmp[1] = src[3] * src[6];
-        tmp[2] = src[1] * src[7];
-        tmp[3] = src[3] * src[5];
-        tmp[4] = src[1] * src[6];
-        tmp[5] = src[2] * src[5];
-        tmp[6] = src[0] * src[7];
-        tmp[7] = src[3] * src[4];
-        tmp[8] = src[0] * src[6];
-        tmp[9] = src[2] * src[4];
-        tmp[10] = src[0] * src[5];
-        tmp[11] = src[1] * src[4];
+        final float btmp0  = src2 * src7;
+        final float btmp1  = src3 * src6;
+        final float btmp2  = src1 * src7;
+        final float btmp3  = src3 * src5;
+        final float btmp4  = src1 * src6;
+        final float btmp5  = src2 * src5;
+        final float btmp6  = src0 * src7;
+        final float btmp7  = src3 * src4;
+        final float btmp8  = src0 * src6;
+        final float btmp9  = src2 * src4;
+        final float btmp10 = src0 * src5;
+        final float btmp11 = src1 * src4;
 
         // calculate second 8 elements (cofactors)
-        dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
-        dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
-        dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
-        dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15];
-        dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15];
-        dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15];
-        dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14];
-        dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14];
-        dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9];
-        dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10];
-        dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10];
-        dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8];
-        dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8];
-        dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
-        dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
-        dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
+        final float dst8  = (btmp0  * src13 + btmp3  * src14 + btmp4  * src15)
+                          - (btmp1  * src13 + btmp2  * src14 + btmp5  * src15);
+        final float dst9  = (btmp1  * src12 + btmp6  * src14 + btmp9  * src15)
+                          - (btmp0  * src12 + btmp7  * src14 + btmp8  * src15);
+        final float dst10 = (btmp2  * src12 + btmp7  * src13 + btmp10 * src15)
+                          - (btmp3  * src12 + btmp6  * src13 + btmp11 * src15);
+        final float dst11 = (btmp5  * src12 + btmp8  * src13 + btmp11 * src14)
+                          - (btmp4  * src12 + btmp9  * src13 + btmp10 * src14);
+        final float dst12 = (btmp2  * src10 + btmp5  * src11 + btmp1  * src9 )
+                          - (btmp4  * src11 + btmp0  * src9  + btmp3  * src10);
+        final float dst13 = (btmp8  * src11 + btmp0  * src8  + btmp7  * src10)
+                          - (btmp6  * src10 + btmp9  * src11 + btmp1  * src8 );
+        final float dst14 = (btmp6  * src9  + btmp11 * src11 + btmp3  * src8 )
+                          - (btmp10 * src11 + btmp2  * src8  + btmp7  * src9 );
+        final float dst15 = (btmp10 * src10 + btmp4  * src8  + btmp9  * src9 )
+                          - (btmp8  * src9  + btmp11 * src10 + btmp5  * src8 );
 
         // calculate determinant
-        float det =
-                src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3]
-                        * dst[3];
+        final float det =
+                src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3;
 
         if (det == 0.0f) {
-
+            return false;
         }
 
         // calculate matrix inverse
-        det = 1 / det;
-        for (int j = 0; j < 16; j++)
-            mInv[j + mInvOffset] = dst[j] * det;
+        final float invdet = 1.0f / det;
+        mInv[     mInvOffset] = dst0  * invdet;
+        mInv[ 1 + mInvOffset] = dst1  * invdet;
+        mInv[ 2 + mInvOffset] = dst2  * invdet;
+        mInv[ 3 + mInvOffset] = dst3  * invdet;
+
+        mInv[ 4 + mInvOffset] = dst4  * invdet;
+        mInv[ 5 + mInvOffset] = dst5  * invdet;
+        mInv[ 6 + mInvOffset] = dst6  * invdet;
+        mInv[ 7 + mInvOffset] = dst7  * invdet;
+
+        mInv[ 8 + mInvOffset] = dst8  * invdet;
+        mInv[ 9 + mInvOffset] = dst9  * invdet;
+        mInv[10 + mInvOffset] = dst10 * invdet;
+        mInv[11 + mInvOffset] = dst11 * invdet;
+
+        mInv[12 + mInvOffset] = dst12 * invdet;
+        mInv[13 + mInvOffset] = dst13 * invdet;
+        mInv[14 + mInvOffset] = dst14 * invdet;
+        mInv[15 + mInvOffset] = dst15 * invdet;
 
         return true;
     }
@@ -488,9 +517,10 @@
     public static void rotateM(float[] rm, int rmOffset,
             float[] m, int mOffset,
             float a, float x, float y, float z) {
-        float[] r = new float[16];
-        setRotateM(r, 0, a, x, y, z);
-        multiplyMM(rm, rmOffset, m, mOffset, r, 0);
+        synchronized(sTemp) {
+            setRotateM(sTemp, 0, a, x, y, z);
+            multiplyMM(rm, rmOffset, m, mOffset, sTemp, 0);
+        }
     }
 
     /**
@@ -505,10 +535,11 @@
      */
     public static void rotateM(float[] m, int mOffset,
             float a, float x, float y, float z) {
-        float[] temp = new float[32];
-        setRotateM(temp, 0, a, x, y, z);
-        multiplyMM(temp, 16, m, mOffset, temp, 0);
-        System.arraycopy(temp, 16, m, mOffset, 16);
+        synchronized(sTemp) {
+            setRotateM(sTemp, 0, a, x, y, z);
+            multiplyMM(sTemp, 16, m, mOffset, sTemp, 0);
+            System.arraycopy(sTemp, 16, m, mOffset, 16);
+        }
     }
 
     /**
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index d2b7378..46f7139 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -130,7 +130,7 @@
         if (window != NULL) {
             native_window_set_buffers_format(window, 0);
             if (native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL)) {
-                LOGE("EGLNativeWindowType %p disconnected failed", window);
+                LOGW("EGLNativeWindowType %p disconnect failed", window);
             }
         }
     }
diff --git a/opengl/libs/GLES2_dbg/Android.mk b/opengl/libs/GLES2_dbg/Android.mk
index c2b1142..70853d8 100644
--- a/opengl/libs/GLES2_dbg/Android.mk
+++ b/opengl/libs/GLES2_dbg/Android.mk
@@ -31,6 +31,9 @@
     LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
 endif
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLES2_dbg\"
+
+
 # we need to access the private Bionic header <bionic_tls.h>
 # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
 # behavior from the bionic Android.mk file
diff --git a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
index 9e77665..41061e1 100644
--- a/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
+++ b/opengl/libs/GLES2_dbg/src/dbgcontext.cpp
@@ -30,13 +30,11 @@
 }
 
 DbgContext::DbgContext(const unsigned version, const gl_hooks_t * const hooks,
-                       const unsigned MAX_VERTEX_ATTRIBS, const GLenum readFormat,
-                       const GLenum readType)
+                       const unsigned MAX_VERTEX_ATTRIBS)
         : lzf_buf(NULL), lzf_readIndex(0), lzf_refSize(0), lzf_refBufSize(0)
         , version(version), hooks(hooks)
         , MAX_VERTEX_ATTRIBS(MAX_VERTEX_ATTRIBS)
-        , readFormat(readFormat), readType(readType)
-        , readBytesPerPixel(GetBytesPerPixel(readFormat, readType))
+        , readBytesPerPixel(4)
         , captureSwap(0), captureDraw(0)
         , vertexAttribs(new VertexAttrib[MAX_VERTEX_ATTRIBS])
         , hasNonVBOAttribs(false), indexBuffers(NULL), indexBuffer(NULL)
@@ -67,11 +65,7 @@
     assert(GL_NO_ERROR == hooks->gl.glGetError());
     GLint MAX_VERTEX_ATTRIBS = 0;
     hooks->gl.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &MAX_VERTEX_ATTRIBS);
-    GLint readFormat, readType;
-    hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
-    hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
-    DbgContext* dbg = new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS, readFormat, readType);
-
+    DbgContext* dbg = new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS);
     glesv2debugger::Message msg, cmd;
     msg.set_context_id(reinterpret_cast<int>(dbg));
     msg.set_expect_response(false);
@@ -100,33 +94,31 @@
 {
     switch (type) {
     case GL_UNSIGNED_SHORT_5_6_5:
-        return 2;
     case GL_UNSIGNED_SHORT_4_4_4_4:
-        return 2;
     case GL_UNSIGNED_SHORT_5_5_5_1:
         return 2;
     case GL_UNSIGNED_BYTE:
         break;
     default:
-        assert(0);
+        LOGE("GetBytesPerPixel: unknown type %x", type);
     }
 
     switch (format) {
     case GL_ALPHA:
-        return 1;
     case GL_LUMINANCE:
         return 1;
-        break;
     case GL_LUMINANCE_ALPHA:
         return 2;
     case GL_RGB:
         return 3;
     case GL_RGBA:
+    case 0x80E1:   // GL_BGRA_EXT
         return 4;
     default:
-        assert(0);
-        return 0;
+        LOGE("GetBytesPerPixel: unknown format %x", format);
     }
+
+    return 1; // in doubt...
 }
 
 void DbgContext::Fetch(const unsigned index, std::string * const data) const
diff --git a/opengl/libs/GLES2_dbg/src/egl.cpp b/opengl/libs/GLES2_dbg/src/egl.cpp
index eb28d06..bbea3bd 100644
--- a/opengl/libs/GLES2_dbg/src/egl.cpp
+++ b/opengl/libs/GLES2_dbg/src/egl.cpp
@@ -41,11 +41,11 @@
         void * pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
                         dbg->readBytesPerPixel);
         dbg->hooks->gl.glReadPixels(viewport[0], viewport[1], viewport[2],
-                                    viewport[3], dbg->readFormat, dbg->readType, pixels);
+                                    viewport[3], GL_RGBA, GL_UNSIGNED_BYTE, pixels);
         dbg->CompressReadPixelBuffer(msg.mutable_data());
         msg.set_data_type(msg.ReferencedImage);
-        msg.set_pixel_format(dbg->readFormat);
-        msg.set_pixel_type(dbg->readType);
+        msg.set_pixel_format(GL_RGBA);
+        msg.set_pixel_type(GL_UNSIGNED_BYTE);
         msg.set_image_width(viewport[2]);
         msg.set_image_height(viewport[3]);
     }
diff --git a/opengl/libs/GLES2_dbg/src/header.h b/opengl/libs/GLES2_dbg/src/header.h
index f2b1fa6..49f3847 100644
--- a/opengl/libs/GLES2_dbg/src/header.h
+++ b/opengl/libs/GLES2_dbg/src/header.h
@@ -87,7 +87,6 @@
     const unsigned int version; // 0 is GLES1, 1 is GLES2
     const gl_hooks_t * const hooks;
     const unsigned int MAX_VERTEX_ATTRIBS;
-    const GLenum readFormat, readType; // implementation supported glReadPixels
     const unsigned int readBytesPerPixel;
 
     unsigned int captureSwap; // number of eglSwapBuffers to glReadPixels
@@ -124,8 +123,7 @@
     unsigned maxAttrib; // number of slots used by program
 
     DbgContext(const unsigned version, const gl_hooks_t * const hooks,
-               const unsigned MAX_VERTEX_ATTRIBS, const GLenum readFormat,
-               const GLenum readType);
+               const unsigned MAX_VERTEX_ATTRIBS);
     ~DbgContext();
 
     void Fetch(const unsigned index, std::string * const data) const;
diff --git a/opengl/libs/GLES2_dbg/src/vertex.cpp b/opengl/libs/GLES2_dbg/src/vertex.cpp
index 029ee3b..28a24206 100644
--- a/opengl/libs/GLES2_dbg/src/vertex.cpp
+++ b/opengl/libs/GLES2_dbg/src/vertex.cpp
@@ -77,7 +77,7 @@
                 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
                                                   dbg->readBytesPerPixel);
                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
-                                   dbg->readFormat, dbg->readType, pixels);
+                        GL_RGBA, GL_UNSIGNED_BYTE, pixels);
             }
             break;
         case glesv2debugger::Message_Function_SKIP:
@@ -134,19 +134,22 @@
     msg.set_arg7(dbg->maxAttrib); // indicate capturing vertex data
     std::string * const data = msg.mutable_data();
     if (GL_UNSIGNED_BYTE == type) {
-        if (dbg->indexBuffer)
+        if (dbg->indexBuffer) {
             FetchIndexed(count, (unsigned char *)dbg->indexBuffer->data +
                          (unsigned long)indices, data, dbg);
-        else
+        } else {
             FetchIndexed(count, (unsigned char *)indices, data, dbg);
+        }
     } else if (GL_UNSIGNED_SHORT == type) {
-        if (dbg->indexBuffer)
+        if (dbg->indexBuffer) {
             FetchIndexed(count, (unsigned short *)((char *)dbg->indexBuffer->data +
                                                    (unsigned long)indices), data, dbg);
-        else
+        } else {
             FetchIndexed(count, (unsigned short *)indices, data, dbg);
-    } else
+        }
+    } else {
         assert(0);
+    }
 
     void * pixels = NULL;
     int viewport[4] = {};
@@ -174,7 +177,7 @@
             Send(msg, cmd);
             expectResponse = cmd.expect_response();
             // TODO: pack glReadPixels data with vertex data instead of
-            //  relying on sperate call for transport, this would allow
+            //  relying on separate call for transport, this would allow
             //  auto generated message loop using EXTEND_Debug macro
             if (dbg->captureDraw > 0) {
                 dbg->captureDraw--;
@@ -182,7 +185,7 @@
                 pixels = dbg->GetReadPixelsBuffer(viewport[2] * viewport[3] *
                                                   dbg->readBytesPerPixel);
                 Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
-                                   dbg->readFormat, dbg->readType, pixels);
+                        GL_RGBA, GL_UNSIGNED_BYTE, pixels);
             }
             break;
         case glesv2debugger::Message_Function_SKIP:
diff --git a/opengl/libs/GLES2_dbg/test/test_main.cpp b/opengl/libs/GLES2_dbg/test/test_main.cpp
index 058bea4..183bf8e 100644
--- a/opengl/libs/GLES2_dbg/test/test_main.cpp
+++ b/opengl/libs/GLES2_dbg/test/test_main.cpp
@@ -29,7 +29,7 @@
     gl_hooks_t hooks;
 
     DbgContextTest()
-            : dbg(1, &hooks, 32, GL_RGBA, GL_UNSIGNED_BYTE) {
+            : dbg(1, &hooks, 32) {
         // You can do set-up work for each test here.
         hooks.gl.glGetError = GetError;
     }
diff --git a/opengl/libs/GLES2_dbg/test/test_server.cpp b/opengl/libs/GLES2_dbg/test/test_server.cpp
index bbbe913..0ab87b0 100644
--- a/opengl/libs/GLES2_dbg/test/test_server.cpp
+++ b/opengl/libs/GLES2_dbg/test/test_server.cpp
@@ -151,7 +151,7 @@
     virtual void SetUp() {
         ServerFileTest::SetUp();
 
-        dbg = new DbgContext(1, &hooks, 32, GL_RGBA, GL_UNSIGNED_BYTE);
+        dbg = new DbgContext(1, &hooks, 32);
         ASSERT_NE((void *)NULL, dbg);
         for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
             ((void **)&hooks)[i] = reinterpret_cast<void *>(glNoop);
diff --git a/opengl/libs/GLES2_dbg/test/test_socket.cpp b/opengl/libs/GLES2_dbg/test/test_socket.cpp
index b2148ac..9f815e2 100644
--- a/opengl/libs/GLES2_dbg/test/test_socket.cpp
+++ b/opengl/libs/GLES2_dbg/test/test_socket.cpp
@@ -44,7 +44,7 @@
     }
 
     virtual void SetUp() {
-        dbg = new DbgContext(1, &hooks, 32, GL_RGBA, GL_UNSIGNED_BYTE);
+        dbg = new DbgContext(1, &hooks, 32);
         ASSERT_TRUE(dbg != NULL);
         for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
             ((void **)&hooks)[i] = (void *)glNoop;
diff --git a/packages/BackupRestoreConfirmation/res/values-am/strings.xml b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
index 41fa6a0..43e4cce 100644
--- a/packages/BackupRestoreConfirmation/res/values-am/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-am/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"ሙሉ ለሙሉ መጠባበቂያ"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"ሙሉ ለሙሉ እነበረበት መልስ"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"ሁሉንም ውሂብ በሙሉ መጠበቂያ ከተያያዘ የዴስክቶፕ ኮምፒዩተር ተጠይቋል። ይህ እንዲከሰት ለመፍቀድ ይፈልጋሉ? "\n\n"እርስዎ ራስዎ የመጠባበቂያውን ጥየቃ ካልጠየቁ ክወናው እንዲካሄድ አይፍቀዱ።"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"ውሂቤን መጠባበቂያ"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"መጠባበቂያ አታድርግ"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"እባክዎ የሙሉ ውሂብ መጠበቂያ ማመስጠር ለመጠቅም የይለፍ ቃል ያስገቡ። ይህም ባዶ ከሆነ፣ የእርስዎ የአሁኑ የመጠበቂያ ይለፍ ቃል ይወሰዳል፡"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"ሙሉ የውሂብ መጠበቂያ ለማመስጠር ከፈለጉ ከታች የይለፍ ቃል ያስገቡ፡"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"ውሂብ እነበረበት መልስ የተመሳጠረ ከሆነ፣ እባክዎ ከታች የይለፍ ቃል ያስገቡ"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"መጠባበቂያ በመጀመር ላይ..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"መጠባበቂያ ጨርሷል"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"እነበረበት መልስ በመጀመር ላይ..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"እነበረበት መመለስ ጨርሷል"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"ክንውን ጊዜው አልቋል"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
index 0d4cf97..f946d49 100644
--- a/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ar/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"نسخ احتياطي بالكامل"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"استعادة كاملة"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"تم طلب الاحتفاظ بنسخة احتياطية كاملة من البيانات على كمبيوتر سطح مكتب متصل. هل تريد السماح بإجراء ذلك؟"\n\n"إذا لم تطلب الاحتفاظ بنسخة احتياطية بنفسك، فلا تسمح بمتابعة العملية."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"الاحتفاظ بنسخة احتياطية من بياناتي"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"عدم النسخ الاحتياطي"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"الرجاء إدخال كلمة المرور للاستخدام لتشفير بيانات النسخة الاحتياطية بالكامل. إذا تم ترك هذا فارغًا، فسيتم استخدام كلمة مرور النسخ الاحتياطي الحالية:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"إذا كنت ترغب في تشفير بيانات النسخة الاحتياطية بالكامل، فأدخل كلمة المرور أدناه:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"إذا كانت بيانات الاسترداد مشفرة، فالرجاء إدخال كلمة المرور أدناه:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"جارٍ بدء النسخ الاحتياطي..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"انتهت عملية النسخ الاحتياطي"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"جارٍ بدء الاستعادة..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"انتهت عملية استعادة"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"انتهت مهلة العملية"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-bg/strings.xml b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
index f90b666..6c6a90f 100644
--- a/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-bg/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Пълно резервно копие"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Пълно възстановяване"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Бе поискано пълно резервно копие на всичките данни до свързан настолен компютър. Искате ли да разрешите това?"\n\n"Ако не сте заявили създаването на копие, не позволявайте операцията да продължи."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Резервно копие на данните ми"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Без резервно копие"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Моля, въведете парола, която да използвате за шифроване на пълното резервно копие на данните. Ако не е попълнена, ще бъде използвана текущата ви парола за резервно копие:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако искате да шифровате пълното резервно копие на данните, въведете парола по-долу:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ако възстановените данни са шифровани, моля, въведете паролата по-долу:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Създаването на резервно копие се стартира..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Създаването на резервно копие завърши"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Възстановяването се стартира..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Възстановяването завърши"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Времето за изчакване на операцията изтече"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
index cdccf59..0d8fa2b 100644
--- a/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-cs/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Úplná záloha"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Úplné obnovení"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Obdrželi jsme požadavek na úplnou zálohu všech dat do připojeného počítače. Chcete tuto akci povolit? "\n\n"Pokud jste o zálohu nežádali, operaci nepovolujte."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Zálohovat data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nezálohovat"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Zadejte prosím heslo pro šifrování dat úplné zálohy. Pokud pole ponecháte prázdné, použije se aktuální heslo pro zálohy:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Chcete-li data úplné zálohy zašifrovat, zadejte heslo:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Pokud jsou obnovená data šifrována, zadejte prosím heslo níže:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Spouští se zálohování..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Zálohování bylo dokončeno"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Spouští se obnovení..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Obnovení bylo dokončeno"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Časový limit operace vypršel"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-da/strings.xml b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
index 5cbaab4..63bc7eb 100644
--- a/packages/BackupRestoreConfirmation/res/values-da/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-da/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Fuld sikkerhedskopiering"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Fuld genoprettelse"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Der er anmodet om en fuld sikkerhedskopiering af alle data til en tilsluttet stationær computer. Vil du tillade dette?"\n\n"Hvis du ikke har anmodet om sikkerhedskopiering, skal du ikke tillade denne handling."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhedskopier mine data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Undlad at sikkerhedskopiere"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Angiv en adgangskode, som skal bruges til kryptering af alle dine sikkerhedsdata. Hvis dette felt er tomt, bruges din aktuelle adgangskode til sikkerhedskopiering:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Hvis du ønsker at kryptere sikkerhedsdataene, skal du indtaste en adgangskode nedenfor:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Hvis gendannelsesdataene er krypteret, skal du angive adgangskoden nedenfor:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Sikkerhedskopiering begynder..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Sikkerhedskopiering er færdig"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Gendannelse begynder..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Gendannelse afsluttet"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Handling fik timeout"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-de/strings.xml b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
index e4bdb6b..cba2b26 100644
--- a/packages/BackupRestoreConfirmation/res/values-de/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-de/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Vollständige Sicherung"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Vollständige Wiederherstellung"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Es wurde eine vollständige Sicherung sämtlicher Daten auf einen verbundenen Desktop-Computer angefordert. Möchten Sie dies zulassen?"\n\n"Wenn Sie die Sicherung nicht selbst angefordert haben, sollten Sie dem Vorgang nicht zustimmen."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Meine Daten sichern"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nicht sichern"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Geben Sie ein Passwort für die Verschlüsselung der vollständigen Sicherungsdaten ein. Wenn Sie dieses Feld leer lassen, wird Ihr aktuelles Sicherungspasswort verwendet:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Wenn Sie die gesamten Sicherungsdaten verschlüsseln möchten, geben Sie unten ein Passwort ein:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Geben Sie das Passwort unten ein, wenn die Daten für die Wiederherstellung verschlüsselt sind:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Sicherung wird gestartet..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Sicherung abgeschlossen"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Wiederherstellung wird gestartet..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Wiederherstellung beendet"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Zeitüberschreitung bei Vorgang"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-el/strings.xml b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
index 9eb4555..7ea104e 100644
--- a/packages/BackupRestoreConfirmation/res/values-el/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-el/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Πλήρες αντίγραφο ασφαλείας"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Πλήρης επαναφορά"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Έχει ζητηθεί ένα πλήρες αντίγραφο ασφαλείας όλων των δεδομένων σε έναν συνδεδεμένο επιτραπέζιο υπολογιστή. Θέλετε να επιτραπεί αυτή η ενέργεια;"\n\n"Αν δεν έχετε ζητήσει οι ίδιοι αυτό το αντίγραφο ασφαλείας, μην επιτρέψετε την ενέργεια."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Δημιουργία αντιγράφων ασφαλείας για τα δεδομένα μου"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Να μην δημιουργείται αντίγραφο ασφαλείας"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Εισαγάγετε έναν κωδικό πρόσβασης για χρήση για την κωδικοποίηση του πλήρους αντιγράφου ασφαλείας δεδομένων. Αν μείνει κενό, θα χρησιμοποιηθεί ο τρέχων κωδικός σας πρόσβασης:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Αν θέλετε να κρυπτογραφήσετε τα πλήρη δεδομένα αντιγράφων ασφαλείας, πληκτρολογήστε έναν κωδικό πρόσβασης παρακάτω:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Εάν η επαναφορά των δεδομένων είναι κρυπτογραφημένη, εισάγετε τον κωδικό πρόσβασης παρακάτω:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Έναρξη διαδικασίας δημιουργίας αντιγράφου ασφαλείας..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Ολοκληρώθηκε η διαδικασία δημιουργίας αντιγράφου ασφαλείας"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Έναρξη διαδικασίας επαναφοράς..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Έληξε η διαδικασία επαναφοράς"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Λήξη χρονικού ορίου λειτουργίας"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
index 79f5a9a..2f1eb52 100644
--- a/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es-rUS/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Realización de la copia de seguridad completa"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauración completa"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en una computadora de escritorio conectada. ¿Deseas permitirla?"\n\n"Si tú no has solicitado la copia de seguridad, no permitas que se realice la operación."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Copia de seguridad de mis datos"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"No realizar una copia de seguridad"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Introduce una contraseña para encriptar los datos de la copia de seguridad completa. Si dejas este campo en blanco, se utilizará tu contraseña actual de copia de seguridad:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Si deseas encriptar los datos de la copia de seguridad completa, introduce una contraseña a continuación:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Si los datos de recuperación están encriptados, vuelve a introducir la contraseña a continuación:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Realizando la copia de seguridad..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"La realización de la copia de seguridad finalizó."</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Restaurando..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"La restauración finalizó."</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Se agotó el tiempo de espera para la operación."</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-es/strings.xml b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
index 8ae4762..359c54c 100644
--- a/packages/BackupRestoreConfirmation/res/values-es/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-es/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Copia de seguridad completa"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauración completa"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Se ha solicitado una copia de seguridad completa de todos los datos en un ordenador conectado. ¿Quieres permitir la copia de seguridad?"\n\n"No debes permitir la copia de seguridad si no has realizado tú la solicitud."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Copia de seguridad de datos"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"No hacer copia de seguridad"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Introduce la contraseña que quieras usar para cifrar los datos de la copia de seguridad completa. Si dejas este campo en blanco, se usará tu contraseña de copia de seguridad actual:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Si quieres cifrar los datos de la copia de seguridad completa, introduce la contraseña a continuación:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Si los datos de restauración están cifrados, introduce la contraseña a continuación:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Iniciando copia de seguridad..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Copia de seguridad finalizada"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Iniciando restauración..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Restauración finalizada"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Tiempo de espera de operación agotado"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
index f50ce6a..7badc7c 100644
--- a/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fi/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Täysi varmuuskopiointi"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Täysi palautus"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Kytketyn tietokoneen kaikista tiedoista on pyydetty täydellistä varmuuskopiota. Haluatko sallia tämän?"\n\n"Jos et ole itse pyytänyt varmuuskopiota, älä salli toimintoa."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Varmuuskopioi omat tiedot"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Älä varmuuskopioi"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Anna salasana kaikkien varmuuskopiotietojen salaamiseksi. Jos tämä jätetään tyhjäksi, nykyistä varmuuskopioinnin salasanaa käytetään:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jos haluat salata kaikki varmuuskopiotiedot, kirjoita salasana alle:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Jos palautustiedot on salattu, anna salasana alla:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Varmuuskopiointi alkaa..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Varmuuskopiointi valmis"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Palautus alkaa..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Palautus päättyi"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Toiminnon aikakatkaisu"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
index 31d1532..caa52a3 100644
--- a/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-fr/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Sauvegarde complète"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauration complète"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Vous avez demandé une sauvegarde complète de l\'ensemble des données vers un ordinateur de bureau connecté. Voulez-vous l\'autoriser ?"\n\n"Si vous n\'avez pas demandé la sauvegarde vous-même, n\'autorisez pas la poursuite de l\'opération."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sauvegarder mes données"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne pas sauvegarder"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Veuillez saisir un mot de passe à utiliser pour chiffrer les données de sauvegarde complète. Si ce champ n\'est pas renseigné, votre mot de passe de sauvegarde actuel sera utilisé :"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Si vous souhaitez chiffrer l\'ensemble des données de sauvegarde, veuillez saisir un mot de passe ci-dessous :"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Si les données de restauration sont chiffrées, veuillez saisir le mot de passe ci-dessous :"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Démarrage de la sauvegarde..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Sauvegarde terminée"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Démarrage de la restauration..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Restauration terminée"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"L\'opération a expiré."</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-hr/strings.xml b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
index ce06db9f..26992d6 100644
--- a/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hr/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Puna sigurnosna kopija"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Potpuno vraćanje"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zatražena je potpuna sigurnosna kopija svih podataka na povezano stolno računalo. Želite li to dozvoliti?"\n\n"Ako niste vi zatražili sigurnosnu kopiju, ne dozvolite nastavak te radnje."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Izradi sigurnosnu kopiju mojih podataka"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne radi sigurnosnu kopiju"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Unesite zaporku koju ćete upotrebljavati za kriptiranje podataka potpune sigurnosne kopije. Ako je ostavite praznom, bit će upotrijebljena vaša trenutačna zaporka za sigurnosno kopiranje:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ako želite kriptirati podatke potpune sigurnosne kopije, u nastavku unesite zaporku:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ako su podaci za vraćanje kriptirani, unesite zaporku u nastavku:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Započinje stvaranje sigurnosne kopije..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Sigurnosna kopija dovršena"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Započinje vraćanje..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Vraćanje završeno"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Isteklo je vrijeme operacije"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
index b244f26..5d69079 100644
--- a/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-hu/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Teljes biztonsági mentés"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Teljes helyreállítás"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Kérés érkezett az összes adat biztonsági mentésére egy csatlakoztatott asztali számítógépre. Engedélyezi, hogy ez megtörténjen?"\n\n"Ha nem Ön kérte a mentést, ne engedélyezze a művelet folytatását."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Adatok biztonsági mentése"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ne mentsen"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Kérjük, írjon be egy jelszót a teljes biztonsági mentés adatainak titkosításához. Ha üresen hagyja, jelenlegi biztonsági jelszavát fogjuk használni:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ha minden mentett adatot szeretne titkosítani, adjon meg egy jelszót alább:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ha a visszaállítási adatok titkosítva vannak, kérjük, adja meg a jelszót alább:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Biztonsági mentés indítása..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"A biztonsági mentés befejeződött"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Helyreállítás indítása..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"A helyreállítás véget ért"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"A művelet túllépte az időkeretet"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-in/strings.xml b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
index 5a26304..adf6636 100644
--- a/packages/BackupRestoreConfirmation/res/values-in/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-in/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Pencadangan sepenuhnya"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Pemulihan sepenuhnya"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Cadangan lengkap semua data ke komputer yang tersambung telah diminta. Apakah Anda ingin mengizinkan hal ini dilakukan?"\n\n"Jika Anda tidak meminta pencadangan ini, jangan izinkan operasi dilanjutkan."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Cadangkan data saya"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Jangan mencadangkan"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Masukkan sandi yang digunakan untuk mengenkripsi data cadangan lengkap. Jika bidang ini dikosongkan, sandi cadangan Anda saat ini akan digunakan:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jika Anda ingin mengenkripsi data cadangan lengkap, masukkan sandi di bawah:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Jika data pemulihan dienkripsi, masukkan sandi di bawah:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Pencadangan dimulai..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Pencadangan selesai"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Pemulihan dimulai..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Pemulihan berakhir"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Waktu tunggu operasi habis"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
index 056b245..fe1aa27 100644
--- a/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-iw/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"גיבוי מלא"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"שחזור מלא"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"הוגשה בקשה לגיבוי מלא של כל הנתונים במחשב שולחני מחובר. האם אתה רוצה לאפשר פעולה זו? "\n\n"אם לא ביקשת את הגיבוי בעצמך, אל תאפשר לפעולה להמשיך."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"גבה את הנתונים שלי"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"אל תגבה"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"הזן סיסמה שתשמש להצפנה של נתוני הגיבוי המלא. אם תשאיר שדה זה ריק, ייעשה שימוש בסיסמת הגיבוי הנוכחית שלך:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"אם אתה רוצה להצפין את נתוני הגיבוי המלא, הזן סיסמה בהמשך:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"אם נתוני השחזור מוצפנים, הזן את הסיסמה למטה:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"מתחיל בגיבוי..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"הגיבוי הסתיים"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"מתחיל בשחזור..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"השחזור הסתיים"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"פרק הזמן שהוקצב לפעולה הסתיים"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
index 0fca3cd..12e044e 100644
--- a/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ko/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"전체 백업"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"전체 복원"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"연결된 데스크톱 컴퓨터에 대한 전체 데이터 백업을 요청했습니다. 백업을 실행하시겠습니까?"\n\n"직접 백업을 요청한 것이 아니라면 작업을 진행하지 마시기 바랍니다."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"데이터 백업"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"백업하지 않음"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"전체 백업 데이터를 암호화하려면 사용할 비밀번호를 입력하세요. 공백으로 남겨 두면 현재 백업 비밀번호가 사용됩니다."</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"전체 백업 데이터를 암호화하려면 아래에 비밀번호를 입력하세요."</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"복원 데이터가 암호화되어 있는 경우, 아래에 비밀번호를 입력하세요."</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"백업 시작 중..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"백업을 완료했습니다."</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"복원 시작 중..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"복원이 종료되었습니다."</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"작업 시간이 초과되었습니다."</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
index 3144731..fdd91f1 100644
--- a/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lt/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Visos atsarginės kopijos kūrimas"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Visas atkūrimas"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Prijungtame staliniame kompiuteryje pageidauta sukurti visų duomenų atsarginę kopiją. Ar norite, kad tai būtų atlikta?"\n\n"Jei patys atsarginės kopijos kurti neprašėte, neleiskite pradėti operacijos."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Kurti atsarginę duomenų kopiją"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nekurti atsarginės kopijos"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Įveskite slaptažodį, kuris bus naudojamas visai atsarginei duomenų kopijai šifruoti. Jei reikšmės neįvesite, bus naudojamas dabartinis atsarginės kopijos slaptažodis:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jei norite užšifruoti visą atsarginę duomenų kopiją, įveskite slaptažodį:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Jei atkūrimo duomenys užšifruoti, įveskite toliau nurodytą slaptažodį:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Pradedama kurti atsarginę kopiją..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Atsarginės kopijos kūrimas baigtas"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Pradedamas atkūrimas..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Atkūrimas baigtas"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Operacijos skirtasis laikas baigėsi"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
index 1ea9558..b53e501 100644
--- a/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-lv/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Pilna dublēšana"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Pilna atjaunošana"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Ir pieprasīta visu datu pilnīga dublēšana savienotā galda datorā. Vai vēlaties to atļaut?"\n\n"Ja neesat pieprasījis dublēšanu, neatļaujiet turpināt šo darbību."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Dublēt manus datus"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Neveidot dublējumu"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Lūdzu, ievadiet paroli, kas tiks izmantota dublējuma datu pilnīgai šifrēšanai. Ja paroles lauciņu atstāsiet tukšu, tiks izmantota jūsu pašreizējā dublējuma parole:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ja vēlaties pilnībā šifrēt dublējuma datus, tālāk ievadiet paroli:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ja atjaunošanas dati ir šifrēti, lūdzu, ievadiet tālāk paroli:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Tiek sākta dublēšana..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Dublēšana pabeigta"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Tiek sākta atjaunošana..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Atjaunošana beidzās"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Iestājās darbības noildze"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
index a54138d..d0435df 100644
--- a/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nb/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Fullstendig sikkerhetskopi"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Fullstendig gjenoppretting"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"En full sikkerhetskopi av alle dataene til en tilkoblet stasjonær datamaskin er forespurt. Vil du tillate dette?"\n\n"Hvis du ikke har bedt om sikkerhetskopieringen selv, må du ikke tillate at operasjonen fortsetter."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sikkerhetskopier dataene mine"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ikke sikkerhetskopiér"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Skriv inn et passord for kryptering av full sikkerhetskopi. Hvis feltet er tomt, brukes det gjeldende passordet ditt for sikkerhetskopiering:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Hvis du vil kryptere alle de sikkerhetskopierte dataene, skriver du inn et passord nedenfor:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Hvis de gjenopprettede dataene er krypterte, må du skrive inn passordet nedenfor:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Sikkerhetskopiering er i gang …"</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Sikkerhetskopieringen er fullført"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Gjenopprettingen er i gang …"</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Gjenopprettingen er fullført"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Handlingen ble tidsavbrutt"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
index 6fc8757..f32ba27 100644
--- a/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-nl/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Volledige back-up"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Volledig herstel"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Er is een volledige back-up van alle gegevens naar een verbonden desktopcomputer aangevraagd. Wilt u dit toestaan?"\n\n"Als u de back-up zelf niet heeft aangevraagd, moet u niet toestaan dat de bewerking wordt uitgevoerd."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Back-up maken van mijn gegevens"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Geen back-up maken"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Geef een wachtwoord op dat u wilt gebruiken voor het coderen van de gegevens van de volledige back-up. Als u dit leeg laat, wordt uw huidige back-upwachtwoord gebruikt:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Als u de gegevens van de volledige back-up wilt coderen, geeft u daarvoor hieronder een wachtwoord op:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Als deze herstelgegevens zijn gecodeerd, geeft u hieronder het wachtwoord op:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Back-up starten..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Back-up klaar"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Herstel starten..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Herstellen beëindigd"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Time-out voor bewerking"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
index 8f0532f..87961a9 100644
--- a/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pl/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Pełna kopia zapasowa"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Pełne przywracanie"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zażądano wykonania pełnej kopii zapasowej wszystkich danych na podłączonym komputerze stacjonarnym. Czy chcesz na to zezwolić?"\n\n"Jeśli żądanie utworzenia kopii zapasowej nie pochodzi od Ciebie, nie zezwalaj na kontynuowanie tej operacji."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Utwórz kopię zapasową danych"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nie twórz kopii zapasowej"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Wpisz hasło do zaszyfrowania pełnej kopii zapasowej. Jeśli pozostawisz puste pole, zostanie użyte aktualne hasło kopii zapasowej:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Jeśli chcesz zaszyfrować pełną kopię zapasową, wprowadź poniżej hasło:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Jeśli przywracane dane są zaszyfrowane, wpisz poniżej hasło:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Rozpoczynanie tworzenia kopii zapasowej..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Tworzenie kopii zapasowej zakończone"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Rozpoczynanie przywracania..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Przywracanie zakończone"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Operacja przekroczyła czas oczekiwania"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
index 3eca061..309b8ce 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt-rPT/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Cópia de segurança completa"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauro completo"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitada uma cópia de segurança completa de todos os dados para um computador de secretária. Pretende permitir esta operação?"\n\n"Caso não tenha solicitado a cópia de segurança, não permita que a operação prossiga."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer cópia de seg. dos dados"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Não efetuar cópia de seg."</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Introduza uma palavra-passe a utilizar para encriptar os dados da cópia de segurança completa. Se deixar o campo em branco, será utilizada a palavra-passe de cópia de segurança atual."</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Se pretender encriptar os dados da cópia de segurança completa, introduza uma palavra-passe abaixo:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Se os dados a restaurar estiverem encriptados, introduza a palavra-passe abaixo:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"A iniciar cópia de segurança..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Cópia de segurança concluída"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"A iniciar restauro..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Restauro concluído"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Tempo limite da operação excedido"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
index 680b538..6be6fca 100644
--- a/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-pt/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Backup completo"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restauração completa"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Foi solicitado um backup completo de todos os dados para um computador conectado. Deseja permitir que isso aconteça?"\n\n"Caso você não tenha solicitado o backup, não permita que a operação prossiga."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Fazer backup de meus dados"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Não fazer backup"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Digite uma senha para usar para criptografar os dados de backup por completo. Se isso for deixado em branco, sua senha atual de backup será usada:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Se você deseja criptografar os dados de backup por completo, digite uma senha abaixo:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Se os dados restaurados forem criptografada, digite a senha abaixo:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Iniciando backup..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"O backup foi concluído"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Iniciando restauração..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"A restauração foi concluída"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"A operação atingiu o tempo limite"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
index 715f312..871fec5 100644
--- a/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ro/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Copie de rezervă completă"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Restaurare completă"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"S-a solicitat crearea unei copii de rezervă complete a tuturor datelor pe un computer desktop conectat. Doriţi să permiteţi acest lucru?"\n\n"Dacă nu aţi solicitat dvs. copierea de rezervă, nu permiteţi ca operaţiunea să continue."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Creaţi copii de rezervă pentru datele dvs."</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nu creaţi copii de rezervă"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Introduceţi o parolă pentru a o utiliza la criptarea datelor copiei de rezervă complete. Dacă acest câmp rămâne necompletat, pentru copierea de rezervă se va utiliza parola dvs. actuală."</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Dacă doriţi să criptaţi datele copiei de rezervă complete, introduceţi o parolă mai jos:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Dacă datele pentru restabilire sunt criptate, introduceţi parola mai jos:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Se începe crearea copiei de rezervă..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Copia de rezervă a fost finalizată"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Se porneşte restaurarea..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Restaurarea s-a încheiat"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Operaţia a expirat"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
index 2051e7a..c064e46 100644
--- a/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-ru/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Полное резервное копирование"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Полное восстановление"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Запрошено резервное копирование всех данных на подключенном компьютере. Разрешить?"\n\n"Если вы не запрашивали этого, не разрешайте выполнение операции."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Создать резервную копию данных"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Не создавать резервную копию"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Введите пароль для шифрования всех резервных данных. Если поле останется пустым, будет использован текущий пароль:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Чтобы зашифровать все резервные данные, введите пароль:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Если восстановленные данные зашифрованы, введите пароль:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Резервное копирование..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Резервное копирование завершено"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Восстановление..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Восстановление завершено"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Время ожидания для операции истекло"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
index bc8ff97..0314c91 100644
--- a/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sk/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Úplná záloha"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Úplné obnovenie"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Bola vyžiadaná úplná záloha všetkých dát do pripojeného počítača. Chcete túto akciu povoliť?"\n\n"Ak ste zálohu nevyžiadali vy, túto operáciu nepovoľujte."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Zálohovať údaje"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Nezálohovať"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Zadajte heslo, ktoré sa použije pri šifrovaní údajov úplnej zálohy. Ak pole ponecháte prázdne, použije sa vaše aktuálne heslo zálohy:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ak chcete šifrovať údaje úplnej zálohy, zadajte heslo nižšie:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ak sú údaje obnovenia šifrované, zadajte heslo nižšie:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Vytváranie zálohy..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Zálohovanie bolo dokončené"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Začína obnovenie..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Obnovenie bolo ukončené"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Časový limit operácie vypršal"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
index 50a5d50..7615042 100644
--- a/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sl/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Popolna varnostna kopija"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Popolna obnova"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Zahtevano je popolno varnostno kopiranje vseh podatkov v povezanem računalniku. Ali želite to dovoliti?"\n\n"Če varnostnega kopiranja niste zahtevali, ne dovolite nadaljevanja postopka."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Varnostno kopiraj moje podatke"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Brez varnostnega kopiranja"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Vnesite geslo za šifriranje podatkov popolnega varnostnega kopiranja. Če to pustite prazno, bo uporabljeno trenutno geslo za varnostno kopiranje:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Če želite šifrirati vse varnostno kopirane podatke, spodaj vnesite geslo:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Če so podatki za obnovitev šifrirani, spodaj vnesite geslo:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Varnostno kopiranje se začenja ..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Varnostno kopiranje je končano"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Obnova se začenja ..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Obnova je končana"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Časovna omejitev postopka je potekla"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
index 1573dc7..094eb12 100644
--- a/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sr/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Прављење резервне копије свих података"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Потпуно враћање"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Захтевана је потпуна резервна копија свих података на повезани стони рачунар. Да ли желите да дозволите то?"\n\n"Ако нисте лично захтевали резервну копију, не дозвољавајте наставак радње."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Направи резервну копију мојих података"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Не прави резервне копије"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Унесите лозинку коју ћете користити за шифровање података потпуне резервне копије. Ако то поље оставите празно, користиће се тренутна лозинка резервне копије:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ако желите да шифрујете податке потпуне резервне копије, унесите лозинку у наставку."</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Ако су подаци за враћање шифровани, унесите лозинку у наставку:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Покретање прављења резервне копије..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Прављење резервне копије је завршено"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Покретање враћања..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Враћање је завршено"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Време за операцију је истекло"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
index 4ac0a54..8df6544 100644
--- a/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sv/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Fullständig säkerhetskopiering"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Fullständig återställning"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"En fullständig säkerhetskopia av alla data till en ansluten dator har begärts. Vill du tillåta detta?"\n\n"Om du inte själv begärde säkerhetskopian ska du inte tillåta detta."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Säkerhetskopiera mina data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Säkerhetskopiera inte"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Ange ett lösenord för kryptering av alla säkerhetskopierade data. Om det här lämnas tomt kommer ditt nuvarande lösenord för säkerhetskopior att användas:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Om du vill kryptera alla säkerhetskopierade data anger du ett lösenord nedan:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Om återställda data är krypterade anger du lösenordet nedan:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Säkerhetskopieringen har startat ..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Säkerhetskopieringen har slutförts"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Återställningen har startat ..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Återställningen har avslutats"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Tidsgränsen för åtgärden har överskridits"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-th/strings.xml b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
index 68af3b8..3bc2ce6 100644
--- a/packages/BackupRestoreConfirmation/res/values-th/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-th/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"การสำรองข้อมูลแบบเต็ม"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"การคืนค่าทั้งหมด"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"เราได้รับการขอให้ทำการสำรองข้อมูลทั้งหมดลงในคอมพิวเตอร์เดสก์ท็อปที่เชื่อมต่ออยู่ คุณต้องการอนุญาตให้ดำเนินการตามนี้หรือไม่"\n\n" หากคุณไม่ได้เป็นผู้ขอให้ทำการสำรองข้อมูลดังกล่าว โปรดอย่าอนุญาตให้ดำเนินการ"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"สำรองข้อมูลของฉัน"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"ไม่ต้องสำรองข้อมูล"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"โปรดป้อนรหัสผ่านเพื่อใช้สำหรับเข้ารหัสข้อมูลที่สำรองแบบเต็มรูปแบบ หากเว้นว่างไว้ รหัสผ่านการสำรองข้อมูลปัจจุบันของคุณจะถูกใช้:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"หากคุณต้องการเข้ารหัสข้อมูลที่สำรองเต็มรูปแบบ โปรดป้อนรหัสผ่านด้านล่างนี้:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"หากมีการเข้ารหัสข้อมูลที่คืนค่า โปรดป้อนรหัสผ่านด้านล่างนี้:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"กำลังเริ่มการสำรองข้อมูล..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"สำรองข้อมูลเสร็จแล้ว"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"กำลังเริ่มการคืนค่า..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"สิ้นสุดการคืนค่าแล้ว"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"หมดเวลาการดำเนินการ"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
index 272b406..f54105d 100644
--- a/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-tl/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Ganap na pag-backup"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Ganap na pagpapanumbalik"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Hiniling ang isang buong pag-backup ng lahat ng data sa isang nakakonektang desktop computer. Gusto mo ba itong payagang maganap? "\n\n"Kung hindi ikaw mismo ang humiling ng pag-backup, huwag payagang magpatuloy ang pagpapatakbo."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"I-back up ang aking data"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Huwag i-back up"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Mangyaring maglagay ng password na gamitin sa pag-e-encrypt ng buong data sa pag-backup. Kung iiwanan itong blangko, gagamitin ang iyong kasalukuyang backup na password:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Kung nais mong i-encrypt ang buong data ng backup, maglagay ng password sa ibaba:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Kung naka-encrypt ang data sa pagpapanumbalik, pakilagay ang password sa ibaba:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Sinisimulan ang pag-backup..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Tapos na ang pag-backup"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Sinisimulan ang pagpapanumbalik..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Natapos na ang pagpapanumbalik"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Naubusan ng oras ang pagpapatakbo"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
index a1c6f2c..3c9fb97 100644
--- a/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-uk/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Повне резервне копіювання"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Повне відновлення"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Надійшов запит на повне резервне копіювання всіх даних на під’єднаний настільний комп’ютер. Дозволити це?"\n\n"Якщо ви не надсилали запит на резервне копіювання, не дозволяйте виконувати цю операцію."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Резервне копіювання даних"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Не створювати резервну копію"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Введіть пароль, який використовується для шифрування повного резервного копіювання даних. Якщо залишити це поле порожнім, буде використано поточний пароль резервного копіювання."</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Якщо ви хочете зашифрувати повне резервне копіювання даних, введіть пароль нижче:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Якщо дані для відновлення зашифровано, введіть пароль нижче:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Початок резервного копіювання..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Резервне копіювання закінчено"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Початок відновлення..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Відновлення закінчено"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Час виконання операції минув"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
index ad98262..1a92acb 100644
--- a/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-vi/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Sao lưu hoàn toàn"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Khôi phục hoàn toàn"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Đã yêu cầu sao lưu đầy đủ toàn bộ dữ liệu tới máy tính được kết nối. Bạn có muốn cho phép điều này xảy ra không?"\n\n"Nếu không phải bản thân bạn yêu cầu sao lưu, đừng cho phép thao tác này tiếp tục."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sao lưu dữ liệu của tôi"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Không sao lưu"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Vui lòng nhập mật khẩu dùng để mã hóa toàn bộ dữ liệu sao lưu. Nếu trường này bị bỏ trống, mật khẩu sao lưu hiện tại của bạn sẽ được sử dụng:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Nếu bạn muốn mã hóa toàn bộ dữ liệu sao lưu, hãy nhập mật khẩu bên dưới:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Nếu dữ liệu khôi phục được mã hóa, vui lòng nhập mật khẩu bên dưới:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Đang bắt đầu sao lưu..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Đã hoàn thành sao lưu"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Đang bắt đầu khôi phục..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Đã kết thúc quá trình khôi phục"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Thao tác hết thời gian chờ"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
index dcaebd2..bf44a0e 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rCN/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"完全备份"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"完全还原"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"系统请求将所有数据完整备份至已连接的桌面计算机。允许此操作吗?"\n\n"如果您本人未要求备份,请阻止该操作。"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"备份我的数据"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"不备份"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"请输入用于加密完整备份数据的密码。如果留空,系统将会使用您当前的备份密码:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"如果您想为整个备份数据加密,请在下方输入密码:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"如果恢复数据已加密,请在下方输入密码:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"开始备份..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"备份已完成"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"开始还原..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"还原已结束"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"操作超时"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
index 00c24df..f61e44c 100644
--- a/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zh-rTW/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"完整備份"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"完整還原"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"系統收到將所有資料完整備份至連線電腦的要求,請問您允許進行備份嗎?"\n\n"如果您本人並未提出備份要求,請勿允許繼續進行這項作業。"</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"備份我的資料"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"不要備份"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"請輸入完整備份資料加密專用的密碼。如果您沒有輸入密碼,系統會使用您目前的備用密碼:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"如果您想要將完整備份資料進行加密,請在下面輸入一組密碼:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"如果還原的資料經過加密處理,請在下面輸入密碼:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"正在開始備份..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"備份完畢"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"正在開始還原..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"還原完畢"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"作業逾時"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
index 98e76cd..822379f 100644
--- a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
@@ -16,8 +16,10 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="backup_confirm_title" msgid="827563724209303345">"Ukulondolozwa okuphelele"</string>
-    <string name="restore_confirm_title" msgid="5469365809567486602">"Ukubuyisela okuphelele"</string>
+    <!-- no translation found for backup_confirm_title (827563724209303345) -->
+    <skip />
+    <!-- no translation found for restore_confirm_title (5469365809567486602) -->
+    <skip />
     <string name="backup_confirm_text" msgid="1878021282758896593">"Kucelwe ukwesekelwa ngokulondoloza okuphelele kwayo yonke imininingo ekwi-desktop yekhompuyutha exhunyiwe. Angifuni ukuvumel alokhu ukuthi kwenzeke?"\n\n"Uma kuwukuthi awuzange ucele ukuthi kwesekelwe ngokulondoloza wena uqobo lwakho, ungavumeli ukuthi lolu hlelo luqhubekele phambili."</string>
     <string name="allow_backup_button_label" msgid="4217228747769644068">"Sekela ngokulondoloza imininingo yami"</string>
     <string name="deny_backup_button_label" msgid="6009119115581097708">"Ungenzi isipele"</string>
@@ -28,9 +30,14 @@
     <string name="backup_enc_password_text" msgid="4981585714795233099">"Sicela ufake i-password ezosetshenziselwa ukubhala ngokufihlekileyo imininingo eyesekwe ngokulondoloza. Uma lokhu kushiywe kungabhalwe lutho, kuzosetshenziswa i-password yokweseka ngokulondoloza yamanje:"</string>
     <string name="backup_enc_password_optional" msgid="1350137345907579306">"Uma ufuna ukufaka ikhowudi kwimininingo yonke eyesekelwe ngokulondoloza faka i-passowrd engezansi:"</string>
     <string name="restore_enc_password_text" msgid="6140898525580710823">"Uma insiza yokubuyiselwa esimweni kwmininingo ibhalwe ngokufihlekileyo, sicela ufake i-password ngezansi:"</string>
-    <string name="toast_backup_started" msgid="550354281452756121">"Ukulondoloza kuyaqala..."</string>
-    <string name="toast_backup_ended" msgid="3818080769548726424">"Ukulondoloza kuphelile"</string>
-    <string name="toast_restore_started" msgid="7881679218971277385">"Ukubuyisa kuyaqala..."</string>
-    <string name="toast_restore_ended" msgid="1764041639199696132">"Ukubuyiswa kuphelile"</string>
-    <string name="toast_timeout" msgid="5276598587087626877">"Isikhathi senqubo siphelile"</string>
+    <!-- no translation found for toast_backup_started (550354281452756121) -->
+    <skip />
+    <!-- no translation found for toast_backup_ended (3818080769548726424) -->
+    <skip />
+    <!-- no translation found for toast_restore_started (7881679218971277385) -->
+    <skip />
+    <!-- no translation found for toast_restore_ended (1764041639199696132) -->
+    <skip />
+    <!-- no translation found for toast_timeout (5276598587087626877) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
index 167d362..c6966f9 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_item.xml
@@ -40,8 +40,8 @@
             android:background="@drawable/recents_thumbnail_bg"
             android:foreground="@drawable/recents_thumbnail_fg">
             <ImageView android:id="@+id/app_thumbnail_image"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_width="@dimen/status_bar_recents_thumbnail_width"
+                android:layout_height="@dimen/status_bar_recents_thumbnail_height"
                 android:visibility="invisible"
             />
         </FrameLayout>
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
index de80a51..586712f 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_item.xml
@@ -38,8 +38,8 @@
             android:background="@drawable/recents_thumbnail_bg"
             android:foreground="@drawable/recents_thumbnail_fg">
             <ImageView android:id="@+id/app_thumbnail_image"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_width="@dimen/status_bar_recents_thumbnail_width"
+                android:layout_height="@dimen/status_bar_recents_thumbnail_height"
                 android:visibility="invisible"
             />
         </FrameLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 07088d5..cd8ccd5 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -33,8 +33,8 @@
         android:background="@drawable/recents_thumbnail_bg"
         android:foreground="@drawable/recents_thumbnail_fg">
         <ImageView android:id="@+id/app_thumbnail_image"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="@dimen/status_bar_recents_thumbnail_width"
+            android:layout_height="@dimen/status_bar_recents_thumbnail_height"
             android:visibility="invisible"
         />
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 41a30c7..eb644b3 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -45,6 +45,12 @@
             android:layout_gravity="center|bottom"
             />
     </FrameLayout>
+    <View
+        android:layout_height="6dp"
+        android:layout_width="6dp"
+        android:visibility="gone"
+        android:id="@+id/spacer"
+        />
     <FrameLayout
         android:layout_height="wrap_content"
         android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index b97e4e8..24c0145 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -49,13 +49,13 @@
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="737483394044014246">"Misa izindlela zokufakwayo"</string>
     <string name="status_bar_use_physical_keyboard" msgid="3695516942412442936">"Sebenzisa ikhibhodi ebangekayo"</string>
     <string name="usb_device_permission_prompt" msgid="3816016361969816903">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> lufinyelele idivayisi ye-USB?"</string>
-    <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuze ufinyelele kwizinto eziphuma ne-USB?"</string>
+    <string name="usb_accessory_permission_prompt" msgid="6888598803988889959">"Vumela uhlelo lokusebenza <xliff:g id="APPLICATION">%1$s</xliff:g> ukuze ufinyelele izinto eziphuma ne-USB?"</string>
     <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma ledivayisi ye-USB ixhunyiwe?"</string>
     <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"Vula <xliff:g id="ACTIVITY">%1$s</xliff:g> uma le-accessory ye-USB ixhunyiwe"</string>
     <string name="usb_accessory_uri_prompt" msgid="6332150684964235705">"Azikho izinhlelo zokusebenza zisebenze ngento ze-USB. Funda okwengeziwe ngalento<xliff:g id="URL">%1$s</xliff:g>"</string>
     <string name="title_usb_accessory" msgid="4966265263465181372">"ama-accessory e-USB"</string>
     <string name="label_view" msgid="6304565553218192990">"Buka"</string>
-    <string name="always_use_device" msgid="1450287437017315906">"Sebenzisa ngokuzenzakalelayo yale divayisi ye-USB"</string>
+    <string name="always_use_device" msgid="1450287437017315906">"Sebenzisa ngokuzenzakalelayo yaledivayisi ye-USB"</string>
     <string name="always_use_accessory" msgid="1210954576979621596">"Sebenzisa ngokuzenzakalelayo kule-accessory ye-USB"</string>
     <string name="compat_mode_on" msgid="6623839244840638213">"Sondeza ukugcwalisa isikrini"</string>
     <string name="compat_mode_off" msgid="4434467572461327898">"Nweba ukugcwalisa isikrini"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e780ae6..5ba1908 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -25,7 +25,7 @@
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
     <drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
-    <drawable name="notification_header_bg">#FF000000</drawable>
+    <drawable name="notification_header_bg">#d8000000</drawable>
     <drawable name="notification_tracking_bg">#d8000000</drawable>
     <color name="notification_list_shadow_top">#80000000</color>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index ee97af2..54bc4e3 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -129,7 +129,7 @@
         }
 
         public void setThumbnail(Bitmap thumbnail) {
-            mThumbnail = compositeBitmap(mDefaultThumbnailBackground, thumbnail);
+            mThumbnail = thumbnail;
         }
 
         public Bitmap getThumbnail() {
@@ -480,13 +480,10 @@
             if (resolveInfo != null) {
                 final ActivityInfo info = resolveInfo.activityInfo;
                 final String title = info.loadLabel(pm).toString();
-                // Drawable icon = info.loadIcon(pm);
                 Drawable icon = getFullResIcon(resolveInfo, pm);
                 if (title != null && title.length() > 0 && icon != null) {
                     if (DEBUG) Log.v(TAG, "creating activity desc for id="
                             + recentInfo.id + ", label=" + title);
-                    ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(
-                            recentInfo.persistentId);
                     ActivityDescription item = new ActivityDescription(recentInfo,
                             resolveInfo, intent, index, info.packageName);
                     activityDescriptions.add(item);
@@ -525,7 +522,9 @@
         synchronized (ad) {
             ad.mLabel = label;
             ad.mIcon = icon;
-            ad.setThumbnail(thumbs != null ? thumbs.mainThumbnail : mDefaultThumbnailBackground);
+            if (thumbs != null && thumbs.mainThumbnail != null) {
+                ad.setThumbnail(thumbs.mainThumbnail);
+            }
         }
     }
 
@@ -661,21 +660,6 @@
         }
     }
 
-    private Bitmap compositeBitmap(Bitmap background, Bitmap thumbnail) {
-        Bitmap outBitmap = background.copy(background.getConfig(), true);
-        if (thumbnail != null) {
-            Canvas canvas = new Canvas(outBitmap);
-            Paint paint = new Paint();
-            paint.setAntiAlias(true);
-            paint.setFilterBitmap(true);
-            paint.setAlpha(255);
-            canvas.drawBitmap(thumbnail, null,
-                    new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint);
-            canvas.setBitmap(null);
-        }
-        return outBitmap;
-    }
-
     private void updateUiElements(Configuration config) {
         final int items = mActivityDescriptions.size();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 65b022a..59b09d49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -29,6 +29,7 @@
 
 import com.android.systemui.R;
 
+// Intimately tied to the design of res/layout/signal_cluster_view.xml
 public class SignalClusterView
         extends LinearLayout 
         implements NetworkController.SignalCluster {
@@ -42,9 +43,11 @@
     private int mWifiStrengthId = 0, mWifiActivityId = 0;
     private boolean mMobileVisible = false;
     private int mMobileStrengthId = 0, mMobileActivityId = 0, mMobileTypeId = 0;
+    private boolean mIsAirplaneMode = false;
 
     ViewGroup mWifiGroup, mMobileGroup;
     ImageView mWifi, mMobile, mWifiActivity, mMobileActivity, mMobileType;
+    View mSpacer;
 
     public SignalClusterView(Context context) {
         this(context, null);
@@ -74,6 +77,7 @@
         mMobile         = (ImageView) findViewById(R.id.mobile_signal);
         mMobileActivity = (ImageView) findViewById(R.id.mobile_inout);
         mMobileType     = (ImageView) findViewById(R.id.mobile_type);
+        mSpacer         =             findViewById(R.id.spacer);
 
         apply();
     }
@@ -109,6 +113,10 @@
         apply();
     }
 
+    public void setIsAirplaneMode(boolean is) {
+        mIsAirplaneMode = is;
+    }
+
     // Run after each indicator change.
     private void apply() {
         if (mWifiGroup == null) return;
@@ -135,6 +143,12 @@
             mMobileGroup.setVisibility(View.GONE);
         }
 
+        if (mMobileVisible && mWifiVisible && mIsAirplaneMode) {
+            mSpacer.setVisibility(View.INVISIBLE);
+        } else {
+            mSpacer.setVisibility(View.GONE);
+        }
+
         if (DEBUG) Slog.d(TAG,
                 String.format("mobile: %s sig=%d act=%d typ=%d",
                     (mMobileVisible ? "VISIBLE" : "GONE"),
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 fdb4548..0dfc4f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -142,6 +142,7 @@
         void setWifiIndicators(boolean visible, int strengthIcon, int activityIcon);
         void setMobileDataIndicators(boolean visible, int strengthIcon, int activityIcon,
                 int typeIcon);
+        void setIsAirplaneMode(boolean is);
     }
 
     /**
@@ -876,6 +877,7 @@
                         mPhoneSignalIconId,
                         mMobileActivityIconId,
                         mDataTypeIconId);
+                cluster.setIsAirplaneMode(mAirplaneMode);
             }
         }
 
diff --git a/packages/VpnDialogs/res/values-am/strings.xml b/packages/VpnDialogs/res/values-am/strings.xml
index 7f61e76..45eaa02 100644
--- a/packages/VpnDialogs/res/values-am/strings.xml
+++ b/packages/VpnDialogs/res/values-am/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"አለያይ"</string>
     <string name="session" msgid="6470628549473641030">"ክፍለ ጊዜ፡"</string>
     <string name="duration" msgid="3584782459928719435">"ጊዜ"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"ለ፡ ተልኳል"</string>
-    <string name="data_received" msgid="4062776929376067820">"ተቀብሏል፡"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"ውሂብ ተላልፏል፡"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"ውሂብ ተቀብሏል"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ባይትስ / <xliff:g id="NUMBER_1">%2$s</xliff:g> ፓኬቶች"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ar/strings.xml b/packages/VpnDialogs/res/values-ar/strings.xml
index cae60a8..17b9937 100644
--- a/packages/VpnDialogs/res/values-ar/strings.xml
+++ b/packages/VpnDialogs/res/values-ar/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"قطع الاتصال"</string>
     <string name="session" msgid="6470628549473641030">"الجلسة"</string>
     <string name="duration" msgid="3584782459928719435">"المدة:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"تم الإرسال:"</string>
-    <string name="data_received" msgid="4062776929376067820">"مستلم:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"البيانات المنقولة:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"البيانات المستلمة:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> بايت / <xliff:g id="NUMBER_1">%2$s</xliff:g> من الحزم"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-bg/strings.xml b/packages/VpnDialogs/res/values-bg/strings.xml
index 5d186a3..fc8fbeb 100644
--- a/packages/VpnDialogs/res/values-bg/strings.xml
+++ b/packages/VpnDialogs/res/values-bg/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Изключване"</string>
     <string name="session" msgid="6470628549473641030">"Сесия:"</string>
     <string name="duration" msgid="3584782459928719435">"Продължителност:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Изпратено:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Предадени данни:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Получени данни:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> байта/ <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index ee737a1..00fbe2d 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Odpojit"</string>
     <string name="session" msgid="6470628549473641030">"Relace:"</string>
     <string name="duration" msgid="3584782459928719435">"Doba trvání:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Odesláno:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Přijato:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Odeslaná data:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Přijatá data:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bajtů / <xliff:g id="NUMBER_1">%2$s</xliff:g> paketů"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-da/strings.xml b/packages/VpnDialogs/res/values-da/strings.xml
index 2a48a90..436c570 100644
--- a/packages/VpnDialogs/res/values-da/strings.xml
+++ b/packages/VpnDialogs/res/values-da/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Fjern tilknytning"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Varighed:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Modtaget:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Data sendt:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Data modtaget:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml
index ff5f3f2..51690da2 100644
--- a/packages/VpnDialogs/res/values-de/strings.xml
+++ b/packages/VpnDialogs/res/values-de/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Verbindung trennen"</string>
     <string name="session" msgid="6470628549473641030">"Sitzung:"</string>
     <string name="duration" msgid="3584782459928719435">"Dauer:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Gesendet:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Erhalten:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Übertragene Daten:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Empfangene Daten:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> Pakete"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-el/strings.xml b/packages/VpnDialogs/res/values-el/strings.xml
index 04a2bb3..58abede 100644
--- a/packages/VpnDialogs/res/values-el/strings.xml
+++ b/packages/VpnDialogs/res/values-el/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Αποσύνδεση"</string>
     <string name="session" msgid="6470628549473641030">"Περίοδος σύνδεσης"</string>
     <string name="duration" msgid="3584782459928719435">"Διάρκεια:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Στάλθηκε:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Έγινε λήψη:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Στοιχεία που μεταδόθηκαν:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Δεδομένα που λήφθηκαν:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> πακέτα"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es-rUS/strings.xml b/packages/VpnDialogs/res/values-es-rUS/strings.xml
index 58e72d1..7c563ae 100644
--- a/packages/VpnDialogs/res/values-es-rUS/strings.xml
+++ b/packages/VpnDialogs/res/values-es-rUS/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sesión:"</string>
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Enviados:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Recibidos:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Datos transmitidos:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Datos recibidos:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-es/strings.xml b/packages/VpnDialogs/res/values-es/strings.xml
index 79ad80c..e957542 100644
--- a/packages/VpnDialogs/res/values-es/strings.xml
+++ b/packages/VpnDialogs/res/values-es/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sesión:"</string>
     <string name="duration" msgid="3584782459928719435">"Duración:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Recibido:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Datos transmitidos:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Datos recibidos:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquetes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fi/strings.xml b/packages/VpnDialogs/res/values-fi/strings.xml
index c8d830c..e2f30ef 100644
--- a/packages/VpnDialogs/res/values-fi/strings.xml
+++ b/packages/VpnDialogs/res/values-fi/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Katkaise yhteys"</string>
     <string name="session" msgid="6470628549473641030">"Käyttökerta"</string>
     <string name="duration" msgid="3584782459928719435">"Kesto:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Lähetetty:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Vastaanotettu:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Siirretyt tiedot:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Vastaanotetut tiedot:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> tavua / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakettia"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-fr/strings.xml b/packages/VpnDialogs/res/values-fr/strings.xml
index e38c1a2..16b8c8f 100644
--- a/packages/VpnDialogs/res/values-fr/strings.xml
+++ b/packages/VpnDialogs/res/values-fr/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Déconnecter"</string>
     <string name="session" msgid="6470628549473641030">"Session :"</string>
     <string name="duration" msgid="3584782459928719435">"Durée :"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Envoyé :"</string>
-    <string name="data_received" msgid="4062776929376067820">"Reçu :"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Données transmises :"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Données reçues :"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> octets / <xliff:g id="NUMBER_1">%2$s</xliff:g> paquets"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hr/strings.xml b/packages/VpnDialogs/res/values-hr/strings.xml
index cdbffbc..9eabfff 100644
--- a/packages/VpnDialogs/res/values-hr/strings.xml
+++ b/packages/VpnDialogs/res/values-hr/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Prekini vezu"</string>
     <string name="session" msgid="6470628549473641030">"Sesija"</string>
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Preneseno podataka:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Primljeni podaci:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajtova: <xliff:g id="NUMBER_0">%1$s</xliff:g>/paketa: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-hu/strings.xml b/packages/VpnDialogs/res/values-hu/strings.xml
index a268402..5872046 100644
--- a/packages/VpnDialogs/res/values-hu/strings.xml
+++ b/packages/VpnDialogs/res/values-hu/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Kapcsolat bontása"</string>
     <string name="session" msgid="6470628549473641030">"Munkamenet:"</string>
     <string name="duration" msgid="3584782459928719435">"Időtartam:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Elküldve:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Érkezett:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Továbbított adatok:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Fogadott adatok:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bájt/<xliff:g id="NUMBER_1">%2$s</xliff:g> adatcsomag"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-in/strings.xml b/packages/VpnDialogs/res/values-in/strings.xml
index 1721d68..9a985e6 100644
--- a/packages/VpnDialogs/res/values-in/strings.xml
+++ b/packages/VpnDialogs/res/values-in/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Putuskan sambungan"</string>
     <string name="session" msgid="6470628549473641030">"Sesi:"</string>
     <string name="duration" msgid="3584782459928719435">"Durasi:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Terkirim:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Diterima:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Data yang Dikirimkan:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Data Diterima:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index 4b8d125..093015a 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"נתק"</string>
     <string name="session" msgid="6470628549473641030">"הפעלה"</string>
     <string name="duration" msgid="3584782459928719435">"משך:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"נשלח:"</string>
-    <string name="data_received" msgid="4062776929376067820">"התקבל:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"הנתונים המועברים:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"הנתונים שהתקבלו:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> בתים / <xliff:g id="NUMBER_1">%2$s</xliff:g> מנות"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ko/strings.xml b/packages/VpnDialogs/res/values-ko/strings.xml
index cfc4ffc..6c99f7b 100644
--- a/packages/VpnDialogs/res/values-ko/strings.xml
+++ b/packages/VpnDialogs/res/values-ko/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"연결 끊기"</string>
     <string name="session" msgid="6470628549473641030">"세션:"</string>
     <string name="duration" msgid="3584782459928719435">"기간:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"보냄:"</string>
-    <string name="data_received" msgid="4062776929376067820">"수신됨:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"전송된 데이터:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"수신된 데이터:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g>바이트/<xliff:g id="NUMBER_1">%2$s</xliff:g>패킷"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lt/strings.xml b/packages/VpnDialogs/res/values-lt/strings.xml
index 5fa0faf..ae8573b 100644
--- a/packages/VpnDialogs/res/values-lt/strings.xml
+++ b/packages/VpnDialogs/res/values-lt/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Atsijungti"</string>
     <string name="session" msgid="6470628549473641030">"Sesija"</string>
     <string name="duration" msgid="3584782459928719435">"Trukmė:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Išsiųsta:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Gauta:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Duomenys perduodami:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Gauti duomenys:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Baitų: <xliff:g id="NUMBER_0">%1$s</xliff:g> baitų / paketų: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-lv/strings.xml b/packages/VpnDialogs/res/values-lv/strings.xml
index 2e1a9f7c..88ff8bb 100644
--- a/packages/VpnDialogs/res/values-lv/strings.xml
+++ b/packages/VpnDialogs/res/values-lv/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Pārtraukt savienojumu"</string>
     <string name="session" msgid="6470628549473641030">"Sesija:"</string>
     <string name="duration" msgid="3584782459928719435">"Ilgums:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Nosūtīts:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Saņemts:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Nosūtītie dati:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Saņemtie dati:"</string>
     <string name="blank_value" msgid="6278484582661984635">"—"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> baiti/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nb/strings.xml b/packages/VpnDialogs/res/values-nb/strings.xml
index fbd9185..f469cce 100644
--- a/packages/VpnDialogs/res/values-nb/strings.xml
+++ b/packages/VpnDialogs/res/values-nb/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Koble fra"</string>
     <string name="session" msgid="6470628549473641030">"Økt:"</string>
     <string name="duration" msgid="3584782459928719435">"Varighet:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Sendt:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Mottatt:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Data overført:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Data mottatt:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> pakker"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-nl/strings.xml b/packages/VpnDialogs/res/values-nl/strings.xml
index 7f6e0b1..807704c 100644
--- a/packages/VpnDialogs/res/values-nl/strings.xml
+++ b/packages/VpnDialogs/res/values-nl/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Verbinding verbreken"</string>
     <string name="session" msgid="6470628549473641030">"Sessie:"</string>
     <string name="duration" msgid="3584782459928719435">"Duur:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Verzonden:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Ontvangen:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Verzonden gegevens:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Ontvangen gegevens:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pakketten"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pl/strings.xml b/packages/VpnDialogs/res/values-pl/strings.xml
index 80c5a7c..207c82d 100644
--- a/packages/VpnDialogs/res/values-pl/strings.xml
+++ b/packages/VpnDialogs/res/values-pl/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Rozłącz"</string>
     <string name="session" msgid="6470628549473641030">"Sesja:"</string>
     <string name="duration" msgid="3584782459928719435">"Czas trwania:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Wysłano:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Odebrano:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Dane przesłane:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Dane odebrane:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Bajty: <xliff:g id="NUMBER_0">%1$s</xliff:g> / pakiety: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt-rPT/strings.xml b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
index c57525d..960a100 100644
--- a/packages/VpnDialogs/res/values-pt-rPT/strings.xml
+++ b/packages/VpnDialogs/res/values-pt-rPT/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Desligar"</string>
     <string name="session" msgid="6470628549473641030">"Sessão"</string>
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Dados Transmitidos:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Dados Recebidos:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes / <xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-pt/strings.xml b/packages/VpnDialogs/res/values-pt/strings.xml
index 8a16e87..92bd1a2 100644
--- a/packages/VpnDialogs/res/values-pt/strings.xml
+++ b/packages/VpnDialogs/res/values-pt/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Desconectar"</string>
     <string name="session" msgid="6470628549473641030">"Sessão:"</string>
     <string name="duration" msgid="3584782459928719435">"Duração:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Enviado:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Recebido:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Dados transmitidos:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Dados recebidos:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bytes/<xliff:g id="NUMBER_1">%2$s</xliff:g> pacotes"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ro/strings.xml b/packages/VpnDialogs/res/values-ro/strings.xml
index 2791f73..fa79ae1 100644
--- a/packages/VpnDialogs/res/values-ro/strings.xml
+++ b/packages/VpnDialogs/res/values-ro/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Deconectaţi"</string>
     <string name="session" msgid="6470628549473641030">"Sesiune:"</string>
     <string name="duration" msgid="3584782459928719435">"Durată:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Trimis:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Primit:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Date transmise:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Date primite:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> (de) octeţi/<xliff:g id="NUMBER_1">%2$s</xliff:g> (de) pachete"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-ru/strings.xml b/packages/VpnDialogs/res/values-ru/strings.xml
index 411c51a..a3888fc 100644
--- a/packages/VpnDialogs/res/values-ru/strings.xml
+++ b/packages/VpnDialogs/res/values-ru/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Разъединить"</string>
     <string name="session" msgid="6470628549473641030">"Сеанс:"</string>
     <string name="duration" msgid="3584782459928719435">"Продолжительность:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Отправлено:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Отправлено:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Получено:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> Б; пакетов: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sk/strings.xml b/packages/VpnDialogs/res/values-sk/strings.xml
index 733efd4..77090aa 100644
--- a/packages/VpnDialogs/res/values-sk/strings.xml
+++ b/packages/VpnDialogs/res/values-sk/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Odpojiť"</string>
     <string name="session" msgid="6470628549473641030">"Relácia"</string>
     <string name="duration" msgid="3584782459928719435">"Trvanie:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Odoslané:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Prijaté:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Prenášané údaje:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Prijaté dáta:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> B/<xliff:g id="NUMBER_1">%2$s</xliff:g> paketov"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sl/strings.xml b/packages/VpnDialogs/res/values-sl/strings.xml
index 92806fc..1dda8b2f 100644
--- a/packages/VpnDialogs/res/values-sl/strings.xml
+++ b/packages/VpnDialogs/res/values-sl/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Prekini povezavo"</string>
     <string name="session" msgid="6470628549473641030">"Seja:"</string>
     <string name="duration" msgid="3584782459928719435">"Trajanje:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Prejeto:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Preneseni podatki:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Prejeti podatki:"</string>
     <string name="blank_value" msgid="6278484582661984635">"-"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Št. bajtov: <xliff:g id="NUMBER_0">%1$s</xliff:g>/št. paketov: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sr/strings.xml b/packages/VpnDialogs/res/values-sr/strings.xml
index 425ee89..3274e5e 100644
--- a/packages/VpnDialogs/res/values-sr/strings.xml
+++ b/packages/VpnDialogs/res/values-sr/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Прекини везу"</string>
     <string name="session" msgid="6470628549473641030">"Сесија:"</string>
     <string name="duration" msgid="3584782459928719435">"Трајање:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Послато:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Примљенo:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Пренесени подаци:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Примљени подаци:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> бајт(ов)а / <xliff:g id="NUMBER_1">%2$s</xliff:g> пакета"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-sv/strings.xml b/packages/VpnDialogs/res/values-sv/strings.xml
index 7cec26c..3c9ef6a 100644
--- a/packages/VpnDialogs/res/values-sv/strings.xml
+++ b/packages/VpnDialogs/res/values-sv/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Koppla från"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Längd:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Skickat:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Mottaget:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Data som överförs:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Mottagna data:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte/<xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-th/strings.xml b/packages/VpnDialogs/res/values-th/strings.xml
index 9865382..17360c8 100644
--- a/packages/VpnDialogs/res/values-th/strings.xml
+++ b/packages/VpnDialogs/res/values-th/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"ยกเลิกการเชื่อมต่อ"</string>
     <string name="session" msgid="6470628549473641030">"เซสชัน"</string>
     <string name="duration" msgid="3584782459928719435">"ระยะเวลา:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"ส่งแล้ว:"</string>
-    <string name="data_received" msgid="4062776929376067820">"ได้รับ:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"ข้อมูลที่ส่ง:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"ข้อมูลที่ได้รับ:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> ไบต์/<xliff:g id="NUMBER_1">%2$s</xliff:g> แพ็คเก็ต"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-tl/strings.xml b/packages/VpnDialogs/res/values-tl/strings.xml
index 4826d8f..7a6b3c0 100644
--- a/packages/VpnDialogs/res/values-tl/strings.xml
+++ b/packages/VpnDialogs/res/values-tl/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Idiskonekta"</string>
     <string name="session" msgid="6470628549473641030">"Session:"</string>
     <string name="duration" msgid="3584782459928719435">"Tagal:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Ipinadala:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Natanggap:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Naipadalang Data:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Natanggap na Data:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> (na) byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> (na) packet"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-uk/strings.xml b/packages/VpnDialogs/res/values-uk/strings.xml
index a12bfea..bdb2435 100644
--- a/packages/VpnDialogs/res/values-uk/strings.xml
+++ b/packages/VpnDialogs/res/values-uk/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Від’єднати"</string>
     <string name="session" msgid="6470628549473641030">"Сеанс:"</string>
     <string name="duration" msgid="3584782459928719435">"Тривалість:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Надіслано:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Отримано:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Передані дані:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Отримані дані:"</string>
     <string name="blank_value" msgid="6278484582661984635">"–"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Байтів: <xliff:g id="NUMBER_0">%1$s</xliff:g> / пакетів: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-vi/strings.xml b/packages/VpnDialogs/res/values-vi/strings.xml
index 985c706..7e10a73 100644
--- a/packages/VpnDialogs/res/values-vi/strings.xml
+++ b/packages/VpnDialogs/res/values-vi/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Ngắt kết nối"</string>
     <string name="session" msgid="6470628549473641030">"Phiên"</string>
     <string name="duration" msgid="3584782459928719435">"Thời lượng:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Đã gửi:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Đã nhận:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Đã truyền dữ liệu:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Đã nhận dữ liệu:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> byte / <xliff:g id="NUMBER_1">%2$s</xliff:g> gói"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rCN/strings.xml b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
index 24774eb..f9294e3 100644
--- a/packages/VpnDialogs/res/values-zh-rCN/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rCN/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"断开连接"</string>
     <string name="session" msgid="6470628549473641030">"会话:"</string>
     <string name="duration" msgid="3584782459928719435">"时长:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"已发送:"</string>
-    <string name="data_received" msgid="4062776929376067820">"已接收:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"传输的数据:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"收到的数据:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 字节/<xliff:g id="NUMBER_1">%2$s</xliff:g> 个数据包"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zh-rTW/strings.xml b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
index 79e6887..5a39ca5 100644
--- a/packages/VpnDialogs/res/values-zh-rTW/strings.xml
+++ b/packages/VpnDialogs/res/values-zh-rTW/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"中斷連線"</string>
     <string name="session" msgid="6470628549473641030">"工作階段:"</string>
     <string name="duration" msgid="3584782459928719435">"持續時間:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"已傳送的資料:"</string>
-    <string name="data_received" msgid="4062776929376067820">"已接收的資料:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"已傳輸的數據:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"已接收的數據:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> 位元組 / <xliff:g id="NUMBER_1">%2$s</xliff:g> 個封包"</string>
 </resources>
diff --git a/packages/VpnDialogs/res/values-zu/strings.xml b/packages/VpnDialogs/res/values-zu/strings.xml
index 67eeeb9..492d3ff 100644
--- a/packages/VpnDialogs/res/values-zu/strings.xml
+++ b/packages/VpnDialogs/res/values-zu/strings.xml
@@ -24,8 +24,8 @@
     <string name="disconnect" msgid="971412338304200056">"Ayixhumekile kwi-inthanethi"</string>
     <string name="session" msgid="6470628549473641030">"Iseshini:"</string>
     <string name="duration" msgid="3584782459928719435">"Ubude besikhathi:"</string>
-    <string name="data_transmitted" msgid="7988167672982199061">"Thunyelwe:"</string>
-    <string name="data_received" msgid="4062776929376067820">"Okwamukelwe:"</string>
+    <!-- outdated translation 8239988320199846094 -->     <string name="data_transmitted" msgid="7988167672982199061">"Idatha Ithunyelwe:"</string>
+    <!-- outdated translation 7431729884377019935 -->     <string name="data_received" msgid="4062776929376067820">"Idatha Etholiwe:"</string>
     <string name="blank_value" msgid="6278484582661984635">"--"</string>
     <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> amaphakethe/ <xliff:g id="NUMBER_1">%2$s</xliff:g> amabhayithi"</string>
 </resources>
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index cbf1c90..91f1527 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -24,6 +24,7 @@
 import android.content.res.Resources;
 import android.graphics.PixelFormat;
 import android.graphics.Canvas;
+import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.Log;
 import android.view.View;
@@ -59,6 +60,10 @@
 
     private boolean mScreenOn = false;
 
+    public interface ShowListener {
+        void onShown(IBinder windowToken);
+    };
+
     /**
      * @param context Used to create views.
      * @param viewManager Keyguard will be attached to this.
@@ -206,7 +211,8 @@
         }
     }
 
-    public synchronized void onScreenTurnedOn() {
+    public synchronized void onScreenTurnedOn(
+            final KeyguardViewManager.ShowListener showListener) {
         if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
         mScreenOn = true;
         if (mKeyguardView != null) {
@@ -214,6 +220,26 @@
 
             // When screen is turned on, need to bind to FaceLock service if we are using FaceLock
             mKeyguardView.bindToFaceLock();
+
+            // Caller should wait for this window to be shown before turning
+            // on the screen.
+            if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+                // Keyguard may be in the process of being shown, but not yet
+                // updated with the window manager...  give it a chance to do so.
+                mKeyguardHost.post(new Runnable() {
+                    @Override public void run() {
+                        if (mKeyguardHost.getVisibility() == View.VISIBLE) {
+                            showListener.onShown(mKeyguardHost.getWindowToken());
+                        } else {
+                            showListener.onShown(null);
+                        }
+                    }
+                });
+            } else {
+                showListener.onShown(null);
+            }
+        } else {
+            showListener.onShown(null);
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 64a9677..0f1d633 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -116,7 +116,6 @@
     private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
     private static final int SET_HIDDEN = 12;
     private static final int KEYGUARD_TIMEOUT = 13;
-    private static final int REPORT_SHOW_DONE = 14;
 
     /**
      * The default amount of time we stay awake (used for all key input)
@@ -239,8 +238,6 @@
 
     private boolean mScreenOn = false;
 
-    private boolean mShowPending = false;
-
     // last known state of the cellular connection
     private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE;
 
@@ -383,19 +380,7 @@
             } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {
                 // Do not enable the keyguard if the prox sensor forced the screen off.
             } else {
-                if (!doKeyguardLocked() && why == WindowManagerPolicy.OFF_BECAUSE_OF_USER) {
-                    // The user has explicitly turned off the screen, causing it
-                    // to lock.  We want to block here until the keyguard window
-                    // has shown, so the power manager won't complete the screen
-                    // off flow until that point, so we know it won't turn *on*
-                    // the screen until this is done.
-                    while (mShowPending) {
-                        try {
-                            wait();
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                }
+                doKeyguardLocked();
             }
         }
     }
@@ -403,12 +388,12 @@
     /**
      * Let's us know the screen was turned on.
      */
-    public void onScreenTurnedOn() {
+    public void onScreenTurnedOn(KeyguardViewManager.ShowListener showListener) {
         synchronized (this) {
             mScreenOn = true;
             mDelayedShowingSequence++;
             if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
-            notifyScreenOnLocked();
+            notifyScreenOnLocked(showListener);
         }
     }
 
@@ -573,7 +558,7 @@
      * work that will happen is done; returns false if the caller can wait for
      * the keyguard to be shown.
      */
-    private boolean doKeyguardLocked() {
+    private void doKeyguardLocked() {
         // if another app is disabling us, don't show
         if (!mExternallyEnabled) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
@@ -587,13 +572,13 @@
             // ends (see the broadcast receiver below)
             // TODO: clean this up when we have better support at the window manager level
             // for apps that wish to be on top of the keyguard
-            return true;
+            return;
         }
 
         // if the keyguard is already showing, don't bother
         if (mKeyguardViewManager.isShowing()) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
-            return true;
+            return;
         }
 
         // if the setup wizard hasn't run yet, don't show
@@ -609,18 +594,16 @@
         if (!lockedOrMissing && !provisioned) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
                     + " and the sim is not locked or missing");
-            return true;
+            return;
         }
 
         if (mLockPatternUtils.isLockScreenDisabled()) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
-            return true;
+            return;
         }
 
         if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
-        mShowPending = true;
         showLocked();
-        return false;
     }
 
     /**
@@ -658,9 +641,10 @@
      * @see #onScreenTurnedOn()
      * @see #handleNotifyScreenOn
      */
-    private void notifyScreenOnLocked() {
+    private void notifyScreenOnLocked(KeyguardViewManager.ShowListener showListener) {
         if (DEBUG) Log.d(TAG, "notifyScreenOnLocked");
-        mHandler.sendEmptyMessage(NOTIFY_SCREEN_ON);
+        Message msg = mHandler.obtainMessage(NOTIFY_SCREEN_ON, showListener);
+        mHandler.sendMessage(msg);
     }
 
     /**
@@ -974,7 +958,7 @@
                     handleNotifyScreenOff();
                     return;
                 case NOTIFY_SCREEN_ON:
-                    handleNotifyScreenOn();
+                    handleNotifyScreenOn((KeyguardViewManager.ShowListener)msg.obj);
                     return;
                 case WAKE_WHEN_READY:
                     handleWakeWhenReady(msg.arg1);
@@ -996,12 +980,6 @@
                         doKeyguardLocked();
                     }
                     break;
-                case REPORT_SHOW_DONE:
-                    synchronized (KeyguardViewMediator.this) {
-                        mShowPending = false;
-                        KeyguardViewMediator.this.notifyAll();
-                    }
-                    break;
             }
         }
     };
@@ -1076,6 +1054,7 @@
                     final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
                     if (sfx != null) {
                         sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+                        sfx.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
                         sfx.play();
                     } else {
                         if (DEBUG) Log.d(TAG, "playSounds: failed to load ringtone from uri: "
@@ -1113,12 +1092,6 @@
             playSounds(true);
 
             mShowKeyguardWakeLock.release();
-
-            // We won't say the show is done yet because the view hierarchy
-            // still needs to do the traversal.  Posting this message allows
-            // us to hold off until that is done.
-            Message msg = mHandler.obtainMessage(REPORT_SHOW_DONE);
-            mHandler.sendMessage(msg);
         }
     }
 
@@ -1284,10 +1257,10 @@
      * Handle message sent by {@link #notifyScreenOnLocked()}
      * @see #NOTIFY_SCREEN_ON
      */
-    private void handleNotifyScreenOn() {
+    private void handleNotifyScreenOn(KeyguardViewManager.ShowListener showListener) {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleNotifyScreenOn");
-            mKeyguardViewManager.onScreenTurnedOn();
+            mKeyguardViewManager.onScreenTurnedOn(showListener);
         }
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index e2a1149..d9bd5f2b 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -46,6 +46,8 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -74,7 +76,7 @@
  * {@link com.android.internal.policy.impl.KeyguardViewManager}
  * via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate.
  */
-public class LockPatternKeyguardView extends KeyguardViewBase {
+public class LockPatternKeyguardView extends KeyguardViewBase implements Handler.Callback {
 
     private static final int TRANSPORT_USERACTIVITY_TIMEOUT = 10000;
 
@@ -103,9 +105,15 @@
     // The following were added to support FaceLock
     private IFaceLockInterface mFaceLockService;
     private boolean mBoundToFaceLockService = false;
-    private boolean mFaceLockServiceRunning = false;
     private View mFaceLockAreaView;
 
+    private boolean mFaceLockServiceRunning = false;
+    private final Object mFaceLockServiceRunningLock = new Object();
+
+    private Handler mHandler;
+    private final int MSG_SHOW_FACELOCK_AREA_VIEW = 0;
+    private final int MSG_HIDE_FACELOCK_AREA_VIEW = 1;
+
     /**
      * The current {@link KeyguardScreen} will use this to communicate back to us.
      */
@@ -244,6 +252,7 @@
             KeyguardWindowController controller) {
         super(context);
 
+        mHandler = new Handler(this);
         mConfiguration = context.getResources().getConfiguration();
         mEnableFallback = false;
         mRequiresSim = TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim"));
@@ -594,10 +603,6 @@
     }
 
     private boolean isSecure() {
-        // TODO: make this work with SIM and Account cases below.
-        boolean usingBiometric = mLockPatternUtils.usingBiometricWeak();
-        if (usingBiometric && mLockPatternUtils.isBiometricEnabled())
-            return true;
         UnlockMode unlockMode = getUnlockMode();
         boolean secure = false;
         switch (unlockMode) {
@@ -705,12 +710,6 @@
                     mKeyguardScreenCallback,
                     mUpdateMonitor.getFailedAttempts());
             view.setEnableFallback(mEnableFallback);
-
-            // TODO(bcolonna): For pattern unlock, it can give us the view where the pattern is
-            // displayed and FaceLock can draw in that area.
-            // For other views it's not so simple and we should probably change how the FaceLock
-            // area is determined.
-            mFaceLockAreaView = view.getUnlockAreaView();
             unlockView = view;
         } else if (unlockMode == UnlockMode.SimPuk) {
             unlockView = new SimPukUnlockScreen(
@@ -760,6 +759,8 @@
             throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
         }
         initializeTransportControlView(unlockView);
+        initializeFaceLockAreaView(unlockView); // Only shows view if FaceLock is enabled
+
         mUnlockScreenMode = unlockMode;
         return unlockView;
     }
@@ -939,6 +940,41 @@
 
     // Everything below pertains to FaceLock - might want to separate this out
 
+    // Only pattern and pin unlock screens actually have a view for the FaceLock area, so it's not
+    // uncommon for it to not exist.  But if it does exist, we need to make sure it's showing if
+    // FaceLock is enabled, and make sure it's not showing if FaceLock is disabled
+    private void initializeFaceLockAreaView(View view) {
+        mFaceLockAreaView = view.findViewById(R.id.faceLockAreaView);
+        if (mFaceLockAreaView == null) {
+            if (DEBUG) Log.d(TAG, "Layout does not have faceLockAreaView");
+        } else {
+            if (mLockPatternUtils.usingBiometricWeak()) {
+                mHandler.sendEmptyMessage(MSG_SHOW_FACELOCK_AREA_VIEW);
+            } else {
+                mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
+            }
+        }
+    }
+
+    // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
+    // This needs to be done in a handler because the call could be coming from a callback from the
+    // FaceLock service that is in a thread that can't modify the UI
+    @Override
+    public boolean handleMessage(Message msg) {
+        switch (msg.what) {
+        case MSG_SHOW_FACELOCK_AREA_VIEW:
+            mFaceLockAreaView.setVisibility(View.VISIBLE);
+            break;
+        case MSG_HIDE_FACELOCK_AREA_VIEW:
+            mFaceLockAreaView.setVisibility(View.GONE);
+            break;
+        default:
+            Log.w(TAG, "Unhandled message");
+            return false;
+        }
+        return true;
+    }
+
     // Binds to FaceLock service, but does not tell it to start
     public void bindToFaceLock() {
         if (mLockPatternUtils.usingBiometricWeak()) {
@@ -987,23 +1023,20 @@
                 throw new RuntimeException("Remote exception");
             }
 
-            // TODO(bcolonna): Need to set location properly (only works for pattern view now)
             if (mFaceLockAreaView != null) {
-                int[] unlockLocationOnScreen = new int[2];
-                mFaceLockAreaView.getLocationOnScreen(unlockLocationOnScreen);
-                int x = unlockLocationOnScreen[0];
-                int y = unlockLocationOnScreen[1];
-                int w = mFaceLockAreaView.getWidth();
-                int h = mFaceLockAreaView.getHeight();
-                if (DEBUG) Log.d(TAG, "(x,y) (wxh): (" + x + "," + y + ") (" + w + "x" + h + ")");
-                startFaceLock(mFaceLockAreaView.getWindowToken(), x, y, w, h);
+                startFaceLock(mFaceLockAreaView.getWindowToken(),
+                        mFaceLockAreaView.getLeft(), mFaceLockAreaView.getTop(),
+                        mFaceLockAreaView.getWidth(), mFaceLockAreaView.getHeight());
             }
         }
 
         // Cleans up if FaceLock service unexpectedly disconnects
         @Override
         public void onServiceDisconnected(ComponentName className) {
-            mFaceLockService = null;
+            synchronized(mFaceLockServiceRunningLock) {
+                mFaceLockService = null;
+                mFaceLockServiceRunning = false;
+            }
             if (DEBUG) Log.w(TAG, "Unexpected disconnect from FaceLock service");
         }
     };
@@ -1012,16 +1045,18 @@
     public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
     {
         if (mLockPatternUtils.usingBiometricWeak()) {
-            if (!mFaceLockServiceRunning) {
-                if (DEBUG) Log.d(TAG, "Starting FaceLock");
-                try {
-                    mFaceLockService.startUi(windowToken, x, y, h, w);
-                } catch (RemoteException e) {
-                    throw new RuntimeException("Remote exception");
+            synchronized (mFaceLockServiceRunningLock) {
+                if (!mFaceLockServiceRunning) {
+                    if (DEBUG) Log.d(TAG, "Starting FaceLock");
+                    try {
+                        mFaceLockService.startUi(windowToken, x, y, h, w);
+                    } catch (RemoteException e) {
+                        throw new RuntimeException("Remote exception");
+                    }
+                    mFaceLockServiceRunning = true;
+                } else {
+                    if (DEBUG) Log.w(TAG, "startFaceLock() attempted while running");
                 }
-                mFaceLockServiceRunning = true;
-            } else {
-                if (DEBUG) Log.w(TAG, "startFaceLock() attempted while running");
             }
         }
     }
@@ -1033,14 +1068,16 @@
             // Note that attempting to stop FaceLock when it's not running is not an issue.
             // FaceLock can return, which stops it and then we try to stop it when the
             // screen is turned off.  That's why we check.
-            if (mFaceLockServiceRunning) {
-                try {
-                    if (DEBUG) Log.d(TAG, "Stopping FaceLock");
-                    mFaceLockService.stopUi();
-                } catch (RemoteException e) {
-                    throw new RuntimeException("Remote exception");
+            synchronized (mFaceLockServiceRunningLock) {
+                if (mFaceLockServiceRunning) {
+                    try {
+                        if (DEBUG) Log.d(TAG, "Stopping FaceLock");
+                        mFaceLockService.stopUi();
+                    } catch (RemoteException e) {
+                        throw new RuntimeException("Remote exception");
+                    }
+                    mFaceLockServiceRunning = false;
                 }
-                mFaceLockServiceRunning = false;
             }
         }
     }
@@ -1052,6 +1089,9 @@
         @Override
         public void unlock() {
             if (DEBUG) Log.d(TAG, "FaceLock unlock");
+            // Note that we don't hide the client FaceLockAreaView because we want to keep the
+            // lock screen covered while the phone is unlocked
+
             stopFaceLock();
             mKeyguardScreenCallback.keyguardDone(true);
             mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
@@ -1062,6 +1102,8 @@
         public void cancel() {
             // In this case, either the user has cancelled out, or FaceLock failed to recognize them
             if (DEBUG) Log.d(TAG, "FaceLock cancel");
+            // Here we hide the client FaceLockViewArea to expose the underlying backup method
+            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
             stopFaceLock();
         }
 
@@ -1070,8 +1112,12 @@
         public void sleepDevice() {
             // In this case, it appears the phone has been turned on accidentally
             if (DEBUG) Log.d(TAG, "FaceLock accidental turn on");
+            // Here we hide the client FaceLockViewArea to expose the underlying backup method
+            mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
             stopFaceLock();
             // TODO(bcolonna): how do we put the phone back to sleep (i.e., turn off the screen)
+            // TODO(bcolonna): this should be removed once the service is no longer calling it
+            // because we are just going to let the lockscreen timeout
         }
     };
 }
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 0cafeb5a..88c42a6 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -199,12 +199,6 @@
         setFocusableInTouchMode(true);
     }
 
-    // TODO(bcolonna): This is to tell FaceLock where to draw...but this covers up the wireless
-    // service text, so we will want to change the way the area is specified
-    public View getUnlockAreaView() {
-        return mLockPatternView;
-    }
-
     public void setEnableFallback(boolean state) {
         if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")");
         mEnableFallback = state;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 903b405..bca95d3 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2135,7 +2135,9 @@
                                 com.android.internal.R.attr.actionModePopupWindowStyle);
                         mActionModePopup.setLayoutInScreenEnabled(true);
                         mActionModePopup.setLayoutInsetDecor(true);
-                        mActionModePopup.setClippingEnabled(false);
+                        mActionModePopup.setFocusable(true);
+                        mActionModePopup.setWindowLayoutType(
+                                WindowManager.LayoutParams.TYPE_APPLICATION);
                         mActionModePopup.setContentView(mActionModeView);
                         mActionModePopup.setWidth(MATCH_PARENT);
 
@@ -2144,10 +2146,12 @@
                                 com.android.internal.R.attr.actionBarSize, heightValue, true);
                         final int height = TypedValue.complexToDimensionPixelSize(heightValue.data,
                                 mContext.getResources().getDisplayMetrics());
-                        mActionModePopup.setHeight(height);
+                        mActionModeView.setContentHeight(height);
+                        mActionModePopup.setHeight(WRAP_CONTENT);
                         mShowActionModePopup = new Runnable() {
                             public void run() {
-                                mActionModePopup.showAtLocation(PhoneWindow.DecorView.this,
+                                mActionModePopup.showAtLocation(
+                                        mActionModeView.getApplicationWindowToken(),
                                         Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
                             }
                         };
@@ -3467,6 +3471,8 @@
         }
 
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
+            if (subMenu == null) return false;
+
             // Set a simple callback for the submenu
             subMenu.setCallback(this);
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 10447ad..a977618 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -40,8 +40,10 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.LocalPowerManager;
 import android.os.Message;
 import android.os.Messenger;
@@ -278,13 +280,14 @@
     int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
     int mUserRotation = Surface.ROTATION_0;
 
-    boolean mAllowAllRotations;
+    int mAllowAllRotations = -1;
     boolean mCarDockEnablesAccelerometer;
     boolean mDeskDockEnablesAccelerometer;
     int mLidKeyboardAccessibility;
     int mLidNavigationAccessibility;
     int mLongPressOnPowerBehavior = -1;
-    boolean mScreenOn = false;
+    boolean mScreenOnEarly = false;
+    boolean mScreenOnFully = false;
     boolean mOrientationSensorEnabled = false;
     int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     static final int DEFAULT_ACCELEROMETER_ROTATION = 0;
@@ -382,9 +385,6 @@
     int mPortraitRotation = 0;   // default portrait rotation
     int mUpsideDownRotation = 0; // "other" portrait rotation
 
-    // Nothing to see here, move along...
-    int mFancyRotationAnimation;
-    
     // What we do when the user long presses on home
     private int mLongPressOnHomeBehavior = -1;
 
@@ -436,12 +436,7 @@
 
         @Override public void onChange(boolean selfChange) {
             updateSettings();
-            try {
-                mWindowManager.setRotation(USE_LAST_ROTATION, false,
-                        mFancyRotationAnimation);
-            } catch (RemoteException e) {
-                // Ignore
-            }
+            updateRotation(false);
         }
     }
     
@@ -454,45 +449,11 @@
         public void onOrientationChanged(int rotation) {
             // Send updates based on orientation value
             if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation);
-            try {
-                mWindowManager.setRotation(rotation, false,
-                        mFancyRotationAnimation);
-            } catch (RemoteException e) {
-                // Ignore
-
-            }
-        }                                      
+            updateRotation(false);
+        }
     }
     MyOrientationListener mOrientationListener;
 
-    boolean useSensorForOrientationLp(int appOrientation) {
-        // The app says use the sensor.
-        if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
-                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
-                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
-                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
-            return true;
-        }
-        // The user preference says we can rotate, and the app is willing to rotate.
-        if (mAccelerometerDefault != 0 &&
-                (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
-                 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) {
-            return true;
-        }
-        // We're in a dock that has a rotation affinity, and the app is willing to rotate.
-        if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR)
-                || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) {
-            // Note we override the nosensor flag here.
-            if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
-                    || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
-                    || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
-                return true;
-            }
-        }
-        // Else, don't use the sensor.
-        return false;
-    }
-    
     /*
      * We always let the sensor be switched on by default except when
      * the user has explicitly disabled sensor based rotation or when the
@@ -544,11 +505,11 @@
         }
         //Could have been invoked due to screen turning on or off or
         //change of the currently visible window's orientation
-        if (localLOGV) Log.v(TAG, "Screen status="+mScreenOn+
+        if (localLOGV) Log.v(TAG, "Screen status="+mScreenOnEarly+
                 ", current orientation="+mCurrentAppOrientation+
                 ", SensorEnabled="+mOrientationSensorEnabled);
         boolean disable = true;
-        if (mScreenOn) {
+        if (mScreenOnEarly) {
             if (needSensorRunningLp()) {
                 disable = false;
                 //enable listener if not already enabled
@@ -720,8 +681,6 @@
                 com.android.internal.R.integer.config_carDockRotation);
         mDeskDockRotation = readRotation(
                 com.android.internal.R.integer.config_deskDockRotation);
-        mAllowAllRotations = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_allowAllRotations);
         mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_carDockEnablesAccelerometer);
         mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
@@ -823,8 +782,6 @@
             mIncallPowerBehavior = Settings.Secure.getInt(resolver,
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
                     Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT);
-            mFancyRotationAnimation = Settings.System.getInt(resolver,
-                    "fancy_rotation_anim", 0) != 0 ? 0x80 : 0;
             int accelerometerDefault = Settings.System.getInt(resolver,
                     Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION);
             
@@ -879,7 +836,7 @@
             updateScreenSaverTimeoutLocked();
         }
         if (updateRotation) {
-            updateRotation(0);
+            updateRotation(true);
         }
         if (addView != null) {
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -1022,8 +979,7 @@
     /** {@inheritDoc} */
     public void adjustConfigurationLw(Configuration config) {
         readLidState();
-
-        mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN);
+        updateKeyboardVisibility();
 
         if (config.keyboard == Configuration.KEYBOARD_NOKEYS) {
             config.hardKeyboardHidden = Configuration.HARDKEYBOARDHIDDEN_YES;
@@ -2091,11 +2047,13 @@
     /** {@inheritDoc} */
     public void animatingWindowLw(WindowState win,
                                 WindowManager.LayoutParams attrs) {
+        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+                + win.isVisibleOrBehindKeyguardLw());
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw()) {
             if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
                 mForceStatusBar = true;
-            } 
+            }
             if (attrs.type >= FIRST_APPLICATION_WINDOW
                     && attrs.type <= LAST_APPLICATION_WINDOW
                     && attrs.x == 0 && attrs.y == 0
@@ -2134,10 +2092,10 @@
                 : null;
 
         if (mStatusBar != null) {
-            if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar
+            if (DEBUG_LAYOUT) Log.i(TAG, "force=" + mForceStatusBar
                     + " top=" + mTopFullscreenOpaqueWindowState);
             if (mForceStatusBar) {
-                if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
+                if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: forced");
                 if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
             } else if (mTopFullscreenOpaqueWindowState != null) {
                 if (localLOGV) {
@@ -2165,11 +2123,11 @@
                                 }
                             }});
                         }
-                    } else if (localLOGV) {
+                    } else if (DEBUG_LAYOUT) {
                         Log.v(TAG, "Preventing status bar from hiding by policy");
                     }
                 } else {
-                    if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar");
+                    if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar: top is not fullscreen");
                     if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT;
                 }
             }
@@ -2290,8 +2248,10 @@
     public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
         // lid changed state
         mLidOpen = lidOpen ? LID_OPEN : LID_CLOSED;
+        updateKeyboardVisibility();
+
         boolean awakeNow = mKeyguardMediator.doLidChangeTq(lidOpen);
-        updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+        updateRotation(true);
         if (awakeNow) {
             // If the lid is opening and we don't have to keep the
             // keyguard up, then we can turn on the screen
@@ -2320,7 +2280,7 @@
     void setHdmiPlugged(boolean plugged) {
         if (mHdmiPlugged != plugged) {
             mHdmiPlugged = plugged;
-            updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+            updateRotation(true);
             Intent intent = new Intent(ACTION_HDMI_PLUGGED);
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
@@ -2797,7 +2757,7 @@
                 } catch (RemoteException e) {
                 }
             }
-            updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+            updateRotation(true);
             updateOrientationListenerLp();
         }
     };
@@ -2806,7 +2766,8 @@
     public void screenTurnedOff(int why) {
         EventLog.writeEvent(70000, 0);
         synchronized (mLock) {
-            mScreenOn = false;
+            mScreenOnEarly = false;
+            mScreenOnFully = false;
         }
         mKeyguardMediator.onScreenTurnedOff(why);
         synchronized (mLock) {
@@ -2814,25 +2775,38 @@
             updateLockScreenTimeout();
             updateScreenSaverTimeoutLocked();
         }
-        try {
-            mWindowManager.waitForAllDrawn();
-        } catch (RemoteException e) {
-        }
-        // Wait for one frame to give surface flinger time to do its
-        // compositing.  Yes this is a hack, but I am really not up right now for
-        // implementing some mechanism to block until SF is done. :p
-        try {
-            Thread.sleep(20);
-        } catch (InterruptedException e) {
-        }
     }
 
     /** {@inheritDoc} */
-    public void screenTurnedOn() {
+    public void screenTurningOn(final ScreenOnListener screenOnListener) {
         EventLog.writeEvent(70000, 1);
-        mKeyguardMediator.onScreenTurnedOn();
+        //Slog.i(TAG, "Screen turning on...");
+        mKeyguardMediator.onScreenTurnedOn(new KeyguardViewManager.ShowListener() {
+            @Override public void onShown(IBinder windowToken) {
+                if (windowToken != null) {
+                    try {
+                        mWindowManager.waitForWindowDrawn(windowToken, new IRemoteCallback.Stub() {
+                            @Override public void sendResult(Bundle data) {
+                                Slog.i(TAG, "Lock screen displayed!");
+                                screenOnListener.onScreenOn();
+                                synchronized (mLock) {
+                                    mScreenOnFully = true;
+                                }
+                            }
+                        });
+                    } catch (RemoteException e) {
+                    }
+                } else {
+                    Slog.i(TAG, "No lock screen!");
+                    screenOnListener.onScreenOn();
+                    synchronized (mLock) {
+                        mScreenOnFully = true;
+                    }
+                }
+            }
+        });
         synchronized (mLock) {
-            mScreenOn = true;
+            mScreenOnEarly = true;
             updateOrientationListenerLp();
             updateLockScreenTimeout();
             updateScreenSaverTimeoutLocked();
@@ -2840,8 +2814,13 @@
     }
 
     /** {@inheritDoc} */
-    public boolean isScreenOn() {
-        return mScreenOn;
+    public boolean isScreenOnEarly() {
+        return mScreenOnEarly;
+    }
+    
+    /** {@inheritDoc} */
+    public boolean isScreenOnFully() {
+        return mScreenOnFully;
     }
     
     /** {@inheritDoc} */
@@ -2890,10 +2869,9 @@
             }
         }
     }
-    
-    public int rotationForOrientationLw(int orientation, int lastRotation,
-            boolean displayEnabled) {
 
+    @Override
+    public int rotationForOrientationLw(int orientation, int lastRotation) {
         if (false) {
             Slog.v(TAG, "rotationForOrientationLw(orient="
                         + orientation + ", last=" + lastRotation
@@ -2904,128 +2882,136 @@
         }
 
         synchronized (mLock) {
+            int sensorRotation = mOrientationListener.getCurrentRotation(); // may be -1
+
+            int preferredRotation = -1;
+            if (mHdmiPlugged) {
+                // Ignore sensor when plugged into HDMI.
+                preferredRotation = mLandscapeRotation;
+            } else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
+                // Ignore sensor when lid switch is open and rotation is forced.
+                preferredRotation = mLidOpenRotation;
+            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
+                    && ((mCarDockEnablesAccelerometer && sensorRotation >= 0)
+                            || mCarDockRotation >= 0)) {
+                // Ignore sensor when in car dock unless explicitly enabled.
+                // This case can override the behavior of NOSENSOR, and can also
+                // enable 180 degree rotation while docked.
+                preferredRotation = mCarDockEnablesAccelerometer && sensorRotation >= 0
+                        ? sensorRotation : mCarDockRotation;
+            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
+                    && ((mDeskDockEnablesAccelerometer && sensorRotation >= 0)
+                            || mDeskDockRotation >= 0)) {
+                // Ignore sensor when in desk dock unless explicitly enabled.
+                // This case can override the behavior of NOSENSOR, and can also
+                // enable 180 degree rotation while docked.
+                preferredRotation = mDeskDockEnablesAccelerometer && sensorRotation >= 0
+                        ? sensorRotation : mDeskDockRotation;
+            } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
+                // Ignore sensor when user locked rotation.
+                preferredRotation = mUserRotation;
+            } else if ((mAccelerometerDefault != 0
+                            && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
+                                    || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
+                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+                    || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+                    || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
+                // Otherwise, use sensor only if requested by the application or enabled
+                // by default for USER or UNSPECIFIED modes.  Does not apply to NOSENSOR.
+                if (mAllowAllRotations < 0) {
+                    // Can't read this during init() because the context doesn't
+                    // have display metrics at that time so we cannot determine
+                    // tablet vs. phone then.
+                    mAllowAllRotations = mContext.getResources().getBoolean(
+                            com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
+                }
+                if (sensorRotation != Surface.ROTATION_180
+                        || mAllowAllRotations == 1
+                        || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
+                    preferredRotation = sensorRotation;
+                } else {
+                    preferredRotation = lastRotation;
+                }
+            }
+
+            // TODO: Sometimes, we might want to override the application-requested
+            //       orientation, such as when HDMI is plugged in or when docked.
+            //       We can do that by modifying the appropriate cases above to return
+            //       the preferred orientation directly instead of continuing on down here.
+
             switch (orientation) {
                 case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
-                    //always return portrait if orientation set to portrait
+                    // Always return portrait if orientation set to portrait.
                     return mPortraitRotation;
-                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
-                    //always return landscape if orientation set to landscape
-                    return mLandscapeRotation;
-                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
-                    //always return portrait if orientation set to portrait
-                    return mUpsideDownRotation;
-                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
-                    //always return seascape if orientation set to reverse landscape
-                    return mSeascapeRotation;
-                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
-                    //return either landscape rotation based on the sensor
-                    return getCurrentLandscapeRotation(lastRotation);
-                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
-                    return getCurrentPortraitRotation(lastRotation);
-            }
 
-            // case for nosensor meaning ignore sensor and consider only lid
-            // or orientation sensor disabled
-            //or case.unspecified
-            if (mHdmiPlugged) {
-                return mLandscapeRotation;
-            } else if (mLidOpen == LID_OPEN) {
-                return mLidOpenRotation;
-            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
-                return mCarDockRotation;
-            } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
-                return mDeskDockRotation;
-            } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
-                return mUserRotation;
-            } else {
-                if (useSensorForOrientationLp(orientation)) {
-                    // Disable 180 degree rotation unless allowed by default for the device
-                    // or explicitly requested by the application.
-                    int rotation = mOrientationListener.getCurrentRotation(lastRotation);
-                    if (rotation == Surface.ROTATION_180
-                            && !mAllowAllRotations
-                            && orientation != ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR) {
+                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+                    // Always return landscape if orientation set to landscape.
+                    return mLandscapeRotation;
+
+                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+                    // Always return portrait if orientation set to portrait.
+                    return mUpsideDownRotation;
+
+                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+                    // Always return seascape if orientation set to reverse landscape.
+                    return mSeascapeRotation;
+
+                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+                    // Return either landscape rotation.
+                    if (isLandscapeOrSeascape(preferredRotation)) {
+                        return preferredRotation;
+                    }
+                    if (isLandscapeOrSeascape(lastRotation)) {
                         return lastRotation;
                     }
-                    return rotation;
-                }
-                return Surface.ROTATION_0;
-            }
-        }
-    }
+                    return mLandscapeRotation;
 
-    public int getLockedRotationLw() {
-        synchronized (mLock) {
-            if (false) {
-                // Not yet working.
-                if (mHdmiPlugged) {
+                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+                    // Return either portrait rotation.
+                    if (isAnyPortrait(preferredRotation)) {
+                        return preferredRotation;
+                    }
+                    if (isAnyPortrait(lastRotation)) {
+                        return lastRotation;
+                    }
+                    return mPortraitRotation;
+
+                default:
+                    // For USER, UNSPECIFIED and NOSENSOR, just return the preferred
+                    // orientation we already calculated.
+                    if (preferredRotation >= 0) {
+                        return preferredRotation;
+                    }
                     return Surface.ROTATION_0;
-                } else if (mLidOpen == LID_OPEN) {
-                    return mLidOpenRotation;
-                } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
-                    return mCarDockRotation;
-                } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
-                    return mDeskDockRotation;
-                } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
-                    return mUserRotation;
-                }
-            }
-            return -1;
-        }
-    }
-
-    private int getCurrentLandscapeRotation(int lastRotation) {
-        // if the user has locked rotation, we ignore the sensor 
-        if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
-            if (isLandscapeOrSeascape(mUserRotation)) {
-                return mUserRotation;
-            } else {
-                // it seems odd to obey the sensor at all if rotation lock is enabled
-                return mLandscapeRotation;
             }
         }
-
-        int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
-        if (isLandscapeOrSeascape(sensorRotation)) {
-            return sensorRotation;
-        }
-        // try to preserve the old rotation if it was landscape
-        if (isLandscapeOrSeascape(lastRotation)) {
-            return lastRotation;
-        }
-        // default to one of the primary landscape rotation
-        return mLandscapeRotation;
     }
 
-    private boolean isLandscapeOrSeascape(int sensorRotation) {
-        return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation;
+    @Override
+    public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
+        switch (orientation) {
+            case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+            case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+                return isAnyPortrait(rotation);
+
+            case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+            case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+            case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+                return isLandscapeOrSeascape(rotation);
+
+            default:
+                return true;
+        }
     }
 
-    private int getCurrentPortraitRotation(int lastRotation) {
-        // if the user has locked rotation, we ignore the sensor 
-        if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
-            if (isAnyPortrait(mUserRotation)) {
-                return mUserRotation;
-            } else {
-                // it seems odd to obey the sensor at all if rotation lock is enabled
-                return mPortraitRotation;
-            }
-        }
-
-        int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
-        if (isAnyPortrait(sensorRotation)) {
-            return sensorRotation;
-        }
-        // try to preserve the old rotation if it was portrait
-        if (isAnyPortrait(lastRotation)) {
-            return lastRotation;
-        }
-        // default to one of the primary portrait rotations
-        return mPortraitRotation;
+    private boolean isLandscapeOrSeascape(int rotation) {
+        return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
     }
 
-    private boolean isAnyPortrait(int sensorRotation) {
-        return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation;
+    private boolean isAnyPortrait(int rotation) {
+        return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
     }
 
 
@@ -3228,7 +3214,7 @@
 
         synchronized (mScreenSaverActivator) {
             mHandler.removeCallbacks(mScreenSaverActivator);
-            if (mScreenSaverEnabled && mScreenOn && mScreenSaverTimeout > 0) {
+            if (mScreenSaverEnabled && mScreenOnEarly && mScreenSaverTimeout > 0) {
                 if (localLOGV)
                     Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
                 mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
@@ -3236,7 +3222,7 @@
                 if (localLOGV) {
                     if (mScreenSaverTimeout == 0)
                         Log.v(TAG, "screen saver disabled by user");
-                    else if (!mScreenOn)
+                    else if (!mScreenOnEarly)
                         Log.v(TAG, "screen saver disabled while screen off");
                     else
                         Log.v(TAG, "screen saver disabled by wakelock");
@@ -3257,7 +3243,7 @@
 
     private void updateLockScreenTimeout() {
         synchronized (mScreenLockTimeout) {
-            boolean enable = (mAllowLockscreenWhenOn && mScreenOn && mKeyguardMediator.isSecure());
+            boolean enable = (mAllowLockscreenWhenOn && mScreenOnEarly && mKeyguardMediator.isSecure());
             if (mLockScreenTimerActive != enable) {
                 if (enable) {
                     if (localLOGV) Log.v(TAG, "setting lockscreen timer");
@@ -3274,26 +3260,19 @@
     /** {@inheritDoc} */
     public void enableScreenAfterBoot() {
         readLidState();
-        updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+        updateKeyboardVisibility();
+
+        updateRotation(true);
     }
 
-    void updateRotation(int animFlags) {
+    private void updateKeyboardVisibility() {
         mPowerManager.setKeyboardVisibility(mLidOpen == LID_OPEN);
-        int rotation = Surface.ROTATION_0;
-        if (mHdmiPlugged) {
-            rotation = Surface.ROTATION_0;
-        } else if (mLidOpen == LID_OPEN) {
-            rotation = mLidOpenRotation;
-        } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) {
-            rotation = mCarDockRotation;
-        } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
-            rotation = mDeskDockRotation;
-        }
-        //if lid is closed orientation will be portrait
+    }
+
+    void updateRotation(boolean alwaysSendConfiguration) {
         try {
             //set orientation on WindowManager
-            mWindowManager.setRotation(rotation, true,
-                    mFancyRotationAnimation | animFlags);
+            mWindowManager.updateRotation(alwaysSendConfiguration);
         } catch (RemoteException e) {
             // Ignore
         }
@@ -3466,7 +3445,7 @@
 
     public boolean allowKeyRepeat() {
         // disable key repeat when screen is off
-        return mScreenOn;
+        return mScreenOnEarly;
     }
 
     private void updateSystemUiVisibility() {
@@ -3522,7 +3501,8 @@
                 pw.print(mLidKeyboardAccessibility);
                 pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
                 pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior);
-        pw.print(prefix); pw.print("mScreenOn="); pw.print(mScreenOn);
+        pw.print(prefix); pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
+                pw.print(" mScreenOnFully="); pw.print(mScreenOnFully);
                 pw.print(" mOrientationSensorEnabled="); pw.print(mOrientationSensorEnabled);
                 pw.print(" mHasSoftInput="); pw.println(mHasSoftInput);
         pw.print(prefix); pw.print("mUnrestrictedScreen=("); pw.print(mUnrestrictedScreenLeft);
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index dca795c..9ee5a30 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -434,9 +434,9 @@
 
         // the following loop works on 2 frames
 
-        ".Y4L01:\n"
+        "1:\n"
         "   cmp r8, r2\n"                   // curOut - maxCurOut
-        "   bcs .Y4L02\n"
+        "   bcs 2f\n"
 
 #define MO_ONE_FRAME \
     "   add r0, r1, r7, asl #1\n"       /* in + inputIndex */\
@@ -460,8 +460,8 @@
         MO_ONE_FRAME    // frame 2
 
         "   cmp r7, r3\n"                   // inputIndex - maxInIdx
-        "   bcc .Y4L01\n"
-        ".Y4L02:\n"
+        "   bcc 1b\n"
+        "2:\n"
 
         "   bic r6, r6, #0xC0000000\n"             // phaseFraction & ...
         // save modified values
@@ -541,9 +541,9 @@
         // r13 sp
         // r14
 
-        ".Y5L01:\n"
+        "3:\n"
         "   cmp r8, r2\n"                   // curOut - maxCurOut
-        "   bcs .Y5L02\n"
+        "   bcs 4f\n"
 
 #define ST_ONE_FRAME \
     "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
@@ -577,8 +577,8 @@
     ST_ONE_FRAME    // frame 1
 
         "   cmp r7, r3\n"                       // inputIndex - maxInIdx
-        "   bcc .Y5L01\n"
-        ".Y5L02:\n"
+        "   bcc 3b\n"
+        "4:\n"
 
         "   bic r6, r6, #0xC0000000\n"              // phaseFraction & ...
         // save modified values
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 2938c45..6ac6c98 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -34,6 +34,7 @@
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -4765,6 +4766,11 @@
         }
     }
 
+    boolean deviceIsProvisioned() {
+        final ContentResolver resolver = mContext.getContentResolver();
+        return (Settings.Secure.getInt(resolver, Settings.Secure.DEVICE_PROVISIONED, 0) != 0);
+    }
+
     // Run a *full* backup pass for the given package, writing the resulting data stream
     // to the supplied file descriptor.  This method is synchronous and does not return
     // to the caller until the backup has been completed.
@@ -4785,12 +4791,19 @@
             }
         }
 
-        if (DEBUG) Slog.v(TAG, "Requesting full backup: apks=" + includeApks
-                + " shared=" + includeShared + " all=" + doAllApps
-                + " pkgs=" + pkgList);
-
         long oldId = Binder.clearCallingIdentity();
         try {
+            // Doesn't make sense to do a full backup prior to setup
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Full backup not supported before setup");
+                return;
+            }
+
+            if (DEBUG) Slog.v(TAG, "Requesting full backup: apks=" + includeApks
+                    + " shared=" + includeShared + " all=" + doAllApps
+                    + " pkgs=" + pkgList);
+            Slog.i(TAG, "Beginning full backup...");
+
             FullBackupParams params = new FullBackupParams(fd, includeApks, includeShared,
                     doAllApps, pkgList);
             final int token = generateToken();
@@ -4822,17 +4835,25 @@
                 // just eat it
             }
             Binder.restoreCallingIdentity(oldId);
+            Slog.d(TAG, "Full backup processing complete.");
         }
-        if (MORE_DEBUG) Slog.d(TAG, "Full backup done; returning to caller");
     }
 
     public void fullRestore(ParcelFileDescriptor fd) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullRestore");
-        Slog.i(TAG, "Beginning full restore...");
 
         long oldId = Binder.clearCallingIdentity();
 
         try {
+            // Check whether the device has been provisioned -- we don't handle
+            // full restores prior to completing the setup process.
+            if (!deviceIsProvisioned()) {
+                Slog.i(TAG, "Full restore not permitted before setup");
+                return;
+            }
+
+            Slog.i(TAG, "Beginning full restore...");
+
             FullRestoreParams params = new FullRestoreParams(fd);
             final int token = generateToken();
             synchronized (mFullConfirmations) {
@@ -4863,7 +4884,7 @@
                 Slog.w(TAG, "Error trying to close fd after full restore: " + e);
             }
             Binder.restoreCallingIdentity(oldId);
-            Slog.i(TAG, "Full restore completed");
+            Slog.i(TAG, "Full restore processing complete.");
         }
     }
 
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index e28c715..86ac296 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -319,7 +319,7 @@
             String id = Settings.Secure.getString(context.getContentResolver(),
                     Settings.Secure.ANDROID_ID);
             if (id != null && id.length() > 0) {
-                String name = new String("android_").concat(id);
+                String name = new String("android-").concat(id);
                 SystemProperties.set("net.hostname", name);
             }
         }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index bb21d81..785db98 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -79,6 +79,8 @@
     private static final String TAG = "PowerManagerService";
     static final String PARTIAL_NAME = "PowerManagerService";
 
+    static final boolean DEBUG_SCREEN_ON = false;
+
     private static final boolean LOG_PARTIAL_WL = false;
 
     // Indicates whether touch-down cycles should be logged as part of the
@@ -161,7 +163,9 @@
     private int mStayOnConditions = 0;
     private final int[] mBroadcastQueue = new int[] { -1, -1, -1 };
     private final int[] mBroadcastWhy = new int[3];
-    private boolean mBroadcastingScreenOff = false;
+    private boolean mPreparingForScreenOn = false;
+    private boolean mSkippedScreenOn = false;
+    private boolean mInitialized = false;
     private int mPartialCount = 0;
     private int mPowerState;
     // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
@@ -557,6 +561,9 @@
         nativeInit();
         synchronized (mLocks) {
             updateNativePowerStateLocked();
+            // We make sure to start out with the screen on due to user activity.
+            // (They did just boot their device, after all.)
+            forceUserActivityLocked();
         }
     }
 
@@ -1122,7 +1129,9 @@
             pw.println("  mNextTimeout=" + mNextTimeout + " now=" + now
                     + " " + ((mNextTimeout-now)/1000) + "s from now");
             pw.println("  mDimScreen=" + mDimScreen
-                    + " mStayOnConditions=" + mStayOnConditions);
+                    + " mStayOnConditions=" + mStayOnConditions
+                    + " mPreparingForScreenOn=" + mPreparingForScreenOn
+                    + " mSkippedScreenOn=" + mSkippedScreenOn);
             pw.println("  mScreenOffReason=" + mScreenOffReason
                     + " mUserState=" + mUserState);
             pw.println("  mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
@@ -1311,8 +1320,16 @@
         }
     }
 
-    private void sendNotificationLocked(boolean on, int why)
-    {
+    private void sendNotificationLocked(boolean on, int why) {
+        if (!mInitialized) {
+            // No notifications sent until first initialization is done.
+            // This is so that when we are moving from our initial state
+            // which looks like the screen was off to it being on, we do not
+            // go through the process of waiting for the higher-level user
+            // space to be ready before turning up the display brightness.
+            // (And also do not send needless broadcasts about the screen.)
+            return;
+        }
         if (!on) {
             mStillNeedSleepNotification = false;
         }
@@ -1341,7 +1358,9 @@
             mBroadcastQueue[0] = on ? 1 : 0;
             mBroadcastQueue[1] = -1;
             mBroadcastQueue[2] = -1;
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
             mBroadcastWakeLock.release();
+            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 1, mBroadcastWakeLock.mCount);
             mBroadcastWakeLock.release();
             index = 0;
         }
@@ -1357,7 +1376,9 @@
 
         // The broadcast queue has changed; make sure the screen is on if it
         // is now possible for it to be.
-        updateNativePowerStateLocked();
+        if (mSkippedScreenOn) {
+            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
+        }
 
         // Now send the message.
         if (index >= 0) {
@@ -1371,6 +1392,21 @@
         }
     }
 
+    private WindowManagerPolicy.ScreenOnListener mScreenOnListener =
+            new WindowManagerPolicy.ScreenOnListener() {
+                @Override public void onScreenOn() {
+                    synchronized (mLocks) {
+                        if (mPreparingForScreenOn) {
+                            mPreparingForScreenOn = false;
+                            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
+                            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP,
+                                    4, mBroadcastWakeLock.mCount);
+                            mBroadcastWakeLock.release();
+                        }
+                    }
+                }
+    };
+
     private Runnable mNotificationTask = new Runnable()
     {
         public void run()
@@ -1387,14 +1423,17 @@
                         mBroadcastWhy[i] = mBroadcastWhy[i+1];
                     }
                     policy = getPolicyLocked();
-                    if (value == 0) {
-                        mBroadcastingScreenOff = true;
+                    if (value == 1 && !mPreparingForScreenOn) {
+                        mPreparingForScreenOn = true;
+                        mBroadcastWakeLock.acquire();
+                        EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_SEND,
+                                mBroadcastWakeLock.mCount);
                     }
                 }
                 if (value == 1) {
                     mScreenOnStart = SystemClock.uptimeMillis();
 
-                    policy.screenTurnedOn();
+                    policy.screenTurningOn(mScreenOnListener);
                     try {
                         ActivityManagerNative.getDefault().wakingUp();
                     } catch (RemoteException e) {
@@ -1432,8 +1471,7 @@
                         synchronized (mLocks) {
                             EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3,
                                     mBroadcastWakeLock.mCount);
-                            mBroadcastingScreenOff = false;
-                            updateNativePowerStateLocked();
+                            updateLightsLocked(mPowerState, SCREEN_ON_BIT);
                             mBroadcastWakeLock.release();
                         }
                     }
@@ -1464,10 +1502,6 @@
             synchronized (mLocks) {
                 EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0,
                         SystemClock.uptimeMillis() - mScreenOffStart, mBroadcastWakeLock.mCount);
-                synchronized (mLocks) {
-                    mBroadcastingScreenOff = false;
-                    updateNativePowerStateLocked();
-                }
                 mBroadcastWakeLock.release();
             }
         }
@@ -1630,6 +1664,11 @@
         };
 
     private int setScreenStateLocked(boolean on) {
+        if (DEBUG_SCREEN_ON) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Slog.i(TAG, "Set screen state: " + on, e);
+        }
         int err = Power.setScreenState(on);
         if (err == 0) {
             mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
@@ -1680,7 +1719,7 @@
             } else {
                 newState &= ~BATTERY_LOW_BIT;
             }
-            if (newState == mPowerState) {
+            if (newState == mPowerState && mInitialized) {
                 return;
             }
 
@@ -1706,10 +1745,7 @@
                          + " newBatteryLow=" + ((newState & BATTERY_LOW_BIT) != 0));
             }
 
-            if (mPowerState != newState) {
-                updateLightsLocked(newState, 0);
-                mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
-            }
+            final boolean stateChanged = mPowerState != newState;
 
             if (oldScreenOn != newScreenOn) {
                 if (newScreenOn) {
@@ -1761,10 +1797,24 @@
                     EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 1, reason,
                             mTotalTouchDownTime, mTouchCycles);
                     if (err == 0) {
-                        mPowerState |= SCREEN_ON_BIT;
                         sendNotificationLocked(true, -1);
+                        // Update the lights *after* taking care of turning the
+                        // screen on, so we do this after our notifications are
+                        // enqueued and thus will delay turning on the screen light
+                        // until the windows are correctly displayed.
+                        if (stateChanged) {
+                            updateLightsLocked(newState, 0);
+                        }
+                        mPowerState |= SCREEN_ON_BIT;
                     }
+
                 } else {
+                    // Update the lights *before* taking care of turning the
+                    // screen off, so we can initiate any animations that are desired.
+                    if (stateChanged) {
+                        updateLightsLocked(newState, 0);
+                    }
+
                     // cancel light sensor task
                     mHandler.removeCallbacks(mAutoBrightnessTask);
                     mLightSensorPendingDecrease = false;
@@ -1787,29 +1837,20 @@
                         mLastTouchDown = 0;
                     }
                 }
+            } else if (stateChanged) {
+                // Screen on/off didn't change, but lights may have.
+                updateLightsLocked(newState, 0);
             }
-            
+
+            mPowerState = (mPowerState & ~LIGHTS_MASK) | (newState & LIGHTS_MASK);
+
             updateNativePowerStateLocked();
+
+            mInitialized = true;
         }
     }
-    
+
     private void updateNativePowerStateLocked() {
-        if ((mPowerState & SCREEN_ON_BIT) != 0) {
-            // Don't turn screen on if we are currently reporting a screen off.
-            // This is to avoid letting the screen go on before things like the
-            // lock screen have been displayed due to it going off.
-            if (mBroadcastingScreenOff) {
-                // Currently broadcasting that the screen is off.  Don't
-                // allow screen to go on until that is done.
-                return;
-            }
-            for (int i=0; i<mBroadcastQueue.length; i++) {
-                if (mBroadcastQueue[i] == 0) {
-                    // A screen off is currently enqueued.
-                    return;
-                }
-            }
-        }
         nativeSetPowerState(
                 (mPowerState & SCREEN_ON_BIT) != 0,
                 (mPowerState & SCREEN_BRIGHT) == SCREEN_BRIGHT);
@@ -1835,8 +1876,43 @@
                 mBatteryService.getBatteryLevel() <= Power.LOW_BATTERY_THRESHOLD);
     }
 
+    private boolean shouldDeferScreenOnLocked() {
+        if (mPreparingForScreenOn) {
+            // Currently waiting for confirmation from the policy that it
+            // is okay to turn on the screen.  Don't allow the screen to go
+            // on until that is done.
+            if (DEBUG_SCREEN_ON) Slog.i(TAG,
+                    "updateLights: delaying screen on due to mPreparingForScreenOn");
+            return true;
+        } else {
+            // If there is a screen-on command in the notification queue, we
+            // can't turn the screen on until it has been processed (and we
+            // have set mPreparingForScreenOn) or it has been dropped.
+            for (int i=0; i<mBroadcastQueue.length; i++) {
+                if (mBroadcastQueue[i] == 1) {
+                    if (DEBUG_SCREEN_ON) Slog.i(TAG,
+                            "updateLights: delaying screen on due to notification queue");
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private void updateLightsLocked(int newState, int forceState) {
         final int oldState = mPowerState;
+
+        // If the screen is not currently on, we will want to delay actually
+        // turning the lights on if we are still getting the UI put up.
+        if ((oldState&SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {
+            // Don't turn screen on until we know we are really ready to.
+            // This is to avoid letting the screen go on before things like the
+            // lock screen have been displayed.
+            if ((mSkippedScreenOn=shouldDeferScreenOnLocked())) {
+                newState &= ~(SCREEN_ON_BIT|SCREEN_BRIGHT_BIT);
+            }
+        }
+
         if ((newState & SCREEN_ON_BIT) != 0) {
             // Only turn on the buttons or keyboard if the screen is also on.
             // We should never see the buttons on but not the screen.
@@ -1943,6 +2019,13 @@
             }
             mScreenBrightness.setTargetLocked(brightness, steps,
                     INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
+            if (DEBUG_SCREEN_ON) {
+                RuntimeException e = new RuntimeException("here");
+                e.fillInStackTrace();
+                Slog.i(TAG, "Setting screen brightness: " + brightness, e);
+                mScreenBrightness.setTargetLocked(brightness, steps,
+                        INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
+            }
         }
 
         if (mSpew) {
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 6ceccaf..253e741 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -120,7 +120,8 @@
                             notifyCallbacksLocked();
                             if (mWallpaperComponent == null || mImageWallpaperPending) {
                                 mImageWallpaperPending = false;
-                                bindWallpaperComponentLocked(mImageWallpaperComponent, true);
+                                bindWallpaperComponentLocked(mImageWallpaperComponent,
+                                        true, false);
                                 saveSettingsLocked();
                             }
                         }
@@ -201,7 +202,7 @@
                     if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
                                 > SystemClock.uptimeMillis()) {
                         Slog.w(TAG, "Reverting to built-in wallpaper!");
-                        bindWallpaperComponentLocked(null, true);
+                        clearWallpaperLocked(true);
                     }
                 }
             }
@@ -230,12 +231,26 @@
                     mWallpaperUpdating = false;
                     ComponentName comp = mWallpaperComponent;
                     clearWallpaperComponentLocked();
-                    bindWallpaperComponentLocked(comp, false);
+                    if (!bindWallpaperComponentLocked(comp, false, false)) {
+                        Slog.w(TAG, "Wallpaper no longer available; reverting to default");
+                        clearWallpaperLocked(false);
+                    }
                 }
             }
         }
 
         @Override
+        public void onPackageModified(String packageName) {
+            synchronized (mLock) {
+                if (mWallpaperComponent == null ||
+                        !mWallpaperComponent.getPackageName().equals(packageName)) {
+                    return;
+                }
+            }
+            doPackagesChanged(true);
+        }
+
+        @Override
         public void onPackageUpdateStarted(String packageName, int uid) {
             synchronized (mLock) {
                 if (mWallpaperComponent != null &&
@@ -265,7 +280,7 @@
                         changed = true;
                         if (doit) {
                             Slog.w(TAG, "Wallpaper uninstalled, removing: " + mWallpaperComponent);
-                            clearWallpaperLocked();
+                            clearWallpaperLocked(false);
                         }
                     }
                 }
@@ -283,7 +298,7 @@
                                 mWallpaperComponent, 0);
                     } catch (NameNotFoundException e) {
                         Slog.w(TAG, "Wallpaper component gone, removing: " + mWallpaperComponent);
-                        clearWallpaperLocked();
+                        clearWallpaperLocked(false);
                     }
                 }
                 if (mNextWallpaperComponent != null
@@ -321,45 +336,51 @@
     public void systemReady() {
         if (DEBUG) Slog.v(TAG, "systemReady");
         synchronized (mLock) {
+            RuntimeException e = null;
             try {
-                bindWallpaperComponentLocked(mNextWallpaperComponent, false);
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Failure starting previous wallpaper", e);
-                try {
-                    bindWallpaperComponentLocked(null, false);
-                } catch (RuntimeException e2) {
-                    Slog.w(TAG, "Failure starting default wallpaper", e2);
-                    clearWallpaperComponentLocked();
+                if (bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
+                    return;
                 }
+            } catch (RuntimeException e1) {
+                e = e1;
             }
+            Slog.w(TAG, "Failure starting previous wallpaper", e);
+            clearWallpaperLocked(false);
         }
     }
     
     public void clearWallpaper() {
         if (DEBUG) Slog.v(TAG, "clearWallpaper");
         synchronized (mLock) {
-            clearWallpaperLocked();
+            clearWallpaperLocked(false);
         }
     }
 
-    public void clearWallpaperLocked() {
+    public void clearWallpaperLocked(boolean defaultFailed) {
         File f = WALLPAPER_FILE;
         if (f.exists()) {
             f.delete();
         }
         final long ident = Binder.clearCallingIdentity();
+        RuntimeException e = null;
         try {
             mImageWallpaperPending = false;
-            bindWallpaperComponentLocked(null, false);
-        } catch (IllegalArgumentException e) {
-            // This can happen if the default wallpaper component doesn't
-            // exist.  This should be a system configuration problem, but
-            // let's not let it crash the system and just live with no
-            // wallpaper.
-            Slog.e(TAG, "Default wallpaper component not found!", e);
+            if (bindWallpaperComponentLocked(defaultFailed
+                    ? mImageWallpaperComponent : null, true, false)) {
+                return;
+            }
+        } catch (IllegalArgumentException e1) {
+            e = e1;
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
+        
+        // This can happen if the default wallpaper component doesn't
+        // exist.  This should be a system configuration problem, but
+        // let's not let it crash the system and just live with no
+        // wallpaper.
+        Slog.e(TAG, "Default wallpaper component not found!", e);
+        clearWallpaperComponentLocked();
     }
 
     public void setDimensionHints(int width, int height) throws RemoteException {
@@ -469,14 +490,14 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 mImageWallpaperPending = false;
-                bindWallpaperComponentLocked(name, false);
+                bindWallpaperComponentLocked(name, false, true);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
     }
     
-    void bindWallpaperComponentLocked(ComponentName componentName, boolean force) {
+    boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force, boolean fromUser) {
         if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
         
         // Has the component changed?
@@ -486,12 +507,12 @@
                     if (componentName == null) {
                         if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
                         // Still using default wallpaper.
-                        return;
+                        return true;
                     }
                 } else if (mWallpaperComponent.equals(componentName)) {
                     // Changing to same wallpaper.
                     if (DEBUG) Slog.v(TAG, "same wallpaper");
-                    return;
+                    return true;
                 }
             }
         }
@@ -516,9 +537,14 @@
             ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
                     PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS);
             if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
-                throw new SecurityException("Selected service does not require "
+                String msg = "Selected service does not require "
                         + android.Manifest.permission.BIND_WALLPAPER
-                        + ": " + componentName);
+                        + ": " + componentName;
+                if (fromUser) {
+                    throw new SecurityException(msg);
+                }
+                Slog.w(TAG, msg);
+                return false;
             }
             
             WallpaperInfo wi = null;
@@ -535,16 +561,29 @@
                         try {
                             wi = new WallpaperInfo(mContext, ris.get(i));
                         } catch (XmlPullParserException e) {
-                            throw new IllegalArgumentException(e);
+                            if (fromUser) {
+                                throw new IllegalArgumentException(e);
+                            }
+                            Slog.w(TAG, e);
+                            return false;
                         } catch (IOException e) {
-                            throw new IllegalArgumentException(e);
+                            if (fromUser) {
+                                throw new IllegalArgumentException(e);
+                            }
+                            Slog.w(TAG, e);
+                            return false;
                         }
                         break;
                     }
                 }
                 if (wi == null) {
-                    throw new SecurityException("Selected service is not a wallpaper: "
-                            + componentName);
+                    String msg = "Selected service is not a wallpaper: "
+                            + componentName;
+                    if (fromUser) {
+                        throw new SecurityException(msg);
+                    }
+                    Slog.w(TAG, msg);
+                    return false;
                 }
             }
             
@@ -561,8 +600,13 @@
                             0));
             if (!mContext.bindService(intent, newConn,
                     Context.BIND_AUTO_CREATE)) {
-                throw new IllegalArgumentException("Unable to bind service: "
-                        + componentName);
+                String msg = "Unable to bind service: "
+                        + componentName;
+                if (fromUser) {
+                    throw new IllegalArgumentException(msg);
+                }
+                Slog.w(TAG, msg);
+                return false;
             }
             
             clearWallpaperComponentLocked();
@@ -577,8 +621,14 @@
             }
             
         } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException("Unknown component " + componentName);
+            String msg = "Unknown component " + componentName;
+            if (fromUser) {
+                throw new IllegalArgumentException(msg);
+            }
+            Slog.w(TAG, msg);
+            return false;
         }
+        return true;
     }
     
     void clearWallpaperComponentLocked() {
@@ -611,7 +661,7 @@
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
             if (!mWallpaperUpdating) {
-                bindWallpaperComponentLocked(null, false);
+                bindWallpaperComponentLocked(null, false, false);
             }
         }
     }
@@ -765,13 +815,11 @@
             loadSettingsLocked();
             if (mNextWallpaperComponent != null && 
                     !mNextWallpaperComponent.equals(mImageWallpaperComponent)) {
-                try {
-                    bindWallpaperComponentLocked(mNextWallpaperComponent, false);
-                } catch (IllegalArgumentException e) {
+                if (!bindWallpaperComponentLocked(mNextWallpaperComponent, false, false)) {
                     // No such live wallpaper or other failure; fall back to the default
                     // live wallpaper (since the profile being restored indicated that the
                     // user had selected a live rather than static one).
-                    bindWallpaperComponentLocked(null, false);
+                    bindWallpaperComponentLocked(null, false, false);
                 }
                 success = true;
             } else {
@@ -786,7 +834,7 @@
                 }
                 if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
                 if (success) {
-                    bindWallpaperComponentLocked(null, false);
+                    bindWallpaperComponentLocked(null, false, false);
                 }
             }
         }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 6830055..ed8fa40 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -718,8 +718,14 @@
      */
     private void manageServicesLocked() {
         populateEnabledServicesLocked(mEnabledServices);
-        updateServicesStateLocked(mInstalledServices, mEnabledServices);
-        disableAccessibilityIfNoEnabledServices(mEnabledServices);
+        final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
+                mEnabledServices);
+        // No enabled installed services => disable accessibility to avoid
+        // sending accessibility events with no recipient across processes. 
+        if (mIsAccessibilityEnabled && enabledInstalledServicesCount == 0) {
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_ENABLED, 0);
+        }
     }
 
     /**
@@ -771,13 +777,15 @@
      *
      * @param installedServices All installed {@link AccessibilityService}s.
      * @param enabledServices The {@link ComponentName}s of the enabled services.
+     * @return The number of enabled installed services.
      */
-    private void updateServicesStateLocked(List<AccessibilityServiceInfo> installedServices,
+    private int updateServicesStateLocked(List<AccessibilityServiceInfo> installedServices,
             Set<ComponentName> enabledServices) {
 
         Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap;
         boolean isEnabled = mIsAccessibilityEnabled;
 
+        int enabledInstalledServices = 0;
         for (int i = 0, count = installedServices.size(); i < count; i++) {
             AccessibilityServiceInfo installedService = installedServices.get(i);
             ComponentName componentName = ComponentName.unflattenFromString(
@@ -790,6 +798,7 @@
                         service = new Service(componentName, installedService, false);
                     }
                     service.bind();
+                    enabledInstalledServices++;
                 } else {
                     if (service != null) {
                         service.unbind();
@@ -801,19 +810,8 @@
                 }
             }
         }
-    }
 
-    /**
-     * Disables accessibility if there are no enabled accessibility services which
-     * to consume the generated accessibility events.
-     *
-     * @param enabledServices The set of enabled services.
-     */
-    private void disableAccessibilityIfNoEnabledServices(Set<ComponentName> enabledServices) {
-        if (enabledServices.isEmpty()) {
-            Settings.Secure.putInt(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_ENABLED, 0);
-        }
+        return enabledInstalledServices;
     }
 
     /**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 41af137..ed960d6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1631,8 +1631,8 @@
         }
         if (app.conProviders.size() > 0) {
             for (ContentProviderRecord cpr : app.conProviders.keySet()) {
-                if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
-                    updateLruProcessInternalLocked(cpr.app, oomAdj,
+                if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
+                    updateLruProcessInternalLocked(cpr.proc, oomAdj,
                             updateActivityTime, i+1);
                 }
             }
@@ -3373,7 +3373,24 @@
         for (i=0; i<N; i++) {
             bringDownServiceLocked(services.get(i), true);
         }
-        
+
+        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
+        for (ContentProviderRecord provider : mProvidersByClass.values()) {
+            if (provider.info.packageName.equals(name)
+                    && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
+                if (!doit) {
+                    return true;
+                }
+                didSomething = true;
+                providers.add(provider);
+            }
+        }
+
+        N = providers.size();
+        for (i=0; i<N; i++) {
+            removeDyingProviderLocked(null, providers.get(i));
+        }
+
         if (doit) {
             if (purgeCache) {
                 AttributeCache ac = AttributeCache.instance();
@@ -5485,7 +5502,7 @@
                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
                 ContentProviderRecord cpr = mProvidersByClass.get(comp);
                 if (cpr == null) {
-                    cpr = new ContentProviderRecord(cpi, app.info);
+                    cpr = new ContentProviderRecord(cpi, app.info, comp);
                     mProvidersByClass.put(comp, cpr);
                 }
                 app.pubProviders.put(cpi.name, cpr);
@@ -5643,25 +5660,25 @@
                 // return it right away.
                 final boolean countChanged = incProviderCount(r, cpr);
                 if (countChanged) {
-                    if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
+                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
                         // If this is a perceptible app accessing the provider,
                         // make sure to count it as being accessed and thus
                         // back up on the LRU list.  This is good because
                         // content providers are often expensive to start.
-                        updateLruProcessLocked(cpr.app, false, true);
+                        updateLruProcessLocked(cpr.proc, false, true);
                     }
                 }
 
-                if (cpr.app != null) {
+                if (cpr.proc != null) {
                     if (false) {
                         if (cpr.name.flattenToShortString().equals(
                                 "com.android.providers.calendar/.CalendarProvider2")) {
                             Slog.v(TAG, "****************** KILLING "
                                 + cpr.name.flattenToShortString());
-                            Process.killProcess(cpr.app.pid);
+                            Process.killProcess(cpr.proc.pid);
                         }
                     }
-                    boolean success = updateOomAdjLocked(cpr.app);
+                    boolean success = updateOomAdjLocked(cpr.proc);
                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
                     // NOTE: there is still a race here where a signal could be
                     // pending on the process even though we managed to update its
@@ -5676,7 +5693,7 @@
                                 "Existing provider " + cpr.name.flattenToShortString()
                                 + " is crashing; detaching " + r);
                         boolean lastRef = decProviderCount(r, cpr);
-                        appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
+                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
                         if (!lastRef) {
                             // This wasn't the last ref our process had on
                             // the provider...  we have now been killed, bail.
@@ -5729,7 +5746,7 @@
                                     + cpi.name);
                             return null;
                         }
-                        cpr = new ContentProviderRecord(cpi, ai);
+                        cpr = new ContentProviderRecord(cpi, ai, comp);
                     } catch (RemoteException ex) {
                         // pm is in same process, this will never happen.
                     }
@@ -5864,7 +5881,7 @@
             //update content provider record entry info
             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
             ContentProviderRecord localCpr = mProvidersByClass.get(comp);
-            if (localCpr.app == r) {
+            if (localCpr.proc == r) {
                 //should not happen. taken care of as a local provider
                 Slog.w(TAG, "removeContentProvider called on local provider: "
                         + cpr.info.name + " in process " + r.processName);
@@ -5940,7 +5957,7 @@
                     }
                     synchronized (dst) {
                         dst.provider = src.provider;
-                        dst.app = r;
+                        dst.proc = r;
                         dst.notifyAll();
                     }
                     updateOomAdjLocked(r);
@@ -8706,9 +8723,9 @@
                     r.dump(pw, "      ");
                 } else {
                     pw.print("  * "); pw.print(e.getKey().flattenToShortString());
-                    if (r.app != null) {
+                    if (r.proc != null) {
                         pw.println(":");
-                        pw.print("      "); pw.println(r.app);
+                        pw.print("      "); pw.println(r.proc);
                     } else {
                         pw.println();
                     }
@@ -9440,7 +9457,7 @@
             cpr.notifyAll();
         }
         
-        mProvidersByClass.remove(cpr.info.name);
+        mProvidersByClass.remove(cpr.name);
         String names[] = cpr.info.authority.split(";");
         for (int j = 0; j < names.length; j++) {
             mProvidersByName.remove(names[j]);
@@ -9454,9 +9471,10 @@
                     && capp.pid != MY_PID) {
                 Slog.i(TAG, "Kill " + capp.processName
                         + " (pid " + capp.pid + "): provider " + cpr.info.name
-                        + " in dying process " + proc.processName);
+                        + " in dying process " + (proc != null ? proc.processName : "??"));
                 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
-                        capp.processName, capp.setAdj, "dying provider " + proc.processName);
+                        capp.processName, capp.setAdj, "dying provider "
+                                + cpr.name.toShortString());
                 Process.killProcessQuiet(capp.pid);
             }
         }
@@ -9515,7 +9533,7 @@
             while (it.hasNext()) {
                 ContentProviderRecord cpr = it.next();
                 cpr.provider = null;
-                cpr.app = null;
+                cpr.proc = null;
 
                 // See if someone is waiting for this provider...  in which
                 // case we don't remove it, but just let it restart.
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index db235ee..9c55597 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -32,15 +32,15 @@
     final ApplicationInfo appInfo;
     final ComponentName name;
     int externals;     // number of non-framework processes supported by this provider
-    ProcessRecord app; // if non-null, hosting application
+    ProcessRecord proc; // if non-null, hosting process.
     ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
     String stringName;
     
-    public ContentProviderRecord(ProviderInfo _info, ApplicationInfo ai) {
+    public ContentProviderRecord(ProviderInfo _info, ApplicationInfo ai, ComponentName _name) {
         super(_info);
         uid = ai.uid;
         appInfo = ai;
-        name = new ComponentName(_info.packageName, _info.name);
+        name = _name;
         noReleaseNeeded = uid == 0 || uid == Process.SYSTEM_UID;
     }
 
@@ -61,7 +61,7 @@
         pw.print(prefix); pw.print("package=");
                 pw.print(info.applicationInfo.packageName);
                 pw.print(" process="); pw.println(info.processName);
-        pw.print(prefix); pw.print("app="); pw.println(app);
+        pw.print(prefix); pw.print("proc="); pw.println(proc);
         if (launchingApp != null) {
             pw.print(prefix); pw.print("launchingApp="); pw.println(launchingApp);
         }
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index bfa2b39..61c96bb 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -194,7 +194,7 @@
 
     // This must be called while inside a transaction.
     boolean stepAnimationLocked(long currentTime, int dw, int dh) {
-        if (!service.mDisplayFrozen && service.mPolicy.isScreenOn()) {
+        if (!service.mDisplayFrozen && service.mPolicy.isScreenOnFully()) {
             // We will run animations as long as the display isn't frozen.
 
             if (animation == WindowManagerService.sDummyAnimation) {
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index dd440bf..f2e7485 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -125,6 +125,12 @@
             mDragWindowHandle.frameTop = 0;
             mDragWindowHandle.frameRight = mService.mCurDisplayWidth;
             mDragWindowHandle.frameBottom = mService.mCurDisplayHeight;
+
+            // Pause rotations before a drag.
+            if (WindowManagerService.DEBUG_ORIENTATION) {
+                Slog.d(WindowManagerService.TAG, "Pausing rotation during drag");
+            }
+            mService.pauseRotationLocked();
         }
     }
 
@@ -142,6 +148,12 @@
 
             mDragWindowHandle = null;
             mDragApplicationHandle = null;
+
+            // Resume rotations after a drag.
+            if (WindowManagerService.DEBUG_ORIENTATION) {
+                Slog.d(WindowManagerService.TAG, "Resuming rotation after drag");
+            }
+            mService.resumeRotationLocked();
         }
     }
 
@@ -257,13 +269,6 @@
         // free our resources and drop all the object references
         mService.mDragState.reset();
         mService.mDragState = null;
-
-        if (WindowManagerService.DEBUG_ORIENTATION) Slog.d(WindowManagerService.TAG, "Performing post-drag rotation");
-        boolean changed = mService.setRotationUncheckedLocked(
-                WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
-        if (changed) {
-            mService.mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
-        }
     }
 
     void notifyMoveLw(float x, float y) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 609016b..02b246a 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -73,6 +73,7 @@
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.LocalPowerManager;
 import android.os.Looper;
 import android.os.Message;
@@ -91,6 +92,7 @@
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
 import android.util.TypedValue;
@@ -384,6 +386,12 @@
     ArrayList<WindowState> mForceRemoves;
 
     /**
+     * Windows that clients are waiting to have drawn.
+     */
+    ArrayList<Pair<WindowState, IRemoteCallback>> mWaitingForDrawn
+            = new ArrayList<Pair<WindowState, IRemoteCallback>>();
+
+    /**
      * Used when rebuilding window list to keep track of windows that have
      * been removed.
      */
@@ -419,14 +427,11 @@
     int mAppDisplayWidth = 0;
     int mAppDisplayHeight = 0;
     int mRotation = 0;
-    int mRequestedRotation = 0;
     int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mAltOrientation = false;
-    int mLastRotationFlags;
     ArrayList<IRotationWatcher> mRotationWatchers
             = new ArrayList<IRotationWatcher>();
-    int mDeferredRotation;
-    int mDeferredRotationAnimFlags;
+    int mDeferredRotationPauseCount;
 
     boolean mLayoutNeeded = true;
     boolean mAnimationPending = false;
@@ -2191,7 +2196,8 @@
         // to hold off on removing the window until the animation is done.
         // If the display is frozen, just remove immediately, since the
         // animation wouldn't be seen.
-        if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
+        if (win.mSurface != null && !mDisplayFrozen && mDisplayEnabled
+                && mPolicy.isScreenOnFully()) {
             // If we are not currently running the exit animation, we
             // need to see about starting one.
             if (wasVisible=win.isWinVisibleLw()) {
@@ -2569,7 +2575,7 @@
                 if (displayed) {
                     if (win.mSurface != null && !win.mDrawPending
                             && !win.mCommitDrawPending && !mDisplayFrozen
-                            && mDisplayEnabled && mPolicy.isScreenOn()) {
+                            && mDisplayEnabled && mPolicy.isScreenOnFully()) {
                         applyEnterAnimationLocked(win);
                     }
                     if ((win.mAttrs.flags
@@ -2862,7 +2868,7 @@
         // frozen, there is no reason to animate and it can cause strange
         // artifacts when we unfreeze the display if some different animation
         // is running.
-        if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
+        if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
             int anim = mPolicy.selectAnimationLw(win, transit);
             int attr = -1;
             Animation a = null;
@@ -2948,7 +2954,7 @@
         // frozen, there is no reason to animate and it can cause strange
         // artifacts when we unfreeze the display if some different animation
         // is running.
-        if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
+        if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
             Animation a;
             if (mNextAppTransitionPackage != null) {
                 a = loadAnimation(mNextAppTransitionPackage, enter ?
@@ -3405,9 +3411,7 @@
                 //send a message to Policy indicating orientation change to take
                 //action like disabling/enabling sensors etc.,
                 mPolicy.setCurrentOrientationLw(req);
-                if (setRotationUncheckedLocked(WindowManagerPolicy.USE_LAST_ROTATION,
-                        mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE,
-                        inTransaction)) {
+                if (updateRotationUncheckedLocked(inTransaction)) {
                     changed = true;
                 }
             }
@@ -3514,7 +3518,7 @@
             if (DEBUG_APP_TRANSITIONS) Slog.v(
                     TAG, "Prepare app transition: transit=" + transit
                     + " mNextAppTransition=" + mNextAppTransition);
-            if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()) {
+            if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()) {
                 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
                         || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
                     mNextAppTransition = transit;
@@ -3598,7 +3602,7 @@
             // If the display is frozen, we won't do anything until the
             // actual window is displayed so there is no reason to put in
             // the starting window.
-            if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn()) {
+            if (mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully()) {
                 return;
             }
 
@@ -3880,7 +3884,7 @@
 
             // If we are preparing an app transition, then delay changing
             // the visibility of this token until we execute that transition.
-            if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOn()
+            if (!mDisplayFrozen && mDisplayEnabled && mPolicy.isScreenOnFully()
                     && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
                 // Already in requested state, don't do anything more.
                 if (wtoken.hiddenRequested != visible) {
@@ -4008,7 +4012,7 @@
         }
 
         synchronized(mWindowMap) {
-            if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOn()) {
+            if (configChanges == 0 && !mDisplayFrozen && mPolicy.isScreenOnFully()) {
                 if (DEBUG_ORIENTATION) Slog.v(TAG, "Skipping set freeze of " + token);
                 return;
             }
@@ -4814,8 +4818,7 @@
         mPolicy.enableScreenAfterBoot();
 
         // Make sure the last requested orientation has been applied.
-        setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
-                mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
+        updateRotationUnchecked(false);
     }
 
     public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -5034,6 +5037,10 @@
         return bm;
     }
 
+    /**
+     * Freeze rotation changes.  (Enable "rotation lock".)
+     * Persists across reboots.
+     */
     public void freezeRotation() {
         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                 "freezeRotation()")) {
@@ -5043,9 +5050,13 @@
         if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
-        setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
+        updateRotationUnchecked(false);
     }
 
+    /**
+     * Thaw rotation changes.  (Disable "rotation lock".)
+     * Persists across reboots.
+     */
     public void thawRotation() {
         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                 "thawRotation()")) {
@@ -5055,30 +5066,56 @@
         if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
 
         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
-        setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
+        updateRotationUnchecked(false);
     }
 
-    public void setRotation(int rotation,
-            boolean alwaysSendConfiguration, int animFlags) {
-        if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
-                "setRotation()")) {
-            throw new SecurityException("Requires SET_ORIENTATION permission");
+    /**
+     * Recalculate the current rotation.
+     *
+     * Called by the window manager policy whenever the state of the system changes
+     * such that the current rotation might need to be updated, such as when the
+     * device is docked or rotated into a new posture.
+     */
+    public void updateRotation(boolean alwaysSendConfiguration) {
+        updateRotationUnchecked(alwaysSendConfiguration);
+    }
+
+    /**
+     * Temporarily pauses rotation changes until resumed.
+     *
+     * This can be used to prevent rotation changes from occurring while the user is
+     * performing certain operations, such as drag and drop.
+     *
+     * This call nests and must be matched by an equal number of calls to {@link #resumeRotation}.
+     */
+    void pauseRotationLocked() {
+        mDeferredRotationPauseCount += 1;
+    }
+
+    /**
+     * Resumes normal rotation changes after being paused.
+     */
+    void resumeRotationLocked() {
+        if (mDeferredRotationPauseCount > 0) {
+            mDeferredRotationPauseCount -= 1;
+            if (mDeferredRotationPauseCount == 0) {
+                boolean changed = updateRotationUncheckedLocked(false);
+                if (changed) {
+                    mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+                }
+            }
         }
-
-        setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
     }
 
-    public void setRotationUnchecked(int rotation,
-            boolean alwaysSendConfiguration, int animFlags) {
-        if(DEBUG_ORIENTATION) Slog.v(TAG,
-                   "setRotationUnchecked(rotation=" + rotation +
-                   " alwaysSendConfiguration=" + alwaysSendConfiguration +
-                   " animFlags=" + animFlags);
+    public void updateRotationUnchecked(
+            boolean alwaysSendConfiguration) {
+        if(DEBUG_ORIENTATION) Slog.v(TAG, "updateRotationUnchecked("
+                   + "alwaysSendConfiguration=" + alwaysSendConfiguration + ")");
 
         long origId = Binder.clearCallingIdentity();
         boolean changed;
         synchronized(mWindowMap) {
-            changed = setRotationUncheckedLocked(rotation, animFlags, false);
+            changed = updateRotationUncheckedLocked(false);
         }
 
         if (changed || alwaysSendConfiguration) {
@@ -5089,152 +5126,113 @@
     }
 
     /**
-     * Apply a new rotation to the screen, respecting the requests of
-     * applications.  Use WindowManagerPolicy.USE_LAST_ROTATION to simply
-     * re-evaluate the desired rotation.
-     * 
-     * Returns null if the rotation has been changed.  In this case YOU
-     * MUST CALL setNewConfiguration() TO UNFREEZE THE SCREEN.
+     * Updates the current rotation.
+     *
+     * Returns true if the rotation has been changed.  In this case YOU
+     * MUST CALL sendNewConfiguration() TO UNFREEZE THE SCREEN.
      */
-    public boolean setRotationUncheckedLocked(int rotation, int animFlags, boolean inTransaction) {
-        if (mDragState != null
-                || (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating())) {
-            // Potential rotation during a drag or while waiting for a previous orientation
-            // change to finish (rotation animation will be dismissed).
-            // Don't do the rotation now, but make a note to perform the rotation later.
-            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation.");
-            if (rotation != WindowManagerPolicy.USE_LAST_ROTATION) {
-                mDeferredRotation = rotation;
-                mDeferredRotationAnimFlags = animFlags;
-            }
+    public boolean updateRotationUncheckedLocked(boolean inTransaction) {
+        if (mDeferredRotationPauseCount > 0) {
+            // Rotation updates have been paused temporarily.  Defer the update until
+            // updates have been resumed.
+            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, rotation is paused.");
             return false;
         }
 
-        boolean changed;
-        if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
-            if (mDeferredRotation != WindowManagerPolicy.USE_LAST_ROTATION) {
-                rotation = mDeferredRotation;
-                mRequestedRotation = rotation;
-                mLastRotationFlags = mDeferredRotationAnimFlags;
+        if (mScreenRotationAnimation != null && mScreenRotationAnimation.isAnimating()) {
+            // Rotation updates cannot be performed while the previous rotation change
+            // animation is still in progress.  Skip this update.  We will try updating
+            // again after the animation is finished and the display is unfrozen.
+            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, animation in progress.");
+            return false;
+        }
+
+        if (!mDisplayEnabled) {
+            // No point choosing a rotation if the display is not enabled.
+            if (DEBUG_ORIENTATION) Slog.v(TAG, "Deferring rotation, display is not enabled.");
+            return false;
+        }
+
+        // TODO: Implement forced rotation changes.
+        //       Set mAltOrientation to indicate that the application is receiving
+        //       an orientation that has different metrics than it expected.
+        //       eg. Portrait instead of Landscape.
+
+        int rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation, mRotation);
+        boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
+                mForcedAppOrientation, rotation);
+
+        if (DEBUG_ORIENTATION) {
+            Slog.v(TAG, "Application requested orientation "
+                    + mForcedAppOrientation + ", got rotation " + rotation
+                    + " which has " + (altOrientation ? "incompatible" : "compatible")
+                    + " metrics");
+        }
+
+        if (mRotation == rotation && mAltOrientation == altOrientation) {
+            // No change.
+            return false;
+        }
+
+        if (DEBUG_ORIENTATION) {
+            Slog.v(TAG,
+                "Rotation changed to " + rotation + (altOrientation ? " (alt)" : "")
+                + " from " + mRotation + (mAltOrientation ? " (alt)" : "")
+                + ", forceApp=" + mForcedAppOrientation);
+        }
+
+        mRotation = rotation;
+        mAltOrientation = altOrientation;
+
+        mWindowsFreezingScreen = true;
+        mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
+        mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT), 2000);
+        mWaitingForConfig = true;
+        mLayoutNeeded = true;
+        startFreezingDisplayLocked(inTransaction);
+        mInputManager.setDisplayOrientation(0, rotation);
+
+        // NOTE: We disable the rotation in the emulator because
+        //       it doesn't support hardware OpenGL emulation yet.
+        if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
+                && mScreenRotationAnimation.hasScreenshot()) {
+            Surface.freezeDisplay(0);
+            if (!inTransaction) {
+                if (SHOW_TRANSACTIONS) Slog.i(TAG,
+                        ">>> OPEN TRANSACTION setRotationUnchecked");
+                Surface.openTransaction();
             }
-            rotation = mRequestedRotation;
+            try {
+                if (mScreenRotationAnimation != null) {
+                    mScreenRotationAnimation.setRotation(rotation);
+                }
+            } finally {
+                if (!inTransaction) {
+                    Surface.closeTransaction();
+                    if (SHOW_TRANSACTIONS) Slog.i(TAG,
+                            "<<< CLOSE TRANSACTION setRotationUnchecked");
+                }
+            }
+            Surface.setOrientation(0, rotation);
+            Surface.unfreezeDisplay(0);
         } else {
-            mRequestedRotation = rotation;
-            mLastRotationFlags = animFlags;
+            Surface.setOrientation(0, rotation);
         }
-        mDeferredRotation = WindowManagerPolicy.USE_LAST_ROTATION;
-        if (DEBUG_ORIENTATION) Slog.v(TAG, "Overwriting rotation value from " + rotation);
-        rotation = mPolicy.rotationForOrientationLw(mForcedAppOrientation,
-                mRotation, mDisplayEnabled);
-        if (DEBUG_ORIENTATION) Slog.v(TAG, "new rotation is set to " + rotation);
+        rebuildBlackFrame(inTransaction);
 
-        int desiredRotation = rotation;
-        int lockedRotation = mPolicy.getLockedRotationLw();
-        if (lockedRotation >= 0 && rotation != lockedRotation) {
-            // We are locked in a rotation but something is requesting
-            // a different rotation...  we will either keep the locked
-            // rotation if it results in the same orientation, or have to
-            // switch into an emulated orientation mode.
-
-            // First, we know that our rotation is actually going to be
-            // the locked rotation.
-            rotation = lockedRotation;
-
-            // Now the difference between the desired and lockedRotation
-            // may mean that the orientation is different...  if that is
-            // not the case, we can just make the desired rotation be the
-            // same as the new locked rotation.
-            switch (lockedRotation) {
-                case Surface.ROTATION_0:
-                    if (rotation == Surface.ROTATION_180) {
-                        desiredRotation = lockedRotation;
-                    }
-                    break;
-                case Surface.ROTATION_90:
-                    if (rotation == Surface.ROTATION_270) {
-                        desiredRotation = lockedRotation;
-                    }
-                    break;
-                case Surface.ROTATION_180:
-                    if (rotation == Surface.ROTATION_0) {
-                        desiredRotation = lockedRotation;
-                    }
-                    break;
-                case Surface.ROTATION_270:
-                    if (rotation == Surface.ROTATION_90) {
-                        desiredRotation = lockedRotation;
-                    }
-                    break;
+        for (int i=mWindows.size()-1; i>=0; i--) {
+            WindowState w = mWindows.get(i);
+            if (w.mSurface != null) {
+                w.mOrientationChanging = true;
             }
         }
-
-        changed = mDisplayEnabled && mRotation != rotation;
-        if (mAltOrientation != (rotation != desiredRotation)) {
-            changed = true;
-            mAltOrientation = rotation != desiredRotation;
+        for (int i=mRotationWatchers.size()-1; i>=0; i--) {
+            try {
+                mRotationWatchers.get(i).onRotationChanged(rotation);
+            } catch (RemoteException e) {
+            }
         }
-
-        if (changed) {
-            if (DEBUG_ORIENTATION) Slog.v(TAG,
-                    "Rotation changed to " + rotation
-                    + " from " + mRotation
-                    + " (forceApp=" + mForcedAppOrientation
-                    + ", req=" + mRequestedRotation + ")");
-            mRotation = rotation;
-            mWindowsFreezingScreen = true;
-            mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
-            mH.sendMessageDelayed(mH.obtainMessage(H.WINDOW_FREEZE_TIMEOUT),
-                    2000);
-            mWaitingForConfig = true;
-            mLayoutNeeded = true;
-            startFreezingDisplayLocked(inTransaction);
-            //Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
-            mInputManager.setDisplayOrientation(0, rotation);
-            if (mDisplayEnabled) {
-                // NOTE: We disable the rotation in the emulator because
-                //       it doesn't support hardware OpenGL emulation yet.
-                if (CUSTOM_SCREEN_ROTATION && mScreenRotationAnimation != null
-                        && mScreenRotationAnimation.hasScreenshot()) {
-                    Surface.freezeDisplay(0);
-                    if (!inTransaction) {
-                        if (SHOW_TRANSACTIONS) Slog.i(TAG,
-                                ">>> OPEN TRANSACTION setRotationUnchecked");
-                        Surface.openTransaction();
-                    }
-                    try {
-                        if (mScreenRotationAnimation != null) {
-                            mScreenRotationAnimation.setRotation(rotation);
-                        }
-                    } finally {
-                        if (!inTransaction) {
-                            Surface.closeTransaction();
-                            if (SHOW_TRANSACTIONS) Slog.i(TAG,
-                                    "<<< CLOSE TRANSACTION setRotationUnchecked");
-                        }
-                    }
-                    Surface.setOrientation(0, rotation, animFlags);
-                    Surface.unfreezeDisplay(0);
-                } else {
-                    Surface.setOrientation(0, rotation, animFlags);
-                }
-                rebuildBlackFrame(inTransaction);
-            }
-
-            for (int i=mWindows.size()-1; i>=0; i--) {
-                WindowState w = mWindows.get(i);
-                if (w.mSurface != null) {
-                    w.mOrientationChanging = true;
-                }
-            }
-            for (int i=mRotationWatchers.size()-1; i>=0; i--) {
-                try {
-                    mRotationWatchers.get(i).onRotationChanged(rotation);
-                } catch (RemoteException e) {
-                }
-            }
-        } //end if changed
-
-        return changed;
+        return true;
     }
 
     public int getRotation() {
@@ -5723,9 +5721,9 @@
             unrotDh = dh;
         }
         int sw = reduceConfigWidthSize(unrotDw, Surface.ROTATION_0, density, unrotDw, unrotDh);
-        sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDw, unrotDh);
+        sw = reduceConfigWidthSize(sw, Surface.ROTATION_90, density, unrotDh, unrotDw);
         sw = reduceConfigWidthSize(sw, Surface.ROTATION_180, density, unrotDw, unrotDh);
-        sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDw, unrotDh);
+        sw = reduceConfigWidthSize(sw, Surface.ROTATION_270, density, unrotDh, unrotDw);
         return sw;
     }
 
@@ -6295,6 +6293,7 @@
         public static final int DRAG_END_TIMEOUT = 21;
         public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22;
         public static final int BOOT_TIMEOUT = 23;
+        public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
 
         private Session mLastReportedHold;
 
@@ -6605,11 +6604,6 @@
                     break;
                 }
 
-                case BOOT_TIMEOUT: {
-                    performBootTimeout();
-                    break;
-                }
-
                 case APP_FREEZE_TIMEOUT: {
                     synchronized (mWindowMap) {
                         Slog.w(TAG, "App freeze timeout expired.");
@@ -6678,6 +6672,27 @@
                     notifyHardKeyboardStatusChange();
                     break;
                 }
+
+                case BOOT_TIMEOUT: {
+                    performBootTimeout();
+                    break;
+                }
+
+                case WAITING_FOR_DRAWN_TIMEOUT: {
+                    Pair<WindowState, IRemoteCallback> pair;
+                    synchronized (mWindowMap) {
+                        pair = (Pair<WindowState, IRemoteCallback>)msg.obj;
+                        Slog.w(TAG, "Timeout waiting for drawn: " + pair.first);
+                        if (!mWaitingForDrawn.remove(pair)) {
+                            return;
+                        }
+                    }
+                    try {
+                        pair.second.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                    break;
+                }
             }
         }
     }
@@ -8112,10 +8127,10 @@
 
                             w.mLastContentInsets.set(w.mContentInsets);
                             w.mLastVisibleInsets.set(w.mVisibleInsets);
-                            // If the screen is currently frozen, then keep
-                            // it frozen until this window draws at its new
+                            // If the screen is currently frozen or off, then keep
+                            // it frozen/off until this window draws at its new
                             // orientation.
-                            if (mDisplayFrozen) {
+                            if (mDisplayFrozen || !mPolicy.isScreenOnFully()) {
                                 if (DEBUG_ORIENTATION) Slog.v(TAG,
                                         "Resizing while display frozen: " + w);
                                 w.mOrientationChanging = true;
@@ -8383,7 +8398,7 @@
 
             if (mDimAnimator != null && mDimAnimator.mDimShown) {
                 animating |= mDimAnimator.updateSurface(dimming, currentTime,
-                        mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOn());
+                        mDisplayFrozen || !mDisplayEnabled || !mPolicy.isScreenOnFully());
             }
 
             if (!blurring && mBlurShown) {
@@ -8575,46 +8590,64 @@
 
         if (updateRotation) {
             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
-            boolean changed = setRotationUncheckedLocked(
-                    WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
+            boolean changed = updateRotationUncheckedLocked(false);
             if (changed) {
                 mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
+            } else {
+                updateRotation = false;
             }
         }
 
-        mWindowMap.notifyAll();
+        if (orientationChangeComplete && !needRelayout && !updateRotation) {
+            checkDrawnWindowsLocked();
+        }
 
         // Check to see if we are now in a state where the screen should
         // be enabled, because the window obscured flags have changed.
         enableScreenIfNeededLocked();
     }
 
-    public void waitForAllDrawn() {
+    void checkDrawnWindowsLocked() {
+        if (mWaitingForDrawn.size() > 0) {
+            for (int j=mWaitingForDrawn.size()-1; j>=0; j--) {
+                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(j);
+                WindowState win = pair.first;
+                //Slog.i(TAG, "Waiting for drawn " + win + ": removed="
+                //        + win.mRemoved + " visible=" + win.isVisibleLw()
+                //        + " shown=" + win.mSurfaceShown);
+                if (win.mRemoved || !win.isVisibleLw()) {
+                    // Window has been removed or made invisible; no draw
+                    // will now happen, so stop waiting.
+                    Slog.w(TAG, "Aborted waiting for drawn: " + pair.first);
+                    try {
+                        pair.second.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                    mWaitingForDrawn.remove(pair);
+                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+                } else if (win.mSurfaceShown) {
+                    // Window is now drawn (and shown).
+                    try {
+                        pair.second.sendResult(null);
+                    } catch (RemoteException e) {
+                    }
+                    mWaitingForDrawn.remove(pair);
+                    mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+                }
+            }
+        }
+    }
+
+    public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
         synchronized (mWindowMap) {
-            while (true) {
-                final int N = mWindows.size();
-                boolean okay = true;
-                for (int i=0; i<N && okay; i++) {
-                    WindowState w = mWindows.get(i);
-                    if (DEBUG_SCREEN_ON) {
-                        Slog.i(TAG, "Window " + w + " vis=" + w.isVisibleLw()
-                                + " obscured=" + w.mObscured + " drawn=" + w.isDrawnLw());
-                    }
-                    if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
-                        if (DEBUG_SCREEN_ON) {
-                            Slog.i(TAG, "Window not yet drawn: " + w);
-                        }
-                        okay = false;
-                        break;
-                    }
-                }
-                if (okay) {
-                    return;
-                }
-                try {
-                    mWindowMap.wait();
-                } catch (InterruptedException e) {
-                }
+            WindowState win = windowForClientLocked(null, token, true);
+            if (win != null) {
+                Pair<WindowState, IRemoteCallback> pair =
+                        new Pair<WindowState, IRemoteCallback>(win, callback);
+                Message m = mH.obtainMessage(H.WAITING_FOR_DRAWN_TIMEOUT, pair);
+                mH.sendMessageDelayed(m, 2000);
+                mWaitingForDrawn.add(pair);
+                checkDrawnWindowsLocked();
             }
         }
     }
@@ -8885,7 +8918,7 @@
             return;
         }
 
-        if (mDisplay == null || !mPolicy.isScreenOn()) {
+        if (mDisplay == null || !mPolicy.isScreenOnFully()) {
             // No need to freeze the screen before the system is ready or if
             // the screen is off.
             return;
@@ -8984,8 +9017,7 @@
         
         if (updateRotation) {
             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
-            configChanged |= setRotationUncheckedLocked(
-                    WindowManagerPolicy.USE_LAST_ROTATION, 0, false);
+            configChanged |= updateRotationUncheckedLocked(false);
         }
         
         if (configChanged) {
@@ -9284,6 +9316,15 @@
                 }
             }
         }
+        if (mWaitingForDrawn.size() > 0) {
+            pw.println();
+            pw.println("  Clients waiting for these windows to be drawn:");
+            for (int i=mWaitingForDrawn.size()-1; i>=0; i--) {
+                Pair<WindowState, IRemoteCallback> pair = mWaitingForDrawn.get(i);
+                pw.print("  Waiting #"); pw.print(i); pw.print(' '); pw.print(pair.first);
+                        pw.print(": "); pw.println(pair.second);
+            }
+        }
         pw.println();
         if (mDisplay != null) {
             pw.print("  Display: init="); pw.print(mInitialDisplayWidth); pw.print("x");
@@ -9349,12 +9390,10 @@
                     pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
                     pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
             pw.print("  mRotation="); pw.print(mRotation);
-                    pw.print(" mRequestedRotation="); pw.print(mRequestedRotation);
                     pw.print(" mAltOrientation="); pw.println(mAltOrientation);
             pw.print("  mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
                     pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
-            pw.print("  mDeferredRotation="); pw.print(mDeferredRotation);
-                    pw.print(", mDeferredRotationAnimFlags="); pw.println(mDeferredRotationAnimFlags);
+            pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
             pw.print("  mAnimationPending="); pw.print(mAnimationPending);
                     pw.print(" mWindowAnimationScale="); pw.print(mWindowAnimationScale);
                     pw.print(" mTransitionWindowAnimationScale="); pw.println(mTransitionAnimationScale);
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 0ee3f17..455d6649 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -870,7 +870,7 @@
     // This must be called while inside a transaction.  Returns true if
     // there is more animation to run.
     boolean stepAnimationLocked(long currentTime, int dw, int dh) {
-        if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) {
+        if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
             // We will run animations as long as the display isn't frozen.
 
             if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
@@ -1101,7 +1101,20 @@
             final Matrix tmpMatrix = mTmpMatrix;
 
             // Compute the desired transformation.
-            tmpMatrix.setTranslate(0, 0);
+            if (screenAnimation) {
+                // If we are doing a screen animation, the global rotation
+                // applied to windows can result in windows that are carefully
+                // aligned with each other to slightly separate, allowing you
+                // to see what is behind them.  An unsightly mess.  This...
+                // thing...  magically makes it call good: scale each window
+                // slightly (two pixels larger in each dimension, from the
+                // window's center).
+                final float w = frame.width();
+                final float h = frame.height();
+                tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
+            } else {
+                tmpMatrix.reset();
+            }
             tmpMatrix.postScale(mGlobalScale, mGlobalScale);
             if (selfTransformation) {
                 tmpMatrix.postConcat(mTransformation.getMatrix());
@@ -1204,11 +1217,18 @@
      * mPolicyVisibility.  Ungh.
      */
     public boolean isVisibleOrBehindKeyguardLw() {
+        if (mRootToken.waitingToShow &&
+                mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
+            return false;
+        }
         final AppWindowToken atoken = mAppToken;
-        return mSurface != null && !mAttachedHidden
+        final boolean animating = atoken != null
+                ? (atoken.animation != null) : false;
+        return mSurface != null && !mDestroying && !mExiting
                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
-                && !mDrawPending && !mCommitDrawPending
-                && !mExiting && !mDestroying;
+                && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
+                                && !mRootToken.hidden)
+                        || mAnimation != null || animating);
     }
 
     /**
@@ -1351,7 +1371,7 @@
                 && (mFrame.top != mLastFrame.top
                         || mFrame.left != mLastFrame.left)
                 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
-                && mService.mPolicy.isScreenOn();
+                && mService.mPolicy.isScreenOnFully();
     }
 
     boolean isFullscreen(int screenWidth, int screenHeight) {
@@ -1436,7 +1456,7 @@
         if (doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
                     + mPolicyVisibility + " mAnimation=" + mAnimation);
-            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
                 doAnimation = false;
             } else if (mPolicyVisibility && mAnimation == null) {
                 // Check for the case where we are currently visible and
@@ -1462,7 +1482,7 @@
 
     boolean hideLw(boolean doAnimation, boolean requestAnim) {
         if (doAnimation) {
-            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
+            if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOnFully()) {
                 doAnimation = false;
             }
         }
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index edbc7b0..f85ce7f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -404,7 +404,9 @@
 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
 {
     if (mQueuedFrames > 0) {
+        // Capture the old state of the layer for comparisons later
         const bool oldOpacity = isOpaque();
+        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
 
         // signal another event if we have more frames pending
         if (android_atomic_dec(&mQueuedFrames) > 1) {
@@ -417,7 +419,8 @@
             return;
         }
 
-        sp<GraphicBuffer> newFrontBuffer(mSurfaceTexture->getCurrentBuffer());
+        // update the active buffer
+        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
 
         const Rect crop(mSurfaceTexture->getCurrentCrop());
         const uint32_t transform(mSurfaceTexture->getCurrentTransform());
@@ -439,16 +442,16 @@
             mFlinger->invalidateHwcGeometry();
         }
 
-        uint32_t bufWidth  = newFrontBuffer->getWidth();
-        uint32_t bufHeight = newFrontBuffer->getHeight();
-        if (mActiveBuffer != NULL) {
-            if (bufWidth != uint32_t(mActiveBuffer->width) ||
-                bufHeight != uint32_t(mActiveBuffer->height)) {
+        uint32_t bufWidth  = mActiveBuffer->getWidth();
+        uint32_t bufHeight = mActiveBuffer->getHeight();
+        if (oldActiveBuffer != NULL) {
+            if (bufWidth != uint32_t(oldActiveBuffer->width) ||
+                bufHeight != uint32_t(oldActiveBuffer->height)) {
                 mFlinger->invalidateHwcGeometry();
             }
         }
 
-        mCurrentOpacity = getOpacityForFormat(newFrontBuffer->format);
+        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
         if (oldOpacity != isOpaque()) {
             recomputeVisibleRegions = true;
         }
@@ -462,9 +465,6 @@
         // FIXME: mPostedDirtyRegion = dirty & bounds
         mPostedDirtyRegion.set(front.w, front.h);
 
-        // update active buffer
-        mActiveBuffer = newFrontBuffer;
-
         if ((front.w != front.requested_w) ||
             (front.h != front.requested_h))
         {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0ef03bb..09097ee 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -566,7 +566,7 @@
 
             const int dpy = 0;
             const int orientation = mCurrentState.orientation;
-            const uint32_t type = mCurrentState.orientationType;
+            // Currently unused: const uint32_t flags = mCurrentState.orientationFlags;
             GraphicPlane& plane(graphicPlane(dpy));
             plane.setOrientation(orientation);
 
@@ -1299,7 +1299,7 @@
     Mutex::Autolock _l(mStateLock);
     if (mCurrentState.orientation != orientation) {
         if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
-            mCurrentState.orientationType = flags;
+            mCurrentState.orientationFlags = flags;
             mCurrentState.orientation = orientation;
             setTransactionFlags(eTransactionNeeded);
             mTransactionCV.wait(mStateLock);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d7f005f..43191b7 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -245,7 +245,7 @@
         }
         LayerVector     layersSortedByZ;
         uint8_t         orientation;
-        uint8_t         orientationType;
+        uint8_t         orientationFlags;
         uint8_t         freezeDisplay;
     };
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 2a25866..ab1597c 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -21,7 +21,6 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
-import static com.android.server.NetworkManagementSocketTagger.tagToKernel;
 
 import android.content.res.Resources;
 import android.net.NetworkStats;
@@ -144,12 +143,6 @@
     }
 
     public void testKernelTags() throws Exception {
-        assertEquals("0", tagToKernel(0x0));
-        assertEquals("214748364800", tagToKernel(0x32));
-        assertEquals("9223372032559808512", tagToKernel(Integer.MAX_VALUE));
-        assertEquals("0", tagToKernel(Integer.MIN_VALUE));
-        assertEquals("9223369837831520256", tagToKernel(Integer.MIN_VALUE - 512));
-
         assertEquals(0, kernelToTag("0x0000000000000000"));
         assertEquals(0x32, kernelToTag("0x0000003200000000"));
         assertEquals(2147483647, kernelToTag("0x7fffffff00000000"));
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index e898aac..3e8d255 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
+import android.location.CountryDetector;
 import android.net.Uri;
 import android.os.SystemProperties;
 import android.provider.Contacts;
@@ -1573,6 +1574,32 @@
     }
 
     /**
+     * Checks if a given number is an emergency number for the country that the user is in. The
+     * current country is determined using the CountryDetector.
+     *
+     * @param number the number to look up.
+     * @param context the specific context which the number should be checked against
+     * @return if a phone number is an emergency number for a local country, based on the
+     * CountryDetector.
+     * @see android.location.CountryDetector
+     * @hide
+     */
+    public static boolean isLocalEmergencyNumber(String number, Context context) {
+        String countryIso;
+        CountryDetector detector = (CountryDetector) context.getSystemService(
+                Context.COUNTRY_DETECTOR);
+        if (detector != null) {
+            countryIso = detector.detectCountry().getCountryIso();
+        } else {
+            Locale locale = context.getResources().getConfiguration().locale;
+            countryIso = locale.getCountry();
+            Log.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: "
+                    + countryIso);
+        }
+        return isEmergencyNumber(number, countryIso);
+    }
+
+    /**
      * isVoiceMailNumber: checks a given number against the voicemail
      *   number provided by the RIL and SIM card. The caller must have
      *   the READ_PHONE_STATE credential.
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 7c37a65..6324550 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -254,9 +254,7 @@
         // Change the callerInfo number ONLY if it is an emergency number
         // or if it is the voicemail number.  If it is either, take a
         // shortcut and skip the query.
-        Locale locale = context.getResources().getConfiguration().locale;
-        String countryIso = getCurrentCountryIso(context, locale);
-        if (PhoneNumberUtils.isEmergencyNumber(number, countryIso)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
             return new CallerInfo().markAsEmergency(context);
         } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
             return new CallerInfo().markAsVoiceMail();
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 17734ca..4912749 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -403,9 +403,7 @@
         cw.number = number;
 
         // check to see if these are recognized numbers, and use shortcuts if we can.
-        CountryDetector detector = (CountryDetector) context.getSystemService(
-            Context.COUNTRY_DETECTOR);
-        if (PhoneNumberUtils.isEmergencyNumber(number, detector.detectCountry().getCountryIso())) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(number, context)) {
             cw.event = EVENT_EMERGENCY_NUMBER;
         } else if (PhoneNumberUtils.isVoiceMailNumber(number)) {
             cw.event = EVENT_VOICEMAIL_NUMBER;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index db19321..83efc51 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -190,7 +190,8 @@
 
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
         boolean isPhoneInEcmMode = inEcm.equals("true");
-        boolean isEmergencyCall = PhoneNumberUtils.isEmergencyNumber(dialString);
+        boolean isEmergencyCall =
+                PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext());
 
         // Cancel Ecm timer if a second emergency call is originating in Ecm mode
         if (isPhoneInEcmMode && isEmergencyCall) {
@@ -1059,7 +1060,7 @@
      * Disable data call when emergency call is connected
      */
     private void disableDataCallInEmergencyCall(String dialString) {
-        if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
             if (Phone.DEBUG_PHONE) log("disableDataCallInEmergencyCall");
             mIsInEmergencyCall = true;
             phone.mDataConnectionTracker.setInternalDataEnabled(false);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
index 680b3cd..3799894 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java
@@ -496,7 +496,7 @@
             return false;
         }
 
-        if (PhoneNumberUtils.isEmergencyNumber(dialString)) {
+        if (PhoneNumberUtils.isLocalEmergencyNumber(dialString, phone.getContext())) {
             return false;
         } else {
             return isShortCodeUSSD(dialString, phone);
diff --git a/test-runner/src/android/test/InstrumentationTestRunner.java b/test-runner/src/android/test/InstrumentationTestRunner.java
index c3d09ff..70cf89e 100644
--- a/test-runner/src/android/test/InstrumentationTestRunner.java
+++ b/test-runner/src/android/test/InstrumentationTestRunner.java
@@ -279,6 +279,7 @@
     private static final String LOG_TAG = "InstrumentationTestRunner";
 
     private final Bundle mResults = new Bundle();
+    private Bundle mArguments;
     private AndroidTestRunner mTestRunner;
     private boolean mDebug;
     private boolean mJustCount;
@@ -292,6 +293,7 @@
     @Override
     public void onCreate(Bundle arguments) {
         super.onCreate(arguments);
+        mArguments = arguments;
 
         // Apk paths used to search for test classes when using TestSuiteBuilders.
         String[] apkPaths =
@@ -379,6 +381,16 @@
         start();
     }
 
+    /**
+     * Get the Bundle object that contains the arguments
+     *
+     * @return the Bundle object
+     * @hide
+     */
+    public Bundle getBundle(){
+        return mArguments;
+    }
+
     List<Predicate<TestMethod>> getBuilderRequirements() {
         return new ArrayList<Predicate<TestMethod>>();
     }
diff --git a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
index 54adc249..b803b98 100644
--- a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
+++ b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java
@@ -72,6 +72,7 @@
      */
     private void fetchStats(NetworkTemplate template) {
         try {
+            mStatsService.forceUpdate();
             NetworkStats stats = mStatsService.getSummaryForAllUid(template, Long.MIN_VALUE,
                     Long.MAX_VALUE, false);
             reportStats(stats);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index f8c32dd..4ba2e18 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -286,11 +286,23 @@
         mWebView.stopLoading();
     }
 
+
+    //TODO: remove. this is temporary for bug investigation
+    @Override
+    public void finish() {
+      Exception e = new Exception("finish() call stack");
+      Log.d(LOGTAG, "finish stack trace", e);
+      super.finish();
+    }
+
     @Override
     protected void onDestroy() {
-        super.onDestroy();
+        //TODO: remove exception log. this is temporary for bug investigation
+        Exception e = new Exception("onDestroy stack trace");
+        Log.d(LOGTAG, "onDestroy stack trace", e);
         mWebView.destroy();
         mWebView = null;
+        super.onDestroy();
     }
 
     @Override
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index f015378..5df018e 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -412,9 +412,31 @@
     @SmallTest
     public void testSET_ORIENTATION() {
         try {
-            mWm.setRotation(0, true, 0);
+            mWm.updateRotation(true);
             mWm.getSwitchState(0);
-            fail("IWindowManager.setRotation did not throw SecurityException as"
+            fail("IWindowManager.updateRotation did not throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        } catch (RemoteException e) {
+            fail("Unexpected remote exception");
+        }
+
+        try {
+            mWm.freezeRotation();
+            mWm.getSwitchState(0);
+            fail("IWindowManager.freezeRotation did not throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        } catch (RemoteException e) {
+            fail("Unexpected remote exception");
+        }
+
+        try {
+            mWm.thawRotation();
+            mWm.getSwitchState(0);
+            fail("IWindowManager.thawRotation did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {
             // expected
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index ed29a78..940b290 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -24,6 +24,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
 import android.view.Display;
@@ -395,7 +396,7 @@
 
     }
 
-    public void setRotation(int arg0, boolean arg1, int arg2) throws RemoteException {
+    public void updateRotation(boolean arg0) throws RemoteException {
         // TODO Auto-generated method stub
 
     }
@@ -451,7 +452,7 @@
         return 0;
     }
 
-    public void waitForAllDrawn() {
+    public void waitForWindowDrawn(IBinder token, IRemoteCallback callback) {
         // TODO Auto-generated method stub
     }