Merge "Import translations. DO NOT MERGE" into jb-mr1-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2287859..14b3681 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -136,6 +136,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/ImageProcessing_intermediates)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/ImageProcessing2_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/ImageProcessing_intermediates)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/17.txt b/api/17.txt
index 7b2f161..ee9a973 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -29625,7 +29625,6 @@
     method protected void onTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
-    method protected void resetResolvedDrawables();
     method public void setAllCaps(boolean);
     method public final void setAutoLinkMask(int);
     method public void setCompoundDrawablePadding(int);
diff --git a/api/current.txt b/api/current.txt
index 7b2f161..ee9a973 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -29625,7 +29625,6 @@
     method protected void onTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean onTextContextMenuItem(int);
     method public void removeTextChangedListener(android.text.TextWatcher);
-    method protected void resetResolvedDrawables();
     method public void setAllCaps(boolean);
     method public final void setAutoLinkMask(int);
     method public void setCompoundDrawablePadding(int);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 463a18c..42c9d34 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -43,6 +43,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 
 import java.io.File;
 import java.lang.reflect.Field;
@@ -174,6 +175,11 @@
             return;
         }
 
+        if ("get-max-users".equals(op)) {
+            runGetMaxUsers();
+            return;
+        }
+
         try {
             if (args.length == 1) {
                 if (args[0].equalsIgnoreCase("-l")) {
@@ -1017,8 +1023,10 @@
             return;
         }
         try {
-            if (!mUm.removeUser(userId)) {
-                System.err.println("Error: couldn't remove user #" + userId + ".");
+            if (mUm.removeUser(userId)) {
+                System.out.println("Success: removed user");
+            } else {
+                System.err.println("Error: couldn't remove user id " + userId);
             }
         } catch (RemoteException e) {
             System.err.println(e.toString());
@@ -1042,6 +1050,11 @@
             System.err.println(PM_NOT_RUNNING_ERR);
         }
     }
+
+    public void runGetMaxUsers() {
+        System.out.println("Maximum supported users: " + UserManager.getMaxSupportedUsers());
+    }
+
     class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
         boolean finished;
         boolean result;
@@ -1118,6 +1131,19 @@
     }
 
     private void runClear() {
+        int userId = 0;
+        String option = nextOption();
+        if (option != null && option.equals("--user")) {
+            String optionData = nextOptionData();
+            if (optionData == null || !isNumber(optionData)) {
+                System.err.println("Error: no USER_ID specified");
+                showUsage();
+                return;
+            } else {
+                userId = Integer.parseInt(optionData);
+            }
+        }
+
         String pkg = nextArg();
         if (pkg == null) {
             System.err.println("Error: no package specified");
@@ -1127,8 +1153,7 @@
 
         ClearDataObserver obs = new ClearDataObserver();
         try {
-            // XXX TO DO: add user arg
-            if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, 0)) {
+            if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs, userId)) {
                 System.err.println("Failed");
             }
 
@@ -1166,7 +1191,7 @@
         return "unknown";
     }
 
-    private boolean isNumber(String s) {
+    private static boolean isNumber(String s) {
         try {
             Integer.parseInt(s);
         } catch (NumberFormatException nfe) {
@@ -1439,7 +1464,7 @@
         System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
         System.err.println("                  [--originating-uri <URI>] [--referrer <URI>] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
-        System.err.println("       pm clear PACKAGE");
+        System.err.println("       pm clear [--user USER_ID] PACKAGE");
         System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
         System.err.println("       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
@@ -1451,6 +1476,7 @@
         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
         System.err.println("       pm create-user USER_NAME");
         System.err.println("       pm remove-user USER_ID");
+        System.err.println("       pm get-max-users");
         System.err.println("");
         System.err.println("pm list packages: prints all packages, optionally only");
         System.err.println("  those whose package name contains the text in FILTER.  Options:");
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index df64035..b810b89 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -19,7 +19,9 @@
 import android.animation.LayoutTransition;
 import android.app.FragmentManager.BackStackEntry;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.util.AttributeSet;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -51,7 +53,11 @@
     private OnClickListener mParentClickListener;
 
     private OnBreadCrumbClickListener mOnBreadCrumbClickListener;
-    
+
+    private int mGravity;
+
+    private static final int DEFAULT_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
+
     /**
      * Interface to intercept clicks on the bread crumbs.
      */
@@ -80,6 +86,14 @@
 
     public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyle, 0);
+
+        mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
+                DEFAULT_GRAVITY);
+
+        a.recycle();
     }
 
     /**
@@ -159,16 +173,50 @@
 
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        // Eventually we should implement our own layout of the views,
-        // rather than relying on a linear layout.
+        // Eventually we should implement our own layout of the views, rather than relying on
+        // a single linear layout.
         final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-
-            int childRight = mPaddingLeft + child.getMeasuredWidth() - mPaddingRight;
-            int childBottom = mPaddingTop + child.getMeasuredHeight() - mPaddingBottom;
-            child.layout(mPaddingLeft, mPaddingTop, childRight, childBottom);
+        if (childCount == 0) {
+            return;
         }
+
+        final View child = getChildAt(0);
+
+        final int childTop = mPaddingTop;
+        final int childBottom = mPaddingTop + child.getMeasuredHeight() - mPaddingBottom;
+
+        int childLeft;
+        int childRight;
+
+        final int layoutDirection = getLayoutDirection();
+        final int horizontalGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
+        switch (Gravity.getAbsoluteGravity(horizontalGravity, layoutDirection)) {
+            case Gravity.RIGHT:
+                childRight = mRight - mLeft - mPaddingRight;
+                childLeft = childRight - child.getMeasuredWidth();
+                break;
+
+            case Gravity.CENTER_HORIZONTAL:
+                childLeft = mPaddingLeft + (mRight - mLeft - child.getMeasuredWidth()) / 2;
+                childRight = childLeft + child.getMeasuredWidth();
+                break;
+
+            case Gravity.LEFT:
+            default:
+                childLeft = mPaddingLeft;
+                childRight = childLeft + child.getMeasuredWidth();
+                break;
+        }
+
+        if (childLeft < mPaddingLeft) {
+            childLeft = mPaddingLeft;
+        }
+
+        if (childRight > mRight - mLeft - mPaddingRight) {
+            childRight = mRight - mLeft - mPaddingRight;
+        }
+
+        child.layout(childLeft, childTop, childRight, childBottom);
     }
 
     @Override
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 0941d71..2bec1c1 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import java.io.BufferedInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -91,7 +92,7 @@
         }
         return result;
     }
-    
+
     /**
      * Copy data from a source stream to destFile.
      * Return true if succeed, return false if failed.
@@ -143,12 +144,16 @@
      */
     public static String readTextFile(File file, int max, String ellipsis) throws IOException {
         InputStream input = new FileInputStream(file);
+        // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
+        // input stream, bytes read not equal to buffer size is not necessarily the correct
+        // indication for EOF; but it is true for BufferedInputStream due to its implementation.
+        BufferedInputStream bis = new BufferedInputStream(input);
         try {
             long size = file.length();
             if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
                 if (size > 0 && (max == 0 || size < max)) max = (int) size;
                 byte[] data = new byte[max + 1];
-                int length = input.read(data);
+                int length = bis.read(data);
                 if (length <= 0) return "";
                 if (length <= max) return new String(data, 0, length);
                 if (ellipsis == null) return new String(data, 0, max);
@@ -161,7 +166,7 @@
                     if (last != null) rolled = true;
                     byte[] tmp = last; last = data; data = tmp;
                     if (data == null) data = new byte[-max];
-                    len = input.read(data);
+                    len = bis.read(data);
                 } while (len == data.length);
 
                 if (last == null && len <= 0) return "";
@@ -178,12 +183,13 @@
                 int len;
                 byte[] data = new byte[1024];
                 do {
-                    len = input.read(data);
+                    len = bis.read(data);
                     if (len > 0) contents.write(data, 0, len);
                 } while (len == data.length);
                 return contents.toString();
             }
         } finally {
+            bis.close();
             input.close();
         }
     }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2739cac..898c766 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -320,6 +320,8 @@
      * @return a value greater than or equal to 1 
      */
     public static int getMaxSupportedUsers() {
+        // Don't allow multiple users on certain builds
+        if (android.os.Build.ID.startsWith("JVP")) return 1;
         return SystemProperties.getInt("fw.max_users",
                 Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
     }
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index de4dd88..affeb90 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -283,6 +283,8 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
         synchronized (mSearchables) {
             for (int i = 0; i < mSearchables.size(); i++) {
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index c72b714..4820c5e 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -612,18 +612,23 @@
                     View.SYSTEM_UI_FLAG_LOW_PROFILE);
             getWindowManager().addView(mWindow.getDecorView(), mWindow.getAttributes());
         } catch (Throwable t) {
-            Slog.w("Crashed adding window view", t);
+            Slog.w(TAG, "Crashed adding window view", t);
             safelyFinish();
             return;
         }
 
         // start it up
-        try {
-            onDreamingStarted();
-        } catch (Throwable t) {
-            Slog.w("Crashed in onDreamingStarted()", t);
-            safelyFinish();
-        }
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    onDreamingStarted();
+                } catch (Throwable t) {
+                    Slog.w(TAG, "Crashed in onDreamingStarted()", t);
+                    safelyFinish();
+                }
+            }
+        });
     }
 
     private void safelyFinish() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 37e0a36..ec1695e 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -925,8 +925,17 @@
             sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
             Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);
 
+            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
+            Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);
+
+            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
+            Log.d(LOG_TAG, "  SAMPLES = " + value[0]);
+
             sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
             Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
+
+            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
+            Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
         }
 
         GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException {
@@ -1433,6 +1442,7 @@
                     EGL_BLUE_SIZE, 8,
                     EGL_ALPHA_SIZE, 8,
                     EGL_DEPTH_SIZE, 0,
+                    EGL_CONFIG_CAVEAT, EGL_NONE,
                     // TODO: Find a better way to choose the stencil size
                     EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0,
                     EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 07bb8f9..7ef6939 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -245,6 +245,7 @@
 
     private static native void nativeOpenTransaction();
     private static native void nativeCloseTransaction();
+    private static native void nativeSetAnimationTransaction();
 
     private native void nativeSetLayer(int zorder);
     private native void nativeSetPosition(float x, float y);
@@ -525,6 +526,11 @@
         nativeCloseTransaction();
     }
 
+    /** flag the transaction as an animation @hide */
+    public static void setAnimationTransaction() {
+        nativeSetAnimationTransaction();
+    }
+
     /** @hide */
     public void setLayer(int zorder) {
         nativeSetLayer(zorder);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 608bdd7..158e0c0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3666,15 +3666,10 @@
             // Padding from the background drawable is stored at this point in mUserPaddingLeftInitial
             // and mUserPaddingRightInitial) so drawable padding will be used as ultimate default if
             // defined.
-            if (startPaddingDefined) {
-                mUserPaddingLeftInitial = startPadding;
-            } else if (leftPaddingDefined) {
+            if (leftPaddingDefined) {
                 mUserPaddingLeftInitial = leftPadding;
             }
-            if (endPaddingDefined) {
-                mUserPaddingRightInitial = endPadding;
-            }
-            else if (rightPaddingDefined) {
+            if (rightPaddingDefined) {
                 mUserPaddingRightInitial = rightPadding;
             }
         }
@@ -10520,9 +10515,6 @@
      * <p>Causes the Runnable to be added to the message queue.
      * The runnable will be run on the user interface thread.</p>
      *
-     * <p>This method can be invoked from outside of the UI thread
-     * only when this View is attached to a window.</p>
-     *
      * @param action The Runnable that will be executed.
      *
      * @return Returns true if the Runnable was successfully placed in to the
@@ -10547,9 +10539,6 @@
      * after the specified amount of time elapses.
      * The runnable will be run on the user interface thread.</p>
      *
-     * <p>This method can be invoked from outside of the UI thread
-     * only when this View is attached to a window.</p>
-     *
      * @param action The Runnable that will be executed.
      * @param delayMillis The delay (in milliseconds) until the Runnable
      *        will be executed.
@@ -10578,9 +10567,6 @@
      * <p>Causes the Runnable to execute on the next animation time step.
      * The runnable will be run on the user interface thread.</p>
      *
-     * <p>This method can be invoked from outside of the UI thread
-     * only when this View is attached to a window.</p>
-     *
      * @param action The Runnable that will be executed.
      *
      * @see #postOnAnimationDelayed
@@ -10602,9 +10588,6 @@
      * after the specified amount of time elapses.
      * The runnable will be run on the user interface thread.</p>
      *
-     * <p>This method can be invoked from outside of the UI thread
-     * only when this View is attached to a window.</p>
-     *
      * @param action The Runnable that will be executed.
      * @param delayMillis The delay (in milliseconds) until the Runnable
      *        will be executed.
@@ -10626,9 +10609,6 @@
     /**
      * <p>Removes the specified Runnable from the message queue.</p>
      *
-     * <p>This method can be invoked from outside of the UI thread
-     * only when this View is attached to a window.</p>
-     *
      * @param action The Runnable to remove from the message handling queue
      *
      * @return true if this view could ask the Handler to remove the Runnable,
@@ -11559,8 +11539,10 @@
 
     /**
      * Resolve all RTL related properties.
+     *
+     * @hide
      */
-    void resolveRtlPropertiesIfNeeded() {
+    public void resolveRtlPropertiesIfNeeded() {
         if (!needRtlPropertiesResolution()) return;
 
         // Order is important here: LayoutDirection MUST be resolved first
@@ -11584,8 +11566,12 @@
         onRtlPropertiesChanged(getLayoutDirection());
     }
 
-    // Reset resolution of all RTL related properties.
-    void resetRtlProperties() {
+    /**
+     * Reset resolution of all RTL related properties.
+     *
+     * @hide
+     */
+    public void resetRtlProperties() {
         resetResolvedLayoutDirection();
         resetResolvedTextDirection();
         resetResolvedTextAlignment();
@@ -14195,7 +14181,7 @@
      *
      * @hide
      */
-    public void resolveDrawables() {
+    protected void resolveDrawables() {
         if (mBackground != null) {
             mBackground.setLayoutDirection(getLayoutDirection());
         }
@@ -14218,7 +14204,10 @@
     public void onResolveDrawables(int layoutDirection) {
     }
 
-    private void resetResolvedDrawables() {
+    /**
+     * @hide
+     */
+    protected void resetResolvedDrawables() {
         mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
     }
 
@@ -14804,14 +14793,14 @@
         if (isRtlCompatibilityMode()) {
             mPaddingLeft = mUserPaddingLeftInitial;
             mPaddingRight = mUserPaddingRightInitial;
+            return;
+        }
+        if (isLayoutRtl()) {
+            mPaddingLeft = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingLeftInitial;
+            mPaddingRight = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingRightInitial;
         } else {
-            if (isLayoutRtl()) {
-                mPaddingLeft = mUserPaddingRightInitial;
-                mPaddingRight = mUserPaddingLeftInitial;
-            } else {
-                mPaddingLeft = mUserPaddingLeftInitial;
-                mPaddingRight = mUserPaddingRightInitial;
-            }
+            mPaddingLeft = (mUserPaddingStart >= 0) ? mUserPaddingStart : mUserPaddingLeftInitial;
+            mPaddingRight = (mUserPaddingEnd >= 0) ? mUserPaddingEnd : mUserPaddingRightInitial;
         }
     }
 
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 0661992..9ce7df9 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5263,6 +5263,21 @@
      * @hide
      */
     @Override
+    public void resolveRtlPropertiesIfNeeded() {
+        super.resolveRtlPropertiesIfNeeded();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resolveRtlPropertiesIfNeeded();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
     public boolean resolveLayoutDirection() {
         final boolean result = super.resolveLayoutDirection();
         if (result) {
@@ -5317,6 +5332,51 @@
      * @hide
      */
     @Override
+    public void resolvePadding() {
+        super.resolvePadding();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resolvePadding();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void resolveDrawables() {
+        super.resolveDrawables();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resolveDrawables();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void resetRtlProperties() {
+        super.resetRtlProperties();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resetRtlProperties();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
     public void resetResolvedLayoutDirection() {
         super.resetResolvedLayoutDirection();
 
@@ -5362,6 +5422,38 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public void resetResolvedPadding() {
+        super.resetResolvedPadding();
+
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resetResolvedPadding();
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    protected void resetResolvedDrawables() {
+        super.resetResolvedDrawables();
+
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.isLayoutDirectionInherited()) {
+                child.resetResolvedDrawables();
+            }
+        }
+    }
+
+    /**
      * Return true if the pressed state should be delayed for children or descendants of this
      * ViewGroup. Generally, this should be done for containers that can scroll, such as a List.
      * This prevents the pressed state from appearing when the user is actually trying to scroll
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index 357a16e..fe5cad4 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -97,9 +97,12 @@
     // Template for JavaScript that performs AndroidVox actions.
     private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE =
             "(function() {" +
-                    "  if ((typeof(cvox) != 'undefined')"+
+                    "  if ((typeof(cvox) != 'undefined')" +
+                    "      && (cvox != null)" +
                     "      && (typeof(cvox.ChromeVox) != 'undefined')" +
+                    "      && (cvox.ChromeVox != null)" +
                     "      && (typeof(cvox.AndroidVox) != 'undefined')" +
+                    "      && (cvox.AndroidVox != null)" +
                     "      && cvox.ChromeVox.isActive) {" +
                     "    return cvox.AndroidVox.performAction('%1s');" +
                     "  } else {" +
@@ -110,9 +113,12 @@
     // JS code used to shut down an active AndroidVox instance.
     private static final String TOGGLE_CVOX_TEMPLATE =
             "javascript:(function() {" +
-                    "  if ((typeof(cvox) != 'undefined')"+
+                    "  if ((typeof(cvox) != 'undefined')" +
+                    "      && (cvox != null)" +
                     "      && (typeof(cvox.ChromeVox) != 'undefined')" +
-                    "      && (typeof(cvox.ChromeVox.host) != 'undefined')) {" +
+                    "      && (cvox.ChromeVox != null)" +
+                    "      && (typeof(cvox.ChromeVox.host) != 'undefined')" +
+                    "      && (cvox.ChromeVox.host != null)) {" +
                     "    cvox.ChromeVox.host.activateOrDeactivateChromeVox(%b);" +
                     "  }" +
                     "})();";
@@ -132,33 +138,60 @@
     }
 
     /**
+     * If JavaScript is enabled, pauses or resumes AndroidVox.
+     *
+     * @param enabled Whether feedback should be enabled.
+     */
+    public void toggleAccessibilityFeedback(boolean enabled) {
+        if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) {
+            return;
+        }
+
+        toggleAndroidVox(enabled);
+
+        if (!enabled && (mTextToSpeech != null)) {
+            mTextToSpeech.stop();
+        }
+    }
+
+    /**
      * Attempts to load scripting interfaces for accessibility.
      * <p>
-     * This should be called when the window is attached.
-     * </p>
+     * This should only be called before a page loads.
      */
-    public void addAccessibilityApisIfNecessary() {
+    private void addAccessibilityApisIfNecessary() {
         if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) {
             return;
         }
 
         addTtsApis();
         addCallbackApis();
-        toggleAndroidVox(true);
     }
 
     /**
      * Attempts to unload scripting interfaces for accessibility.
      * <p>
-     * This should be called when the window is detached.
-     * </p>
+     * This should only be called before a page loads.
      */
-    public void removeAccessibilityApisIfNecessary() {
-        toggleAndroidVox(false);
+    private void removeAccessibilityApisIfNecessary() {
         removeTtsApis();
         removeCallbackApis();
     }
 
+    /**
+     * Destroys this accessibility injector.
+     */
+    public void destroy() {
+        if (mTextToSpeech != null) {
+            mTextToSpeech.shutdown();
+            mTextToSpeech = null;
+        }
+
+        if (mCallback != null) {
+            mCallback = null;
+        }
+    }
+
     private void toggleAndroidVox(boolean state) {
         if (!mAccessibilityScriptInjected) {
             return;
@@ -517,7 +550,12 @@
      *         settings.
      */
     private boolean isJavaScriptEnabled() {
-        return mWebView.getSettings().getJavaScriptEnabled();
+        final WebSettings settings = mWebView.getSettings();
+        if (settings == null) {
+            return false;
+        }
+
+        return settings.getJavaScriptEnabled();
     }
 
     /**
@@ -732,7 +770,7 @@
         private final String mInterfaceName;
 
         private boolean mResult = false;
-        private long mResultId = -1;
+        private int mResultId = -1;
 
         private CallbackHandler(String interfaceName) {
             mInterfaceName = interfaceName;
@@ -784,34 +822,46 @@
          * @return Whether the result was received.
          */
         private boolean waitForResultTimedLocked(int resultId) {
-            if (DEBUG)
-                Log.d(TAG, "Waiting for CVOX result...");
-            long waitTimeMillis = RESULT_TIMEOUT;
             final long startTimeMillis = SystemClock.uptimeMillis();
+
+            if (DEBUG)
+                Log.d(TAG, "Waiting for CVOX result with ID " + resultId + "...");
+
             while (true) {
+                // Fail if we received a callback from the future.
+                if (mResultId > resultId) {
+                    if (DEBUG)
+                        Log.w(TAG, "Aborted CVOX result");
+                    return false;
+                }
+
+                final long elapsedTimeMillis = (SystemClock.uptimeMillis() - startTimeMillis);
+
+                // Succeed if we received the callback we were expecting.
+                if (DEBUG)
+                    Log.w(TAG, "Check " + mResultId + " versus expected " + resultId);
+                if (mResultId == resultId) {
+                    if (DEBUG)
+                        Log.w(TAG, "Received CVOX result after " + elapsedTimeMillis + " ms");
+                    return true;
+                }
+
+                final long waitTimeMillis = (RESULT_TIMEOUT - elapsedTimeMillis);
+
+                // Fail if we've already exceeded the timeout.
+                if (waitTimeMillis <= 0) {
+                    if (DEBUG)
+                        Log.w(TAG, "Timed out while waiting for CVOX result");
+                    return false;
+                }
+
                 try {
-                    if (mResultId == resultId) {
-                        if (DEBUG)
-                            Log.w(TAG, "Received CVOX result");
-                        return true;
-                    }
-                    if (mResultId > resultId) {
-                        if (DEBUG)
-                            Log.w(TAG, "Obsolete CVOX result");
-                        return false;
-                    }
-                    final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                    waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis;
-                    if (waitTimeMillis <= 0) {
-                        if (DEBUG)
-                            Log.w(TAG, "Timed out while waiting for CVOX result");
-                        return false;
-                    }
+                    if (DEBUG)
+                        Log.w(TAG, "Start waiting...");
                     mResultLock.wait(waitTimeMillis);
                 } catch (InterruptedException ie) {
                     if (DEBUG)
                         Log.w(TAG, "Interrupted while waiting for CVOX result");
-                    /* ignore */
                 }
             }
         }
@@ -827,11 +877,11 @@
         @SuppressWarnings("unused")
         public void onResult(String id, String result) {
             if (DEBUG)
-                Log.w(TAG, "Saw CVOX result of '" + result + "'");
-            final long resultId;
+                Log.w(TAG, "Saw CVOX result of '" + result + "' for ID " + id);
+            final int resultId;
 
             try {
-                resultId = Long.parseLong(id);
+                resultId = Integer.parseInt(id);
             } catch (NumberFormatException e) {
                 return;
             }
@@ -840,6 +890,9 @@
                 if (resultId > mResultId) {
                     mResult = Boolean.parseBoolean(result);
                     mResultId = resultId;
+                } else {
+                    if (DEBUG)
+                        Log.w(TAG, "Result with ID " + resultId + " was stale vesus " + mResultId);
                 }
                 mResultLock.notifyAll();
             }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 7d0d0ba..0f8966e 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -2132,6 +2132,10 @@
 
     private void destroyJava() {
         mCallbackProxy.blockMessages();
+        if (mAccessibilityInjector != null) {
+            mAccessibilityInjector.destroy();
+            mAccessibilityInjector = null;
+        }
         if (mWebViewCore != null) {
             // Tell WebViewCore to destroy itself
             synchronized (this) {
@@ -3967,8 +3971,6 @@
         // null, and that will be the case
         mWebView.setCertificate(null);
 
-        // reset the flag since we set to true in if need after
-        // loading is see onPageFinished(Url)
         if (isAccessibilityInjectionEnabled()) {
             getAccessibilityInjector().onPageStarted(url);
         }
@@ -5397,7 +5399,7 @@
         if (mWebView.hasWindowFocus()) setActive(true);
 
         if (isAccessibilityInjectionEnabled()) {
-            getAccessibilityInjector().addAccessibilityApisIfNecessary();
+            getAccessibilityInjector().toggleAccessibilityFeedback(true);
         }
 
         updateHwAccelerated();
@@ -5410,11 +5412,7 @@
         if (mWebView.hasWindowFocus()) setActive(false);
 
         if (isAccessibilityInjectionEnabled()) {
-            getAccessibilityInjector().removeAccessibilityApisIfNecessary();
-        } else {
-            // Ensure the injector is cleared if we're detaching from the window
-            // and accessibility is disabled.
-            mAccessibilityInjector = null;
+            getAccessibilityInjector().toggleAccessibilityFeedback(false);
         }
 
         updateHwAccelerated();
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index e74e37c..de8b80d 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -188,10 +188,11 @@
         resetPaddingToInitialValues();
         int newPadding = (mCheckMarkDrawable != null) ?
                 mCheckMarkWidth + mBasePadding : mBasePadding;
-        mNeedRequestlayout |= (mPaddingRight != newPadding);
         if (isLayoutRtl()) {
+            mNeedRequestlayout |= (mPaddingLeft != newPadding);
             mPaddingLeft = newPadding;
         } else {
+            mNeedRequestlayout |= (mPaddingRight != newPadding);
             mPaddingRight = newPadding;
         }
         if (mNeedRequestlayout) {
@@ -200,18 +201,6 @@
         }
     }
 
-    @Override
-    public void setPadding(int left, int top, int right, int bottom) {
-        super.setPadding(left, top, right, bottom);
-        setBasePadding(isLayoutRtl());
-    }
-
-    @Override
-    public void setPaddingRelative(int start, int top, int end, int bottom) {
-        super.setPaddingRelative(start, top, end, bottom);
-        setBasePadding(isLayoutRtl());
-    }
-
     private void setBasePadding(boolean isLayoutRtl) {
         if (isLayoutRtl) {
             mBasePadding = mPaddingLeft;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 958b669..751ed7c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -367,6 +367,7 @@
     private boolean mSingleLine;
     private int mDesiredHeightAtMeasure = -1;
     private boolean mIncludePad = true;
+    private int mDeferScroll = -1;
 
     // tmp primitives, so we don't alloc them on each draw
     private Rect mTempRect;
@@ -6317,6 +6318,11 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
+        if (mDeferScroll >= 0) {
+            int curs = mDeferScroll;
+            mDeferScroll = -1;
+            bringPointIntoView(curs);
+        }
         if (changed && mEditor != null) mEditor.invalidateTextDisplayList();
     }
 
@@ -6399,6 +6405,10 @@
      * This has to be called after layout. Returns true if anything changed.
      */
     public boolean bringPointIntoView(int offset) {
+        if (isLayoutRequested()) {
+            mDeferScroll = offset;
+            return false;
+        }
         boolean changed = false;
 
         Layout layout = isShowingHint() ? mHintLayout: mLayout;
@@ -7108,13 +7118,13 @@
             registerForPreDraw();
         }
 
+        checkForResize();
+
         if (curs >= 0) {
             mHighlightPathBogus = true;
             if (mEditor != null) mEditor.makeBlink();
             bringPointIntoView(curs);
         }
-
-        checkForResize();
     }
 
     /**
@@ -7161,6 +7171,7 @@
 
             if (oldStart >= 0 || newStart >= 0) {
                 invalidateCursor(Selection.getSelectionStart(buf), oldStart, newStart);
+                checkForResize();
                 registerForPreDraw();
                 if (mEditor != null) mEditor.makeBlink();
             }
@@ -8314,6 +8325,9 @@
         }
     }
 
+    /**
+     * @hide
+     */
     protected void resetResolvedDrawables() {
         mResolvedDrawables = false;
     }
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index a2a38dc..4e405f4 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -25,7 +25,9 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
 import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
 import android.os.Vibrator;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -667,11 +669,16 @@
      * Triggers haptic feedback.
      */
     private synchronized void vibrate(long duration) {
-        if (mVibrator == null) {
-            mVibrator = (android.os.Vibrator)
-                    getContext().getSystemService(Context.VIBRATOR_SERVICE);
+        final boolean hapticEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+                UserHandle.USER_CURRENT) != 0;
+        if (hapticEnabled) {
+            if (mVibrator == null) {
+                mVibrator = (android.os.Vibrator) getContext()
+                        .getSystemService(Context.VIBRATOR_SERVICE);
+            }
+            mVibrator.vibrate(duration);
         }
-        mVibrator.vibrate(duration);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index f535a08..aebc4f6 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -21,7 +21,9 @@
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
 import android.os.Vibrator;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.Gravity;
@@ -811,11 +813,16 @@
      * Triggers haptic feedback.
      */
     private synchronized void vibrate(long duration) {
-        if (mVibrator == null) {
-            mVibrator = (android.os.Vibrator)
-                    getContext().getSystemService(Context.VIBRATOR_SERVICE);
+        final boolean hapticEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+                UserHandle.USER_CURRENT) != 0;
+        if (hapticEnabled) {
+            if (mVibrator == null) {
+                mVibrator = (android.os.Vibrator) getContext()
+                        .getSystemService(Context.VIBRATOR_SERVICE);
+            }
+            mVibrator.vibrate(duration);
         }
-        mVibrator.vibrate(duration);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index 2d89234..d33d50c 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -25,7 +25,9 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
+import android.os.UserHandle;
 import android.os.Vibrator;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -573,11 +575,16 @@
      * Triggers haptic feedback.
      */
     private synchronized void vibrate(long duration) {
-        if (mVibrator == null) {
-            mVibrator = (android.os.Vibrator)
-                    getContext().getSystemService(Context.VIBRATOR_SERVICE);
+        final boolean hapticEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+                UserHandle.USER_CURRENT) != 0;
+        if (hapticEnabled) {
+            if (mVibrator == null) {
+                mVibrator = (android.os.Vibrator) getContext()
+                        .getSystemService(Context.VIBRATOR_SERVICE);
+            }
+            mVibrator.vibrate(duration);
         }
-        mVibrator.vibrate(duration);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index f507a79..0f49776 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -31,7 +31,9 @@
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.os.Vibrator;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -543,7 +545,10 @@
     }
 
     private void vibrate() {
-        if (mVibrator != null) {
+        final boolean hapticEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+                UserHandle.USER_CURRENT) != 0;
+        if (mVibrator != null && hapticEnabled) {
             mVibrator.vibrate(mVibrationDuration);
         }
     }
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index 7990b4c..e22d1e8 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -32,7 +32,9 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.os.Vibrator;
+import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -593,7 +595,10 @@
     }
 
     private void vibrate() {
-        if (mVibrator != null) {
+        final boolean hapticEnabled = Settings.System.getIntForUser(
+                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+                UserHandle.USER_CURRENT) != 0;
+        if (mVibrator != null && hapticEnabled) {
             mVibrator.vibrate(mVibrationDuration);
         }
     }
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 1bba5b4..fd7a6a7 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -145,7 +145,7 @@
 static void ToColor_S4444_Opaque(SkColor dst[], const void* src, int width,

                                  SkColorTable*) {

     SkASSERT(width > 0);

-    const SkPMColor* s = (const SkPMColor*)src;

+    const SkPMColor16* s = (const SkPMColor16*)src;

     do {

         SkPMColor c = SkPixel4444ToPixel32(*s++);

         *dst++ = SkColorSetRGB(SkGetPackedR32(c), SkGetPackedG32(c),

diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 4982f31..531445f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -526,6 +526,10 @@
     SurfaceComposerClient::closeGlobalTransaction();
 }
 
+static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
+    SurfaceComposerClient::setAnimationTransaction();
+}
+
 static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint zorder) {
     sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
     if (surface == NULL) return;
@@ -819,6 +823,8 @@
             (void*)nativeOpenTransaction },
     {"nativeCloseTransaction", "()V",
             (void*)nativeCloseTransaction },
+    {"nativeSetAnimationTransaction", "()V",
+            (void*)nativeSetAnimationTransaction },
     {"nativeSetLayer", "(I)V",
             (void*)nativeSetLayer },
     {"nativeSetPosition", "(FF)V",
diff --git a/core/res/res/layout-land/keyguard_glow_pad_container.xml b/core/res/res/layout-land/keyguard_glow_pad_container.xml
new file mode 100644
index 0000000..f8364f1
--- /dev/null
+++ b/core/res/res/layout-land/keyguard_glow_pad_container.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/keyguard_glow_pad_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center" />
+</merge>
\ No newline at end of file
diff --git a/core/res/res/layout-land/keyguard_host_view.xml b/core/res/res/layout-land/keyguard_host_view.xml
index 6003b42..521853f 100644
--- a/core/res/res/layout-land/keyguard_host_view.xml
+++ b/core/res/res/layout-land/keyguard_host_view.xml
@@ -45,9 +45,6 @@
         android:paddingBottom="@dimen/keyguard_security_view_margin"
         android:gravity="center">
 
-        <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
-        <include layout="@layout/keyguard_selector_view"/>
-
     </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
diff --git a/core/res/res/layout-land/keyguard_status_area.xml b/core/res/res/layout-land/keyguard_status_area.xml
new file mode 100644
index 0000000..f562d9f
--- /dev/null
+++ b/core/res/res/layout-land/keyguard_status_area.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_status_area"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="end"
+    android:layout_marginTop="-16dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/kg_status_date_font_size"
+        />
+
+    <TextView
+        android:id="@+id/alarm_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        android:drawablePadding="4dip"
+        />
+
+    <TextView
+        android:id="@+id/owner_info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+
+    <TextView
+        android:id="@+id/status1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+
+    <TextView
+        android:id="@+id/status_security_message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:gravity="right"
+        android:layout_marginTop="12dp"
+        android:singleLine="false"
+        android:maxLines="3"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="16dp"
+        />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index 58e108c..20726d0 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -27,21 +27,21 @@
     android:gravity="center_horizontal"
     android:orientation="vertical">
 
+    <include layout="@layout/keyguard_widget_region"
+        android:layout_width="match_parent"
+        android:layout_height="153dp" />
+
     <com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper
         android:id="@+id/view_flipper"
-        android:layout_height="match_parent"
+        android:layout_height="0dp"
         android:clipChildren="false"
         android:clipToPadding="false"
+        android:layout_weight="1"
         android:paddingLeft="@dimen/keyguard_security_view_margin"
         android:paddingTop="@dimen/keyguard_security_view_margin"
         android:paddingRight="@dimen/keyguard_security_view_margin"
         android:paddingBottom="@dimen/keyguard_security_view_margin"
         android:gravity="center">
-
-        <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
-        <include layout="@layout/keyguard_selector_view"/>
-
     </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
-
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
 
diff --git a/core/res/res/layout-port/keyguard_status_area.xml b/core/res/res/layout-port/keyguard_status_area.xml
new file mode 100644
index 0000000..e0a49dc
--- /dev/null
+++ b/core/res/res/layout-port/keyguard_status_area.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_status_area"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="right"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="0dp"
+        android:layout_gravity="right">
+        <TextView
+            android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textSize="@dimen/kg_status_date_font_size"
+            />
+
+        <TextView
+            android:id="@+id/alarm_status"
+            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearance"
+            android:textSize="@dimen/kg_status_line_font_size"
+            android:drawablePadding="4dip"
+            />
+    </LinearLayout>
+
+    <TextView
+        android:id="@+id/owner_info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+
+    <TextView
+        android:id="@+id/status1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+
+    <TextView
+        android:id="@+id/status_security_message"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+        
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
index a3e9b59..23c1e9c 100644
--- a/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
+++ b/core/res/res/layout-sw600dp-port/keyguard_host_view.xml
@@ -45,8 +45,7 @@
         android:paddingBottom="@dimen/keyguard_security_view_margin"
         android:layout_gravity="center">
 
-        <!-- SelectorView is always used, so add it here. The rest are loaded dynamically -->
-        <include layout="@layout/keyguard_selector_view"/>
+
 
     </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
 
diff --git a/core/res/res/layout-sw600dp-port/keyguard_status_area.xml b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
new file mode 100644
index 0000000..f21254a
--- /dev/null
+++ b/core/res/res/layout-sw600dp-port/keyguard_status_area.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_status_area"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="end"
+    android:layout_marginTop="-16dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/date"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/kg_status_date_font_size"
+        />
+
+    <TextView
+        android:id="@+id/alarm_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="28dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        android:drawablePadding="4dip"
+        />
+
+    <TextView
+        android:id="@+id/owner_info"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+
+    <TextView
+        android:id="@+id/status1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end"
+        android:layout_marginTop="4dp"
+        android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearance"
+        android:textSize="@dimen/kg_status_line_font_size"
+        />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-sw600dp/keyguard_navigation.xml b/core/res/res/layout-sw600dp/keyguard_navigation.xml
new file mode 100644
index 0000000..2e6fa37
--- /dev/null
+++ b/core/res/res/layout-sw600dp/keyguard_navigation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/default_navigation" />
+</merge>
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
index 4f94f96..47d4728 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_landscape.xml
@@ -89,7 +89,6 @@
                     android:layout_weight="1"
                     android:gravity="center"
                     android:layout_gravity="center"
-                    android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
                     android:singleLine="true"
                     android:textStyle="normal"
                     android:inputType="textPassword"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
index 9a649fbb..6dd85cb 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_password_portrait.xml
@@ -93,7 +93,6 @@
                     android:inputType="textPassword"
                     android:gravity="center"
                     android:layout_gravity="center"
-                    android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
                     android:textSize="24sp"
                     android:textAppearance="?android:attr/textAppearanceMedium"
                     android:background="@null"
diff --git a/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml b/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
new file mode 100644
index 0000000..2e6fa37
--- /dev/null
+++ b/core/res/res/layout-sw600dp/keyguard_sim_puk_pin_navigation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/default_navigation" />
+</merge>
diff --git a/core/res/res/layout/default_navigation.xml b/core/res/res/layout/default_navigation.xml
new file mode 100644
index 0000000..b13103c
--- /dev/null
+++ b/core/res/res/layout/default_navigation.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/keyguard_click_area"
+    android:gravity="center">
+
+    <!-- message area for security screen -->
+    <TextView
+        android:id="@+id/keyguard_message_area"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="start"
+        android:ellipsize="marquee"
+        android:layout_marginEnd="4dip"
+        android:layout_marginStart="4dip"
+        android:textSize="22dip"
+        android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/empty_navigation.xml b/core/res/res/layout/empty_navigation.xml
new file mode 100644
index 0000000..6422070
--- /dev/null
+++ b/core/res/res/layout/empty_navigation.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android" />
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_account_view.xml b/core/res/res/layout/keyguard_account_view.xml
index 481f0c1..d1f9225 100644
--- a/core/res/res/layout/keyguard_account_view.xml
+++ b/core/res/res/layout/keyguard_account_view.xml
@@ -23,7 +23,7 @@
     android:layout_height="match_parent"
     android:orientation="vertical">
 
-    <include layout="@layout/keyguard_navigation"/>
+    <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
 
     <RelativeLayout
         android:layout_width="match_parent"
@@ -69,4 +69,12 @@
 
     </RelativeLayout>
 
+    <include layout="@layout/keyguard_emergency_carrier_area"
+        android:id="@+id/keyguard_selector_fade_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
+
 </com.android.internal.policy.impl.keyguard.KeyguardAccountView>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml
index 62cbac4..f9a593f 100644
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ b/core/res/res/layout/keyguard_emergency_carrier_area.xml
@@ -23,7 +23,8 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:gravity="center_horizontal"
+    android:gravity="center"
+    android:layout_gravity="center_horizontal"
     android:layout_alignParentBottom="true">
 
     <com.android.internal.policy.impl.keyguard.CarrierText
@@ -33,7 +34,6 @@
         android:ellipsize="marquee"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textSize="@dimen/kg_status_line_font_size"
-        android:layout_marginLeft="@dimen/kg_emergency_button_shift"
         android:textColor="?android:attr/textColorSecondary"/>
 
     <com.android.internal.policy.impl.keyguard.EmergencyButton
@@ -46,7 +46,6 @@
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textSize="@dimen/kg_status_line_font_size"
         android:textColor="?android:attr/textColorSecondary"
-        android:layout_marginLeft="@dimen/kg_emergency_button_shift"
         android:drawablePadding="8dip" />
 
 </LinearLayout>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml b/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml
new file mode 100644
index 0000000..68840ab
--- /dev/null
+++ b/core/res/res/layout/keyguard_emergency_carrier_area_and_recovery.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This contains emergency call button and carrier as shared by pin/pattern/password screens -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:gravity="center"
+    android:layout_gravity="center_horizontal"
+    android:layout_alignParentBottom="true">
+
+    <com.android.internal.policy.impl.keyguard.CarrierText
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:textSize="@dimen/kg_status_line_font_size"
+        android:textColor="?android:attr/textColorSecondary"/>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        style="?android:attr/buttonBarStyle"
+        android:orientation="horizontal"
+        android:gravity="center"
+        android:weightSum="2">
+
+        <com.android.internal.policy.impl.keyguard.EmergencyButton
+            android:id="@+id/emergency_call_button"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
+            android:text="@string/kg_emergency_call_label"
+            style="?android:attr/buttonBarButtonStyle"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:textSize="@dimen/kg_status_line_font_size"
+            android:textColor="?android:attr/textColorSecondary"
+            android:drawablePadding="8dip" />
+
+        <Button android:id="@+id/forgot_password_button"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:drawableLeft="@drawable/lockscreen_forgot_password_button"
+            style="?android:attr/buttonBarButtonStyle"
+            android:textSize="@dimen/kg_status_line_font_size"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:drawablePadding="8dip" 
+            android:visibility="gone"/>
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index e25d035..845c265 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -27,17 +27,13 @@
 
     <include layout="@layout/keyguard_navigation"/>
 
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="1" />
-
     <RelativeLayout
         android:id="@+id/face_unlock_area_view"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/face_unlock_height"
-        android:background="@drawable/intro_bg"
-        android:gravity="center">
+        android:layout_height="@*android:dimen/face_unlock_height"
+        android:background="@*android:drawable/intro_bg"
+        android:gravity="center"
+        android:layout_weight="1">
 
         <View
             android:id="@+id/spotlightMask"
@@ -59,4 +55,11 @@
 
     </RelativeLayout>
 
+    <include layout="@layout/keyguard_emergency_carrier_area"
+        android:id="@+id/keyguard_selector_fade_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
 </com.android.internal.policy.impl.keyguard.KeyguardFaceUnlockView>
diff --git a/core/res/res/layout/keyguard_glow_pad_container.xml b/core/res/res/layout/keyguard_glow_pad_container.xml
index f8364f1..376d0e9 100644
--- a/core/res/res/layout/keyguard_glow_pad_container.xml
+++ b/core/res/res/layout/keyguard_glow_pad_container.xml
@@ -21,5 +21,6 @@
     <include layout="@layout/keyguard_glow_pad_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center" />
+        android:layout_gravity="bottom|center_horizontal"
+        android:layout_marginBottom="-80dp"/>
 </merge>
\ No newline at end of file
diff --git a/core/res/res/layout/keyguard_navigation.xml b/core/res/res/layout/keyguard_navigation.xml
index c29dc70..8230c52 100644
--- a/core/res/res/layout/keyguard_navigation.xml
+++ b/core/res/res/layout/keyguard_navigation.xml
@@ -16,20 +16,6 @@
 ** limitations under the License.
 */
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/keyguard_click_area"
-    android:gravity="center">
-
-    <!-- message area for security screen -->
-    <TextView
-        android:id="@+id/keyguard_message_area"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start"
-        android:ellipsize="marquee"
-        android:layout_marginEnd="4dip"
-        android:layout_marginStart="4dip"
-        android:textSize="22dip"
-        android:textAppearance="?android:attr/textAppearanceMedium"/>
-
-</LinearLayout>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/empty_navigation" />
+</merge>
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index f7071d2..ab8aa85 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -22,88 +22,107 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:gravity="center_horizontal">
+    android:layout_gravity="center">
 
-    <LinearLayout
-        android:layout_height="0dip"
+    <FrameLayout
         android:layout_width="match_parent"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:gravity="center">
+        android:layout_height="0dp"
+        android:layout_weight="1">
 
-        <include layout="@layout/keyguard_navigation"/>
-
-     </LinearLayout>
-
-    <!-- Password entry field -->
-    <!-- Note: the entire container is styled to look like the edit field,
-         since the backspace/IME switcher looks better inside -->
-    <LinearLayout
-        android:layout_gravity="center_vertical|fill_horizontal"
-        android:layout_width="match_parent"
-        android:orientation="horizontal"
-        android:background="#70000000"
-        android:layout_marginStart="4dip"
-        android:layout_marginEnd="4dip">
-
-        <EditText android:id="@+id/passwordEntry"
-            android:layout_width="0dip"
+        <LinearLayout
             android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:gravity="center_horizontal"
-            android:layout_gravity="center_vertical"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:singleLine="true"
-            android:textStyle="normal"
-            android:inputType="textPassword"
-            android:textSize="36sp"
-            android:background="@null"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="#ffffffff"
-            android:imeOptions="flagForceAscii|actionDone"
-            />
+            android:layout_width="match_parent"
+            android:orientation="vertical"
+            android:layout_gravity="center">
 
-        <!-- This delete button is only visible for numeric PIN entry -->
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:src="@*android:drawable/ic_input_delete"
-            android:clickable="true"
-            android:padding="8dip"
-            android:background="?android:attr/selectableItemBackground"
-            android:visibility="gone"
-            />
+            <LinearLayout
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"
+                android:orientation="vertical"
+                android:gravity="center">
+                <include layout="@layout/keyguard_navigation"/>
+            </LinearLayout>
 
-        <ImageView android:id="@+id/switch_ime_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@*android:drawable/ic_lockscreen_ime"
-            android:clickable="true"
-            android:padding="8dip"
-            android:layout_gravity="center"
-            android:background="?android:attr/selectableItemBackground"
-            android:visibility="gone"
-            />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
 
-    </LinearLayout>
+                <!-- Password entry field -->
+                <!-- Note: the entire container is styled to look like the edit field,
+                     since the backspace/IME switcher looks better inside -->
+                <LinearLayout
+                    android:layout_gravity="center_vertical|fill_horizontal"
+                    android:layout_width="match_parent"
+                    android:orientation="horizontal"
+                    android:background="#70000000"
+                    android:layout_marginStart="4dip"
+                    android:layout_marginEnd="4dip">
 
-    <!-- Numeric keyboard -->
-    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
-        android:layout_width="match_parent"
-        android:layout_marginStart="4dip"
-        android:layout_marginEnd="4dip"
-        android:paddingTop="4dip"
-        android:paddingBottom="4dip"
-        android:background="#40000000"
-        android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
-        android:visibility="gone"
-        android:clickable="true"
-    />
+                    <EditText android:id="@+id/passwordEntry"
+                        android:layout_width="0dip"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:gravity="center_horizontal"
+                        android:layout_gravity="center_vertical"
+                        android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+                        android:singleLine="true"
+                        android:textStyle="normal"
+                        android:inputType="textPassword"
+                        android:textSize="36sp"
+                        android:background="@null"
+                        android:textAppearance="?android:attr/textAppearanceMedium"
+                        android:textColor="#ffffffff"
+                        android:imeOptions="flagForceAscii|actionDone"
+                        />
 
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/kg_secure_padding_height"
-        android:background="@drawable/lockscreen_protection_pattern" />
+                    <!-- This delete button is only visible for numeric PIN entry -->
+                    <ImageButton android:id="@+id/delete_button"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="center_vertical"
+                        android:src="@*android:drawable/ic_input_delete"
+                        android:clickable="true"
+                        android:padding="8dip"
+                        android:background="?android:attr/selectableItemBackground"
+                        android:visibility="gone"
+                        />
+
+                    <ImageView android:id="@+id/switch_ime_button"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:src="@*android:drawable/ic_lockscreen_ime"
+                        android:clickable="true"
+                        android:padding="8dip"
+                        android:layout_gravity="center"
+                        android:background="?android:attr/selectableItemBackground"
+                        android:visibility="gone"
+                        />
+
+                </LinearLayout>
+
+                <!-- Numeric keyboard -->
+                <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginStart="4dip"
+                    android:layout_marginEnd="4dip"
+                    android:paddingTop="4dip"
+                    android:paddingBottom="4dip"
+                    android:background="#40000000"
+                    android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
+                    android:visibility="gone"
+                    android:clickable="true"
+                />
+            </LinearLayout>
+        </LinearLayout>
+    </FrameLayout>
+    <include layout="@layout/keyguard_emergency_carrier_area"
+             android:id="@+id/keyguard_selector_fade_container"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:orientation="vertical"
+             android:layout_gravity="bottom|center_horizontal"
+             android:gravity="center_horizontal" />
 
 </com.android.internal.policy.impl.keyguard.KeyguardPasswordView>
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 311f77f..bec03b4 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -28,39 +28,42 @@
     android:layout_height="match_parent"
     android:gravity="center_horizontal">
 
-    <LinearLayout
-        android:layout_height="0dip"
+    <FrameLayout
         android:layout_width="match_parent"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:gravity="center">
+        android:layout_height="match_parent">
 
-        <include layout="@layout/keyguard_navigation"/>
-
-        <Button android:id="@+id/forgot_password_button"
-            android:layout_width="wrap_content"
+        <LinearLayout
             android:layout_height="wrap_content"
-            android:textSize="@dimen/kg_status_line_font_size"
-            android:visibility="gone"/>
+            android:layout_width="wrap_content"
+            android:orientation="vertical"
+            android:layout_gravity="center">
 
-    </LinearLayout>
+            <include layout="@layout/keyguard_navigation"/>
 
-    <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
-    the pattern view for it to compute its size. This is an unusual case, caused by
-    LockPatternView's requirement to maintain a square aspect ratio based on the width
-    of the screen. -->
-    <com.android.internal.widget.LockPatternView
-        android:id="@+id/lockPatternView"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginEnd="8dip"
-        android:layout_marginBottom="4dip"
-        android:layout_marginStart="8dip"
-        android:layout_gravity="center_horizontal" />
+            <!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
+            the pattern view for it to compute its size. This is an unusual case, caused by
+            LockPatternView's requirement to maintain a square aspect ratio based on the width
+            of the screen. -->
+            <com.android.internal.widget.LockPatternView
+                android:id="@+id/lockPatternView"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:layout_marginEnd="8dip"
+                android:layout_marginBottom="4dip"
+                android:layout_marginStart="8dip"
+                android:layout_gravity="center_horizontal"
+                android:gravity="center" />
 
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/kg_secure_padding_height"
-        android:background="@drawable/lockscreen_protection_pattern" />
+            <include layout="@layout/keyguard_emergency_carrier_area_and_recovery"
+                android:id="@+id/keyguard_selector_fade_container"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:layout_gravity="bottom|center_horizontal"
+                android:gravity="center_horizontal" />
+
+        </LinearLayout>
+    </FrameLayout>
 
 </com.android.internal.policy.impl.keyguard.KeyguardPatternView>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index e0a3ce3..80d9d61 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -143,7 +143,6 @@
             android:layout_width="0dip"
             android:layout_weight="1"
             android:gravity="center"
-            android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
             android:layout_gravity="center_vertical"
             android:singleLine="true"
             android:textStyle="normal"
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index 0212f73..3d61bae 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -106,12 +106,10 @@
         android:layout_marginEnd="16dip">
 
         <EditText android:id="@+id/passwordEntry"
-            android:layout_width="0dip"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
             android:gravity="center_horizontal"
             android:layout_gravity="center_vertical"
-            android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
             android:singleLine="true"
             android:textStyle="normal"
             android:inputType="textPassword"
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
index 3d3c504..daaf35b 100644
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ b/core/res/res/layout/keyguard_selector_view.xml
@@ -28,15 +28,9 @@
     android:clipToPadding="false"
     android:orientation="vertical">
 
-    <include layout="@layout/keyguard_widget_region"
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:layout_weight="0.45" />
-
     <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="0dip"
-        android:layout_weight="0.55"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
         android:layout_gravity="center"
         android:clipChildren="false"
         android:clipToPadding="false"
@@ -47,11 +41,8 @@
         <include layout="@layout/keyguard_emergency_carrier_area"
             android:id="@+id/keyguard_selector_fade_container"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical"
-            android:layout_gravity="bottom|center_horizontal"
-            android:gravity="center_horizontal" />
-
+            android:layout_height="48dp"
+            android:layout_gravity="bottom|center_horizontal" />
     </FrameLayout>
 
 </com.android.internal.policy.impl.keyguard.KeyguardSelectorView>
diff --git a/core/res/res/layout/keyguard_sim_pin_view.xml b/core/res/res/layout/keyguard_sim_pin_view.xml
index 91dd6d0..163dc15 100644
--- a/core/res/res/layout/keyguard_sim_pin_view.xml
+++ b/core/res/res/layout/keyguard_sim_pin_view.xml
@@ -26,78 +26,87 @@
     android:gravity="center_horizontal">
 
     <LinearLayout
-        android:layout_height="0dip"
         android:layout_width="match_parent"
+        android:layout_height="0dp"
         android:layout_weight="1"
-        android:orientation="vertical"
-        android:gravity="center">
+        android:orientation="vertical">
 
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_lockscreen_sim"/>
-
-        <include layout="@layout/keyguard_navigation"/>
-
-     </LinearLayout>
-
-    <!-- Password entry field -->
-    <!-- Note: the entire container is styled to look like the edit field,
-         since the backspace/IME switcher looks better inside -->
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:layout_marginEnd="4dip"
-        android:layout_marginStart="4dip"
-        android:gravity="center_vertical"
-        android:background="#70000000">
-
-        <!-- displays dots as user enters pin -->
-        <EditText android:id="@+id/sim_pin_entry"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
+        <LinearLayout
+            android:layout_height="0dip"
+            android:layout_width="match_parent"
             android:layout_weight="1"
-            android:maxLines="1"
-            android:singleLine="true"
-            android:gravity="center_horizontal"
-            android:layout_gravity="center_vertical"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:textStyle="normal"
-            android:inputType="textPassword"
-            android:textSize="36sp"
-            android:background="@null"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="#ffffffff"
-            android:imeOptions="flagForceAscii|actionDone"
-        />
+            android:orientation="vertical"
+            android:gravity="center">
 
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_lockscreen_sim"/>
+
+            <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
+         </LinearLayout>
+
+        <!-- Password entry field -->
+        <!-- Note: the entire container is styled to look like the edit field,
+             since the backspace/IME switcher looks better inside -->
+        <LinearLayout
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:src="@android:drawable/ic_input_delete"
+            android:orientation="horizontal"
+            android:layout_marginEnd="4dip"
+            android:layout_marginStart="4dip"
+            android:gravity="center_vertical"
+            android:background="#70000000">
+
+            <!-- displays dots as user enters pin -->
+            <EditText android:id="@+id/sim_pin_entry"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:maxLines="1"
+                android:singleLine="true"
+                android:gravity="center_horizontal"
+                android:layout_gravity="center_vertical"
+                android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+                android:textStyle="normal"
+                android:inputType="textPassword"
+                android:textSize="36sp"
+                android:background="@null"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textColor="#ffffffff"
+                android:imeOptions="flagForceAscii|actionDone"
+            />
+
+            <ImageButton android:id="@+id/delete_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:src="@android:drawable/ic_input_delete"
+                android:clickable="true"
+                android:padding="8dip"
+                android:background="?android:attr/selectableItemBackground"
+            />
+        </LinearLayout>
+
+        <!-- Numeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+            android:layout_width="match_parent"
+            android:layout_marginStart="4dip"
+            android:layout_marginEnd="4dip"
+            android:paddingTop="4dip"
+            android:paddingBottom="4dip"
+            android:background="#40000000"
+            android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
             android:clickable="true"
-            android:padding="8dip"
-            android:background="?android:attr/selectableItemBackground"
         />
     </LinearLayout>
 
-    <!-- Numeric keyboard -->
-    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+    <include layout="@layout/keyguard_emergency_carrier_area"
+        android:id="@+id/keyguard_selector_fade_container"
         android:layout_width="match_parent"
-        android:layout_marginStart="4dip"
-        android:layout_marginEnd="4dip"
-        android:paddingTop="4dip"
-        android:paddingBottom="4dip"
-        android:background="#40000000"
-        android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
-        android:clickable="true"
-    />
-
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/kg_secure_padding_height"
-        android:background="@drawable/lockscreen_protection_pattern" />
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
 
 </com.android.internal.policy.impl.keyguard.KeyguardSimPinView>
diff --git a/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml b/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
new file mode 100644
index 0000000..2e6fa37
--- /dev/null
+++ b/core/res/res/layout/keyguard_sim_puk_pin_account_navigation.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <include layout="@layout/default_navigation" />
+</merge>
diff --git a/core/res/res/layout/keyguard_sim_puk_view.xml b/core/res/res/layout/keyguard_sim_puk_view.xml
index 0c41a34..6e45b0b 100644
--- a/core/res/res/layout/keyguard_sim_puk_view.xml
+++ b/core/res/res/layout/keyguard_sim_puk_view.xml
@@ -27,78 +27,87 @@
     android:gravity="center_horizontal">
 
     <LinearLayout
-        android:layout_height="0dip"
         android:layout_width="match_parent"
+        android:layout_height="0dp"
         android:layout_weight="1"
-        android:orientation="vertical"
-        android:gravity="center">
+        android:orientation="vertical">
 
-        <ImageView
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_lockscreen_sim"/>
-
-        <include layout="@layout/keyguard_navigation"/>
-
-     </LinearLayout>
-
-    <!-- Password entry field -->
-    <!-- Note: the entire container is styled to look like the edit field,
-         since the backspace/IME switcher looks better inside -->
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-        android:layout_marginEnd="4dip"
-        android:layout_marginStart="4dip"
-        android:gravity="center_vertical"
-        android:background="#70000000">
-
-        <!-- displays dots as user enters pin -->
-        <EditText android:id="@+id/sim_pin_entry"
-            android:layout_width="0dip"
-            android:layout_height="wrap_content"
+        <LinearLayout
+            android:layout_height="0dip"
+            android:layout_width="match_parent"
             android:layout_weight="1"
-            android:maxLines="1"
-            android:singleLine="true"
-            android:gravity="center_horizontal"
-            android:layout_gravity="center_vertical"
-            android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
-            android:textStyle="normal"
-            android:inputType="textPassword"
-            android:textSize="36sp"
-            android:background="@null"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="#ffffffff"
-            android:imeOptions="flagForceAscii|actionDone"
-        />
+            android:orientation="vertical"
+            android:gravity="center">
 
-        <ImageButton android:id="@+id/delete_button"
-            android:layout_width="wrap_content"
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_lockscreen_sim"/>
+
+            <include layout="@layout/keyguard_sim_puk_pin_account_navigation"/>
+
+         </LinearLayout>
+
+        <!-- Password entry field -->
+        <!-- Note: the entire container is styled to look like the edit field,
+             since the backspace/IME switcher looks better inside -->
+        <LinearLayout
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:src="@android:drawable/ic_input_delete"
+            android:orientation="horizontal"
+            android:layout_marginEnd="4dip"
+            android:layout_marginStart="4dip"
+            android:gravity="center_vertical"
+            android:background="#70000000">
+
+            <!-- displays dots as user enters pin -->
+            <EditText android:id="@+id/sim_pin_entry"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:maxLines="1"
+                android:singleLine="true"
+                android:gravity="center_horizontal"
+                android:layout_gravity="center_vertical"
+                android:layout_marginStart="@*android:dimen/keyguard_lockscreen_pin_margin_left"
+                android:textStyle="normal"
+                android:inputType="textPassword"
+                android:textSize="36sp"
+                android:background="@null"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:textColor="#ffffffff"
+                android:imeOptions="flagForceAscii|actionDone"
+            />
+
+            <ImageButton android:id="@+id/delete_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:src="@android:drawable/ic_input_delete"
+                android:clickable="true"
+                android:padding="8dip"
+                android:background="?android:attr/selectableItemBackground"
+            />
+        </LinearLayout>
+
+        <!-- Numeric keyboard -->
+        <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+            android:layout_width="match_parent"
+            android:layout_marginStart="4dip"
+            android:layout_marginEnd="4dip"
+            android:paddingTop="4dip"
+            android:paddingBottom="4dip"
+            android:background="#40000000"
+            android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
             android:clickable="true"
-            android:padding="8dip"
-            android:background="?android:attr/selectableItemBackground"
         />
     </LinearLayout>
 
-    <!-- Numeric keyboard -->
-    <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+    <include layout="@layout/keyguard_emergency_carrier_area"
+        android:id="@+id/keyguard_selector_fade_container"
         android:layout_width="match_parent"
-        android:layout_marginStart="4dip"
-        android:layout_marginEnd="4dip"
-        android:paddingTop="4dip"
-        android:paddingBottom="4dip"
-        android:background="#40000000"
-        android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
-        android:clickable="true"
-    />
-
-    <Space
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/kg_secure_padding_height"
-        android:background="@drawable/lockscreen_protection_pattern" />
-
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_gravity="bottom|center_horizontal"
+        android:gravity="center_horizontal" />
 </com.android.internal.policy.impl.keyguard.KeyguardSimPukView>
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
index 0d3d574..1de0f6c 100644
--- a/core/res/res/layout/keyguard_status_view.xml
+++ b/core/res/res/layout/keyguard_status_view.xml
@@ -21,86 +21,44 @@
 <com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/keyguard_status_view"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:gravity="center_horizontal">
 
     <com.android.internal.policy.impl.keyguard.KeyguardStatusView
+        android:id="@+id/keyguard_status_view_face_palm"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center_horizontal|top"
-        android:contentDescription="@string/keyguard_accessibility_status">
+        android:contentDescription="@*android:string/keyguard_accessibility_status">
 
-        <com.android.internal.policy.impl.keyguard.ClockView
-            android:id="@+id/clock_view"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/kg_clock_top_margin"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:layout_gravity="end">
-
-            <TextView android:id="@+id/clock_text"
+        <LinearLayout android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:layout_gravity="center_vertical"
+                      android:orientation="vertical">
+            <com.android.internal.policy.impl.keyguard.ClockView
+                android:id="@+id/clock_view"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:singleLine="true"
-                android:ellipsize="none"
-                android:textSize="@dimen/kg_status_clock_font_size"
-                android:textAppearance="?android:attr/textAppearanceMedium"
-                android:textColor="#ffffffff"
-                android:drawablePadding="2dip"
-                />
+                android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
+                android:layout_gravity="right">
 
-        </com.android.internal.policy.impl.keyguard.ClockView>
+                <TextView android:id="@+id/clock_text"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:singleLine="true"
+                          android:ellipsize="none"
+                          android:textSize="@dimen/kg_status_clock_font_size"
+                          android:textAppearance="?android:attr/textAppearanceMedium"
+                          android:textColor="#ffffffff"
+                          android:drawablePadding="2dip"
+                          />
 
-        <TextView
-            android:id="@+id/date"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="end"
-            android:layout_marginTop="-16dp"
-            android:layout_marginBottom="24dp"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_date_font_size"
-            />
+            </com.android.internal.policy.impl.keyguard.ClockView>
 
-        <TextView
-            android:id="@+id/alarm_status"
-            android:layout_gravity="end"
-            android:layout_marginTop="4dp"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_line_font_size"
-            android:drawablePadding="4dip"
-            />
-
-        <TextView
-            android:id="@+id/owner_info"
-            android:layout_gravity="end"
-            android:layout_marginTop="4dp"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_line_font_size"
-            />
-
-        <TextView
-            android:id="@+id/status1"
-            android:layout_gravity="end"
-            android:layout_marginTop="4dp"
-            android:layout_marginEnd="@dimen/kg_status_line_font_right_margin"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textSize="@dimen/kg_status_line_font_size"
-            />
+            <include layout="@layout/keyguard_status_area" />
+        </LinearLayout>
 
     </com.android.internal.policy.impl.keyguard.KeyguardStatusView>
-
-</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
\ No newline at end of file
+</com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_widget_region.xml b/core/res/res/layout/keyguard_widget_region.xml
index 01b5551..ed10c2b 100644
--- a/core/res/res/layout/keyguard_widget_region.xml
+++ b/core/res/res/layout/keyguard_widget_region.xml
@@ -39,7 +39,8 @@
         android:orientation="horizontal"
         android:paddingLeft="@dimen/kg_widget_pager_horizontal_padding"
         android:paddingRight="@dimen/kg_widget_pager_horizontal_padding"
-        android:layout_marginTop="@dimen/kg_runway_lights_top_margin">
+        android:layout_marginTop="@dimen/kg_runway_lights_top_margin"
+        android:visibility="gone">
         <com.android.internal.policy.impl.keyguard.KeyguardGlowStripView
             android:id="@+id/left_strip"
             android:paddingTop="@dimen/kg_runway_lights_vertical_padding"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0f73ff5..c93008d 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou tablet te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer verkeerdelik geteken. Na nog <xliff:g id="NUMBER_1">%d</xliff:g> onsuksesvolle pogings, sal jy gevra word om jou foon te ontsluit deur middel van \'n e-posrekening."\n\n" Probeer weer oor <xliff:g id="NUMBER_2">%d</xliff:g> sekondes."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Moet volume bo veilige vlak verhoog word?"\n"Deur vir lang tydperke op hoë volume te luister, kan jou gehoor beskadig."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hou twee vingers in om toeganklikheid te aktiveer."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Toeganklikheid geaktiveer."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toeganklikheid gekanselleer."</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g> ."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f60ac3e..495c0e2 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊ ቱኮዎን እንዲከፍቱ ይጠየቃሉ።"\n\n" ከ<xliff:g id="NUMBER_2">%d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።"\n\n"እባክዎ ከ<xliff:g id="NUMBER_2">%d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"ድምጽ አደጋ ከሌለው መጠን በላይ ይጨመር??"\n"ለረጅም ጊዜ በከፍተኛ ድምጽ መስማት የመስማት ችሎታዎን ሊጎዳይ ይችላል።"</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"ተደራሽነትን ለማንቃት ሁለት ጣቶችዎን ባሉበት ያቆዩዋቸው።"</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"ተደራሽነት ነቅቷል።"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"ተደራሽነት ተሰርዟል።"</string>
     <string name="user_switched" msgid="3768006783166984410">"የአሁኑ ተጠቃሚ <xliff:g id="NAME">%1$s</xliff:g>።"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 501946b..6fa8b50 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic."\n\n" Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vols augmentar el volum per sobre del nivell de seguretat?"\n"Escoltar música a un volum alt durant períodes llargs pot perjudicar l\'oïda."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén premuts els dos dits per activar l\'accessibilitat."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"S\'ha activat l\'accessibilitat."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilitat cancel·lada."</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuari actual: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index e14e7de..db09717 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg vil du blive bedt om at låse din tablet op ved hjælp af en e-mailkonto"\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%d</xliff:g> gange. Efter <xliff:g id="NUMBER_1">%d</xliff:g> yderligere mislykkede forsøg til vil du blive bedt om at låse din telefon op ved hjælp af en e-mailkonto."\n\n" Prøv igen om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Skal lydstyrken være over det sikre niveau?"\n"Du kan skade din hørelse ved at lytte ved høj lydstyrke i længere tid."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hold fortsat to fingre nede for at aktivere tilgængelighed."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgængelighed aktiveret."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgængelighed er annulleret."</string>
     <string name="user_switched" msgid="3768006783166984410">"Nuværende bruger <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 9ced98c..e55a272f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το tablet σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%d</xliff:g> ανεπιτυχείς προσπάθειες ακόμη, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου."\n\n" Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%d</xliff:g> δευτερόλεπτα."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Αύξηση έντασης ήχου πάνω από το επίπεδο ασφαλείας;"\n"Αν ακούτε μουσική σε υψηλή ένταση για μεγάλο χρονικό διάστημα ενδέχεται να προκληθεί βλάβη στην ακοή σας."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Αγγίξτε παρατεταμένα με δύο δάχτυλα για να ενεργοποιήσετε τη λειτουργία προσβασιμότητας."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ενεργοποιήθηκε η προσβασιμότητα."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Η λειτουργία προσβασιμότητας ακυρώθηκε."</string>
     <string name="user_switched" msgid="3768006783166984410">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9011e9d..a96995a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%d</xliff:g> times. After <xliff:g id="NUMBER_1">%d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account."\n\n" Try again in <xliff:g id="NUMBER_2">%d</xliff:g> seconds."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Raise volume above safe level?"\n"Listening at high volume for long periods may damage your hearing."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Keep holding down two fingers to enable accessibility."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibility enabled."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibility cancelled."</string>
     <string name="user_switched" msgid="3768006783166984410">"Current user <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index b45f001..d41ce82 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el tablet."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has fallado <xliff:g id="NUMBER_0">%d</xliff:g> veces al dibujar el patrón de desbloqueo. Si fallas otras <xliff:g id="NUMBER_1">%d</xliff:g> veces, deberás usar una cuenta de correo electrónico para desbloquear el teléfono."\n\n" Inténtalo de nuevo en <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"¿Subir el volumen por encima del nivel de seguridad?"\n"Escuchar sonidos a alto volumen durante largos períodos de tiempo puede dañar tus oídos."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantén la pantalla pulsada con dos dedos para habilitar las funciones de accesibilidad."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accesibilidad habilitada"</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accesibilidad cancelada"</string>
     <string name="user_switched" msgid="3768006783166984410">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index fbb9f3e..cf237dc 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga."\n\n" Proovige uuesti <xliff:g id="NUMBER_2">%d</xliff:g> sekundi pärast."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Kas suurendada helitugevust üle ohutu piiri?"\n"Pikaajaline suure helitugevusega muusika kuulamine võib kahjustada kuulmist."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Hõlbustuse lubamiseks hoidke kaht sõrme all."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Hõlbustus on lubatud."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hõlbustus on tühistatud."</string>
     <string name="user_switched" msgid="3768006783166984410">"Praegune kasutaja <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3a91039..5357009 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"<xliff:g id="NUMBER_0">%d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email."\n\n" Riprova tra <xliff:g id="NUMBER_2">%d</xliff:g> secondi."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentare il volume oltre il livello di sicurezza?"\n"Ascoltare musica ad alto volume per lunghi periodi potrebbe danneggiare l\'udito."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Continua a tenere premuto con due dita per attivare l\'accessibilità."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Accessibilità attivata."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Accessibilità annullata."</string>
     <string name="user_switched" msgid="3768006783166984410">"Utente corrente <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-land/bools.xml b/core/res/res/values-land/bools.xml
new file mode 100644
index 0000000..b0630ad
--- /dev/null
+++ b/core/res/res/values-land/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <bool name="kg_share_status_area">false</bool>
+    <bool name="kg_sim_puk_account_full_screen">false</bool>
+</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index ee0260a..1240d6c 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Netinkamai nupiešėte atrakinimo piešinį <xliff:g id="NUMBER_0">%d</xliff:g> k. Po dar <xliff:g id="NUMBER_1">%d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami „Google“ prisijungimo duomenis."\n\n" Bandykite dar kartą po <xliff:g id="NUMBER_2">%d</xliff:g> sek."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Padidinti garsumą viršijant saugų lygį?"\n"Ilgai klausantis dideliu garsumu gali sutrikti klausa."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Laikykite palietę dviem pirštais, kad įgalintumėte pritaikymo neįgaliesiems režimą."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pritaikymas neįgaliesiems įgalintas."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pritaikymo neįgaliesiems režimas atšauktas."</string>
     <string name="user_switched" msgid="3768006783166984410">"Dabartinis naudotojas: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index dd26946..25c036b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem planšetdators būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Jūs nepareizi norādījāt atbloķēšanas kombināciju <xliff:g id="NUMBER_0">%d</xliff:g> reizes. Pēc vēl <xliff:g id="NUMBER_1">%d</xliff:g> neveiksmīgiem mēģinājumiem tālrunis būs jāatbloķē, izmantojot e-pasta kontu."\n\n"Mēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%d</xliff:g> sekundēm."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vai palielināt skaļumu virs drošības līmeņa?"\n"Ilgstoši klausoties skaņu lielā skaļumā, var tikt bojāta dzirde."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Lai iespējotu pieejamību, turiet nospiestus divus pirkstus."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Pieejamības režīms ir iespējots."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Pieejamība ir atcelta."</string>
     <string name="user_switched" msgid="3768006783166984410">"Pašreizējais lietotājs: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c10d7b4..78cc0e9 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp nettbrettet via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Du har tegnet opplåsningsmønsteret feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%d</xliff:g> gale forsøk, blir du bedt om å låse opp telefonen via en e-postkonto."\n\n" Prøv på nytt om <xliff:g id="NUMBER_2">%d</xliff:g> sekunder."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Vil du øke lydnivået over trygt nivå?"\n"Lytting på høyt lydnivå i lange perioder kan skade hørselen din."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Fortsett å holde nede to fingre for å aktivere tilgjengelighet."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Tilgjengelighet er aktivert."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Tilgjengelighetstjenesten ble avbrutt."</string>
     <string name="user_switched" msgid="3768006783166984410">"Gjeldende bruker: <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 41037d6..df8ec78 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw tablet te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"U heeft uw ontgrendelingspatroon <xliff:g id="NUMBER_0">%d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%d</xliff:g> mislukte pogingen wordt u gevraagd uw telefoon te ontgrendelen via een e-mailaccount."\n\n" Probeer het over <xliff:g id="NUMBER_2">%d</xliff:g> seconden opnieuw."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Wilt u het volume verhogen tot boven het aanbevolen geluidsniveau?"\n"Te lang luisteren op een te hoog volume kan leiden tot gehoorbeschadiging."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Blijf het scherm met twee vingers aanraken om toegankelijkheid in te schakelen."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Toegankelijkheid ingeschakeld."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Toegankelijkheid geannuleerd."</string>
     <string name="user_switched" msgid="3768006783166984410">"Huidige gebruiker <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-port/bools.xml b/core/res/res/values-port/bools.xml
index fc62b69..1e2a4f2 100644
--- a/core/res/res/values-port/bools.xml
+++ b/core/res/res/values-port/bools.xml
@@ -16,4 +16,6 @@
 
 <resources>
     <bool name="action_bar_embed_tabs">false</bool>
+    <bool name="kg_share_status_area">true</bool>
+    <bool name="kg_sim_puk_account_full_screen">true</bool>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 9a06263..1a22702 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Desenhou a sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Depois de mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem sucesso, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email."\n\n" Tente novamente dentro de <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível de segurança?"\n"Ouvir em volume alto durante longos períodos de tempo poderá prejudicar a sua audição."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Mantenha os dois dedos para ativar a acessibilidade."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
     <string name="user_switched" msgid="3768006783166984410">"<xliff:g id="NAME">%1$s</xliff:g> do utilizador atual."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index ddc4e04..b712146 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1304,8 +1304,8 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingiza"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Chagua programu"</string>
-    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Gawa na"</string>
-    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Gawa na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Shiriki na"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Shiriki na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa &amp; shika"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
     <string name="description_direction_down" msgid="5087739728639014595">"Sogeza chini kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Umekosea katika kuweka mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> bila kufaulu, utaombwa kufungua kompyuta yako ndogo kwa kutumia akaunti yako ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Umekosea kuchora mchoro wako wa kufungua mara <xliff:g id="NUMBER_0">%d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%d</xliff:g> yasiyofaulu, utaombwa kufungua simu yako kwa kutumia akaunti ya barua pepe."\n\n" Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%d</xliff:g>."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Ongeza sauti zaidi ya kiwango salama? "\n"Kusikiliza kwa sauti ya juu kwa muda mrefu kunaweza kuharibu uwezo wako wa kusikia."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Endelea kushikilia chini kwa vidole vyako viwili ili kuwezesha ufikivu."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ufikivu umewezeshwa."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ufikivu umeghairiwa."</string>
     <string name="user_switched" msgid="3768006783166984410">"Mtumiaji wa sasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values-sw380dp-land/dimens.xml b/core/res/res/values-sw380dp-land/dimens.xml
index d1a1bed..20eb1be 100644
--- a/core/res/res/values-sw380dp-land/dimens.xml
+++ b/core/res/res/values-sw380dp-land/dimens.xml
@@ -19,5 +19,5 @@
 -->
 <resources>
     <!-- Top margin for the clock view --> 
-    <dimen name="kg_clock_top_margin">67dp</dimen>
+    <dimen name="kg_clock_top_margin">48dp</dimen>
 </resources>
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
index 2f65eab..3753aba 100644
--- a/core/res/res/values-sw600dp/bools.xml
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -17,4 +17,6 @@
 <resources>
     <bool name="target_honeycomb_needs_options_menu">false</bool>
     <bool name="show_ongoing_ime_switcher">true</bool>
+    <bool name="kg_share_status_area">false</bool>
+    <bool name="kg_sim_puk_account_full_screen">false</bool>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ef48346..75142fb 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1418,8 +1418,7 @@
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Udwebe ngokungalungile iphathini yakho yokuvula izikhathi ezingu-<xliff:g id="NUMBER_0">%d</xliff:g>. Emva <xliff:g id="NUMBER_1">%d</xliff:g> kweminye imizamo engaphumelelanga, uzocelwa ukuvula ithebhulethi yakho usebenzisa ukungena ngemvume kwi-Google."\n\n" Sicela uzame futhi kwengu-<xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google"\n\n" Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%d</xliff:g> imizuzwana."</string>
     <string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Khulisa ivolomu ngaphezu kweleveli yokuphepha?"\n"Ukulalela ngevolomu ephezulu izikhathi ezide kungalimaza ukuzwa kwakho."</string>
-    <!-- no translation found for continue_to_enable_accessibility (1626427372316070258) -->
-    <skip />
+    <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"Gcina ucindezele iminwe yakho emibili ukuze unike amandla ukufinyelela."</string>
     <string name="accessibility_enabled" msgid="1381972048564547685">"Ukufinyelela kunikwe amandla."</string>
     <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Ukufinyelela kukhanseliwe."</string>
     <string name="user_switched" msgid="3768006783166984410">"Umsebenzisi wamanje <xliff:g id="NAME">%1$s</xliff:g>."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 384f1ab..3550df9 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5781,4 +5781,10 @@
         <attr name="leftToRight" format="boolean" />
     </declare-styleable>
 
+    <!-- Attributes that can be used with <code>&lt;FragmentBreadCrumbs&gt;</code>
+    tags. -->
+    <declare-styleable name="FragmentBreadCrumbs">
+        <attr name="gravity" />
+    </declare-styleable>
+
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 345175e..948a3d3 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -255,13 +255,13 @@
     <dimen name="kg_widget_view_height">0dp</dimen>
 
     <!-- Size of the clock font in keyguard's status view -->
-    <dimen name="kg_status_clock_font_size">94dp</dimen>
+    <dimen name="kg_status_clock_font_size">75dp</dimen>
 
     <!-- Size of the date font in keyguard's status view  -->
-    <dimen name="kg_status_date_font_size">17dp</dimen>
+    <dimen name="kg_status_date_font_size">15dp</dimen>
 
     <!-- Size of the generic status lines keyguard's status view  -->
-    <dimen name="kg_status_line_font_size">14sp</dimen>
+    <dimen name="kg_status_line_font_size">13dp</dimen>
 
     <!-- Size of margin on the right of keyguard's status view -->
     <dimen name="kg_status_line_font_right_margin">16dp</dimen>
@@ -278,10 +278,6 @@
     <!-- Horizontal gap between keys in PIN and SIM PIN numeric keyboards in keyguard -->
     <dimen name="kg_pin_key_height">60dp</dimen>
 
-    <!-- Shift emergency button from the left edge by this amount.  Used by landscape layout on
-         phones -->
-    <dimen name="kg_emergency_button_shift">0dp</dimen>
-
     <!-- Space reserved at the bottom of secure views (pin/pattern/password/SIM pin/SIM puk) -->
     <dimen name="kg_secure_padding_height">46dp</dimen>
 
@@ -295,10 +291,10 @@
     <dimen name="kg_widget_pager_horizontal_padding">16dp</dimen>
 
     <!-- Top padding for the widget pager -->
-    <dimen name="kg_widget_pager_top_padding">16dp</dimen>
+    <dimen name="kg_widget_pager_top_padding">0dp</dimen>
 
     <!-- Bottom padding for the widget pager -->
-    <dimen name="kg_widget_pager_bottom_padding">6dp</dimen>
+    <dimen name="kg_widget_pager_bottom_padding">0dp</dimen>
 
     <!-- Top margin for the runway lights. We add a negative margin in large
         devices to account for the widget pager padding -->
@@ -308,5 +304,5 @@
     <dimen name="accessibility_touch_slop">80dip</dimen>
 
     <!-- Margin around the various security views -->
-    <dimen name="keyguard_security_view_margin">0dp</dimen>
+    <dimen name="keyguard_security_view_margin">8dp</dimen>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index b79348a..e76b67b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1191,6 +1191,8 @@
   <java-symbol type="bool" name="config_lidControlsSleep" />
   <java-symbol type="bool" name="config_reverseDefaultRotation" />
   <java-symbol type="bool" name="config_showNavigationBar" />
+  <java-symbol type="bool" name="kg_share_status_area" />
+  <java-symbol type="bool" name="kg_sim_puk_account_full_screen" />  
   <java-symbol type="bool" name="target_honeycomb_needs_options_menu" />
   <java-symbol type="color" name="kg_multi_user_text_active" />
   <java-symbol type="color" name="kg_multi_user_text_inactive" />
@@ -1298,6 +1300,7 @@
   <java-symbol type="id" name="keyguard_user_name" />
   <java-symbol type="id" name="keyguard_transport_control" />
   <java-symbol type="id" name="keyguard_status_view" />
+  <java-symbol type="id" name="keyguard_status_view_face_palm" />
   <java-symbol type="id" name="keyguard_users_grid" />
   <java-symbol type="id" name="clock_text" />
   <java-symbol type="id" name="clock_view" />
@@ -1305,6 +1308,7 @@
   <java-symbol type="id" name="left_strip" />
   <java-symbol type="id" name="right_strip" />
   <java-symbol type="id" name="keyguard_multi_user_selector" />
+  <java-symbol type="id" name="status_security_message" />
 
   <java-symbol type="integer" name="config_carDockRotation" />
   <java-symbol type="integer" name="config_defaultUiModeType" />
diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk
new file mode 100755
index 0000000..cb55bba
--- /dev/null
+++ b/data/sounds/AudioPackage10.mk
@@ -0,0 +1,64 @@
+#
+# Audio Package 10 - Mako
+# 
+# Include this file in a product makefile to include these audio files
+#
+# 
+
+LOCAL_PATH:= frameworks/base/data/sounds
+
+PRODUCT_COPY_FILES += \
+        $(LOCAL_PATH)/alarms/ogg/Argon.ogg:system/media/audio/alarms/Argon.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Carbon.ogg:system/media/audio/alarms/Carbon.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Helium.ogg:system/media/audio/alarms/Helium.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Krypton.ogg:system/media/audio/alarms/Krypton.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Neon.ogg:system/media/audio/alarms/Neon.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Oxygen.ogg:system/media/audio/alarms/Oxygen.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Osmium.ogg:system/media/audio/alarms/Osmium.ogg \
+        $(LOCAL_PATH)/alarms/ogg/Platinum.ogg:system/media/audio/alarms/Platinum.ogg \
+	$(LOCAL_PATH)/effects/ogg/Effect_Tick.ogg:system/media/audio/ui/Effect_Tick.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressStandard_120.ogg:system/media/audio/ui/KeypressStandard.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressSpacebar_120.ogg:system/media/audio/ui/KeypressSpacebar.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressDelete_120.ogg:system/media/audio/ui/KeypressDelete.ogg \
+	$(LOCAL_PATH)/effects/ogg/KeypressReturn_120.ogg:system/media/audio/ui/KeypressReturn.ogg \
+	$(LOCAL_PATH)/effects/ogg/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
+	$(LOCAL_PATH)/effects/ogg/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/ogg/camera_focus.ogg:system/media/audio/ui/camera_focus.ogg \
+	$(LOCAL_PATH)/effects/ogg/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/ogg/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Capella.ogg:system/media/audio/notifications/Capella.ogg \
+	$(LOCAL_PATH)/notifications/ogg/CetiAlpha.ogg:system/media/audio/notifications/CetiAlpha.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Hojus.ogg:system/media/audio/notifications/Hojus.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Mira.ogg:system/media/audio/notifications/Mira.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Pollux.ogg:system/media/audio/notifications/Pollux.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Syrma.ogg:system/media/audio/notifications/Syrma.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Talitha.ogg:system/media/audio/notifications/Talitha.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Tejat.ogg:system/media/audio/notifications/Tejat.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Aquila.ogg:system/media/audio/ringtones/Aquila.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Atria.ogg:system/media/audio/ringtones/Atria.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/ArgoNavis.ogg:system/media/audio/ringtones/ArgoNavis.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Centaurus.ogg:system/media/audio/ringtones/Centaurus.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Girtab.ogg:system/media/audio/ringtones/Girtab.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Hydra.ogg:system/media/audio/ringtones/Hydra.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Kuma.ogg:system/media/audio/ringtones/Kuma.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Machina.ogg:system/media/audio/ringtones/Machina.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Orion.ogg:system/media/audio/ringtones/Orion.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Pegasus.ogg:system/media/audio/ringtones/Pegasus.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Pyxis.ogg:system/media/audio/ringtones/Pyxis.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Rasalas.ogg:system/media/audio/ringtones/Rasalas.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Scarabaeus.ogg:system/media/audio/ringtones/Scarabaeus.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Sceptrum.ogg:system/media/audio/ringtones/Sceptrum.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Solarium.ogg:system/media/audio/ringtones/Solarium.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Themos.ogg:system/media/audio/ringtones/Themos.ogg \
+	$(LOCAL_PATH)/ringtones/ogg/Zeta.ogg:system/media/audio/ringtones/Zeta.ogg
diff --git a/data/sounds/alarms/ogg/Argon.ogg b/data/sounds/alarms/ogg/Argon.ogg
new file mode 100644
index 0000000..35addf5
--- /dev/null
+++ b/data/sounds/alarms/ogg/Argon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Carbon.ogg b/data/sounds/alarms/ogg/Carbon.ogg
new file mode 100644
index 0000000..b02a1cc
--- /dev/null
+++ b/data/sounds/alarms/ogg/Carbon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Helium.ogg b/data/sounds/alarms/ogg/Helium.ogg
new file mode 100644
index 0000000..36694cb
--- /dev/null
+++ b/data/sounds/alarms/ogg/Helium.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Krypton.ogg b/data/sounds/alarms/ogg/Krypton.ogg
new file mode 100755
index 0000000..48f956b
--- /dev/null
+++ b/data/sounds/alarms/ogg/Krypton.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Neon.ogg b/data/sounds/alarms/ogg/Neon.ogg
new file mode 100644
index 0000000..3089a27
--- /dev/null
+++ b/data/sounds/alarms/ogg/Neon.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Oxygen.ogg b/data/sounds/alarms/ogg/Oxygen.ogg
new file mode 100644
index 0000000..4dc8ade
--- /dev/null
+++ b/data/sounds/alarms/ogg/Oxygen.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Platinum.ogg b/data/sounds/alarms/ogg/Platinum.ogg
new file mode 100644
index 0000000..d5f0893
--- /dev/null
+++ b/data/sounds/alarms/ogg/Platinum.ogg
Binary files differ
diff --git a/data/sounds/alarms/ogg/Promethium.ogg b/data/sounds/alarms/ogg/Promethium.ogg
index 2a195a3..d5f0893 100644
--- a/data/sounds/alarms/ogg/Promethium.ogg
+++ b/data/sounds/alarms/ogg/Promethium.ogg
Binary files differ
diff --git a/data/sounds/alarms/wav/Argon.wav b/data/sounds/alarms/wav/Argon.wav
new file mode 100755
index 0000000..56e57fc
--- /dev/null
+++ b/data/sounds/alarms/wav/Argon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Carbon.wav b/data/sounds/alarms/wav/Carbon.wav
new file mode 100755
index 0000000..2b855e1
--- /dev/null
+++ b/data/sounds/alarms/wav/Carbon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Helium.wav b/data/sounds/alarms/wav/Helium.wav
new file mode 100644
index 0000000..17710b0
--- /dev/null
+++ b/data/sounds/alarms/wav/Helium.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Krypton.wav b/data/sounds/alarms/wav/Krypton.wav
new file mode 100644
index 0000000..9095e30
--- /dev/null
+++ b/data/sounds/alarms/wav/Krypton.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Neon.wav b/data/sounds/alarms/wav/Neon.wav
new file mode 100644
index 0000000..0e9101a
--- /dev/null
+++ b/data/sounds/alarms/wav/Neon.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Oxygen.wav b/data/sounds/alarms/wav/Oxygen.wav
new file mode 100644
index 0000000..bd41869
--- /dev/null
+++ b/data/sounds/alarms/wav/Oxygen.wav
Binary files differ
diff --git a/data/sounds/alarms/wav/Platinum.wav b/data/sounds/alarms/wav/Platinum.wav
new file mode 100755
index 0000000..08ea03e
--- /dev/null
+++ b/data/sounds/alarms/wav/Platinum.wav
Binary files differ
diff --git a/data/sounds/ringtones/ogg/ArgoNavis.ogg b/data/sounds/ringtones/ogg/ArgoNavis.ogg
index 8bee29e..d25b5e8 100644
--- a/data/sounds/ringtones/ogg/ArgoNavis.ogg
+++ b/data/sounds/ringtones/ogg/ArgoNavis.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Perseus.ogg b/data/sounds/ringtones/ogg/Perseus.ogg
index e5f3fc2..48348e5 100644
--- a/data/sounds/ringtones/ogg/Perseus.ogg
+++ b/data/sounds/ringtones/ogg/Perseus.ogg
Binary files differ
diff --git a/data/sounds/ringtones/ogg/Rigel.ogg b/data/sounds/ringtones/ogg/Rigel.ogg
index 4fcb3c0..de3d92f 100644
--- a/data/sounds/ringtones/ogg/Rigel.ogg
+++ b/data/sounds/ringtones/ogg/Rigel.ogg
Binary files differ
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index e812ccb..46c4398 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -191,28 +191,21 @@
       <li><a href="<?cs var:toroot ?>guide/topics/ui/menus.html">
           <span class="en">Menus</span></span>
           </a></li>
-      <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
-           <span class="en">Dialogs</span>
-          </a></li>
       <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
            <span class="en">Action Bar</span>
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/topics/ui/settings.html">
             <span class="en">Settings</span>
           </a></li>
-      <li class="nav-section">
-          <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/index.html">
-              <span class="en">Notifications</span>
-            </a></div>
-          <ul>
-          <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/toasts.html">
-              <span class="en">Toast Notifications</span>
-            </a></li>
-          <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/notifications.html">
-              <span class="en">Status Notifications</span>
-            </a></li>
-          </ul>
-      </li>
+      <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
+           <span class="en">Dialogs</span>
+          </a></li>
+      <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/notifications.html">
+          <span class="en">Notifications</span>
+        </a></li>
+      <li><a href="<?cs var:toroot ?>guide/topics/ui/notifiers/toasts.html">
+          <span class="en">Toasts</span>
+        </a></li>
       <li class="nav-section">
         <div class="nav-section-header"><a href="<?cs var:toroot ?>guide/topics/search/index.html">
             <span class="en">Search</span>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index fbff532..2de6260 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -4,26 +4,43 @@
 <div id="qv-wrapper">
 <div id="qv">
 <h2>In this document</h2>
+<ol>
+  <li><a href="#NotificationUI">Notification Display Elements</a>
     <ol>
-        <li>
-            <a href="#NotificationUI">Notification Display Elements</a>
-        </li>
-        <li>
-        <a href="#CreateNotification">Creating a Notification</a>
-        </li>
-        <li>
-            <a href="#Managing">Managing Notifications</a>
-        </li>
-        <li>
-            <a href="#NotificationResponse">Preserving Navigation when Starting an Activity</a>
-        </li>
-        <li>
-            <a href="#Progress">Displaying Progress in a Notification</a>
-        </li>
-        <li>
-            <a href="#CustomNotification">Custom Notification Layouts</a>
-        </li>
+      <li><a href="#NormalNotify">Normal view</a></li>
+      <li><a href="#BigNotify">Big view</a></li>
     </ol>
+  </li>
+  <li><a href="#CreateNotification">Creating a Notification</a>
+    <ol>
+      <li><a href="#Required">Required notification contents</a></li>
+      <li><a href="#Optional">Optional notification contents and settings</a></li>
+      <li><a href="#Actions">Notification actions</a></li>
+      <li><a href="#SimpleNotification">Creating a simple notification</a></li>
+      <li><a href="#ApplyStyle">Applying a big view style to a notification</a></li>
+    </ol>
+  </li>
+  <li><a href="#Managing">Managing Notifications</a>
+    <ol>
+      <li><a href="#Updating">Updating notifications</a></li>
+      <li><a href="#Removing">Removing notifications</a></li>
+    </ol>
+  </li>
+  <li><a href="#NotificationResponse">Preserving Navigation when Starting an Activity</a>
+    <ol>
+      <li><a href="#DirectEntry">Setting up a regular activity PendingIntent</a></li>
+      <li><a href="#ExtendedNotification">Setting up a special activity PendingIntent</a></li>
+    </ol>
+  </li>
+  <li><a href="#Progress">Displaying Progress in a Notification</a>
+    <ol>
+      <li><a href="#FixedProgress">Displaying a fixed-duration progress indicator</a></li>
+      <li><a href="#ActivityIndicator">Displaying a continuing activity indicator</a></li>
+    </ol>
+  </li>
+  <li><a href="#CustomNotification">Custom Notification Layouts</a></li>
+</ol>
+
     <h2>Key classes</h2>
     <ol>
         <li>{@link android.app.NotificationManager}</li>
@@ -54,13 +71,12 @@
 <img
     id="figure1"
     src="{@docRoot}images/ui/notifications/iconic_notification.png"
-    height="32"
-    alt="" />
+    height="120" alt="" />
 <p class="img-caption">
     <strong>Figure 1.</strong> Notifications in the notification area.
 </p>
 <img id="figure2" src="{@docRoot}images/ui/notifications/normal_notification.png"
-    height="240" alt="" />
+     height="293" alt="" />
 <p class="img-caption">
     <strong>Figure 2.</strong> Notifications in the notification drawer.
 </p>
@@ -98,7 +114,7 @@
 <img
     src="{@docRoot}images/ui/notifications/normal_notification_callouts.png"
     alt=""
-    height="204"
+    height="153"
     id="figure3" />
 <p class="img-caption">
   <strong>Figure 3.</strong> Notification in normal view.
diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd
index 1a1fb1f..92c146a 100644
--- a/docs/html/guide/topics/ui/notifiers/toasts.jd
+++ b/docs/html/guide/topics/ui/notifiers/toasts.jd
@@ -1,17 +1,8 @@
-page.title=Toast Notifications
-parent.title=Notifications
-parent.link=index.html
+page.title=Toasts
 @jd:body
 
 <div id="qv-wrapper">
-  <div id="qv">
-    <h2>Quickview</h2>
-    <ol>
-      <li>A toast is a message that appears on the surface of the screen for a moment, but it
-does not take focus (or pause the current activity), so it cannot accept user input</li>
-      <li>You can customize the toast layout to include images</li>
-    </ol>
-    
+  <div id="qv">    
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
@@ -26,22 +17,17 @@
   </div>
 </div>
 
-<p>A toast notification is a message that pops up on the surface of the window.
-It only fills the amount of space required for the message and the user's current
-activity remains visible and interactive. The notification automatically fades in and 
-out, and does not accept interaction events.</p>
+<p>A toast provides simple feedback about an operation in a small popup.
+It only fills the amount of space required for the message and the current
+activity remains visible and interactive. 
+For example, navigating away from an email before you send it triggers a 
+"Draft saved" toast to let you know that you can continue editing later. 
+Toasts automatically disappear after a timeout.</p>
 
-<p>The screenshot below shows an example toast notification from the Alarm application.
-Once an alarm is turned on, a toast is displayed to assure you that the 
-alarm was set.</p>
 <img src="{@docRoot}images/toast.png" alt="" />
 
-<p>A toast can be created and displayed from an {@link android.app.Activity} or 
-{@link android.app.Service}. If you create a toast notification from a Service, it
-appears in front of the Activity currently in focus.</p>
-
-<p>If user response to the notification is required, consider using a 
-<a href="notifications.html">Status Bar Notification</a>.</p>
+<p>If user response to a status message is required, consider instead using a 
+<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notification</a>.</p>
 
 
 <h2 id="Basics">The Basics</h2>
@@ -90,8 +76,6 @@
 
 <h2 id="CustomToastView">Creating a Custom Toast View</h2>
 
-<img src="{@docRoot}images/custom_toast.png" alt="" style="float:right" />
-
 <p>If a simple text message isn't enough, you can create a customized layout for your
 toast notification. To create a custom layout, define a View layout,
 in XML or in your application code, and pass the root {@link android.view.View} object
@@ -105,17 +89,17 @@
               android:orientation="horizontal"
               android:layout_width="fill_parent"
               android:layout_height="fill_parent"
-              android:padding="10dp"
+              android:padding="8dp"
               android:background="#DAAA"
               >
-    &lt;ImageView android:id="@+id/image"
+    &lt;ImageView android:src="@drawable/droid"
                android:layout_width="wrap_content"
-               android:layout_height="fill_parent"
-               android:layout_marginRight="10dp"
+               android:layout_height="wrap_content"
+               android:layout_marginRight="8dp"
                />
     &lt;TextView android:id="@+id/text"
               android:layout_width="wrap_content"
-              android:layout_height="fill_parent"
+              android:layout_height="wrap_content"
               android:textColor="#FFF"
               />
 &lt;/LinearLayout>
@@ -126,13 +110,11 @@
 
 <pre>
 LayoutInflater inflater = getLayoutInflater();
-View layout = inflater.inflate(R.layout.toast_layout,
+View layout = inflater.inflate(R.layout.custom_toast,
                                (ViewGroup) findViewById(R.id.toast_layout_root));
 
-ImageView image = (ImageView) layout.findViewById(R.id.image);
-image.setImageResource(R.drawable.android);
 TextView text = (TextView) layout.findViewById(R.id.text);
-text.setText("Hello! This is a custom toast!");
+text.setText("This is a custom toast");
 
 Toast toast = new Toast(getApplicationContext());
 toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
diff --git a/docs/html/images/toast.png b/docs/html/images/toast.png
index 223048a..b4c709a 100644
--- a/docs/html/images/toast.png
+++ b/docs/html/images/toast.png
Binary files differ
diff --git a/docs/html/images/ui/notifications/iconic_notification.png b/docs/html/images/ui/notifications/iconic_notification.png
index 4cabfdb..e72fe4e 100644
--- a/docs/html/images/ui/notifications/iconic_notification.png
+++ b/docs/html/images/ui/notifications/iconic_notification.png
Binary files differ
diff --git a/docs/html/images/ui/notifications/normal_notification.png b/docs/html/images/ui/notifications/normal_notification.png
index 3cf0231..9bea5fb 100644
--- a/docs/html/images/ui/notifications/normal_notification.png
+++ b/docs/html/images/ui/notifications/normal_notification.png
Binary files differ
diff --git a/docs/html/images/ui/notifications/normal_notification_callouts.png b/docs/html/images/ui/notifications/normal_notification_callouts.png
index db57daf..6880e90 100644
--- a/docs/html/images/ui/notifications/normal_notification_callouts.png
+++ b/docs/html/images/ui/notifications/normal_notification_callouts.png
Binary files differ
diff --git a/docs/html/tools/building/building-cmdline.jd b/docs/html/tools/building/building-cmdline.jd
index 6154d96..e0d0d3f 100644
--- a/docs/html/tools/building/building-cmdline.jd
+++ b/docs/html/tools/building/building-cmdline.jd
@@ -261,8 +261,18 @@
   device:</p>
 
   <ul>
-    <li>Enable USB Debugging on your device. You can find the setting on most Android devices by
-    going to <strong>Settings > Applications > Development > USB debugging</strong>.</li>
+    <li>Enable <strong>USB debugging</strong> on your device.
+      <ul>
+        <li>On most devices running Android 3.2 or older, you can find the option under
+          <strong>Settings > Applications > Development</strong>.</li>
+        <li>On Android 4.0 and newer, it's in <strong>Settings > Developer options</strong>.
+          <p class="note"><strong>Note:</strong> On Android 4.2 and newer, <strong>Developer
+          options</strong> is hidden by default. To make it available, go
+          to <strong>Settings > About phone</strong> and tap <strong>Build number</strong>
+          seven times. Return to the previous screen to find <strong>Developer options</strong>.</p>
+        </li>
+      </ul>
+    </li>
 
     <li>Ensure that your development computer can detect your device when connected via USB</li>
   </ul>
diff --git a/docs/html/tools/building/building-eclipse.jd b/docs/html/tools/building/building-eclipse.jd
index c73fe97..304aa7e 100644
--- a/docs/html/tools/building/building-eclipse.jd
+++ b/docs/html/tools/building/building-eclipse.jd
@@ -84,8 +84,18 @@
     <code>android:debuggable</code> attribute of the <code>&lt;application&gt;</code>
     element to <code>true</code>. As of ADT 8.0, this is done by default when you build in debug mode.</li>
 
-    <li>Enable USB Debugging on your device. You can find the setting on most Android devices by
-    going to <strong>Settings > Applications > Development > USB debugging</strong>.</li>
+    <li>Enable <strong>USB debugging</strong> on your device.
+      <ul>
+        <li>On most devices running Android 3.2 or older, you can find the option under
+          <strong>Settings > Applications > Development</strong>.</li>
+        <li>On Android 4.0 and newer, it's in <strong>Settings > Developer options</strong>.
+          <p class="note"><strong>Note:</strong> On Android 4.2 and newer, <strong>Developer
+          options</strong> is hidden by default. To make it available, go
+          to <strong>Settings > About phone</strong> and tap <strong>Build number</strong>
+          seven times. Return to the previous screen to find <strong>Developer options</strong>.</p>
+        </li>
+      </ul>
+    </li>
 
     <li>Ensure that your development computer can detect your device when connected via USB</li>
   </ul>
diff --git a/docs/html/tools/device.jd b/docs/html/tools/device.jd
index d5fd581..61cd08a 100644
--- a/docs/html/tools/device.jd
+++ b/docs/html/tools/device.jd
@@ -58,11 +58,17 @@
     <p class="note"><strong>Note:</strong> If you manually enable debugging in the manifest
  file, be sure to disable it before you build for release (your published application
 should usually <em>not</em> be debuggable).</p></li>
-  <li>Turn on "USB Debugging" on your device.
-    <p>On the device, go to <strong>Settings > Applications > Development</strong> 
-    and enable <strong>USB debugging</strong> 
-    (on an Android 4.0 device, the setting is 
-located in <strong>Settings > Developer options</strong>).</p>
+  <li>Enable <strong>USB debugging</strong> on your device.
+    <ul>
+      <li>On most devices running Android 3.2 or older, you can find the option under
+        <strong>Settings > Applications > Development</strong>.</li>
+      <li>On Android 4.0 and newer, it's in <strong>Settings > Developer options</strong>.
+        <p class="note"><strong>Note:</strong> On Android 4.2 and newer, <strong>Developer
+        options</strong> is hidden by default. To make it available, go
+        to <strong>Settings > About phone</strong> and tap <strong>Build number</strong>
+        seven times. Return to the previous screen to find <strong>Developer options</strong>.</p>
+      </li>
+    </ul>
   </li>
   <li>Set up your system to detect your device.
     <ul>
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 0c428e7..80603b2 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -40,7 +40,7 @@
 immediately run the app.</p>
 
 <p>How you run your app depends on two things: whether you have a real Android-powered device and
-whether you’re using Eclipse. This lesson shows you how to install and run your app on a
+whether you're using Eclipse. This lesson shows you how to install and run your app on a
 real device and on the Android emulator, and in both cases with either Eclipse or the command line
 tools.</p>
 
@@ -85,12 +85,21 @@
 
 <ol>
   <li>Plug in your device to your development machine with a USB cable.
-If you’re developing on Windows, you might need to install the appropriate USB driver for your
+If you're developing on Windows, you might need to install the appropriate USB driver for your
 device. For help installing drivers, see the <a href="{@docRoot}tools/extras/oem-usb.html">OEM USB
-Drivers</a> document.</li>
-  <li>Ensure that <strong>USB debugging</strong> is enabled in the device Settings (open Settings
-and navitage to <strong>Applications > Development</strong> on most devices, or click
-<strong>Developer options</strong> on Android 4.0 and higher).</li>
+Drivers</a> document.</li>  
+  <li>Enable <strong>USB debugging</strong> on your device.
+    <ul>
+      <li>On most devices running Android 3.2 or older, you can find the option under
+        <strong>Settings > Applications > Development</strong>.</li>
+      <li>On Android 4.0 and newer, it's in <strong>Settings > Developer options</strong>.
+        <p class="note"><strong>Note:</strong> On Android 4.2 and newer, <strong>Developer
+        options</strong> is hidden by default. To make it available, go
+        to <strong>Settings > About phone</strong> and tap <strong>Build number</strong>
+        seven times. Return to the previous screen to find <strong>Developer options</strong>.</p>
+      </li>
+    </ul>
+  </li>
 </ol>
 
 <p>To run the app from Eclipse, open one of your project's files and click
@@ -118,7 +127,7 @@
 
 <h2 id="Emulator">Run on the Emulator</h2>
 
-<p>Whether you’re using Eclipse or the command line, to run your app on the emulator you need to
+<p>Whether you're using Eclipse or the command line, to run your app on the emulator you need to
 first create an <a href="{@docRoot}tools/devices/index.html">Android Virtual Device</a> (AVD). An
 AVD is a device configuration for the Android emulator that allows you to model different
 devices.</p>
diff --git a/graphics/java/android/renderscript/ScriptGroup.java b/graphics/java/android/renderscript/ScriptGroup.java
index 8943f75..7afdb39 100644
--- a/graphics/java/android/renderscript/ScriptGroup.java
+++ b/graphics/java/android/renderscript/ScriptGroup.java
@@ -77,7 +77,6 @@
         ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>();
         ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>();
         ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>();
-        boolean mSeen;
         int dagNumber;
 
         Node mNext;
@@ -176,39 +175,24 @@
             mRS = rs;
         }
 
-        private void validateCycleRecurse(Node n, int depth) {
-            n.mSeen = true;
-
-            //android.util.Log.v("RSR", " validateCycleRecurse outputCount " + n.mOutputs.size());
-            for (int ct=0; ct < n.mOutputs.size(); ct++) {
-                final ConnectLine cl = n.mOutputs.get(ct);
+        // do a DFS from original node, looking for original node
+        // any cycle that could be created must contain original node
+        private void validateCycle(Node target, Node original) {
+            for (int ct = 0; ct < target.mOutputs.size(); ct++) {
+                final ConnectLine cl = target.mOutputs.get(ct);
                 if (cl.mToK != null) {
                     Node tn = findNode(cl.mToK.mScript);
-                    if (tn.mSeen) {
+                    if (tn.equals(original)) {
                         throw new RSInvalidStateException("Loops in group not allowed.");
                     }
-                    validateCycleRecurse(tn, depth + 1);
+                    validateCycle(tn, original);
                 }
                 if (cl.mToF != null) {
                     Node tn = findNode(cl.mToF.mScript);
-                    if (tn.mSeen) {
+                    if (tn.equals(original)) {
                         throw new RSInvalidStateException("Loops in group not allowed.");
                     }
-                    validateCycleRecurse(tn, depth + 1);
-                }
-            }
-        }
-
-        private void validateCycle() {
-            //android.util.Log.v("RSR", "validateCycle");
-
-            for (int ct=0; ct < mNodes.size(); ct++) {
-                for (int ct2=0; ct2 < mNodes.size(); ct2++) {
-                    mNodes.get(ct2).mSeen = false;
-                }
-                Node n = mNodes.get(ct);
-                if (n.mInputs.size() == 0) {
-                    validateCycleRecurse(n, 0);
+                    validateCycle(tn, original);
                 }
             }
         }
@@ -327,7 +311,7 @@
 
             Node nf = findNode(from);
             if (nf == null) {
-                throw new RSInvalidStateException("From kernel not found.");
+                throw new RSInvalidStateException("From script not found.");
             }
 
             Node nt = findNode(to.mScript);
@@ -341,7 +325,7 @@
             nf.mOutputs.add(cl);
             nt.mInputs.add(cl);
 
-            validateCycle();
+            validateCycle(nf, nf);
             return this;
         }
 
@@ -362,7 +346,7 @@
 
             Node nf = findNode(from);
             if (nf == null) {
-                throw new RSInvalidStateException("From kernel not found.");
+                throw new RSInvalidStateException("From script not found.");
             }
 
             Node nt = findNode(to);
@@ -376,7 +360,7 @@
             nf.mOutputs.add(cl);
             nt.mInputs.add(cl);
 
-            validateCycle();
+            validateCycle(nf, nf);
             return this;
         }
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index cc536f2..2b50091 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2427,17 +2427,39 @@
 }
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
-
-    if (fabs(sweepAngle) >= 360.0f) {
-        return drawOval(left, top, right, bottom, paint);
+        float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
+    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p)) {
+        return DrawGlInfo::kStatusDone;
     }
 
-    mCaches.activeTexture(0);
-    const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
-            startAngle, sweepAngle, useCenter, paint);
-    return drawShape(left, top, texture, paint);
+    if (fabs(sweepAngle) >= 360.0f) {
+        return drawOval(left, top, right, bottom, p);
+    }
+
+    // TODO: support fills (accounting for concavity if useCenter && sweepAngle > 180)
+    if (p->getStyle() != SkPaint::kStroke_Style || p->getPathEffect() != 0 || p->getStrokeCap() != SkPaint::kButt_Cap) {
+        mCaches.activeTexture(0);
+        const PathTexture* texture = mCaches.arcShapeCache.getArc(right - left, bottom - top,
+                startAngle, sweepAngle, useCenter, p);
+        return drawShape(left, top, texture, p);
+    }
+
+    SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
+    if (p->getStyle() == SkPaint::kStrokeAndFill_Style) {
+        rect.outset(p->getStrokeWidth() / 2, p->getStrokeWidth() / 2);
+    }
+
+    SkPath path;
+    if (useCenter) {
+        path.moveTo(rect.centerX(), rect.centerY());
+    }
+    path.arcTo(rect, startAngle, sweepAngle, !useCenter);
+    if (useCenter) {
+        path.close();
+    }
+    drawConvexPath(path, p);
+
+    return DrawGlInfo::kStatusDrew;
 }
 
 // See SkPaintDefaults.h
diff --git a/libs/hwui/PathRenderer.cpp b/libs/hwui/PathRenderer.cpp
index 5b55c2b..dd13d79 100644
--- a/libs/hwui/PathRenderer.cpp
+++ b/libs/hwui/PathRenderer.cpp
@@ -80,11 +80,24 @@
  *
  * Note that we can't add and normalize the two vectors, that would result in a rectangle having an
  * offset of (sqrt(2)/2, sqrt(2)/2) at each corner, instead of (1, 1)
+ *
+ * NOTE: assumes angles between normals 90 degrees or less
  */
 inline vec2 totalOffsetFromNormals(const vec2& normalA, const vec2& normalB) {
     return (normalA + normalB) / (1 + fabs(normalA.dot(normalB)));
 }
 
+inline void scaleOffsetForStrokeWidth(vec2& offset, float halfStrokeWidth,
+        float inverseScaleX, float inverseScaleY) {
+    if (halfStrokeWidth == 0.0f) {
+        // hairline - compensate for scale
+        offset.x *= 0.5f * inverseScaleX;
+        offset.y *= 0.5f * inverseScaleY;
+    } else {
+        offset *= halfStrokeWidth;
+    }
+}
+
 void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
     Vertex* buffer = vertexBuffer.alloc<Vertex>(perimeter.size());
 
@@ -119,13 +132,7 @@
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
-        if (halfStrokeWidth == 0.0f) {
-            // hairline - compensate for scale
-            totalOffset.x *= 0.5f * inverseScaleX;
-            totalOffset.y *= 0.5f * inverseScaleY;
-        } else {
-            totalOffset *= halfStrokeWidth;
-        }
+        scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
 
         Vertex::set(&buffer[currentIndex++],
                 current->position[0] + totalOffset.x,
@@ -145,6 +152,55 @@
     copyVertex(&buffer[currentIndex++], &buffer[1]);
 }
 
+void getStrokeVerticesFromUnclosedVertices(const Vector<Vertex>& vertices, float halfStrokeWidth,
+        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
+    Vertex* buffer = vertexBuffer.alloc<Vertex>(vertices.size() * 2);
+
+    int currentIndex = 0;
+    const Vertex* current = &(vertices[0]);
+    vec2 lastNormal;
+    for (unsigned int i = 0; i < vertices.size() - 1; i++) {
+        const Vertex* next = &(vertices[i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset;
+        if (i == 0) {
+            totalOffset = nextNormal;
+        } else {
+            totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        }
+        scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] + totalOffset.x,
+                current->position[1] + totalOffset.y);
+
+        Vertex::set(&buffer[currentIndex++],
+                current->position[0] - totalOffset.x,
+                current->position[1] - totalOffset.y);
+
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    vec2 totalOffset = lastNormal;
+    scaleOffsetForStrokeWidth(totalOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+
+    Vertex::set(&buffer[currentIndex++],
+            current->position[0] + totalOffset.x,
+            current->position[1] + totalOffset.y);
+    Vertex::set(&buffer[currentIndex++],
+            current->position[0] - totalOffset.x,
+            current->position[1] - totalOffset.y);
+#if VERTEX_DEBUG
+    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+        ALOGD("point at %f %f", buffer[i].position[0], buffer[i].position[1]);
+    }
+#endif
+}
+
 void getFillVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer,
          float inverseScaleX, float inverseScaleY) {
     AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
@@ -202,11 +258,167 @@
 
 #if VERTEX_DEBUG
     for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
-        ALOGD("point at %f %f", buffer[i].position[0], buffer[i].position[1]);
+        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
     }
 #endif
 }
 
+
+void getStrokeVerticesFromUnclosedVerticesAA(const Vector<Vertex>& vertices, float halfStrokeWidth,
+        VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
+    AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * vertices.size() + 2);
+
+    // avoid lines smaller than hairline since they break triangle based sampling. instead reducing
+    // alpha value (TODO: support different X/Y scale)
+    float maxAlpha = 1.0f;
+    if (halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
+            halfStrokeWidth * inverseScaleX < 0.5f) {
+        maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
+        halfStrokeWidth = 0.0f;
+    }
+
+    // there is no outer/inner here, using them for consistency with below approach
+    int offset = 2 * (vertices.size() - 2);
+    int currentAAOuterIndex = 2;
+    int currentAAInnerIndex = 2 * offset + 5; // reversed
+    int currentStrokeIndex = currentAAInnerIndex + 7;
+
+    const Vertex* last = &(vertices[0]);
+    const Vertex* current = &(vertices[1]);
+    vec2 lastNormal(current->position[1] - last->position[1],
+            last->position[0] - current->position[0]);
+    lastNormal.normalize();
+
+    {
+        // start cap
+        vec2 totalOffset = lastNormal;
+        vec2 AAOffset = totalOffset;
+        AAOffset.x *= 0.5f * inverseScaleX;
+        AAOffset.y *= 0.5f * inverseScaleY;
+
+        vec2 innerOffset = totalOffset;
+        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+        vec2 outerOffset = innerOffset + AAOffset;
+        innerOffset -= AAOffset;
+
+        // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
+        vec2 capAAOffset(AAOffset.y, -AAOffset.x);
+        AlphaVertex::set(&buffer[0],
+                last->position[0] + outerOffset.x + capAAOffset.x,
+                last->position[1] + outerOffset.y + capAAOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[1],
+                last->position[0] + innerOffset.x - capAAOffset.x,
+                last->position[1] + innerOffset.y - capAAOffset.y,
+                maxAlpha);
+
+        AlphaVertex::set(&buffer[2 * offset + 6],
+                last->position[0] - outerOffset.x + capAAOffset.x,
+                last->position[1] - outerOffset.y + capAAOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[2 * offset + 7],
+                last->position[0] - innerOffset.x - capAAOffset.x,
+                last->position[1] - innerOffset.y - capAAOffset.y,
+                maxAlpha);
+        copyAlphaVertex(&buffer[2 * offset + 8], &buffer[0]);
+        copyAlphaVertex(&buffer[2 * offset + 9], &buffer[1]);
+        copyAlphaVertex(&buffer[2 * offset + 10], &buffer[1]); // degenerate tris (the only two!)
+        copyAlphaVertex(&buffer[2 * offset + 11], &buffer[2 * offset + 7]);
+    }
+
+    for (unsigned int i = 1; i < vertices.size() - 1; i++) {
+        const Vertex* next = &(vertices[i + 1]);
+        vec2 nextNormal(next->position[1] - current->position[1],
+                current->position[0] - next->position[0]);
+        nextNormal.normalize();
+
+        vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
+        vec2 AAOffset = totalOffset;
+        AAOffset.x *= 0.5f * inverseScaleX;
+        AAOffset.y *= 0.5f * inverseScaleY;
+
+        vec2 innerOffset = totalOffset;
+        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+        vec2 outerOffset = innerOffset + AAOffset;
+        innerOffset -= AAOffset;
+
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + outerOffset.x,
+                current->position[1] + outerOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[currentAAOuterIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                maxAlpha);
+
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] + innerOffset.x,
+                current->position[1] + innerOffset.y,
+                maxAlpha);
+        AlphaVertex::set(&buffer[currentStrokeIndex++],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                maxAlpha);
+
+        AlphaVertex::set(&buffer[currentAAInnerIndex--],
+                current->position[0] - innerOffset.x,
+                current->position[1] - innerOffset.y,
+                maxAlpha);
+        AlphaVertex::set(&buffer[currentAAInnerIndex--],
+                current->position[0] - outerOffset.x,
+                current->position[1] - outerOffset.y,
+                0.0f);
+
+        last = current;
+        current = next;
+        lastNormal = nextNormal;
+    }
+
+    {
+        // end cap
+        vec2 totalOffset = lastNormal;
+        vec2 AAOffset = totalOffset;
+        AAOffset.x *= 0.5f * inverseScaleX;
+        AAOffset.y *= 0.5f * inverseScaleY;
+
+        vec2 innerOffset = totalOffset;
+        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
+        vec2 outerOffset = innerOffset + AAOffset;
+        innerOffset -= AAOffset;
+
+        // TODO: support square cap by changing this offset to incorporate halfStrokeWidth
+        vec2 capAAOffset(-AAOffset.y, AAOffset.x);
+
+        AlphaVertex::set(&buffer[offset + 2],
+                current->position[0] + outerOffset.x + capAAOffset.x,
+                current->position[1] + outerOffset.y + capAAOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[offset + 3],
+                current->position[0] + innerOffset.x - capAAOffset.x,
+                current->position[1] + innerOffset.y - capAAOffset.y,
+                maxAlpha);
+
+        AlphaVertex::set(&buffer[offset + 4],
+                current->position[0] - outerOffset.x + capAAOffset.x,
+                current->position[1] - outerOffset.y + capAAOffset.y,
+                0.0f);
+        AlphaVertex::set(&buffer[offset + 5],
+                current->position[0] - innerOffset.x - capAAOffset.x,
+                current->position[1] - innerOffset.y - capAAOffset.y,
+                maxAlpha);
+
+        copyAlphaVertex(&buffer[vertexBuffer.getSize() - 2], &buffer[offset + 3]);
+        copyAlphaVertex(&buffer[vertexBuffer.getSize() - 1], &buffer[offset + 5]);
+    }
+
+#if VERTEX_DEBUG
+    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
+    }
+#endif
+}
+
+
 void getStrokeVerticesFromPerimeterAA(const Vector<Vertex>& perimeter, float halfStrokeWidth,
         VertexBuffer& vertexBuffer, float inverseScaleX, float inverseScaleY) {
     AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(6 * perimeter.size() + 8);
@@ -215,7 +427,7 @@
     // alpha value (TODO: support different X/Y scale)
     float maxAlpha = 1.0f;
     if (halfStrokeWidth != 0 && inverseScaleX == inverseScaleY &&
-            halfStrokeWidth * inverseScaleX < 1.0f) {
+            halfStrokeWidth * inverseScaleX < 0.5f) {
         maxAlpha *= (2 * halfStrokeWidth) / inverseScaleX;
         halfStrokeWidth = 0.0f;
     }
@@ -242,13 +454,7 @@
         AAOffset.y *= 0.5f * inverseScaleY;
 
         vec2 innerOffset = totalOffset;
-        if (halfStrokeWidth == 0.0f) {
-            // hairline! - compensate for scale
-            innerOffset.x *= 0.5f * inverseScaleX;
-            innerOffset.y *= 0.5f * inverseScaleY;
-        } else {
-            innerOffset *= halfStrokeWidth;
-        }
+        scaleOffsetForStrokeWidth(innerOffset, halfStrokeWidth, inverseScaleX, inverseScaleY);
         vec2 outerOffset = innerOffset + AAOffset;
         innerOffset -= AAOffset;
 
@@ -296,6 +502,12 @@
     copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset]);
     copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset + 1]);
     // don't need to create last degenerate tri
+
+#if VERTEX_DEBUG
+    for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) {
+        ALOGD("point at %f %f, alpha %f", buffer[i].position[0], buffer[i].position[1], buffer[i].alpha);
+    }
+#endif
 }
 
 void PathRenderer::convexPathVertices(const SkPath &path, const SkPaint* paint,
@@ -320,7 +532,10 @@
             threshInvScaleY *= bounds.height() / (bounds.height() + paint->getStrokeWidth());
         }
     }
-    convexPathPerimeterVertices(path, threshInvScaleX * threshInvScaleX,
+
+    // force close if we're filling the path, since fill path expects closed perimeter.
+    bool forceClose = style != SkPaint::kStroke_Style;
+    bool wasClosed = convexPathPerimeterVertices(path, forceClose, threshInvScaleX * threshInvScaleX,
             threshInvScaleY * threshInvScaleY, tempVertices);
 
     if (!tempVertices.size()) {
@@ -337,11 +552,22 @@
     if (style == SkPaint::kStroke_Style) {
         float halfStrokeWidth = paint->getStrokeWidth() * 0.5f;
         if (!isAA) {
-            getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
-                    inverseScaleX, inverseScaleY);
+            if (wasClosed) {
+                getStrokeVerticesFromPerimeter(tempVertices, halfStrokeWidth, vertexBuffer,
+                        inverseScaleX, inverseScaleY);
+            } else {
+                getStrokeVerticesFromUnclosedVertices(tempVertices, halfStrokeWidth, vertexBuffer,
+                        inverseScaleX, inverseScaleY);
+            }
+
         } else {
-            getStrokeVerticesFromPerimeterAA(tempVertices, halfStrokeWidth, vertexBuffer,
-                    inverseScaleX, inverseScaleY);
+            if (wasClosed) {
+                getStrokeVerticesFromPerimeterAA(tempVertices, halfStrokeWidth, vertexBuffer,
+                        inverseScaleX, inverseScaleY);
+            } else {
+                getStrokeVerticesFromUnclosedVerticesAA(tempVertices, halfStrokeWidth, vertexBuffer,
+                        inverseScaleX, inverseScaleY);
+            }
         }
     } else {
         // For kStrokeAndFill style, the path should be adjusted externally, as it will be treated as a fill here.
@@ -354,19 +580,27 @@
 }
 
 
-void PathRenderer::convexPathPerimeterVertices(const SkPath& path,
+void pushToVector(Vector<Vertex>& vertices, float x, float y) {
+    // TODO: make this not yuck
+    vertices.push();
+    Vertex* newVertex = &(vertices.editArray()[vertices.size() - 1]);
+    Vertex::set(newVertex, x, y);
+}
+
+bool PathRenderer::convexPathPerimeterVertices(const SkPath& path, bool forceClose,
         float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
     ATRACE_CALL();
 
-    SkPath::Iter iter(path, true);
-    SkPoint pos;
+    // TODO: to support joins other than sharp miter, join vertices should be labelled in the
+    // perimeter, or resolved into more vertices. Reconsider forceClose-ing in that case.
+    SkPath::Iter iter(path, forceClose);
     SkPoint pts[4];
     SkPath::Verb v;
     Vertex* newVertex = 0;
     while (SkPath::kDone_Verb != (v = iter.next(pts))) {
             switch (v) {
                 case SkPath::kMove_Verb:
-                    pos = pts[0];
+                    pushToVector(outputVertices, pts[0].x(), pts[0].y());
                     ALOGV("Move to pos %f %f", pts[0].x(), pts[0].y());
                     break;
                 case SkPath::kClose_Verb:
@@ -377,10 +611,7 @@
                             pts[0].x(), pts[0].y(),
                             pts[1].x(), pts[1].y());
 
-                    // TODO: make this not yuck
-                    outputVertices.push();
-                    newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
-                    Vertex::set(newVertex, pts[1].x(), pts[1].y());
+                    pushToVector(outputVertices, pts[1].x(), pts[1].y());
                     break;
                 case SkPath::kQuad_Verb:
                     ALOGV("kQuad_Verb");
@@ -403,6 +634,14 @@
                     break;
             }
     }
+
+    int size = outputVertices.size();
+    if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
+            outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
+        outputVertices.pop();
+        return true;
+    }
+    return false;
 }
 
 void PathRenderer::recursiveCubicBezierVertices(
@@ -419,10 +658,7 @@
 
     if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
-        // TODO: make this not yuck
-        outputVertices.push();
-        Vertex* newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
-        Vertex::set(newVertex, p2x, p2y);
+        pushToVector(outputVertices, p2x, p2y);
     } else {
         float p1c1x = (p1x + c1x) * 0.5f;
         float p1c1y = (p1y + c1y) * 0.5f;
@@ -463,10 +699,7 @@
 
     if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
-        // TODO: make this not yuck
-        outputVertices.push();
-        Vertex* newVertex = &(outputVertices.editArray()[outputVertices.size() - 1]);
-        Vertex::set(newVertex, bx, by);
+        pushToVector(outputVertices, bx, by);
     } else {
         float acx = (ax + cx) * 0.5f;
         float bcx = (bx + cx) * 0.5f;
diff --git a/libs/hwui/PathRenderer.h b/libs/hwui/PathRenderer.h
index 28a5b90..e9f347b 100644
--- a/libs/hwui/PathRenderer.h
+++ b/libs/hwui/PathRenderer.h
@@ -71,10 +71,8 @@
             const mat4 *transform, VertexBuffer& vertexBuffer);
 
 private:
-    static void convexPathPerimeterVertices(
-        const SkPath &path,
-        float sqrInvScaleX, float sqrInvScaleY,
-        Vector<Vertex> &outputVertices);
+    static bool convexPathPerimeterVertices(const SkPath &path, bool forceClose,
+        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
 
 /*
   endpoints a & b,
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f26d322..f77cbfb 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -153,11 +153,10 @@
     private static final int MSG_SET_A2DP_CONNECTION_STATE = 22;
     // end of messages handled under wakelock
     private static final int MSG_SET_RSX_CONNECTION_STATE = 23; // change remote submix connection
-    private static final int MSG_SET_FORCE_RSX_USE = 24;        // force remote submix audio routing
-    private static final int MSG_CHECK_MUSIC_ACTIVE = 25;
-    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 26;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 27;
-    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 28;
+    private static final int MSG_CHECK_MUSIC_ACTIVE = 24;
+    private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 25;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 26;
+    private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 27;
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
     // persisted
@@ -2221,13 +2220,6 @@
                 on ? 1 : 0 /*arg1*/,
                 address /*arg2*/,
                 null/*obj*/, 0/*delay*/);
-
-        // Note that we are  currently forcing use of remote submix as soon as corresponding device
-        //   is made available
-        sendMsg(mAudioHandler, MSG_SET_FORCE_RSX_USE, SENDMSG_REPLACE,
-                AudioSystem.FOR_MEDIA,
-                on ? AudioSystem.FORCE_REMOTE_SUBMIX : AudioSystem.FORCE_NONE,
-                null/*obj*/, 0/*delay*/);
     }
 
     private void onSetRsxConnectionState(int available, int address) {
@@ -3320,7 +3312,6 @@
 
                 case MSG_SET_FORCE_USE:
                 case MSG_SET_FORCE_BT_A2DP_USE:
-                case MSG_SET_FORCE_RSX_USE:
                     setForceUse(msg.arg1, msg.arg2);
                     break;
 
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 260ddc7..dde2979 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -360,9 +360,8 @@
     public static final int FORCE_ANALOG_DOCK = 8;
     public static final int FORCE_DIGITAL_DOCK = 9;
     public static final int FORCE_NO_BT_A2DP = 10;
-    public static final int FORCE_REMOTE_SUBMIX = 11;
-    public static final int FORCE_SYSTEM_ENFORCED = 12;
-    private static final int NUM_FORCE_CONFIG = 13;
+    public static final int FORCE_SYSTEM_ENFORCED = 11;
+    private static final int NUM_FORCE_CONFIG = 12;
     public static final int FORCE_DEFAULT = FORCE_NONE;
 
     // usage for setForceUse, must match AudioSystem::force_use
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 4756078..f4fccbe 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -3831,6 +3831,7 @@
                         outWidth, outHeight, Bitmap.Config.ARGB_8888);
 
                 // Copy int[] to IntBuffer
+                decBuffer.rewind();
                 decBuffer.put(decArray, 0, thumbnailSize);
                 decBuffer.rewind();
 
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
index 2cf795d..87d56fd 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusionEngine.java
@@ -42,16 +42,7 @@
     private static final String NETWORK = LocationManager.NETWORK_PROVIDER;
     private static final String GPS = LocationManager.GPS_PROVIDER;
 
-    // threshold below which a location is considered stale enough
-    // that we shouldn't use its bearing, altitude, speed etc
-    private static final double WEIGHT_THRESHOLD = 0.5;
-    // accuracy in meters at which a Location's weight is halved (compared to 0 accuracy)
-    private static final double ACCURACY_HALFLIFE_M = 20.0;
-    // age in seconds at which a Location's weight is halved (compared to 0 age)
-    private static final double AGE_HALFLIFE_S = 60.0;
-
-    private static final double ACCURACY_DECAY_CONSTANT_M = Math.log(2) / ACCURACY_HALFLIFE_M;
-    private static final double AGE_DECAY_CONSTANT_S = Math.log(2) / AGE_HALFLIFE_S;
+    public static final long SWITCH_ON_FRESHNESS_CLIFF_NS = 11 * 1000000000; // 11 seconds
 
     private final Context mContext;
     private final LocationManager mLocationManager;
@@ -62,8 +53,6 @@
     private Location mFusedLocation;
     private Location mGpsLocation;
     private Location mNetworkLocation;
-    private double mNetworkWeight;
-    private double mGpsWeight;
 
     private boolean mEnabled;
     private ProviderRequestUnbundled mRequest;
@@ -102,10 +91,6 @@
         Log.i(TAG, "engine stopped (" + mContext.getPackageName() + ")");
     }
 
-    private boolean isAvailable() {
-        return mStats.get(GPS).available || mStats.get(NETWORK).available;
-    }
-
     /** Called on mLooper thread */
     public void enable() {
         mEnabled = true;
@@ -130,7 +115,6 @@
         public boolean requested;
         public long requestTime;
         public long minTime;
-        public long lastRequestTtff;
         @Override
         public String toString() {
             StringBuilder s = new StringBuilder();
@@ -171,9 +155,6 @@
             return;
         }
 
-        ProviderStats gpsStats = mStats.get(GPS);
-        ProviderStats networkStats = mStats.get(NETWORK);
-
         long networkInterval = Long.MAX_VALUE;
         long gpsInterval = Long.MAX_VALUE;
         for (LocationRequest request : mRequest.getLocationRequests()) {
@@ -209,104 +190,46 @@
         }
     }
 
-    private static double weighAccuracy(Location loc) {
-        double accuracy = loc.getAccuracy();
-        return Math.exp(-accuracy * ACCURACY_DECAY_CONSTANT_M);
-    }
+    /**
+     * Test whether one location (a) is better to use than another (b).
+     */
+    private static boolean isBetterThan(Location locationA, Location locationB) {
+      if (locationA == null) {
+        return false;
+      }
+      if (locationB == null) {
+        return true;
+      }
+      // A provider is better if the reading is sufficiently newer.  Heading
+      // underground can cause GPS to stop reporting fixes.  In this case it's
+      // appropriate to revert to cell, even when its accuracy is less.
+      if (locationA.getElapsedRealtimeNanos() > locationB.getElapsedRealtimeNanos() + SWITCH_ON_FRESHNESS_CLIFF_NS) {
+        return true;
+      }
 
-    private static double weighAge(Location loc) {
-        long ageSeconds = SystemClock.elapsedRealtimeNanos() - loc.getElapsedRealtimeNanos();
-        ageSeconds /= 1000000000L;
-        if (ageSeconds < 0) ageSeconds = 0;
-        return Math.exp(-ageSeconds * AGE_DECAY_CONSTANT_S);
-    }
-
-    private double weigh(double gps, double network) {
-        return (gps * mGpsWeight) + (network * mNetworkWeight);
-    }
-
-    private double weigh(double gps, double network, double wrapMin, double wrapMax) {
-        // apply aliasing
-        double wrapWidth = wrapMax - wrapMin;
-        if (gps - network > wrapWidth / 2) network += wrapWidth;
-        else if (network - gps > wrapWidth / 2) gps += wrapWidth;
-
-        double result = weigh(gps, network);
-
-        // remove aliasing
-        if (result > wrapMax) result -= wrapWidth;
-        return result;
+      // A provider is better if it has better accuracy.  Assuming both readings
+      // are fresh (and by that accurate), choose the one with the smaller
+      // accuracy circle.
+      if (!locationA.hasAccuracy()) {
+        return false;
+      }
+      if (!locationB.hasAccuracy()) {
+        return true;
+      }
+      return locationA.getAccuracy() < locationB.getAccuracy();
     }
 
     private void updateFusedLocation() {
-        // naive fusion
-        mNetworkWeight = weighAccuracy(mNetworkLocation) * weighAge(mNetworkLocation);
-        mGpsWeight = weighAccuracy(mGpsLocation) * weighAge(mGpsLocation);
-        // scale mNetworkWeight and mGpsWeight so that they add to 1
-        double totalWeight = mNetworkWeight + mGpsWeight;
-        mNetworkWeight /= totalWeight;
-        mGpsWeight /= totalWeight;
-
-        Location fused = new Location(LocationManager.FUSED_PROVIDER);
-        // fuse lat/long
-        // assumes the two locations are close enough that earth curvature doesn't matter
-        fused.setLatitude(weigh(mGpsLocation.getLatitude(), mNetworkLocation.getLatitude()));
-        fused.setLongitude(weigh(mGpsLocation.getLongitude(), mNetworkLocation.getLongitude(),
-                -180.0, 180.0));
-
-        // fused accuracy
-        //TODO: use some real math instead of this crude fusion
-        // one suggestion is to fuse in a quadratic manner, eg
-        // sqrt(weigh(gpsAcc^2, netAcc^2)).
-        // another direction to explore is to consider the difference in the 2
-        // locations. If the component locations overlap, the fused accuracy is
-        // better than the component accuracies. If they are far apart,
-        // the fused accuracy is much worse.
-        fused.setAccuracy((float)weigh(mGpsLocation.getAccuracy(), mNetworkLocation.getAccuracy()));
-
-        // fused time - now
-        fused.setTime(System.currentTimeMillis());
-        fused.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
-
-        // fuse altitude
-        if (mGpsLocation.hasAltitude() && !mNetworkLocation.hasAltitude() &&
-                mGpsWeight > WEIGHT_THRESHOLD) {
-            fused.setAltitude(mGpsLocation.getAltitude());   // use GPS
-        } else if (!mGpsLocation.hasAltitude() && mNetworkLocation.hasAltitude() &&
-                mNetworkWeight > WEIGHT_THRESHOLD) {
-            fused.setAltitude(mNetworkLocation.getAltitude());   // use Network
-        } else if (mGpsLocation.hasAltitude() && mNetworkLocation.hasAltitude()) {
-            fused.setAltitude(weigh(mGpsLocation.getAltitude(), mNetworkLocation.getAltitude()));
+        // may the best location win!
+        if (isBetterThan(mGpsLocation, mNetworkLocation)) {
+            mFusedLocation = new Location(mGpsLocation);
+        } else {
+            mFusedLocation = new Location(mNetworkLocation);
         }
-
-        // fuse speed
-        if (mGpsLocation.hasSpeed() && !mNetworkLocation.hasSpeed() &&
-                mGpsWeight > WEIGHT_THRESHOLD) {
-            fused.setSpeed(mGpsLocation.getSpeed());   // use GPS if its not too old
-        } else if (!mGpsLocation.hasSpeed() && mNetworkLocation.hasSpeed() &&
-                mNetworkWeight > WEIGHT_THRESHOLD) {
-            fused.setSpeed(mNetworkLocation.getSpeed());   // use Network
-        } else if (mGpsLocation.hasSpeed() && mNetworkLocation.hasSpeed()) {
-            fused.setSpeed((float)weigh(mGpsLocation.getSpeed(), mNetworkLocation.getSpeed()));
-        }
-
-        // fuse bearing
-        if (mGpsLocation.hasBearing() && !mNetworkLocation.hasBearing() &&
-                mGpsWeight > WEIGHT_THRESHOLD) {
-            fused.setBearing(mGpsLocation.getBearing());   // use GPS if its not too old
-        } else if (!mGpsLocation.hasBearing() && mNetworkLocation.hasBearing() &&
-                mNetworkWeight > WEIGHT_THRESHOLD) {
-            fused.setBearing(mNetworkLocation.getBearing());   // use Network
-        } else if (mGpsLocation.hasBearing() && mNetworkLocation.hasBearing()) {
-            fused.setBearing((float)weigh(mGpsLocation.getBearing(), mNetworkLocation.getBearing(),
-                    0.0, 360.0));
-        }
-
         if (mNetworkLocation != null) {
-            fused.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, mNetworkLocation);
+            mFusedLocation.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, mNetworkLocation);
         }
-
-        mFusedLocation = fused;
+        mFusedLocation.setProvider(LocationManager.FUSED_PROVIDER);
 
         mCallback.reportLocation(mFusedLocation);
     }
@@ -349,9 +272,9 @@
         StringBuilder s = new StringBuilder();
         s.append("mEnabled=" + mEnabled).append(' ').append(mRequest).append('\n');
         s.append("fused=").append(mFusedLocation).append('\n');
-        s.append(String.format("gps %.3f %s\n", mGpsWeight, mGpsLocation));
+        s.append(String.format("gps %s\n", mGpsLocation));
         s.append("    ").append(mStats.get(GPS)).append('\n');
-        s.append(String.format("net %.3f %s\n", mNetworkWeight, mNetworkLocation));
+        s.append(String.format("net %s\n", mNetworkLocation));
         s.append("    ").append(mStats.get(NETWORK)).append('\n');
         pw.append(s);
     }
diff --git a/packages/SystemUI/res/anim/recent_app_enter.xml b/packages/SystemUI/res/anim/recent_app_enter.xml
deleted file mode 100644
index 4947eee..0000000
--- a/packages/SystemUI/res/anim/recent_app_enter.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- Special window zoom animation: this is the element that enters the screen,
-     it starts at 200% and scales down.  Goes with zoom_exit.xml. -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@android:anim/decelerate_interpolator">
-    <scale android:fromXScale="0.25" android:toXScale="1.0"
-           android:fromYScale="0.25" android:toYScale="1.0"
-           android:pivotX="0%p" android:pivotY="0%p"
-           android:duration="500" />
-    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-            android:duration="500"/>
-</set>
diff --git a/packages/SystemUI/res/anim/recent_app_leave.xml b/packages/SystemUI/res/anim/recent_app_leave.xml
deleted file mode 100644
index 3d83988..0000000
--- a/packages/SystemUI/res/anim/recent_app_leave.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2009, 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.
-*/
--->
-
-<!-- Special window zoom animation: this is the element that enters the screen,
-     it starts at 200% and scales down.  Goes with zoom_exit.xml. -->
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-        android:interpolator="@android:anim/decelerate_interpolator">
-    <scale android:fromXScale="1.0" android:toXScale="0.25"
-           android:fromYScale="1.0" android:toYScale="0.25"
-           android:pivotX="0%p" android:pivotY="0%p"
-           android:duration="500" />
-    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
-            android:duration="500"/>
-</set>
diff --git a/packages/SystemUI/res/anim/recents_launch_from_launcher_enter.xml b/packages/SystemUI/res/anim/recents_launch_from_launcher_enter.xml
new file mode 100644
index 0000000..73ae9f2
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_from_launcher_enter.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:detachWallpaper="true"
+     android:shareInterpolator="false"
+     android:zAdjustment="normal">
+  <!--scale android:fromXScale="2.0" android:toXScale="1.0"
+         android:fromYScale="2.0" android:toYScale="1.0"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:pivotX="50%p" android:pivotY="50%p"
+         android:duration="250" /-->
+  <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/anim/recents_launch_from_launcher_exit.xml b/packages/SystemUI/res/anim/recents_launch_from_launcher_exit.xml
new file mode 100644
index 0000000..becc9d0
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_launch_from_launcher_exit.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="normal">
+  <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/anim/recents_return_to_launcher_enter.xml b/packages/SystemUI/res/anim/recents_return_to_launcher_enter.xml
new file mode 100644
index 0000000..efa9019
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_return_to_launcher_enter.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="normal">
+  <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/anim/recents_return_to_launcher_exit.xml b/packages/SystemUI/res/anim/recents_return_to_launcher_exit.xml
new file mode 100644
index 0000000..e95e667
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_return_to_launcher_exit.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="normal">
+  <!--scale android:fromXScale="1.0" android:toXScale="2.0"
+         android:fromYScale="1.0" android:toYScale="2.0"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:pivotX="50%p" android:pivotY="50%p"
+         android:duration="250" /-->
+  <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notifications.png b/packages/SystemUI/res/drawable-hdpi/ic_notifications.png
new file mode 100644
index 0000000..612ab72
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notifications.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notifications2.png b/packages/SystemUI/res/drawable-hdpi/ic_notifications2.png
new file mode 100644
index 0000000..315c488
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notifications2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
index 55c46b0..172fd55 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
index e30cb8f..5318a6e 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png
new file mode 100644
index 0000000..3ed7418
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png
new file mode 100644
index 0000000..5e20eea
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_settings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notifications.png b/packages/SystemUI/res/drawable-mdpi/ic_notifications.png
new file mode 100644
index 0000000..612ab72
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notifications.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notifications2.png b/packages/SystemUI/res/drawable-mdpi/ic_notifications2.png
new file mode 100644
index 0000000..1d07cbf
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notifications2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
index b1910cf..6104424 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
index 3abafdd..625da59 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png
new file mode 100644
index 0000000..44cfc5b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png
new file mode 100644
index 0000000..0c3fdcd
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_settings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notifications.png b/packages/SystemUI/res/drawable-xhdpi/ic_notifications.png
new file mode 100644
index 0000000..28a902c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notifications.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notifications2.png b/packages/SystemUI/res/drawable-xhdpi/ic_notifications2.png
new file mode 100644
index 0000000..b02e7a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notifications2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
index 5dc93c2..477c067 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
index a97de79..6e5c4af 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png
new file mode 100644
index 0000000..80fdb79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png
new file mode 100644
index 0000000..ac7c1a7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_settings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notifications.xml b/packages/SystemUI/res/drawable/ic_notifications.xml
new file mode 100644
index 0000000..2c8012e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notifications.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+         android:drawable="@drawable/ic_notifications" />
+    <item
+         android:drawable="@drawable/ic_notifications" />
+</selector>
+
diff --git a/packages/SystemUI/res/drawable/ic_notify_button_bg.xml b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml
new file mode 100644
index 0000000..85f1ea2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notify_button_bg.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"  android:drawable="@*android:drawable/list_selector_pressed_holo_dark" />
+    <item                               android:drawable="@*android:drawable/list_selector_disabled_holo_dark" />
+</selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_clear.xml b/packages/SystemUI/res/drawable/ic_notify_clear.xml
index 9c432b2..2163198 100644
--- a/packages/SystemUI/res/drawable/ic_notify_clear.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_clear.xml
@@ -16,6 +16,6 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
-        android:drawable="@drawable/ic_notify_clear_pressed" />
+        android:drawable="@drawable/ic_notify_clear_normal" />
     <item android:drawable="@drawable/ic_notify_clear_normal" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/ic_notify_settings.xml b/packages/SystemUI/res/drawable/ic_notify_settings.xml
new file mode 100644
index 0000000..9303ca4
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notify_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+         android:drawable="@drawable/ic_notify_settings_normal" />
+    <item
+         android:drawable="@drawable/ic_notify_settings_normal" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout/flip_settings.xml b/packages/SystemUI/res/layout/flip_settings.xml
new file mode 100644
index 0000000..1b8898c5
--- /dev/null
+++ b/packages/SystemUI/res/layout/flip_settings.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<com.android.systemui.statusbar.phone.QuickSettingsScrollView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_marginBottom="@dimen/close_handle_underlap"
+    android:overScrollMode="ifContentScrolls"
+    >
+    <com.android.systemui.statusbar.phone.QuickSettingsContainerView
+        android:id="@+id/quick_settings_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:animateLayoutChanges="true"
+        android:columnCount="@integer/quick_settings_num_columns"
+        />
+</com.android.systemui.statusbar.phone.QuickSettingsScrollView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index cb4c227..5408f76 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -50,7 +50,7 @@
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/close_handle_underlap"
         android:orientation="vertical"
-	    android:animateLayoutChanges="true"
+        android:animateLayoutChanges="false"
         >
 
         <include layout="@layout/status_bar_expanded_header"
@@ -68,19 +68,30 @@
             android:visibility="gone"
             />
 
-        <ScrollView
-            android:id="@+id/scroll"
+        <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:fadingEdge="none"
-            android:overScrollMode="ifContentScrolls"
             >
-            <com.android.systemui.statusbar.policy.NotificationRowLayout
-                android:id="@+id/latestItems"
+            <ViewStub android:id="@+id/flip_settings_stub"
+                android:layout="@layout/flip_settings"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                systemui:rowHeight="@dimen/notification_row_min_height"
                 />
-        </ScrollView>
+    
+            <ScrollView
+                android:id="@+id/scroll"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:fadingEdge="none"
+                android:overScrollMode="ifContentScrolls"
+                >
+                <com.android.systemui.statusbar.policy.NotificationRowLayout
+                    android:id="@+id/latestItems"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    systemui:rowHeight="@dimen/notification_row_min_height"
+                    />
+            </ScrollView>
+        </FrameLayout>
     </LinearLayout>
 </com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index f1a8d82..c13405a 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -70,21 +70,37 @@
         android:textColor="#00A040"
         android:padding="2dp"
         />
-    
-    <ImageView android:id="@+id/settings_button"
-        android:layout_width="50dp"
-        android:layout_height="50dp"
-        android:scaleType="center"
-        android:src="@drawable/ic_notify_quicksettings"
-        android:contentDescription="@string/accessibility_settings_button"
-        />
 
     <ImageView android:id="@+id/clear_all_button"
         android:layout_width="50dp"
         android:layout_height="50dp"
-        android:layout_marginLeft="18dp"
+        android:layout_marginRight="12dp"
         android:scaleType="center"
         android:src="@drawable/ic_notify_clear"
+        android:background="@drawable/ic_notify_button_bg"
         android:contentDescription="@string/accessibility_clear_all"
         />     
+
+    <FrameLayout
+        android:layout_width="50dp"
+        android:layout_height="50dp"
+        >
+        <ImageView android:id="@+id/settings_button"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
+            android:scaleType="center"
+            android:src="@drawable/ic_notify_settings"
+            android:background="@drawable/ic_notify_button_bg"
+            android:contentDescription="@string/accessibility_settings_button"
+            />
+        <ImageView android:id="@+id/notification_button"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
+            android:scaleType="center"
+            android:src="@drawable/ic_notifications"
+            android:background="@drawable/ic_notify_button_bg"
+            android:visibility="gone"
+            android:contentDescription="@string/accessibility_notifications_button"
+            />
+    </FrameLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 4b895ec..07aca6c 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -42,20 +42,11 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             />
-        <include layout="@layout/quick_settings"
+        <ViewStub android:id="@+id/quick_settings_stub"
+            android:layout="@layout/quick_settings"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             />
     </com.android.systemui.statusbar.phone.PanelHolder>
 
-    <ViewStub
-        android:layout="@layout/status_bar_help"
-        android:id="@+id/status_bar_cling_stub"
-        android:inflatedId="@+id/status_bar_cling"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginTop="@*android:dimen/status_bar_height"
-        android:visibility="gone"
-        />
-
 </com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 209ad11..48a02ab 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -20,6 +20,9 @@
 <!-- These resources are around just to allow their values to be customized
      for different hardware and product builds. -->
 <resources>
+    <!-- Enable quick settings on tablets -->
+    <bool name="config_hasSettingsPanel">true</bool>
+
     <!-- The number of columns in the QuickSettings -->
     <integer name="quick_settings_num_columns">3</integer>
 
@@ -28,4 +31,7 @@
 
     <!-- Whether rotation lock shows up in quick settings or not -->
     <bool name="quick_settings_show_rotation_lock">true</bool>
+
+    <!-- Enable the "flip settings" panel -->
+    <bool name="config_hasFlipSettingsPanel">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 942e814..a27630d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -97,5 +97,10 @@
 
     <integer name="blinds_pop_duration_ms">10</integer>
 
+    <!-- Disable the separate quick settings panel -->
+    <bool name="config_hasSettingsPanel">true</bool>
+
+    <!-- Enable the "flip settings" panel -->
+    <bool name="config_hasFlipSettingsPanel">true</bool>
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4bf6c10..4de0891 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -52,7 +52,7 @@
     <dimen name="status_bar_recents_item_padding">0dip</dimen>
     <!-- When recents first appears, how far the icon and label of the primary activity
          travel -->
-    <dimen name="status_bar_recents_app_icon_translate_distance">100dp</dimen>
+    <dimen name="status_bar_recents_app_icon_translate_distance">35dip</dimen>
 
     <!-- Where to place the app icon over the thumbnail -->
     <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 4a73200..2cc3446 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -19,4 +19,5 @@
     <item type="id" name="expandable_tag" />
     <item type="id" name="user_expanded_tag" />
     <item type="id" name="user_lock_tag" />
+    <item type="id" name="status_bar_cling_stub" />
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index a874c6d..6877cba 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -156,7 +156,7 @@
                     mBackgroundWidth = mBackgroundHeight = -1;
                     mBackground = null;
                     mRedrawNeeded = true;
-                    drawFrameLocked();
+                    drawFrameLocked(false);
                 }
             }
         }
@@ -234,7 +234,7 @@
                         Log.d(TAG, "Visibility changed to visible=" + visible);
                     }
                     mVisible = visible;
-                    drawFrameLocked();
+                    drawFrameLocked(false);
                 }
             }
         }
@@ -263,7 +263,7 @@
                     mYOffset = yOffset;
                     mOffsetsChanged = true;
                 }
-                drawFrameLocked();
+                drawFrameLocked(false);
             }
         }
 
@@ -277,7 +277,8 @@
 
             synchronized (mLock) {
                 mRedrawNeeded = true;
-                drawFrameLocked();
+                mBackgroundWidth = mBackgroundHeight = -1;
+                drawFrameLocked(true);
             }
         }
 
@@ -290,25 +291,26 @@
 
             synchronized (mLock) {
                 mRedrawNeeded = true;
-                drawFrameLocked();
+                drawFrameLocked(false);
             }
         }
 
-        void drawFrameLocked() {
-            if (!mVisible) {
-                if (DEBUG) {
-                    Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
+        void drawFrameLocked(boolean force) {
+            if (!force) {
+                if (!mVisible) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Suppressed drawFrame since wallpaper is not visible.");
+                    }
+                    return;
                 }
-                return;
-            }
-            if (!mRedrawNeeded && !mOffsetsChanged) {
-                if (DEBUG) {
-                    Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
-                            + "and offsets have not changed.");
+                if (!mRedrawNeeded && !mOffsetsChanged) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
+                                + "and offsets have not changed.");
+                    }
+                    return;
                 }
-                return;
             }
-
             // If we don't yet know the size of the wallpaper bitmap,
             // we need to get it now.
             boolean updateWallpaper = mBackgroundWidth < 0 || mBackgroundHeight < 0 ;
@@ -332,7 +334,8 @@
             int yPixels = availh < 0 ? (int)(availh * mYOffset + .5f) : (availh / 2);
 
             mOffsetsChanged = false;
-            if (!mRedrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
+            if (!force && !mRedrawNeeded
+                    && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
                 if (DEBUG) {
                     Log.d(TAG, "Suppressed drawFrame since the image has not "
                             + "actually moved an integral number of pixels.");
@@ -343,6 +346,11 @@
             mLastXTranslation = xPixels;
             mLastYTranslation = yPixels;
 
+            if (DEBUG) {
+                Log.d(TAG, "drawFrameUnlocked(" + force + "): mBackgroundWxH=" + mBackgroundWidth + "x"
+                        + mBackgroundHeight + " SurfaceFrame=" + frame.toShortString()
+                        + " X,YOffset=" + mXOffset + "," + mYOffset);
+            }
             if (mIsHwAccelerated) {
                 if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
                     drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
@@ -657,6 +665,7 @@
                     EGL_ALPHA_SIZE, 0,
                     EGL_DEPTH_SIZE, 0,
                     EGL_STENCIL_SIZE, 0,
+                    EGL_CONFIG_CAVEAT, EGL_NONE,
                     EGL_NONE
             };
         }
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index f71f554..bc61ab0 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -184,8 +184,8 @@
 
     private void vibrate() {
         Context context = getContext();
-        if (Settings.System.getInt(context.getContentResolver(),
-                Settings.System.HAPTIC_FEEDBACK_ENABLED, 1) != 0) {
+        if (Settings.System.getIntForUser(context.getContentResolver(),
+                Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0) {
             Resources res = context.getResources();
             Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
             vibrator.vibrate(res.getInteger(R.integer.config_search_panel_view_vibration_duration));
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
index 79069b8..ef9f36e 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.WallpaperManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -26,6 +27,7 @@
 import android.os.UserHandle;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.WindowManager;
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUIApplication;
@@ -42,6 +44,7 @@
     private IntentFilter mIntentFilter;
     private boolean mShowing;
     private boolean mForeground;
+
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -79,6 +82,9 @@
 
     @Override
     public void onPause() {
+        overridePendingTransition(
+                R.anim.recents_return_to_launcher_enter,
+                R.anim.recents_return_to_launcher_exit);
         mForeground = false;
         super.onPause();
     }
@@ -92,8 +98,23 @@
         super.onStop();
     }
 
+    private void updateWallpaperVisibility(boolean visible) {
+        int wpflags = visible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;
+        int curflags = getWindow().getAttributes().flags
+                & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+        if (wpflags != curflags) {
+            getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
+        }
+    }
+
     @Override
     public void onStart() {
+        // Hide wallpaper if it's not a static image
+        if (WallpaperManager.getInstance(this).getWallpaperInfo() != null) {
+            updateWallpaperVisibility(false);
+        } else {
+            updateWallpaperVisibility(true);
+        }
         mShowing = true;
         if (mRecentsPanel != null) {
             mRecentsPanel.refreshViews();
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 8607508..57d2ed3 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -520,7 +520,7 @@
 
     public void onWindowAnimationStart() {
         if (mItemToAnimateInWhenWindowAnimationIsFinished != null) {
-            final int startDelay = 100;
+            final int startDelay = 150;
             final int duration = 250;
             final ViewHolder holder = mItemToAnimateInWhenWindowAnimationIsFinished;
             final TimeInterpolator cubic = new DecelerateInterpolator(1.5f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 3e929d6..577b1f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -485,7 +485,11 @@
                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
 
             if (firstTask == null) {
-                mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+                ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+                        R.anim.recents_launch_from_launcher_enter,
+                        R.anim.recents_launch_from_launcher_exit);
+                mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
+                        UserHandle.USER_CURRENT));
             } else {
                 Bitmap first = firstTask.getThumbnail();
                 final Resources res = mContext.getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 3fd413a..d0fc340 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -57,9 +57,9 @@
         mPanelHolder = ph;
         final int N = ph.getChildCount();
         for (int i=0; i<N; i++) {
-            final PanelView v = (PanelView) ph.getChildAt(i);
-            if (v != null) {
-                addPanel(v);
+            final View v = ph.getChildAt(i);
+            if (v != null && v instanceof PanelView) {
+                addPanel((PanelView) v);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index d68151d..64bce22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
 import android.app.Notification;
@@ -61,6 +62,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.ViewPropertyAnimator;
 import android.view.ViewStub;
 import android.view.WindowManager;
 import android.view.animation.AccelerateInterpolator;
@@ -188,12 +190,16 @@
     TextView mNotificationPanelDebugText;
 
     // settings
+    QuickSettings mQS;
+    boolean mHasSettingsPanel, mHasFlipSettings;
     SettingsPanelView mSettingsPanel;
+    View mFlipSettingsView;
+    QuickSettingsContainerView mSettingsContainer;
     int mSettingsPanelGravity;
 
     // top bar
     View mClearButton;
-    View mSettingsButton;
+    ImageView mSettingsButton, mNotificationButton;
 
     // carrier/wifi label
     private TextView mCarrierLabel;
@@ -289,8 +295,12 @@
             if (MULTIUSER_DEBUG) Slog.d(TAG, String.format("User setup changed: " +
                     "selfChange=%s userSetup=%s mUserSetup=%s",
                     selfChange, userSetup, mUserSetup));
-            if (mSettingsPanel != null)
+            if (mSettingsButton != null) {
+                mSettingsButton.setVisibility(userSetup ? View.VISIBLE : View.INVISIBLE);
+            }
+            if (mSettingsPanel != null) {
                 mSettingsPanel.setEnabled(userSetup);
+            }
             if (userSetup != mUserSetup) {
                 mUserSetup = userSetup;
                 if (!mUserSetup && mStatusBarView != null)
@@ -354,10 +364,6 @@
         mNotificationPanel = (PanelView) mStatusBarWindow.findViewById(R.id.notification_panel);
         mNotificationPanelIsFullScreenWidth =
             (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
-        mNotificationPanel.setSystemUiVisibility(
-                  View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
-                  View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
-                  View.STATUS_BAR_DISABLE_CLOCK);
 
         // make the header non-responsive to clicks
         mNotificationPanel.findViewById(R.id.header).setOnTouchListener(
@@ -420,18 +426,41 @@
         mClearButton.setVisibility(View.INVISIBLE);
         mClearButton.setEnabled(false);
         mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
-        mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button);
+
+        mHasSettingsPanel = res.getBoolean(R.bool.config_hasSettingsPanel);
+        mHasFlipSettings = res.getBoolean(R.bool.config_hasFlipSettingsPanel);
+
+        mSettingsButton = (ImageView) mStatusBarWindow.findViewById(R.id.settings_button);
         if (mSettingsButton != null) {
-            if (mStatusBarView.hasFullWidthNotifications()) {
-                mSettingsButton.setOnClickListener(mSettingsButtonListener);
-                mSettingsButton.setVisibility(View.VISIBLE);
+            mSettingsButton.setOnClickListener(mSettingsButtonListener);
+            if (mHasSettingsPanel) {
+                if (mStatusBarView.hasFullWidthNotifications()) {
+                    // the settings panel is hiding behind this button
+                    mSettingsButton.setImageResource(R.drawable.ic_notify_quicksettings);
+                    mSettingsButton.setVisibility(View.VISIBLE);
+                } else {
+                    // there is a settings panel, but it's on the other side of the (large) screen
+                    mSettingsButton.setVisibility(View.GONE);
+                }
             } else {
-                mSettingsButton.setVisibility(View.GONE);
+                // no settings panel, go straight to settings
+                mSettingsButton.setVisibility(View.VISIBLE);
+                mSettingsButton.setImageResource(R.drawable.ic_notify_settings);
             }
         }
-        
+        if (mHasFlipSettings) {
+            mNotificationButton = (ImageView) mStatusBarWindow.findViewById(R.id.notification_button);
+            if (mNotificationButton != null) {
+                mNotificationButton.setOnClickListener(mNotificationButtonListener);
+            }
+        }
+
         mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
         mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
+        mScrollView.setSystemUiVisibility(
+                View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
+                View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
+                View.STATUS_BAR_DISABLE_CLOCK);
 
         mTicker = new MyTicker(context, mStatusBarView);
 
@@ -490,18 +519,55 @@
             });
         }
 
-        // Quick Settings (WIP)
-        mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
-        mSettingsPanel.setBar(mStatusBarView);
-        mSettingsPanel.setService(this);
-        mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController,
-                mLocationController);
-        mSettingsPanel.setSystemUiVisibility(
-                View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
+        // Quick Settings (where available, some restrictions apply)
+        if (mHasSettingsPanel) {
+            // first, figure out where quick settings should be inflated
+            final View settings_stub;
+            if (mHasFlipSettings) {
+                // a version of quick settings that flips around behind the notifications
+                settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
+                if (settings_stub != null) {
+                    mFlipSettingsView = ((ViewStub)settings_stub).inflate();
+                    mFlipSettingsView.setVisibility(View.GONE);
+                    mFlipSettingsView.setVerticalScrollBarEnabled(false);
+                }
+            } else {
+                // full quick settings panel
+                settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
+                if (settings_stub != null) {
+                    mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
+                } else {
+                    mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
+                }
 
-        if (!ActivityManager.isHighEndGfx()) {
-            mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
-                    R.color.notification_panel_solid_background)));
+                if (mSettingsPanel != null) {
+                    mSettingsPanel.setBar(mStatusBarView);
+                    
+                    if (!ActivityManager.isHighEndGfx()) {
+                        mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
+                                R.color.notification_panel_solid_background)));
+                    }
+                }
+            }
+
+            // wherever you find it, Quick Settings needs a container to survive
+            mSettingsContainer = (QuickSettingsContainerView)
+                    mStatusBarWindow.findViewById(R.id.quick_settings_container);
+            if (mSettingsContainer != null) {
+                mQS = new QuickSettings(mContext, mSettingsContainer);
+                mSettingsContainer.setSystemUiVisibility(
+                        View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
+                        | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
+
+                if (mSettingsPanel != null) {
+                    mSettingsPanel.setQuickSettings(mQS);
+                }
+                mQS.setService(this);
+                mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
+                        mLocationController);
+            } else {
+                mQS = null; // fly away, be free
+            }
         }
 
         mClingShown = ! (DEBUG_CLINGS 
@@ -958,7 +1024,8 @@
         final boolean emergencyCallsShownElsewhere = mEmergencyCallLabel != null;
         final boolean makeVisible =
             !(emergencyCallsShownElsewhere && mNetworkController.isEmergencyOnly())
-            && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight);
+            && mPile.getHeight() < (mNotificationPanel.getHeight() - mCarrierLabelHeight - mNotificationHeaderHeight)
+            && mScrollView.getVisibility() == View.VISIBLE;
         
         if (force || mCarrierLabelVisible != makeVisible) {
             mCarrierLabelVisible = makeVisible;
@@ -1213,6 +1280,17 @@
             return;
         }
 
+        if (mHasFlipSettings && !mExpandedVisible) {
+            // reset things to their proper state
+            mScrollView.setScaleX(1f);
+            mScrollView.setVisibility(View.VISIBLE);
+            mSettingsButton.setAlpha(1f);
+            mSettingsButton.setVisibility(View.VISIBLE);
+            mNotificationPanel.setVisibility(View.GONE);
+            mFlipSettingsView.setVisibility(View.GONE);
+            mNotificationButton.setVisibility(View.GONE);
+        }
+
         mExpandedVisible = true;
         mPile.setLayoutTransitionsEnabled(true);
         if (mNavigationBarView != null)
@@ -1267,6 +1345,53 @@
         mStatusBarView.collapseAllPanels(true);
     }
 
+    public ViewPropertyAnimator setVisibilityWhenDone(
+            final ViewPropertyAnimator a, final View v, final int vis) {
+        a.setListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                v.setVisibility(vis);
+                a.setListener(null); // oneshot
+            }
+        });
+        return a;
+    }
+
+    public Animator setVisibilityWhenDone(
+            final Animator a, final View v, final int vis) {
+        a.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                v.setVisibility(vis);
+            }
+        });
+        return a;
+    }
+
+    public Animator interpolator(TimeInterpolator ti, Animator a) {
+        a.setInterpolator(ti);
+        return a;
+    }
+
+    public Animator startDelay(int d, Animator a) {
+        a.setStartDelay(d);
+        return a;
+    }
+    
+    public Animator start(Animator a) {
+        a.start();
+        return a;
+    }
+
+    final TimeInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
+    final TimeInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
+    final int FLIP_DURATION_OUT = 125;
+    final int FLIP_DURATION_IN = 225;
+    final int FLIP_DURATION = (FLIP_DURATION_IN + FLIP_DURATION_OUT);
+
+    Animator mScrollViewAnim, mFlipSettingsViewAnim, mNotificationButtonAnim,
+        mSettingsButtonAnim, mClearButtonAnim;
+
     @Override
     public void animateExpandNotificationsPanel() {
         if (SPEW) Slog.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
@@ -1275,6 +1400,47 @@
         }
 
         mNotificationPanel.expand();
+        if (mHasFlipSettings) {
+            if (mScrollView.getVisibility() != View.VISIBLE) {
+                if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
+                if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+                if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+                if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+                if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+
+                mScrollView.setVisibility(View.VISIBLE);
+                mScrollViewAnim = start(
+                    startDelay(FLIP_DURATION_OUT,
+                        interpolator(mDecelerateInterpolator,
+                            ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 0f, 1f)
+                                .setDuration(FLIP_DURATION_IN)
+                            )));
+                mFlipSettingsViewAnim = start(
+                    setVisibilityWhenDone(
+                        interpolator(mAccelerateInterpolator,
+                                ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 1f, 0f)
+                                )
+                            .setDuration(FLIP_DURATION_OUT),
+                        mFlipSettingsView, View.INVISIBLE));
+                mNotificationButtonAnim = start(
+                    setVisibilityWhenDone(
+                        ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 0f)
+                            .setDuration(FLIP_DURATION),
+                        mNotificationButton, View.INVISIBLE));
+                mSettingsButton.setVisibility(View.VISIBLE);
+                mSettingsButtonAnim = start(
+                    ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 1f)
+                        .setDuration(FLIP_DURATION));
+                mClearButton.setVisibility(View.VISIBLE);
+                mClearButton.setAlpha(0f);
+                setAreThereNotifications(); // this will show/hide the button as necessary
+                mNotificationPanel.postDelayed(new Runnable() {
+                    public void run() {
+                        updateCarrierLabelVisibility(false);
+                    }
+                }, FLIP_DURATION - 150);
+            }
+        }
 
         if (false) postStartTracing();
     }
@@ -1286,7 +1452,53 @@
             return;
         }
 
-        mSettingsPanel.expand();
+        if (mHasFlipSettings) {
+            mNotificationPanel.expand();
+            if (mFlipSettingsView.getVisibility() != View.VISIBLE) {
+                if (mFlipSettingsViewAnim != null) mFlipSettingsViewAnim.cancel();
+                if (mScrollViewAnim != null) mScrollViewAnim.cancel();
+                if (mSettingsButtonAnim != null) mSettingsButtonAnim.cancel();
+                if (mNotificationButtonAnim != null) mNotificationButtonAnim.cancel();
+                if (mClearButtonAnim != null) mClearButtonAnim.cancel();
+
+                mFlipSettingsView.setVisibility(View.VISIBLE);
+                mFlipSettingsView.setScaleX(0f);
+                mFlipSettingsViewAnim = start(
+                    startDelay(FLIP_DURATION_OUT,
+                        interpolator(mDecelerateInterpolator,
+                            ObjectAnimator.ofFloat(mFlipSettingsView, View.SCALE_X, 0f, 1f)
+                                .setDuration(FLIP_DURATION_IN)
+                            )));
+                mScrollViewAnim = start(
+                    setVisibilityWhenDone(
+                        interpolator(mAccelerateInterpolator,
+                                ObjectAnimator.ofFloat(mScrollView, View.SCALE_X, 1f, 0f)
+                                )
+                            .setDuration(FLIP_DURATION_OUT), 
+                        mScrollView, View.INVISIBLE));
+                mSettingsButtonAnim = start(
+                    setVisibilityWhenDone(
+                        ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA, 0f)
+                            .setDuration(FLIP_DURATION),
+                            mScrollView, View.INVISIBLE));
+                mNotificationButton.setVisibility(View.VISIBLE);
+                mNotificationButtonAnim = start(
+                    ObjectAnimator.ofFloat(mNotificationButton, View.ALPHA, 1f)
+                        .setDuration(FLIP_DURATION));
+                mClearButtonAnim = start(
+                    setVisibilityWhenDone(
+                        ObjectAnimator.ofFloat(mClearButton, View.ALPHA, 0f)
+                        .setDuration(FLIP_DURATION),
+                        mClearButton, View.INVISIBLE));
+                mNotificationPanel.postDelayed(new Runnable() {
+                    public void run() {
+                        updateCarrierLabelVisibility(false);
+                    }
+                }, FLIP_DURATION - 150);
+            }
+        } else if (mSettingsPanel != null) {
+            mSettingsPanel.expand();
+        }
 
         if (false) postStartTracing();
     }
@@ -1596,7 +1808,7 @@
         mCommandQueue.setNavigationIconHints(
                 altBack ? (mNavigationIconHints | StatusBarManager.NAVIGATION_HINT_BACK_ALT)
                         : (mNavigationIconHints & ~StatusBarManager.NAVIGATION_HINT_BACK_ALT));
-        mSettingsPanel.setImeWindowStatus(vis > 0);
+        if (mQS != null) mQS.setImeWindowStatus(vis > 0);
     }
 
     @Override
@@ -1820,10 +2032,12 @@
         lp.leftMargin = mNotificationPanelMarginPx;
         mNotificationPanel.setLayoutParams(lp);
 
-        lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
-        lp.gravity = mSettingsPanelGravity;
-        lp.rightMargin = mNotificationPanelMarginPx;
-        mSettingsPanel.setLayoutParams(lp);
+        if (mSettingsPanel != null) {
+            lp = (FrameLayout.LayoutParams) mSettingsPanel.getLayoutParams();
+            lp.gravity = mSettingsPanelGravity;
+            lp.rightMargin = mNotificationPanelMarginPx;
+            mSettingsPanel.setLayoutParams(lp);
+        }
 
         updateCarrierLabelVisibility(false);
     }
@@ -1916,7 +2130,25 @@
 
     private View.OnClickListener mSettingsButtonListener = new View.OnClickListener() {
         public void onClick(View v) {
-            animateExpandSettingsPanel();
+            if (mHasSettingsPanel) {
+                animateExpandSettingsPanel();
+            } else {
+                try {
+                    // Dismiss the lock screen when Settings starts.
+                    ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+                } catch (RemoteException e) {
+                }
+                Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+                animateCollapsePanels();
+            }
+        }
+    };
+
+    private View.OnClickListener mNotificationButtonListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            animateExpandNotificationsPanel();
         }
     };
 
@@ -2010,7 +2242,7 @@
         }
 
         // Update the QuickSettings container
-        mSettingsPanel.updateResources();
+        if (mQS != null) mQS.updateResources();
 
         loadDimens();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 96f729e..3c2f0e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -109,7 +109,8 @@
 
         if (mFullWidthNotifications) {
             // No double swiping. If either panel is open, nothing else can be pulled down.
-            return (mSettingsPanel.getExpandedHeight() + mNotificationPanel.getExpandedHeight()> 0) 
+            return ((mSettingsPanel == null ? 0 : mSettingsPanel.getExpandedHeight()) 
+                        + mNotificationPanel.getExpandedHeight() > 0) 
                     ? null 
                     : mNotificationPanel;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index 8c390c8..5b550c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -88,7 +88,7 @@
     private Context mContext;
     private PanelBar mBar;
     private QuickSettingsModel mModel;
-    private QuickSettingsContainerView mContainerView;
+    private ViewGroup mContainerView;
 
     private DisplayManager mDisplayManager;
     private WifiDisplayStatus mWifiDisplayStatus;
@@ -717,6 +717,7 @@
         for (QuickSettingsTileView v : mDynamicSpannedTiles) {
             v.setColumnSpan(span);
         }
+        ((QuickSettingsContainerView)mContainerView).updateResources();
         mContainerView.requestLayout();
 
         // Reset the dialog
@@ -754,6 +755,7 @@
             mBrightnessDialog.setCanceledOnTouchOutside(true);
 
             mBrightnessController = new BrightnessController(mContext,
+                    (ImageView) mBrightnessDialog.findViewById(R.id.brightness_icon),
                     (ToggleSlider) mBrightnessDialog.findViewById(R.id.brightness_slider));
             mBrightnessController.addStateChangedCallback(mModel);
             mBrightnessDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
index 4e10fa3..a58eb22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SettingsPanelView.java
@@ -53,7 +53,6 @@
         super.onFinishInflate();
 
         mQSContainer = (QuickSettingsContainerView) findViewById(R.id.quick_settings_container);
-        mQS = new QuickSettings(getContext(), mQSContainer);
 
         Resources resources = getContext().getResources();
         mHandleBar = resources.getDrawable(R.drawable.status_bar_close);
@@ -62,6 +61,10 @@
 
         setContentDescription(resources.getString(R.string.accessibility_desc_quick_settings));
     }
+    
+    public void setQuickSettings(QuickSettings qs) {
+        mQS = qs;
+    }
 
     @Override
     public void setBar(PanelBar panelBar) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 0176f42..89c70e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -42,6 +42,7 @@
     private ExpandHelper mExpandHelper;
     private NotificationRowLayout latestItems;
     private NotificationPanelView mNotificationPanel;
+    private ScrollView mScrollView;
 
     PhoneStatusBar mService;
 
@@ -55,13 +56,13 @@
     protected void onAttachedToWindow () {
         super.onAttachedToWindow();
         latestItems = (NotificationRowLayout) findViewById(R.id.latestItems);
-        ScrollView scroller = (ScrollView) findViewById(R.id.scroll);
+        mScrollView = (ScrollView) findViewById(R.id.scroll);
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
         int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_min_height);
         int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_row_max_height);
         mExpandHelper = new ExpandHelper(mContext, latestItems, minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
-        mExpandHelper.setScrollView(scroller);
+        mExpandHelper.setScrollView(mScrollView);
     }
 
     @Override
@@ -80,7 +81,7 @@
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
         boolean intercept = false;
-        if (mNotificationPanel.isFullyExpanded()) {
+        if (mNotificationPanel.isFullyExpanded() && mScrollView.getVisibility() == View.VISIBLE) {
             intercept = mExpandHelper.onInterceptTouchEvent(ev);
         }
         if (!intercept) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
index 0009503..e18b28a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessController.java
@@ -28,6 +28,7 @@
 import android.util.Slog;
 import android.view.IWindowManager;
 import android.widget.CompoundButton;
+import android.widget.ImageView;
 
 import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
 
@@ -40,6 +41,7 @@
     private final int mMaximumBacklight;
 
     private final Context mContext;
+    private final ImageView mIcon;
     private final ToggleSlider mControl;
     private final boolean mAutomaticAvailable;
     private final IPowerManager mPower;
@@ -52,8 +54,9 @@
         public void onBrightnessLevelChanged();
     }
 
-    public BrightnessController(Context context, ToggleSlider control) {
+    public BrightnessController(Context context, ImageView icon, ToggleSlider control) {
         mContext = context;
+        mIcon = icon;
         mControl = control;
         mUserTracker = new CurrentUserTracker(mContext);
 
@@ -84,8 +87,10 @@
                 automatic = 0;
             }
             control.setChecked(automatic != 0);
+            updateIcon(automatic != 0);
         } else {
             control.setChecked(false);
+            updateIcon(false /*automatic*/);
             //control.hideToggle();
         }
         
@@ -105,6 +110,7 @@
     public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) {
         setMode(automatic ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC
                 : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+        updateIcon(automatic);
         if (!automatic) {
             final int val = value + mMinimumBacklight;
             setBrightness(val);
@@ -136,4 +142,12 @@
         } catch (RemoteException ex) {
         }        
     }
+
+    private void updateIcon(boolean automatic) {
+        if (mIcon != null) {
+            mIcon.setImageResource(automatic ?
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_on :
+                    com.android.systemui.R.drawable.ic_qs_brightness_auto_off);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
index 194f1f6..f71842e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SettingsView.java
@@ -78,6 +78,7 @@
                 });
 
         mBrightness = new BrightnessController(context,
+                (ImageView)findViewById(R.id.brightness_icon),
                 (ToggleSlider)findViewById(R.id.brightness));
         mDoNotDisturb = new DoNotDisturbController(context,
                 (CompoundButton)findViewById(R.id.do_not_disturb_checkbox));
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 11b58bc..9ea47f9 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -314,7 +314,8 @@
         }
 
         // one more thing: optionally add a list of users to switch to
-        if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {
+        // temporarily enable this by default
+        if (true || SystemProperties.getBoolean("fw.power_user_switcher", false)) {
             addUsersToMenu(mItems);
         }
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e8af0a5..91d5eaa 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1473,16 +1473,24 @@
         return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
     }
 
+    @Override
     public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
         return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
     }
 
+    @Override
     public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) {
-        return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
-                && attrs.type != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
-                && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER
-                && attrs.type != WindowManager.LayoutParams.TYPE_DREAM
-                && attrs.type != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND;
+        switch (attrs.type) {
+            case TYPE_STATUS_BAR:
+            case TYPE_NAVIGATION_BAR:
+            case TYPE_WALLPAPER:
+            case TYPE_DREAM:
+            case TYPE_UNIVERSE_BACKGROUND:
+            case TYPE_KEYGUARD:
+                return false;
+            default:
+                return true;
+        }
     }
 
     /** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
index 1e73c5b..ebca4ac 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardAccountView.java
@@ -60,7 +60,7 @@
     private EditText mPassword;
     private Button mOk;
     public boolean mEnableFallback;
-    private KeyguardNavigationManager mNavigationManager;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
 
     /**
      * Shown while making asynchronous check of password.
@@ -83,7 +83,9 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mNavigationManager = new KeyguardNavigationManager(this);
+
+        // We always set a dummy NavigationManager to avoid null checks
+        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
 
         mLogin = (EditText) findViewById(R.id.login);
         mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
@@ -138,8 +140,9 @@
         mLogin.setText("");
         mPassword.setText("");
         mLogin.requestFocus();
-        mNavigationManager.setMessage(mLockPatternUtils.isPermanentlyLocked() ?
-                R.string.kg_login_too_many_attempts : R.string.kg_login_instructions);
+        boolean permLocked = mLockPatternUtils.isPermanentlyLocked();
+        mSecurityMessageDisplay.setMessage(permLocked ? R.string.kg_login_too_many_attempts :
+            R.string.kg_login_instructions, permLocked ? true : false);
     }
 
     /** {@inheritDoc} */
@@ -179,7 +182,7 @@
                     // dismiss keyguard
                     mCallback.dismiss(true);
                 } else {
-                    mNavigationManager.setMessage(R.string.kg_login_invalid_input);
+                    mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
                     mPassword.setText("");
                     mCallback.reportFailedUnlockAttempt();
                 }
@@ -313,5 +316,10 @@
         reset();
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;
+        reset();
+    }
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
index d059e36..78fdda3 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardFaceUnlockView.java
@@ -16,6 +16,7 @@
 package com.android.internal.policy.impl.keyguard;
 
 import android.content.Context;
+import android.os.PowerManager;
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -29,12 +30,12 @@
 
 public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecurityView {
 
-    private static final String TAG = "KeyguardFaceUnlockView";
+    private static final String TAG = "FULKeyguardFaceUnlockView";
     private static final boolean DEBUG = false;
     private KeyguardSecurityCallback mKeyguardSecurityCallback;
     private LockPatternUtils mLockPatternUtils;
     private BiometricSensorUnlock mBiometricUnlock;
-    private KeyguardNavigationManager mNavigationManager;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
     private View mFaceUnlockAreaView;
     private ImageButton mCancelButton;
 
@@ -49,7 +50,6 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mNavigationManager = new KeyguardNavigationManager(this);
 
         initializeBiometricUnlockView();
     }
@@ -140,11 +140,14 @@
             final boolean backupIsTimedOut = (
                     monitor.getFailedUnlockAttempts() >=
                     LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
-            // TODO: These max attempts checks are also checked in KeyguardSecurityModel so they
-            // might not be necessary here anymore.
-            if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_RINGING
+            PowerManager powerManager = (PowerManager) mContext.getSystemService(
+                    Context.POWER_SERVICE);
+            // TODO: Some of these conditions are handled in KeyguardSecurityModel and may not be
+            // necessary here.
+            if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
                     && !monitor.getMaxBiometricUnlockAttemptsReached()
-                    && !backupIsTimedOut) {
+                    && !backupIsTimedOut
+                    && powerManager.isScreenOn()) {
                 mBiometricUnlock.start();
             } else {
                 mBiometricUnlock.stopAndShowBackup();
@@ -173,4 +176,8 @@
         }
     };
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;    
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 460f3c6..ebc54b32 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -43,11 +43,10 @@
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.View.BaseSavedState;
 import android.view.animation.AnimationUtils;
 import android.widget.RemoteViews.OnClickHandler;
+import android.widget.TextView;
 import android.widget.ViewFlipper;
 
 import com.android.internal.R;
@@ -65,8 +64,8 @@
 
     // also referenced in SecuritySettings.java
     static final int APPWIDGET_HOST_ID = 0x4B455947;
-    private static final String KEYGUARD_WIDGET_PREFS = "keyguard_widget_prefs";
 
+    // transport control states
     private static final int TRANSPORT_GONE = 0;
     private static final int TRANSPORT_INVISIBLE = 1;
     private static final int TRANSPORT_VISIBLE = 2;
@@ -80,7 +79,7 @@
     private boolean mEnableMenuKey;
     private boolean mIsVerifyUnlockOnly;
     private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
-    private SecurityMode mCurrentSecuritySelection = SecurityMode.None;
+    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
 
     protected Runnable mLaunchRunnable;
 
@@ -163,6 +162,10 @@
         addDefaultWidgets();
         updateSecurityViews();
         setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
+
+        if (KeyguardUpdateMonitor.getInstance(mContext).getIsFirstBoot()) {
+            showPrimarySecurityScreen(false);
+        }
     }
 
     private void updateSecurityViews() {
@@ -192,7 +195,8 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mAppWidgetHost.startListening();
-        maybePopulateWidgets();
+        // TODO: Re-enable when we have layouts that can support a better variety of widgets.
+        // maybePopulateWidgets();
         disableStatusViewInteraction();
         post(mSwitchPageRunnable);
     }
@@ -257,9 +261,6 @@
         }
 
         public void dismiss(boolean authenticated) {
-            // If the biometric unlock was suppressed due to a user switch, it can now be safely
-            // unsuppressed because the user has left the unlock screen.
-            KeyguardUpdateMonitor.getInstance(mContext).clearBiometricUnlockUserSwitched();
             showNextSecurityScreenOrFinish(authenticated);
         }
 
@@ -286,7 +287,7 @@
 
         @Override
         public void showBackupSecurity() {
-            KeyguardHostView.this.showBackupSecurity();
+            KeyguardHostView.this.showBackupSecurityScreen();
         }
 
         @Override
@@ -410,13 +411,30 @@
     }
 
     /**
+     * Shows the primary security screen for the user. This will be either the multi-selector
+     * or the user's security method.
+     * @param turningOff true if the device is being turned off
+     */
+    void showPrimarySecurityScreen(boolean turningOff) {
+        SecurityMode securityMode = mSecurityModel.getSecurityMode();
+        if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
+        if (!turningOff && KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
+            // If we're not turning off, then allow biometric alternate.
+            // We'll reload it when the device comes back on.
+            securityMode = mSecurityModel.getAlternateFor(securityMode);
+        }
+        showSecurityScreen(securityMode);
+    }
+
+    /**
      * Shows the backup security screen for the current security mode.  This could be used for
      * password recovery screens but is currently only used for pattern unlock to show the
      * account unlock screen and biometric unlock to show the user's normal unlock.
      */
-    private void showBackupSecurity() {
+    private void showBackupSecurityScreen() {
         if (DEBUG) Log.d(TAG, "showBackupSecurity()");
-        showSecurityScreen(mSecurityModel.getBackupSecurityMode());
+        SecurityMode backup = mSecurityModel.getBackupSecurityMode(mCurrentSecuritySelection);
+        showSecurityScreen(backup);
     }
 
     public boolean showNextSecurityScreenIfPresent() {
@@ -464,14 +482,19 @@
                     break;
 
                 default:
-                    showSecurityScreen(SecurityMode.None);
+                    Log.v(TAG, "Bad security screen " + mCurrentSecuritySelection + ", fail safe");
+                    showPrimarySecurityScreen(false);
                     break;
             }
         } else {
-            // Not authenticated but we were asked to dismiss so go back to selector screen.
-            showSecurityScreen(SecurityMode.None);
+            showPrimarySecurityScreen(false);
         }
         if (finish) {
+            // If the alternate unlock was suppressed, it can now be safely
+            // enabled because the user has left keyguard.
+            KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
+            KeyguardUpdateMonitor.getInstance(mContext).setIsFirstBoot(false);
+
             // If there's a pending runnable because the user interacted with a widget
             // and we're leaving keyguard, then run it.
             if (mLaunchRunnable != null) {
@@ -519,11 +542,51 @@
         };
     };
 
+    private KeyguardStatusViewManager mKeyguardStatusViewManager;
+
+    // Used to ignore callbacks from methods that are no longer current (e.g. face unlock).
+    // This avoids unwanted asynchronous events from messing with the state.
+    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
+
+        @Override
+        public void userActivity(long timeout) {
+        }
+
+        @Override
+        public void showBackupSecurity() {
+        }
+
+        @Override
+        public void setOnDismissRunnable(Runnable runnable) {
+        }
+
+        @Override
+        public void reportSuccessfulUnlockAttempt() {
+        }
+
+        @Override
+        public void reportFailedUnlockAttempt() {
+        }
+
+        @Override
+        public boolean isVerifyUnlockOnly() {
+            return false;
+        }
+
+        @Override
+        public int getFailedAttempts() {
+            return 0;
+        }
+
+        @Override
+        public void dismiss(boolean securityVerified) {
+        }
+    };
+
     @Override
     public void reset() {
         mIsVerifyUnlockOnly = false;
         mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
-        requestFocus();
     }
 
     /**
@@ -544,13 +607,39 @@
                 break;
             }
         }
-        if (view == null) {
+        boolean simPukFullScreen = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
+        int layoutId = getLayoutIdFor(securityMode);
+        if (view == null && layoutId != 0) {
             final LayoutInflater inflater = LayoutInflater.from(mContext);
-            View v = inflater.inflate(getLayoutIdFor(securityMode), this, false);
+            View v = inflater.inflate(layoutId, this, false);
             mSecurityViewContainer.addView(v);
             updateSecurityView(v);
+
             view = (KeyguardSecurityView) v;
+            TextView navigationText = ((TextView) findViewById(R.id.keyguard_message_area));
+
+            // Some devices can fit a navigation area, others cannot. On devices that cannot,
+            // we display the security message in status area.
+            if (navigationText != null) {
+                view.setSecurityMessageDisplay(new KeyguardNavigationManager(navigationText));
+            } else {
+                view.setSecurityMessageDisplay(mKeyguardStatusViewManager);
+            }
         }
+
+        if (securityMode == SecurityMode.SimPin || securityMode == SecurityMode.SimPuk ||
+            securityMode == SecurityMode.Account) {
+            if (simPukFullScreen) {
+                mAppWidgetRegion.setVisibility(View.GONE);
+            }
+        }
+
+        if (view instanceof KeyguardSelectorView) {
+            KeyguardSelectorView selectorView = (KeyguardSelectorView) view;
+            View carrierText = selectorView.findViewById(R.id.keyguard_selector_fade_container);
+            selectorView.setCarrierArea(carrierText);
+        }
+
         return view;
     }
 
@@ -561,15 +650,20 @@
      * @param securityMode
      */
     private void showSecurityScreen(SecurityMode securityMode) {
-        if (DEBUG) Log.d(TAG, "showSecurityScreen");
+        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");
+
         if (securityMode == mCurrentSecuritySelection) return;
 
         KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);
         KeyguardSecurityView newView = getSecurityView(securityMode);
 
         // Emulate Activity life cycle
-        oldView.onPause();
+        if (oldView != null) {
+            oldView.onPause();
+            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view
+        }
         newView.onResume();
+        newView.setKeyguardCallback(mCallback);
 
         final boolean needsInput = newView.needsInput();
         if (mViewMediatorCallback != null) {
@@ -580,10 +674,12 @@
         final int childCount = mSecurityViewContainer.getChildCount();
 
         // Do flip animation to the next screen
-        mSecurityViewContainer.setInAnimation(
-                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_animate_in));
-        mSecurityViewContainer.setOutAnimation(
-                AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_animate_out));
+        if (false) {
+            mSecurityViewContainer.setInAnimation(
+                    AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_animate_in));
+            mSecurityViewContainer.setOutAnimation(
+                    AnimationUtils.loadAnimation(mContext, R.anim.keyguard_security_animate_out));
+        }
         final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
         for (int i = 0; i < childCount; i++) {
             if (mSecurityViewContainer.getChildAt(i).getId() == securityViewIdForMode) {
@@ -592,22 +688,17 @@
             }
         }
 
-
         if (securityMode == SecurityMode.None) {
             // Discard current runnable if we're switching back to the selector view
             setOnDismissRunnable(null);
-            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
-        } else {
-            setSystemUiVisibility(getSystemUiVisibility() & (~View.STATUS_BAR_DISABLE_BACK));
         }
-
         mCurrentSecuritySelection = securityMode;
     }
 
     @Override
     public void onScreenTurnedOn() {
         if (DEBUG) Log.d(TAG, "screen on");
-        showSecurityScreen(mCurrentSecuritySelection);
+        showPrimarySecurityScreen(false);
         getSecurityView(mCurrentSecuritySelection).onResume();
 
         // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
@@ -619,7 +710,7 @@
     @Override
     public void onScreenTurnedOff() {
         if (DEBUG) Log.d(TAG, "screen off");
-        showSecurityScreen(SecurityMode.None);
+        showPrimarySecurityScreen(true);
         getSecurityView(mCurrentSecuritySelection).onPause();
     }
 
@@ -703,7 +794,7 @@
             case SimPin: return R.layout.keyguard_sim_pin_view;
             case SimPuk: return R.layout.keyguard_sim_puk_view;
             default:
-                throw new RuntimeException("No layout for securityMode " + securityMode);
+                return 0;
         }
     }
 
@@ -740,17 +831,12 @@
                 public void onListenerDetached() {
                     int page = getWidgetPosition(R.id.keyguard_transport_control);
                     if (page != -1) {
-                        if (page == mAppWidgetContainer.getCurrentPage()) {
-                            // Switch back to clock view if music was showing.
-                            mAppWidgetContainer
-                                .setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
-                        }
                         mAppWidgetContainer.removeView(mTransportControl);
-                        // XXX keep view attached to hierarchy so we still get show/hide events
-                        // from AudioManager
+                        // XXX keep view attached so we still get show/hide events from AudioManager
                         KeyguardHostView.this.addView(mTransportControl);
                         mTransportControl.setVisibility(View.GONE);
                         mTransportState = TRANSPORT_GONE;
+                        mTransportControl.post(mSwitchPageRunnable);
                     }
                 }
 
@@ -769,6 +855,10 @@
                 }
             });
         }
+
+        mKeyguardStatusViewManager = ((KeyguardStatusView)
+                findViewById(R.id.keyguard_status_view_face_palm)).getManager();
+
     }
 
     private void maybePopulateWidgets() {
@@ -920,7 +1010,9 @@
 
                 @Override
                 public void showUnlockHint() {
-                    mKeyguardSelectorView.ping();
+                    if (mKeyguardSelectorView != null) {
+                        mKeyguardSelectorView.ping();
+                    }
                 }
 
             };
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java
index 646ab92..cec2668 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardNavigationManager.java
@@ -16,36 +16,27 @@
 
 package com.android.internal.policy.impl.keyguard;
 
-import android.view.View;
 import android.widget.TextView;
 
-import com.android.internal.R;
-
-public class KeyguardNavigationManager {
+public class KeyguardNavigationManager implements SecurityMessageDisplay {
 
     private TextView mMessageArea;
-    private KeyguardSecurityView mKeyguardSecurityView;
-    private View mClickArea;
 
-    public KeyguardNavigationManager(KeyguardSecurityView view) {
-        mKeyguardSecurityView = view;
-        mMessageArea = (TextView) ((View) view).findViewById(R.id.keyguard_message_area);
-        mMessageArea.setSelected(true); // Make marquee work
-
-        mClickArea = ((View) view).findViewById(R.id.keyguard_click_area);
-        mClickArea.setOnClickListener(new View.OnClickListener() {
-            public void onClick(View v) {
-                mKeyguardSecurityView.getCallback().dismiss(false);
-            }
-        });
+    public KeyguardNavigationManager(TextView messageArea) {
+        if (messageArea != null) {
+            mMessageArea = messageArea;
+            mMessageArea.setSelected(true); // Make marquee work
+        }
     }
 
-    public void setMessage(CharSequence msg) {
+    public void setMessage(CharSequence msg, boolean important) {
+        if (mMessageArea == null) return;
         mMessageArea.setText(msg);
         mMessageArea.announceForAccessibility(mMessageArea.getText());
     }
 
-    public void setMessage(int resId) {
+    public void setMessage(int resId, boolean important) {
+        if (mMessageArea == null) return;
         if (resId != 0) {
             mMessageArea.setText(resId);
             mMessageArea.announceForAccessibility(mMessageArea.getText());
@@ -54,7 +45,8 @@
         }
     }
 
-    public void setMessage(int resId, Object... formatArgs) {
+    public void setMessage(int resId, boolean important, Object... formatArgs) {
+        if (mMessageArea == null) return;
         if (resId != 0) {
             mMessageArea.setText(mMessageArea.getContext().getString(resId, formatArgs));
             mMessageArea.announceForAccessibility(mMessageArea.getText());
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
index a4e8ea4..1868507 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPasswordView.java
@@ -61,7 +61,7 @@
     private PasswordEntryKeyboardView mKeyboardView;
     private PasswordEntryKeyboardHelper mKeyboardHelper;
     private boolean mIsAlpha;
-    private KeyguardNavigationManager mNavigationManager;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
 
     // To avoid accidental lockout due to events while the device in in the pocket, ignore
     // any passwords with length less than or equal to this length.
@@ -86,6 +86,13 @@
         mLockPatternUtils = utils;
     }
 
+    @Override
+    public void onWindowFocusChanged(boolean hasWindowFocus) {
+        if (hasWindowFocus) {
+            reset();
+        }
+    }
+
     public void reset() {
         // start fresh
         mPasswordEntry.setText("");
@@ -101,17 +108,18 @@
     }
 
     private void resetState() {
-        mNavigationManager.setMessage(
-                mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions);
+        mSecurityMessageDisplay.setMessage(
+                mIsAlpha ? R.string.kg_password_instructions : R.string.kg_pin_instructions, false);
         mPasswordEntry.setEnabled(true);
         mKeyboardView.setEnabled(true);
     }
 
     @Override
     protected void onFinishInflate() {
-        mLockPatternUtils = new LockPatternUtils(mContext); // TODO: use common one
+        // We always set a dummy NavigationManager to avoid null checks
+        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
 
-        mNavigationManager = new KeyguardNavigationManager(this);
+        mLockPatternUtils = new LockPatternUtils(mContext); // TODO: use common one
 
         final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
         mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
@@ -190,7 +198,9 @@
             }
 
             public void afterTextChanged(Editable s) {
-                mCallback.userActivity(0);
+                if (mCallback != null) {
+                    mCallback.userActivity(0);
+                }
             }
         });
 
@@ -209,12 +219,13 @@
             });
         }
 
-        // If no icon is visible, reset the left margin on the password field so the text is
+        // If no icon is visible, reset the start margin on the password field so the text is
         // still centered.
         if (!imeOrDeleteButtonVisible) {
             android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
             if (params instanceof MarginLayoutParams) {
-                ((MarginLayoutParams)params).leftMargin = 0;
+                final MarginLayoutParams mlp = (MarginLayoutParams) params;
+                mlp.setMarginStart(0);
                 mPasswordEntry.setLayoutParams(params);
             }
         }
@@ -288,8 +299,8 @@
                 long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                 handleAttemptLockout(deadline);
             }
-            mNavigationManager.setMessage(
-                    mIsAlpha ? R.string.kg_wrong_password : R.string.kg_wrong_pin);
+            mSecurityMessageDisplay.setMessage(
+                    mIsAlpha ? R.string.kg_wrong_password : R.string.kg_wrong_pin, true);
         }
         mPasswordEntry.setText("");
     }
@@ -304,8 +315,8 @@
             @Override
             public void onTick(long millisUntilFinished) {
                 int secondsRemaining = (int) (millisUntilFinished / 1000);
-                mNavigationManager.setMessage(
-                        R.string.kg_too_many_failed_attempts_countdown, secondsRemaining);
+                mSecurityMessageDisplay.setMessage(
+                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
             }
 
             @Override
@@ -367,5 +378,10 @@
     public void afterTextChanged(Editable s) {
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;
+        reset();
+    }
 }
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
index e4b7798..dcf40bf 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardPatternView.java
@@ -65,7 +65,6 @@
     private Button mForgotPatternButton;
     private KeyguardSecurityCallback mCallback;
     private boolean mEnableFallback;
-    private KeyguardNavigationManager mNavigationManager;
 
     /**
      * Keeps track of the last time we poked the wake lock during dispatching of the touch event.
@@ -84,6 +83,7 @@
         }
     };
     private Rect mTempRect = new Rect();
+    private SecurityMessageDisplay mSecurityMessageDisplay;
 
     enum FooterMode {
         Normal,
@@ -111,7 +111,9 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mNavigationManager = new KeyguardNavigationManager(this);
+        // We always set a dummy NavigationManager to avoid null checks
+        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
+
         mLockPatternUtils = mLockPatternUtils == null
                 ? new LockPatternUtils(mContext) : mLockPatternUtils;
 
@@ -183,7 +185,7 @@
         if (deadline != 0) {
             handleAttemptLockout(deadline);
         } else {
-            mNavigationManager.setMessage(R.string.kg_pattern_instructions);
+            mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
         }
 
         // the footer depends on how many total attempts the user has failed
@@ -255,7 +257,7 @@
                     long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                     handleAttemptLockout(deadline);
                 } else {
-                    mNavigationManager.setMessage(R.string.kg_wrong_pattern);
+                    mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern, true);
                     mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
                 }
             }
@@ -282,8 +284,7 @@
         private void next() {
             // if we are ready to enable the fallback or if we depleted the list of accounts
             // then finish and get out
-            if (mAccountIndex >= mAccounts.length) {
-                mEnableFallback = true;
+            if (mEnableFallback || mAccountIndex >= mAccounts.length) {
                 return;
             }
 
@@ -320,21 +321,23 @@
         mLockPatternView.clearPattern();
         mLockPatternView.setEnabled(false);
         final long elapsedRealtime = SystemClock.elapsedRealtime();
-        updateFooter(FooterMode.ForgotLockPattern);
+        if (mEnableFallback) {
+            updateFooter(FooterMode.ForgotLockPattern);
+        }
 
         mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
 
             @Override
             public void onTick(long millisUntilFinished) {
                 final int secondsRemaining = (int) (millisUntilFinished / 1000);
-                mNavigationManager.setMessage(
-                        R.string.kg_too_many_failed_attempts_countdown, secondsRemaining);
+                mSecurityMessageDisplay.setMessage(
+                        R.string.kg_too_many_failed_attempts_countdown, true, secondsRemaining);
             }
 
             @Override
             public void onFinish() {
                 mLockPatternView.setEnabled(true);
-                mNavigationManager.setMessage(R.string.kg_pattern_instructions);
+                mSecurityMessageDisplay.setMessage(R.string.kg_pattern_instructions, false);
                 // TODO mUnlockIcon.setVisibility(View.VISIBLE);
                 mFailedPatternAttemptsSinceLastTimeout = 0;
                 if (mEnableFallback) {
@@ -370,6 +373,11 @@
         return mCallback;
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;
+        reset();
+    }
 }
 
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
index e573072..59e2ca9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityModel.java
@@ -17,6 +17,7 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.telephony.TelephonyManager;
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
@@ -27,6 +28,7 @@
      * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
      */
     enum SecurityMode {
+        Invalid, // NULL state
         None, // No security enabled
         Pattern, // Unlock by drawing a pattern.
         Password, // Unlock by entering a password or PIN
@@ -52,7 +54,7 @@
      * Returns true if biometric unlock is installed and selected.  If this returns false there is
      * no need to even construct the biometric unlock.
      */
-    private boolean isBiometricUnlockEnabled() {
+    boolean isBiometricUnlockEnabled() {
         return mLockPatternUtils.usingBiometricWeak()
                 && mLockPatternUtils.isBiometricWeakInstalled();
     }
@@ -66,7 +68,8 @@
         final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >=
                 LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
         return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut
-                || monitor.didBiometricUnlockUserSwitch();
+                || !monitor.isAlternateUnlockEnabled()
+                || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
     }
 
     SecurityMode getSecurityMode() {
@@ -126,15 +129,7 @@
      *
      * @return backup method or current security mode
      */
-    SecurityMode getBackupSecurityMode() {
-        SecurityMode mode = getSecurityMode();
-
-        // Note that getAlternateFor() cannot be called here because we want to get the backup for
-        // biometric unlock even if it's suppressed; it just has to be enabled.
-        if (isBiometricUnlockEnabled()
-                && (mode == SecurityMode.Password || mode == SecurityMode.Pattern)) {
-            mode = SecurityMode.Biometric;
-        }
+    SecurityMode getBackupSecurityMode(SecurityMode mode) {
         switch(mode) {
             case Biometric:
                 return getSecurityMode();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
index d80c1db..19bcae9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSecurityView.java
@@ -61,4 +61,5 @@
      */
     KeyguardSecurityCallback getCallback();
 
+    void setSecurityMessageDisplay(SecurityMessageDisplay display);
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index b6b731e..1d26def 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -172,10 +172,13 @@
         super.onFinishInflate();
         mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view);
         mGlowPadView.setOnTriggerListener(mOnTriggerListener);
-        mFadeView = (View) findViewById(R.id.keyguard_selector_fade_container);
         updateTargets();
     }
 
+    public void setCarrierArea(View carrierArea) {
+        mFadeView = carrierArea;
+    }
+
     public boolean isTargetPresent(int resId) {
         return mGlowPadView.getTargetPosition(resId) != -1;
     }
@@ -324,4 +327,7 @@
         return mCallback;
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
index 5a9ffcf..7878e46 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPinView.java
@@ -55,7 +55,7 @@
     private PasswordEntryKeyboardView mKeyboardView;
     private PasswordEntryKeyboardHelper mKeyboardHelper;
     private LockPatternUtils mLockPatternUtils;
-    private KeyguardNavigationManager mNavigationManager;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
 
     private volatile boolean mSimCheckInProgress;
 
@@ -76,7 +76,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mNavigationManager = new KeyguardNavigationManager(this);
+        // We always set a dummy NavigationManager to avoid null checks
+        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
 
         mPinEntry = (EditText) findViewById(R.id.sim_pin_entry);
         mPinEntry.setOnEditorActionListener(this);
@@ -112,7 +113,7 @@
 
     public void reset() {
         // start fresh
-        mNavigationManager.setMessage(R.string.kg_sim_pin_instructions);
+        mSecurityMessageDisplay.setMessage(R.string.kg_sim_pin_instructions, true);
 
         // make sure that the number of entered digits is consistent when we
         // erase the SIM unlock code, including orientation changes.
@@ -193,7 +194,7 @@
     private void checkPin() {
         if (mPinEntry.getText().length() < 4) {
             // otherwise, display a message to the user, and don't submit.
-            mNavigationManager.setMessage(R.string.kg_invalid_sim_pin_hint);
+            mSecurityMessageDisplay.setMessage(R.string.kg_invalid_sim_pin_hint, true);
             mPinEntry.setText("");
             mCallback.userActivity(0);
             return;
@@ -216,7 +217,8 @@
                                 KeyguardUpdateMonitor.getInstance(getContext()).reportSimUnlocked();
                                 mCallback.dismiss(true);
                             } else {
-                                mNavigationManager.setMessage(R.string.kg_password_wrong_pin_code);
+                                mSecurityMessageDisplay.setMessage
+                                    (R.string.kg_password_wrong_pin_code, true);
                                 mPinEntry.setText("");
                             }
                             mCallback.userActivity(0);
@@ -263,4 +265,9 @@
     public void afterTextChanged(Editable s) {
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;
+        reset();
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
index 2cdb52d..562d893 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSimPukView.java
@@ -48,7 +48,7 @@
     private ProgressDialog mSimUnlockProgressDialog = null;
     private KeyguardSecurityCallback mCallback;
 
-    private KeyguardNavigationManager mNavigationManager;
+    private SecurityMessageDisplay mSecurityMessageDisplay;
 
     private PasswordEntryKeyboardView mKeyboardView;
 
@@ -91,7 +91,7 @@
             } else if (state == CONFIRM_PIN) {
                 if (confirmPin()) {
                     state = DONE;
-                    msg = R.string.kg_login_checking_password;
+                    msg = R.string.lockscreen_sim_unlock_progress_dialog_message;
                     updateSim();
                 } else {
                     msg = R.string.kg_invalid_confirm_pin_hint;
@@ -99,7 +99,7 @@
             }
             mSimPinEntry.setText(null);
             if (msg != 0) {
-                mNavigationManager.setMessage(msg);
+                mSecurityMessageDisplay.setMessage(msg, true);
             }
         }
 
@@ -107,7 +107,7 @@
             mPinText="";
             mPukText="";
             state = ENTER_PUK;
-            mNavigationManager.setMessage(R.string.kg_puk_enter_puk_hint);
+            mSecurityMessageDisplay.setMessage(R.string.kg_puk_enter_puk_hint, true);
             mSimPinEntry.requestFocus();
         }
     }
@@ -130,7 +130,8 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mNavigationManager = new KeyguardNavigationManager(this);
+        // We always set a dummy NavigationManager to avoid null checks
+        mSecurityMessageDisplay = new KeyguardNavigationManager(null);
 
         mSimPinEntry = (TextView) findViewById(R.id.sim_pin_entry);
         mSimPinEntry.setOnEditorActionListener(this);
@@ -279,7 +280,7 @@
                                 mCallback.dismiss(true);
                             } else {
                                 mStateMachine.reset();
-                                mNavigationManager.setMessage(R.string.kg_invalid_puk);
+                                mSecurityMessageDisplay.setMessage(R.string.kg_invalid_puk, true);
                             }
                             mCheckInProgress = false;
                         }
@@ -333,4 +334,9 @@
     public void afterTextChanged(Editable s) {
     }
 
+    @Override
+    public void setSecurityMessageDisplay(SecurityMessageDisplay display) {
+        mSecurityMessageDisplay = display;
+        reset();
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
index 5704425..00cd5b9 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusView.java
@@ -44,4 +44,7 @@
         mStatusViewManager = new KeyguardStatusViewManager(this);
     }
 
+    KeyguardStatusViewManager getManager() {
+        return mStatusViewManager;
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
index f97d67d..5b85064 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStatusViewManager.java
@@ -27,7 +27,10 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -36,10 +39,14 @@
 import android.view.View;
 import android.widget.TextView;
 
+import java.util.Date;
+
+import libcore.util.MutableInt;
+
 /***
  * Manages a number of views inside of the given layout. See below for a list of widgets.
  */
-class KeyguardStatusViewManager {
+class KeyguardStatusViewManager implements SecurityMessageDisplay {
     private static final boolean DEBUG = false;
     private static final String TAG = "KeyguardStatusView";
 
@@ -55,6 +62,9 @@
     private TextView mStatus1View;
     private TextView mOwnerInfoView;
     private TextView mAlarmStatusView;
+    private TextView mSecurityMessage;
+    private static final int SECURITY_MESSAGE_DURATION = 5000;
+    private static final boolean SECURITY_MESSAGE_TIMES_OUT = false;
 
     // Top-level container view for above views
     private View mContainer;
@@ -65,6 +75,10 @@
     // last known plugged in state
     private boolean mPluggedIn = false;
 
+    // Whether to use the last line as a combined line to either display owner info / charging.
+    // If false, each item will be given a dedicated space.
+    private boolean mShareStatusRegion = false;
+    
     // last known battery level
     private int mBatteryLevel = 100;
 
@@ -79,6 +93,10 @@
     protected boolean mBatteryCharged;
     protected boolean mBatteryIsLow;
 
+    private Handler mHandler;
+    private Runnable mClearSecurityMessageRunnable;
+    private CharSequence mSecurityMessageContents = "";
+
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
         @Override
         public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
@@ -102,8 +120,10 @@
     public KeyguardStatusViewManager(View view) {
         if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
         mContainer = view;
-        mDateFormatString = getContext().getResources().getText(
-                com.android.internal.R.string.abbrev_wday_month_day_no_year);
+        Resources res = getContext().getResources();
+        mDateFormatString = 
+                res.getText(com.android.internal.R.string.abbrev_wday_month_day_no_year);
+        mShareStatusRegion = res.getBoolean(R.bool.kg_share_status_area);
         mLockPatternUtils = new LockPatternUtils(view.getContext());
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(view.getContext());
 
@@ -112,6 +132,12 @@
         mAlarmStatusView = (TextView) view.findViewById(R.id.alarm_status);
         mOwnerInfoView = (TextView) view.findViewById(R.id.owner_info);
         mClockView = (ClockView) view.findViewById(R.id.clock_view);
+        mSecurityMessage = (TextView) view.findViewById(R.id.status_security_message);
+
+        // This is required to ensure marquee works
+        if (mSecurityMessage != null) {
+            mSecurityMessage.setSelected(true);
+        }
 
         // Use custom font in mDateView
         mDateView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
@@ -129,9 +155,17 @@
         // Registering this callback immediately updates the battery state, among other things.
         mUpdateMonitor.registerCallback(mInfoCallback);
 
-        resetStatusInfo();
         refreshDate();
-        updateOwnerInfo();
+        resetStatusInfo();
+
+        mHandler = new Handler(Looper.myLooper());
+        mClearSecurityMessageRunnable = new Runnable() {
+            @Override
+            public void run() {
+                mSecurityMessageContents = "";
+                updateStatusLines();
+            }
+        };
     }
 
     public void onPause() {
@@ -154,6 +188,42 @@
         updateStatusLines();
     }
 
+    public void setMessage(CharSequence msg, boolean important) {
+        if (!important) {
+            mSecurityMessageContents = "";
+        } else {
+            mSecurityMessageContents = msg;
+        }
+        securityMessageChanged();
+    }
+
+    public void setMessage(int resId, boolean important) {
+        if (resId != 0 && important) {
+            mSecurityMessageContents = getContext().getResources().getText(resId);
+        } else {
+            mSecurityMessageContents = "";
+        }
+        securityMessageChanged();
+    }
+
+    public void setMessage(int resId, boolean important, Object... formatArgs) {
+        if (resId != 0 && important) {
+            mSecurityMessageContents = getContext().getString(resId, formatArgs);
+        } else {
+            mSecurityMessageContents = "";
+        }
+        securityMessageChanged();
+    }
+
+    public void securityMessageChanged() {
+        updateStatusLines();
+        if (SECURITY_MESSAGE_TIMES_OUT) {
+            mHandler.removeCallbacks(mClearSecurityMessageRunnable);
+            mHandler.postDelayed(mClearSecurityMessageRunnable, SECURITY_MESSAGE_DURATION);
+        }
+        mSecurityMessage.announceForAccessibility(mSecurityMessage.getText());
+    }
+
     /**
      * Update the status lines based on these rules:
      * AlarmStatus: Alarm state always gets it's own line.
@@ -163,8 +233,21 @@
      */
     void updateStatusLines() {
         updateAlarmInfo();
-        updateOwnerInfo();
-        updateStatus1();
+        boolean statusAreaUsed = updateSecurityMessage();
+        statusAreaUsed = updateStatus1(statusAreaUsed) || statusAreaUsed;
+        updateOwnerInfo(statusAreaUsed);
+    }
+
+    private boolean updateSecurityMessage() {
+        if (mSecurityMessage == null) return false;
+        if (!TextUtils.isEmpty(mSecurityMessageContents)) {
+            mSecurityMessage.setText(mSecurityMessageContents);
+            mSecurityMessage.setVisibility(View.VISIBLE);
+            return true;
+        } else {
+            mSecurityMessage.setVisibility(View.GONE);
+            return false;
+        }
     }
 
     private void updateAlarmInfo() {
@@ -178,13 +261,31 @@
         }
     }
 
-    private void updateOwnerInfo() {
+    private boolean updateStatus1(boolean statusAreaUsed) {
+        MutableInt icon = new MutableInt(0);
+        CharSequence string = getPriorityTextMessage(icon);
+
+        boolean dontShow = statusAreaUsed && mShareStatusRegion;
+        if (!dontShow && !TextUtils.isEmpty(string)) {
+            maybeSetUpperCaseText(mStatus1View, string);
+            mStatus1View.setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
+            mStatus1View.setVisibility(View.VISIBLE);
+            return true;
+        } else {
+            mStatus1View.setVisibility(View.GONE);
+            return false;
+        }
+    }
+
+    private void updateOwnerInfo(boolean statusAreaUsed) {
         final ContentResolver res = getContext().getContentResolver();
         final boolean ownerInfoEnabled = Settings.Secure.getIntForUser(res,
                 Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
         String text = Settings.Secure.getStringForUser(res, Settings.Secure.LOCK_SCREEN_OWNER_INFO,
                 UserHandle.USER_CURRENT);
-        if (ownerInfoEnabled && !TextUtils.isEmpty(text)) {
+
+        boolean dontShow = statusAreaUsed && mShareStatusRegion;
+        if (!dontShow && ownerInfoEnabled && !TextUtils.isEmpty(text)) {
             text = text.trim(); // Remove trailing newlines
             maybeSetUpperCaseText(mOwnerInfoView, text);
             mOwnerInfoView.setVisibility(View.VISIBLE);
@@ -193,18 +294,6 @@
         }
     }
 
-    private void updateStatus1() {
-        MutableInt icon = new MutableInt(0);
-        CharSequence string = getPriorityTextMessage(icon);
-        if (!TextUtils.isEmpty(string)) {
-            maybeSetUpperCaseText(mStatus1View, string);
-            mStatus1View.setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
-            mStatus1View.setVisibility(View.VISIBLE);
-        } else {
-            mStatus1View.setVisibility(View.GONE);
-        }
-    }
-
     private CharSequence getPriorityTextMessage(MutableInt icon) {
         CharSequence string = null;
         if (mShowingBatteryInfo) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 63a074a..d8e1c1a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -102,7 +102,7 @@
     private int mFailedAttempts = 0;
     private int mFailedBiometricUnlockAttempts = 0;
 
-    private boolean mBiometricUnlockUserSwitched;
+    private boolean mAlternateUnlockEnabled;
 
     private boolean mClockVisible;
 
@@ -195,6 +195,7 @@
             }
         }
     };
+    private boolean mIsFirstBoot;
 
     /**
      * When we receive a
@@ -406,7 +407,7 @@
                 cb.onUserSwitched(userId);
             }
         }
-        mBiometricUnlockUserSwitched = true;
+        setAlternateUnlockEnabled(false);
         try {
             reply.sendResult(null);
         } catch (RemoteException e) {
@@ -724,12 +725,12 @@
         return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
     }
 
-    public boolean didBiometricUnlockUserSwitch() {
-        return mBiometricUnlockUserSwitched;
+    public boolean isAlternateUnlockEnabled() {
+        return mAlternateUnlockEnabled;
     }
 
-    public void clearBiometricUnlockUserSwitched() {
-        mBiometricUnlockUserSwitched = false;
+    public void setAlternateUnlockEnabled(boolean enabled) {
+        mAlternateUnlockEnabled = enabled;
     }
 
     public boolean isSimLocked() {
@@ -752,4 +753,12 @@
                 || simState == IccCardConstants.State.PUK_REQUIRED
                 || simState == IccCardConstants.State.PERM_DISABLED);
     }
+
+    public void setIsFirstBoot(boolean b) {
+        mIsFirstBoot = b;
+    }
+    
+    public boolean getIsFirstBoot() {
+        return mIsFirstBoot;
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
index 1754f7f..0ad2404 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewManager.java
@@ -210,14 +210,25 @@
         mKeyguardView.setLockPatternUtils(mLockPatternUtils);
         mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
 
-        if (options != null && options.getBoolean(LockPatternUtils.KEYGUARD_SHOW_USER_SWITCHER)) {
-            mKeyguardView.goToUserSwitcher();
-            mKeyguardView.showNextSecurityScreenIfPresent();
+        // HACK
+        // The keyguard view will have set up window flags in onFinishInflate before we set
+        // the view mediator callback. Make sure it knows the correct IME state.
+        if (mViewMediatorCallback != null) {
+            KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
+                    R.id.keyguard_password_view);
+
+            if (kpv != null) {
+                mViewMediatorCallback.setNeedsInput(kpv.needsInput());
+            }
         }
 
-        if (options != null &&
-                options.getBoolean(LockPatternUtils.KEYGUARD_SHOW_SECURITY_CHALLENGE)) {
-            mKeyguardView.showNextSecurityScreenIfPresent();
+        if (options != null) {
+            if (options.getBoolean(LockPatternUtils.KEYGUARD_SHOW_USER_SWITCHER)) {
+                mKeyguardView.goToUserSwitcher();
+            }
+            if (options.getBoolean(LockPatternUtils.KEYGUARD_SHOW_SECURITY_CHALLENGE)) {
+                mKeyguardView.showNextSecurityScreenIfPresent();
+            }
         }
 
         if (mScreenOn) {
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 3ed952c..92f9dfd 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -309,8 +309,9 @@
                 options.putBoolean(LockPatternUtils.KEYGUARD_SHOW_USER_SWITCHER, true);
                 options.putBoolean(LockPatternUtils.KEYGUARD_SHOW_SECURITY_CHALLENGE, true);
                 resetStateLocked(options);
-
                 adjustStatusBarLocked();
+                // Disable face unlock when the user switches.
+                KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
             }
         }
 
@@ -519,6 +520,11 @@
             if (DEBUG) Log.d(TAG, "onSystemReady");
             mSystemReady = true;
             mUpdateMonitor.registerCallback(mUpdateCallback);
+            
+            // Disable alternate unlock right after boot until things have settled.
+            mUpdateMonitor.setAlternateUnlockEnabled(false);
+            mUpdateMonitor.setIsFirstBoot(true);
+            
             doKeyguardLocked();
         }
         // Most services aren't available until the system reaches the ready state, so we
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
index bd79d67..4ff6f27 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetRegion.java
@@ -29,6 +29,9 @@
     private int mPage = 0;
     private Callbacks mCallbacks;
 
+    // We are disabling touch interaction of the widget region for factory ROM. 
+    private static final boolean DISABLE_TOUCH_INTERACTION = true;
+
     private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
 
     public KeyguardWidgetRegion(Context context) {
@@ -52,19 +55,21 @@
         mPager.setPageSwitchListener(this);
 
         setSoundEffectsEnabled(false);
-        setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                showPagingFeedback();
-            }
-        });
+        if (!DISABLE_TOUCH_INTERACTION) {
+            setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    showPagingFeedback();
+                }
+            });
+        }
     }
 
     public void showPagingFeedback() {
-        if (true || (mPage < mPager.getPageCount() - 1)) {
+        if ((mPage < mPager.getPageCount() - 1)) {
             mLeftStrip.makeEmGo();
         }
-        if (true || (mPage > 0)) {
+        if ((mPage > 0)) {
             mRightStrip.makeEmGo();
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index fc7c90f..86c05b1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -77,6 +77,9 @@
     private static final int MIN_SNAP_VELOCITY = 1500;
     private static final int MIN_FLING_VELOCITY = 250;
 
+    // We are disabling touch interaction of the widget region for factory ROM. 
+    private static final boolean DISABLE_TOUCH_INTERACTION = true;
+
     static final int AUTOMATIC_PAGE_SPACING = -1;
 
     protected int mFlingThresholdVelocity;
@@ -90,6 +93,8 @@
     protected boolean mFirstLayout = true;
 
     protected int mCurrentPage;
+    protected int mChildCountOnLastMeasure;
+
     protected int mNextPage = INVALID_PAGE;
     protected int mMaxScrollX;
     protected Scroller mScroller;
@@ -315,6 +320,7 @@
             return;
         }
 
+        mForceScreenScrolled = true;
         mCurrentPage = Math.max(0, Math.min(currentPage, getPageCount() - 1));
         updateCurrentPageScroll();
         updateScrollingIndicator();
@@ -498,6 +504,11 @@
         // ensure that the cache is filled with good values.
         invalidateCachedOffsets();
 
+        if (mChildCountOnLastMeasure != getChildCount()) {
+            setCurrentPage(mCurrentPage);
+        }
+        mChildCountOnLastMeasure = getChildCount();
+
         if (childCount > 0) {
             if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getMeasuredWidth() + ", "
                     + getChildWidth(0));
@@ -595,10 +606,7 @@
 
     @Override
     public void onChildViewRemoved(View parent, View child) {
-        invalidate();
-        invalidateCachedOffsets();
-        // This prevents a crash when a child is removed that was the current page.
-        mCurrentPage = Math.min(mCurrentPage, getChildCount() - 1);
+        // TODO Auto-generated method stub
     }
 
     protected void invalidateCachedOffsets() {
@@ -621,6 +629,8 @@
     }
 
     protected int getChildOffset(int index) {
+        if (index < 0 || index > getChildCount() - 1) return 0;
+
         int[] childOffsets = Float.compare(mLayoutScale, 1f) == 0 ?
                 mChildOffsets : mChildOffsetsWithLayoutScale;
 
@@ -642,6 +652,8 @@
     }
 
     protected int getRelativeChildOffset(int index) {
+        if (index < 0 || index > getChildCount() - 1) return 0;
+
         if (mChildRelativeOffsets != null && mChildRelativeOffsets[index] != -1) {
             return mChildRelativeOffsets[index];
         } else {
@@ -853,6 +865,10 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (DISABLE_TOUCH_INTERACTION) {
+            return false;
+        }
+
         /*
          * This method JUST determines whether we want to intercept the motion.
          * If we return true, onTouchEvent will be called and we do the actual
@@ -1091,6 +1107,10 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
+        if (DISABLE_TOUCH_INTERACTION) {
+            return false;
+        }
+
         // Skip touch handling if there are no pages to swipe
         if (getChildCount() <= 0) return super.onTouchEvent(ev);
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs b/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
similarity index 67%
copy from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
copy to policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
index 9eb5d43..b57d8c1 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SecurityMessageDisplay.java
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#pragma version(1)
-#pragma rs java_package_name(com.android.rs.image)
+package com.android.internal.policy.impl.keyguard;
 
-void root(const uchar4 *v_in, uchar4 *v_out) {
-    *v_out = *v_in;
+public interface SecurityMessageDisplay {
+    public void setMessage(CharSequence msg, boolean important);
+
+    public void setMessage(int resId, boolean important);
+
+    public void setMessage(int resId, boolean important, Object... formatArgs);
 }
-
-
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index c18fe0e..e7e4f87 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -304,6 +304,8 @@
 
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+
         // Dump the state of all the app widget providers
         synchronized (mAppWidgetServices) {
             IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index 840e006..0fe66fc 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -52,12 +52,12 @@
 # NotificationManagerService.java
 # ---------------------------
 # when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(notification|3)
+2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes
 # calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(required_flags|1),(forbidden_flags|1)
+2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
 # when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(required_flags|1),(forbidden_flags|1)
+2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
 
 
 # ---------------------------
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index c5016e6..6948927 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -609,10 +609,9 @@
     }
 
     /**
-     * Throw SecurityException if caller has neither COARSE or FINE.
-     * Otherwise, return the best permission.
+     * Returns the best permission available to the caller.
      */
-    private String checkPermission() {
+    private String getBestCallingPermission() {
         if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) ==
                 PackageManager.PERMISSION_GRANTED) {
             return ACCESS_FINE_LOCATION;
@@ -620,9 +619,20 @@
                 PackageManager.PERMISSION_GRANTED) {
             return ACCESS_COARSE_LOCATION;
         }
+        return null;
+    }
 
-        throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
-                " ACCESS_FINE_LOCATION permission");
+    /**
+     * Throw SecurityException if caller has neither COARSE or FINE.
+     * Otherwise, return the best permission.
+     */
+    private String checkPermission() {
+        String perm = getBestCallingPermission();
+        if (perm == null) {
+            throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
+                    " ACCESS_FINE_LOCATION permission");
+        }
+        return perm;
     }
 
     /**
@@ -635,19 +645,15 @@
         }
     }
 
-    private boolean isAllowedProviderSafe(String provider) {
+    private String getMinimumPermissionForProvider(String provider) {
         if (LocationManager.GPS_PROVIDER.equals(provider) ||
                 LocationManager.PASSIVE_PROVIDER.equals(provider)) {
             // gps and passive providers require FINE permission
-            return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
-                    == PackageManager.PERMISSION_GRANTED;
+            return ACCESS_FINE_LOCATION;
         } else if (LocationManager.NETWORK_PROVIDER.equals(provider) ||
                 LocationManager.FUSED_PROVIDER.equals(provider)) {
             // network and fused providers are ok with COARSE or FINE
-            return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
-                    == PackageManager.PERMISSION_GRANTED) ||
-                    (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
-                    == PackageManager.PERMISSION_GRANTED);
+            return ACCESS_COARSE_LOCATION;
         } else {
             // mock providers
             LocationProviderInterface lp = mMockProviders.get(provider);
@@ -656,20 +662,43 @@
                 if (properties != null) {
                     if (properties.mRequiresSatellite) {
                         // provider requiring satellites require FINE permission
-                        return mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
-                                == PackageManager.PERMISSION_GRANTED;
+                        return ACCESS_FINE_LOCATION;
                     } else if (properties.mRequiresNetwork || properties.mRequiresCell) {
                         // provider requiring network and or cell require COARSE or FINE
-                        return (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
-                                == PackageManager.PERMISSION_GRANTED) ||
-                                (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
-                                 == PackageManager.PERMISSION_GRANTED);
+                        return ACCESS_COARSE_LOCATION;
                     }
                 }
             }
         }
 
-        return false;
+        return null;
+    }
+
+    private boolean isPermissionSufficient(String perm, String minPerm) {
+        if (ACCESS_FINE_LOCATION.equals(minPerm)) {
+            return ACCESS_FINE_LOCATION.equals(perm);
+        } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
+            return ACCESS_FINE_LOCATION.equals(perm) ||
+                    ACCESS_COARSE_LOCATION.equals(perm);
+        } else {
+            return false;
+        }
+    }
+
+    private void checkPermissionForProvider(String perm, String provider) {
+        String minPerm = getMinimumPermissionForProvider(provider);
+        if (!isPermissionSufficient(perm, minPerm)) {
+            if (ACCESS_FINE_LOCATION.equals(minPerm)) {
+                throw new SecurityException("Location provider \"" + provider +
+                        "\" requires ACCESS_FINE_LOCATION permission.");
+            } else if (ACCESS_COARSE_LOCATION.equals(minPerm)) {
+                throw new SecurityException("Location provider \"" + provider +
+                        "\" requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.");                
+            } else {
+                throw new SecurityException("Insufficient permission for location provider \"" +
+                        provider + "\".");
+            }
+        }
     }
 
     /**
@@ -703,6 +732,7 @@
     @Override
     public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
         ArrayList<String> out;
+        String perm = getBestCallingPermission();
         int callingUserId = UserHandle.getCallingUserId();
         long identity = Binder.clearCallingIdentity();
         try {
@@ -713,7 +743,7 @@
                     if (LocationManager.FUSED_PROVIDER.equals(name)) {
                         continue;
                     }
-                    if (isAllowedProviderSafe(name)) {
+                    if (isPermissionSufficient(perm, getMinimumPermissionForProvider(name))) {
                         if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) {
                             continue;
                         }
@@ -980,26 +1010,12 @@
         return receiver;
     }
 
-    private boolean isProviderAllowedByCoarsePermission(String provider) {
-        if (LocationManager.FUSED_PROVIDER.equals(provider)) {
-            return true;
-        }
-        if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
-            return true;
-        }
-        if (LocationManager.NETWORK_PROVIDER.equals(provider)) {
-            return true;
-        }
-        return false;
-    }
-
     private String checkPermissionAndRequest(LocationRequest request) {
-        String perm = checkPermission();
+        String perm = getBestCallingPermission();
+        String provider = request.getProvider();
+        checkPermissionForProvider(perm, provider);
 
         if (ACCESS_COARSE_LOCATION.equals(perm)) {
-            if (!isProviderAllowedByCoarsePermission(request.getProvider())) {
-                throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
-            }
             switch (request.getQuality()) {
                 case LocationRequest.ACCURACY_FINE:
                     request.setQuality(LocationRequest.ACCURACY_BLOCK);
@@ -1324,7 +1340,7 @@
      */
     @Override
     public ProviderProperties getProviderProperties(String provider) {
-        checkPermission();
+        checkPermissionForProvider(getBestCallingPermission(), provider);
 
         LocationProviderInterface p;
         synchronized (mLock) {
@@ -1337,13 +1353,8 @@
 
     @Override
     public boolean isProviderEnabled(String provider) {
-        String perms = checkPermission();
+        checkPermissionForProvider(getBestCallingPermission(), provider);
         if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
-        if (ACCESS_COARSE_LOCATION.equals(perms) &&
-                !isProviderAllowedByCoarsePermission(provider)) {
-            throw new SecurityException("The \"" + provider +
-                    "\" provider requires ACCESS_FINE_LOCATION permission");
-        }
 
         long identity = Binder.clearCallingIdentity();
         try {
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 09a606e..4a54efe 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -916,7 +916,7 @@
         //     behalf of the download manager without affecting other apps.
         if (!pkg.equals("com.android.providers.downloads")
                 || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
-            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag,
+            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId,
                     notification.toString());
         }
 
@@ -1207,7 +1207,7 @@
      */
     private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
             int mustNotHaveFlags, boolean sendDelete, int userId) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag,
+        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
                 mustHaveFlags, mustNotHaveFlags);
 
         synchronized (mNotificationList) {
@@ -1231,20 +1231,34 @@
     }
 
     /**
+     * Determine whether the userId applies to the notification in question, either because
+     * they match exactly, or one of them is USER_ALL (which is treated as a wildcard).
+     */
+    private boolean notificationMatchesUserId(NotificationRecord r, int userId) {
+        return
+                // looking for USER_ALL notifications? match everything
+                   userId == UserHandle.USER_ALL
+                // a notification sent to USER_ALL matches any query
+                || r.userId == UserHandle.USER_ALL
+                // an exact user match
+                || r.userId == userId;
+    }
+
+    /**
      * Cancels all notifications from a given package that have all of the
      * {@code mustHaveFlags}.
      */
     boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
             int mustNotHaveFlags, boolean doit, int userId) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags,
-                mustNotHaveFlags);
+        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId,
+                mustHaveFlags, mustNotHaveFlags);
 
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
             boolean canceledSomething = false;
             for (int i = N-1; i >= 0; --i) {
                 NotificationRecord r = mNotificationList.get(i);
-                if (userId != UserHandle.USER_ALL && r.userId != userId) {
+                if (!notificationMatchesUserId(r, userId)) {
                     continue;
                 }
                 if ((r.notification.flags & mustHaveFlags) != mustHaveFlags) {
@@ -1322,7 +1336,7 @@
             for (int i=N-1; i>=0; i--) {
                 NotificationRecord r = mNotificationList.get(i);
 
-                if (r.userId != userId) {
+                if (!notificationMatchesUserId(r, userId)) {
                     continue;
                 }
 
@@ -1376,7 +1390,7 @@
         final int len = list.size();
         for (int i=0; i<len; i++) {
             NotificationRecord r = list.get(i);
-            if (r.userId != userId || r.id != id) {
+            if (!notificationMatchesUserId(r, userId) || r.id != id) {
                 continue;
             }
             if (tag == null) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index daed0a2..7132e1e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3930,48 +3930,54 @@
             removeDyingProviderLocked(null, providers.get(i), true);
         }
 
-        if (mIntentSenderRecords.size() > 0) {
-            Iterator<WeakReference<PendingIntentRecord>> it
-                    = mIntentSenderRecords.values().iterator();
-            while (it.hasNext()) {
-                WeakReference<PendingIntentRecord> wpir = it.next();
-                if (wpir == null) {
+        if (name == null) {
+            // Remove pending intents.  For now we only do this when force
+            // stopping users, because we have some problems when doing this
+            // for packages -- app widgets are not currently cleaned up for
+            // such packages, so they can be left with bad pending intents.
+            if (mIntentSenderRecords.size() > 0) {
+                Iterator<WeakReference<PendingIntentRecord>> it
+                        = mIntentSenderRecords.values().iterator();
+                while (it.hasNext()) {
+                    WeakReference<PendingIntentRecord> wpir = it.next();
+                    if (wpir == null) {
+                        it.remove();
+                        continue;
+                    }
+                    PendingIntentRecord pir = wpir.get();
+                    if (pir == null) {
+                        it.remove();
+                        continue;
+                    }
+                    if (name == null) {
+                        // Stopping user, remove all objects for the user.
+                        if (pir.key.userId != userId) {
+                            // Not the same user, skip it.
+                            continue;
+                        }
+                    } else {
+                        if (UserHandle.getAppId(pir.uid) != appId) {
+                            // Different app id, skip it.
+                            continue;
+                        }
+                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
+                            // Different user, skip it.
+                            continue;
+                        }
+                        if (!pir.key.packageName.equals(name)) {
+                            // Different package, skip it.
+                            continue;
+                        }
+                    }
+                    if (!doit) {
+                        return true;
+                    }
+                    didSomething = true;
                     it.remove();
-                    continue;
-                }
-                PendingIntentRecord pir = wpir.get();
-                if (pir == null) {
-                    it.remove();
-                    continue;
-                }
-                if (name == null) {
-                    // Stopping user, remove all objects for the user.
-                    if (pir.key.userId != userId) {
-                        // Not the same user, skip it.
-                        continue;
+                    pir.canceled = true;
+                    if (pir.key.activity != null) {
+                        pir.key.activity.pendingResults.remove(pir.ref);
                     }
-                } else {
-                    if (UserHandle.getAppId(pir.uid) != appId) {
-                        // Different app id, skip it.
-                        continue;
-                    }
-                    if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
-                        // Different user, skip it.
-                        continue;
-                    }
-                    if (!pir.key.packageName.equals(name)) {
-                        // Different package, skip it.
-                        continue;
-                    }
-                }
-                if (!doit) {
-                    return true;
-                }
-                didSomething = true;
-                it.remove();
-                pir.canceled = true;
-                if (pir.key.activity != null) {
-                    pir.key.activity.pendingResults.remove(pir.ref);
                 }
             }
         }
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 03ff21f..bb19cc7 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -628,6 +628,7 @@
         private final String[] mDaemons;
         private final String[][] mArguments;
         private final LocalSocket[] mSockets;
+        private final String mOuterInterface;
 
         private long mTimer = -1;
 
@@ -638,10 +639,15 @@
             // TODO: clear arguments from memory once launched
             mArguments = new String[][] {racoon, mtpd};
             mSockets = new LocalSocket[mDaemons.length];
+
+            // This is the interface which VPN is running on,
+            // mConfig.interfaze will change to point to OUR
+            // internal interface soon. TODO - add inner/outer to mconfig
+            mOuterInterface = mConfig.interfaze;
         }
 
         public void check(String interfaze) {
-            if (interfaze.equals(mConfig.interfaze)) {
+            if (interfaze.equals(mOuterInterface)) {
                 Log.i(TAG, "Legacy VPN is going down with " + interfaze);
                 exit();
             }
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index 3e541dd..c441b02 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -198,6 +198,12 @@
             updateRememberedDisplaysLocked();
             scheduleStatusChangedBroadcastLocked();
         }
+
+        if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)
+                && mDisplayDevice != null) {
+            mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName());
+            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
+        }
     }
 
     public void requestForgetLocked(String address) {
@@ -397,7 +403,7 @@
     };
 
     private final class WifiDisplayDevice extends DisplayDevice {
-        private final String mName;
+        private String mName;
         private final int mWidth;
         private final int mHeight;
         private final float mRefreshRate;
@@ -423,6 +429,11 @@
             sendTraversalRequestLocked();
         }
 
+        public void setNameLocked(String name) {
+            mName = name;
+            mInfo = null;
+        }
+
         @Override
         public void performTraversalInTransactionLocked() {
             setSurfaceInTransactionLocked(mSurface);
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index b76ad45..4e692a2 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -162,6 +162,11 @@
     // Poll interval in milliseconds for watching boot animation finished.
     private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
 
+    // If the battery level drops by this percentage and the user activity timeout
+    // has expired, then assume the device is receiving insufficient current to charge
+    // effectively and terminate the dream.
+    private static final int DREAM_BATTERY_LEVEL_DRAIN_CUTOFF = 5;
+
     private Context mContext;
     private LightsService mLightsService;
     private BatteryService mBatteryService;
@@ -256,6 +261,14 @@
     // The current plug type, such as BatteryManager.BATTERY_PLUGGED_WIRELESS.
     private int mPlugType;
 
+    // The current battery level percentage.
+    private int mBatteryLevel;
+
+    // The battery level percentage at the time the dream started.
+    // This is used to terminate a dream and go to sleep if the battery is
+    // draining faster than it is charging and the user activity timeout has expired.
+    private int mBatteryLevelWhenDreamStarted;
+
     // True if the device should wake up when plugged or unplugged.
     private boolean mWakeUpWhenPluggedOrUnpluggedConfig;
 
@@ -1067,12 +1080,14 @@
             final int oldPlugType = mPlugType;
             mIsPowered = mBatteryService.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
             mPlugType = mBatteryService.getPlugType();
+            mBatteryLevel = mBatteryService.getBatteryLevel();
 
             if (DEBUG) {
                 Slog.d(TAG, "updateIsPoweredLocked: wasPowered=" + wasPowered
                         + ", mIsPowered=" + mIsPowered
                         + ", oldPlugType=" + oldPlugType
-                        + ", mPlugType=" + mPlugType);
+                        + ", mPlugType=" + mPlugType
+                        + ", mBatteryLevel=" + mBatteryLevel);
             }
 
             if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
@@ -1126,8 +1141,7 @@
         }
         if (!wasPowered && mIsPowered
                 && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS
-                && mBatteryService.getBatteryLevel() >=
-                        WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
+                && mBatteryLevel >= WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) {
             return false;
         }
 
@@ -1403,7 +1417,7 @@
             mSandmanScheduled = false;
             boolean canDream = canDreamLocked();
             if (DEBUG_SPEW) {
-                Log.d(TAG, "handleSandman: canDream=" + canDream
+                Slog.d(TAG, "handleSandman: canDream=" + canDream
                         + ", mWakefulness=" + wakefulnessToString(mWakefulness));
             }
 
@@ -1431,10 +1445,24 @@
                 if (mWakefulness == WAKEFULNESS_NAPPING) {
                     mWakefulness = WAKEFULNESS_DREAMING;
                     mDirty |= DIRTY_WAKEFULNESS;
+                    mBatteryLevelWhenDreamStarted = mBatteryLevel;
                     updatePowerStateLocked();
                     continueDreaming = true;
                 } else if (mWakefulness == WAKEFULNESS_DREAMING) {
-                    continueDreaming = true;
+                    if (!isBeingKeptAwakeLocked()
+                            && mBatteryLevel < mBatteryLevelWhenDreamStarted
+                                    - DREAM_BATTERY_LEVEL_DRAIN_CUTOFF) {
+                        // If the user activity timeout expired and the battery appears
+                        // to be draining faster than it is charging then stop dreaming
+                        // and go to sleep.
+                        Slog.i(TAG, "Stopping dream because the battery appears to "
+                                + "be draining faster than it is charging.  "
+                                + "Battery level when dream started: "
+                                + mBatteryLevelWhenDreamStarted + "%.  "
+                                + "Battery level now: " + mBatteryLevel + "%.");
+                    } else {
+                        continueDreaming = true;
+                    }
                 }
             }
             if (!continueDreaming) {
@@ -1704,8 +1732,11 @@
     }
 
     /**
-     * Reboot the device, passing 'reason' (may be null)
-     * to the underlying __reboot system call.  Should not return.
+     * Reboots the device.
+     *
+     * @param confirm If true, shows a reboot confirmation dialog.
+     * @param reason The reason for the reboot, or null if none.
+     * @param wait If true, this call waits for the reboot to complete and does not return.
      */
     @Override // Binder call
     public void reboot(boolean confirm, String reason, boolean wait) {
@@ -1713,15 +1744,17 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            rebootInternal(false, confirm, reason, wait);
+            shutdownOrRebootInternal(false, confirm, reason, wait);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
     /**
-     * Shutdown the devic, passing 'reason' (may be null)
-     * to the underlying __reboot system call.  Should not return.
+     * Shuts down the device.
+     *
+     * @param confirm If true, shows a shutdown confirmation dialog.
+     * @param wait If true, this call waits for the shutdown to complete and does not return.
      */
     @Override // Binder call
     public void shutdown(boolean confirm, boolean wait) {
@@ -1729,19 +1762,20 @@
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            rebootInternal(true, confirm, null, wait);
+            shutdownOrRebootInternal(true, confirm, null, wait);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
     }
 
-    private void rebootInternal(final boolean shutdown, final boolean confirm,
+    private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
             final String reason, boolean wait) {
         if (mHandler == null || !mSystemReady) {
-            throw new IllegalStateException("Too early to call reboot()");
+            throw new IllegalStateException("Too early to call shutdown() or reboot()");
         }
 
         Runnable runnable = new Runnable() {
+            @Override
             public void run() {
                 synchronized (this) {
                     if (shutdown) {
@@ -1789,6 +1823,7 @@
 
     private void crashInternal(final String message) {
         Thread t = new Thread("PowerManagerService.crash()") {
+            @Override
             public void run() {
                 throw new RuntimeException(message);
             }
@@ -2087,6 +2122,8 @@
             pw.println("  mWakefulness=" + wakefulnessToString(mWakefulness));
             pw.println("  mIsPowered=" + mIsPowered);
             pw.println("  mPlugType=" + mPlugType);
+            pw.println("  mBatteryLevel=" + mBatteryLevel);
+            pw.println("  mBatteryLevelWhenDreamStarted=" + mBatteryLevelWhenDreamStarted);
             pw.println("  mStayOn=" + mStayOn);
             pw.println("  mProximityPositive=" + mProximityPositive);
             pw.println("  mBootCompleted=" + mBootCompleted);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index b67fb51..269eac0 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -618,6 +618,7 @@
         if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
                 TAG, ">>> OPEN TRANSACTION animateLocked");
         Surface.openTransaction();
+        Surface.setAnimationTransaction();
         try {
             updateAppWindowsLocked();
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 77d815b..c341872 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -2823,16 +2823,9 @@
                                 "Relayout window turning screen on: " + win);
                         win.mTurnOnScreen = true;
                     }
-                    int diff = 0;
-                    if (win.mConfiguration != mCurConfiguration
-                            && (win.mConfiguration == null
-                                    || (diff=mCurConfiguration.diff(win.mConfiguration)) != 0)) {
-                        win.mConfiguration = mCurConfiguration;
-                        if (DEBUG_CONFIGURATION) {
-                            Slog.i(TAG, "Window " + win + " visible with new config: "
-                                    + win.mConfiguration + " / 0x"
-                                    + Integer.toHexString(diff));
-                        }
+                    if (win.isConfigChanged()) {
+                        if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + win
+                                + " visible with new config: " + win.mConfiguration);
                         outConfig.setTo(mCurConfiguration);
                     }
                 }
@@ -8260,7 +8253,7 @@
                 Slog.v(TAG, "1ST PASS " + win
                         + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
                         + " mLayoutAttached=" + win.mLayoutAttached
-                        + " screen changed=" + win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE));
+                        + " screen changed=" + win.isConfigChanged());
                 final AppWindowToken atoken = win.mAppToken;
                 if (gone) Slog.v(TAG, "  GONE: mViewVisibility="
                         + win.mViewVisibility + " mRelayoutCalled="
@@ -8282,7 +8275,7 @@
             // windows, since that means "perform layout as normal,
             // just don't display").
             if (!gone || !win.mHaveFrame || win.mLayoutNeeded
-                    || win.isConfigDiff(ActivityInfo.CONFIG_SCREEN_SIZE)
+                    || win.isConfigChanged()
                     || win.mAttrs.type == TYPE_UNIVERSE_BACKGROUND) {
                 if (!win.mLayoutAttached) {
                     if (initial) {
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java
index 2920824..2303fc3 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Blend.java
@@ -52,8 +52,10 @@
             new AdapterView.OnItemSelectedListener() {
                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                     currentIntrinsic = pos;
-                    runTest();
-                    act.updateDisplay();
+                    if (mRS != null) {
+                        runTest();
+                        act.updateDisplay();
+                    }
                 }
 
                 public void onNothingSelected(AdapterView parent) {
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
index 8009daa..bb3f2f3 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/TestBase.java
@@ -123,6 +123,7 @@
 
     public void destroy() {
         mRS.destroy();
+        mRS = null;
     }
 
     public void updateBitmap(Bitmap b) {
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
similarity index 88%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
index a83e819..ba8711b 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/colormatrix.fs
@@ -29,10 +29,10 @@
     Mat = m;
 }
 
-void root(const uchar4 *in, uchar4 *out) {
-    float4 f = convert_float4(*in);
+uchar4 __attribute__((kernel)) root(uchar4 in) {
+    float4 f = convert_float4(in);
     f = rsMatrixMultiply(&Mat, f);
     f = clamp(f, 0.f, 255.f);
-    *out = convert_uchar4(f);
+    return convert_uchar4(f);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs
similarity index 94%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs
index 98128279..772503f 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve3x3.fs
@@ -24,7 +24,7 @@
 
 float gCoeffs[9];
 
-void root(uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
     uint32_t x1 = min((int32_t)x+1, gWidth-1);
     uint32_t x2 = max((int32_t)x-1, 0);
     uint32_t y1 = min((int32_t)y+1, gHeight-1);
@@ -61,7 +61,7 @@
     p20 += p02;
 
     p20 = clamp(p20, 0.f, 255.f);
-    *out = convert_uchar4(p20);
+    return convert_uchar4(p20);
 }
 
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs
similarity index 96%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs
index e6d03c9..a916bfb 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/convolve5x5.fs
@@ -24,7 +24,7 @@
 
 float gCoeffs[25];
 
-void root(uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
     uint32_t x0 = max((int32_t)x-2, 0);
     uint32_t x1 = max((int32_t)x-1, 0);
     uint32_t x2 = x;
@@ -68,7 +68,7 @@
               + convert_float4(rsGetElementAt_uchar4(gIn, x4, y4)) * gCoeffs[24];
 
     p0 = clamp(p0 + p1 + p2 + p3 + p4, 0.f, 255.f);
-    *out = convert_uchar4(p0);
+    return convert_uchar4(p0);
 }
 
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.fs
similarity index 90%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.fs
index 9eb5d43..5f03483 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/copy.fs
@@ -17,8 +17,8 @@
 #pragma version(1)
 #pragma rs java_package_name(com.android.rs.image)
 
-void root(const uchar4 *v_in, uchar4 *v_out) {
-    *v_out = *v_in;
+uchar4 __attribute__((kernel)) root(uchar4 v_in) {
+    return v_in;
 }
 
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
index 3809912..2eacb7d 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye.rsh
@@ -26,7 +26,7 @@
     neg_center = -center;
     inv_dimensions.x = 1.f / (float)dim_x;
     inv_dimensions.y = 1.f / (float)dim_y;
-    alpha = k * 2.0 + 0.75;
+    alpha = k * 2.0f + 0.75f;
 
     axis_scale = (float2)1.f;
     if (dim_x > dim_y)
@@ -34,15 +34,15 @@
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
     
-    const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
+    const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
     const float bound = sqrt(bound2);
-    const float radius = 1.15 * bound;
+    const float radius = 1.15f * bound;
     radius2 = radius*radius;
     const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
     factor = bound / max_radian;
 }
 
-void root(uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
     // Convert x and y to floating point coordinates with center as origin
     const float2 inCoord = {(float)x, (float)y};
     const float2 coord = mad(inCoord, inv_dimensions, neg_center);
@@ -53,6 +53,6 @@
     const float scalar = radian * factor * inv_dist;
     const float2 new_coord = mad(coord, scalar, center);
     const float4 fout = rsSample(in_alloc, sampler, new_coord);
-    *out = rsPackColorTo8888(fout);
+    return rsPackColorTo8888(fout);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh
index 08b4126..fcf0a3d 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx.rsh
@@ -26,7 +26,7 @@
     neg_center = -center;
     inv_dimensions.x = 1.f / (float)dim_x;
     inv_dimensions.y = 1.f / (float)dim_y;
-    alpha = k * 2.0 + 0.75;
+    alpha = k * 2.0f + 0.75f;
 
     axis_scale = (float2)1.f;
     if (dim_x > dim_y)
@@ -34,15 +34,15 @@
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
 
-    const float bound2 = 0.25 * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
+    const float bound2 = 0.25f * (axis_scale.x*axis_scale.x + axis_scale.y*axis_scale.y);
     const float bound = sqrt(bound2);
-    const float radius = 1.15 * bound;
+    const float radius = 1.15f * bound;
     radius2 = radius*radius;
     const float max_radian = M_PI_2 - atan(alpha / bound * sqrt(radius2 - bound2));
     factor = bound / max_radian;
 }
 
-void root(uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
     // Convert x and y to floating point coordinates with center as origin
     const float2 inCoord = {(float)x, (float)y};
     const float2 coord = mad(inCoord, inv_dimensions, neg_center);
@@ -53,6 +53,6 @@
     const float scalar = radian * factor * inv_dist;
     const float2 new_coord = mad(coord, scalar, center);
     const float4 fout = rsSample(in_alloc, sampler, new_coord);
-    *out = rsPackColorTo8888(fout);
+    return rsPackColorTo8888(fout);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.fs
similarity index 100%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_approx_relaxed.fs
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
similarity index 100%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/fisheye_relaxed.fs
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.fs
similarity index 89%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.fs
index c8531f3..4ae095d 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/grain.fs
@@ -18,8 +18,8 @@
 #pragma rs java_package_name(com.android.rs.image)
 #pragma rs_fp_relaxed
 
-void genRand(uchar *out) {
-    *out = (uchar)rsRand(0xff);
+uchar __attribute__((kernel)) genRand() {
+    return (uchar)rsRand(0xff);
 }
 
 /*
@@ -42,7 +42,7 @@
 int32_t gHMask;
 
 rs_allocation gBlendSource;
-void blend9(uchar *out, uint32_t x, uint32_t y) {
+uchar __attribute__((kernel)) blend9(uint32_t x, uint32_t y) {
     uint32_t x1 = (x-1) & gWMask;
     uint32_t x2 = (x+1) & gWMask;
     uint32_t y1 = (y-1) & gHMask;
@@ -70,14 +70,14 @@
     p20 += p02;
 
     p20 = min(p20 >> 10, (uint)255);
-    *out = (uchar)p20;
+    return (uchar)p20;
 }
 
 float gNoiseStrength;
 
 rs_allocation gNoise;
-void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
-    float4 ip = convert_float4(*in);
+uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
+    float4 ip = convert_float4(in);
     float pnoise = (float) rsGetElementAt_uchar(gNoise, x & gWMask, y & gHMask);
 
     float energy_level = ip.r + ip.g + ip.b;
@@ -89,5 +89,5 @@
 
     uchar4 p = convert_uchar4(ip);
     p.a = 0xff;
-    *out = p;
+    return p;
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.fs
similarity index 86%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.fs
index c420cac..90ba058 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/greyscale.fs
@@ -20,11 +20,11 @@
 
 const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
 
-void root(const uchar4 *v_in, uchar4 *v_out) {
-    float4 f4 = rsUnpackColor8888(*v_in);
+uchar4 __attribute__((kernel)) root(uchar4 v_in) {
+    float4 f4 = rsUnpackColor8888(v_in);
 
     float3 mono = dot(f4.rgb, gMonoMult);
-    *v_out = rsPackColorTo8888(mono);
+    return rsPackColorTo8888(mono);
 }
 
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels.rsh
index 7c5d930..e289906 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels.rsh
@@ -21,24 +21,26 @@
 float overInWMinInB;
 rs_matrix3x3 colorMat;
 
-void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
-    float3 pixel = convert_float4(in[0]).rgb;
+uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
+    uchar4 out;
+    float3 pixel = convert_float4(in).rgb;
     pixel = rsMatrixMultiply(&colorMat, pixel);
     pixel = clamp(pixel, 0.f, 255.f);
     pixel = (pixel - inBlack) * overInWMinInB;
     pixel = pixel * outWMinOutB + outBlack;
     pixel = clamp(pixel, 0.f, 255.f);
-    out->xyz = convert_uchar3(pixel);
-    out->w = 0xff;
+    out.xyz = convert_uchar3(pixel);
+    out.w = 0xff;
+    return out;
 }
 
-void root4(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
-    float4 pixel = convert_float4(in[0]);
+uchar4 __attribute__((kernel)) root4(uchar4 in, uint32_t x, uint32_t y) {
+    float4 pixel = convert_float4(in);
     pixel.rgb = rsMatrixMultiply(&colorMat, pixel.rgb);
     pixel = clamp(pixel, 0.f, 255.f);
     pixel = (pixel - inBlack) * overInWMinInB;
     pixel = pixel * outWMinOutB + outBlack;
     pixel = clamp(pixel, 0.f, 255.f);
-    out->xyzw = convert_uchar4(pixel);
+    return convert_uchar4(pixel);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
similarity index 100%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels_relaxed.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/levels_relaxed.fs
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.fs
similarity index 75%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.fs
index da81d2e..ac2061b 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/mandelbrot.fs
@@ -23,7 +23,7 @@
 float lowerBoundY = -2.f;
 float scaleFactor = 4.f;
 
-void root(uchar4 *v_out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uint32_t x, uint32_t y) {
   float2 p;
   p.x = lowerBoundX + ((float)x / gDimX) * scaleFactor;
   p.y = lowerBoundY + ((float)y / gDimY) * scaleFactor;
@@ -41,16 +41,16 @@
 
   if(iter >= gMaxIteration) {
     // write a non-transparent black pixel
-    *v_out = (uchar4){0, 0, 0, 0xff};
+    return (uchar4){0, 0, 0, 0xff};
   } else {
-    float mi3 = gMaxIteration / 3.;
+    float mi3 = gMaxIteration / 3.f;
     if (iter <= (gMaxIteration / 3))
-      *v_out = (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
+      return (uchar4){0xff * (iter / mi3), 0, 0, 0xff};
     else if (iter <= (((gMaxIteration / 3) * 2)))
-      *v_out = (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
-                        (0xff * ((iter - mi3) / mi3)), 0, 0xff};
+      return (uchar4){0xff - (0xff * ((iter - mi3) / mi3)),
+                      (0xff * ((iter - mi3) / mi3)), 0, 0xff};
     else
-      *v_out = (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
-                        (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
+      return (uchar4){0, 0xff - (0xff * ((iter - (mi3 * 2)) / mi3)),
+                      (0xff * ((iter - (mi3 * 2)) / mi3)), 0xff};
   }
 }
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.fs
similarity index 70%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.fs
index 3dfa94b..86e155a 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.rs
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/threshold.fs
@@ -56,51 +56,49 @@
     }
 }
 
-void copyIn(const uchar4 *in, float4 *out) {
-    *out = convert_float4(*in);
+float4 __attribute__((kernel)) copyIn(uchar4 in) {
+    return convert_float4(in);
 }
 
-void vert(uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) vert(uint32_t x, uint32_t y) {
     float3 blurredPixel = 0;
-    const float *gPtr = gaussian;
+    int gi = 0;
+    uchar4 out;
     if ((y > radius) && (y < (height - radius))) {
         for (int r = -radius; r <= radius; r ++) {
-            const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel2, x, y + r);
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
+            float4 i = rsGetElementAt_float4(ScratchPixel2, x, y + r);
+            blurredPixel += i.xyz * gaussian[gi++];
         }
     } else {
         for (int r = -radius; r <= radius; r ++) {
             int validH = rsClamp((int)y + r, (int)0, (int)(height - 1));
-            const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel2, x, validH);
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
+            float4 i = rsGetElementAt_float4(ScratchPixel2, x, validH);
+            blurredPixel += i.xyz * gaussian[gi++];
         }
     }
 
-    out->xyz = convert_uchar3(clamp(blurredPixel, 0.f, 255.f));
-    out->w = 0xff;
+    out.xyz = convert_uchar3(clamp(blurredPixel, 0.f, 255.f));
+    out.w = 0xff;
+    return out;
 }
 
-void horz(float4 *out, uint32_t x, uint32_t y) {
-    float3 blurredPixel = 0;
-    const float *gPtr = gaussian;
+float4 __attribute__((kernel)) horz(uint32_t x, uint32_t y) {
+    float4 blurredPixel = 0;
+    int gi = 0;
     if ((x > radius) && (x < (width - radius))) {
         for (int r = -radius; r <= radius; r ++) {
-            const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel1, x + r, y);
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
+            float4 i = rsGetElementAt_float4(ScratchPixel1, x + r, y);
+            blurredPixel += i * gaussian[gi++];
         }
     } else {
         for (int r = -radius; r <= radius; r ++) {
             // Stepping left and right away from the pixel
             int validX = rsClamp((int)x + r, (int)0, (int)(width - 1));
-            const float4 *i = (const float4 *)rsGetElementAt(ScratchPixel1, validX, y);
-            blurredPixel += i->xyz * gPtr[0];
-            gPtr++;
+            float4 i = rsGetElementAt_float4(ScratchPixel1, validX, y);
+            blurredPixel += i * gaussian[gi++];
         }
     }
 
-    out->xyz = blurredPixel;
+    return blurredPixel;
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette.rsh
index a1e4ae5..04ca1f1 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette.rsh
@@ -31,29 +31,29 @@
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
 
-    const float max_dist = 0.5 * length(axis_scale);
+    const float max_dist = 0.5f * length(axis_scale);
     sloped_inv_max_dist = desired_slope * 1.f/max_dist;
 
     // Range needs to be between 1.3 to 0.6. When scale is zero then range is
     // 1.3 which means no vignette at all because the luminousity difference is
     // less than 1/256.  Expect input scale to be between 0.0 and 1.0.
-    const float neg_range = 0.7*sqrt(desired_scale) - 1.3;
+    const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
     sloped_neg_range = exp(neg_range * desired_slope);
 
     shade = desired_shade;
     opp_shade = 1.f - desired_shade;
 }
 
-void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
     // Convert x and y to floating point coordinates with center as origin
-    const float4 fin = convert_float4(*in);
+    const float4 fin = convert_float4(in);
     const float2 inCoord = {(float)x, (float)y};
     const float2 coord = mad(inCoord, inv_dimensions, neg_center);
     const float sloped_dist_ratio = length(axis_scale * coord)  * sloped_inv_max_dist;
-    const float lumen = opp_shade + shade / ( 1.0 + sloped_neg_range * exp(sloped_dist_ratio) );
+    const float lumen = opp_shade + shade / ( 1.0f + sloped_neg_range * exp(sloped_dist_ratio) );
     float4 fout;
     fout.rgb = fin.rgb * lumen;
     fout.w = fin.w;
-    *out = convert_uchar4(fout);
+    return convert_uchar4(fout);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx.rsh b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx.rsh
index 7f7bdcf..05a5929 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx.rsh
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx.rsh
@@ -31,22 +31,22 @@
     else
         axis_scale.x = (float)dim_x / (float)dim_y;
 
-    const float max_dist = 0.5 * length(axis_scale);
+    const float max_dist = 0.5f * length(axis_scale);
     sloped_inv_max_dist = desired_slope * 1.f/max_dist;
 
     // Range needs to be between 1.3 to 0.6. When scale is zero then range is
     // 1.3 which means no vignette at all because the luminousity difference is
     // less than 1/256.  Expect input scale to be between 0.0 and 1.0.
-    const float neg_range = 0.7*sqrt(desired_scale) - 1.3;
+    const float neg_range = 0.7f*sqrt(desired_scale) - 1.3f;
     sloped_neg_range = exp(neg_range * desired_slope);
 
     shade = desired_shade;
     opp_shade = 1.f - desired_shade;
 }
 
-void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
+uchar4 __attribute__((kernel)) root(uchar4 in, uint32_t x, uint32_t y) {
     // Convert x and y to floating point coordinates with center as origin
-    const float4 fin = convert_float4(*in);
+    const float4 fin = convert_float4(in);
     const float2 inCoord = {(float)x, (float)y};
     const float2 coord = mad(inCoord, inv_dimensions, neg_center);
     const float sloped_dist_ratio = fast_length(axis_scale * coord)  * sloped_inv_max_dist;
@@ -55,6 +55,6 @@
     float4 fout;
     fout.rgb = fin.rgb * lumen;
     fout.w = fin.w;
-    *out = convert_uchar4(fout);
+    return convert_uchar4(fout);
 }
 
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.fs
similarity index 100%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_approx_relaxed.fs
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
similarity index 100%
rename from tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.rs
rename to tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vignette_relaxed.fs
diff --git a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
index 26cb97b..fd594f7 100644
--- a/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/os/SystemClock_Delegate.java
@@ -66,7 +66,7 @@
      * @return elapsed nanoseconds since boot.
      */
     @LayoutlibDelegate
-    /*package*/ static long elapsedRealtimeNano() {
+    /*package*/ static long elapsedRealtimeNanos() {
         return System.nanoTime() - sBootTimeNano;
     }
 
diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
new file mode 100644
index 0000000..f75ee50
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Choreographer}
+ *
+ * Through the layoutlib_create tool, the original  methods of Choreographer have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Choreographer_Delegate {
+
+    @LayoutlibDelegate
+    public static float getRefreshRate() {
+        return 60.f;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
index 6ccdcb6..53dc821 100644
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
@@ -16,11 +16,8 @@
 
 package android.view;
 
-import com.android.layoutlib.bridge.android.BridgeWindowManager;
-import com.android.layoutlib.bridge.impl.RenderAction;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
-import android.os.RemoteException;
 
 /**
  * Delegate used to provide new implementation of a select few methods of {@link Display}
@@ -31,4 +28,9 @@
  */
 public class Display_Delegate {
 
+    @LayoutlibDelegate
+    static void updateDisplayInfoLocked(Display theDisplay) {
+        // do nothing
+    }
+
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
similarity index 95%
rename from tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
rename to tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 3fcc8ef..da736b7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.layoutlib.bridge.android;
+package android.view;
 
 import com.android.internal.view.IInputContext;
 import com.android.internal.view.IInputMethodClient;
@@ -28,7 +28,6 @@
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
 import android.view.Display;
-import android.view.Display_Delegate;
 import android.view.Gravity;
 import android.view.IApplicationToken;
 import android.view.IDisplayContentChangeListener;
@@ -45,16 +44,21 @@
  * Basic implementation of {@link IWindowManager} so that {@link Display} (and
  * {@link Display_Delegate}) can return a valid instance.
  */
-public class BridgeWindowManager implements IWindowManager {
+public class IWindowManagerImpl implements IWindowManager {
 
     private final Configuration mConfig;
     private final DisplayMetrics mMetrics;
     private final int mRotation;
+    private final boolean mHasSystemNavBar;
+    private final boolean mHasNavigationBar;
 
-    public BridgeWindowManager(Configuration config, DisplayMetrics metrics, int rotation) {
+    public IWindowManagerImpl(Configuration config, DisplayMetrics metrics, int rotation,
+            boolean hasSystemNavBar, boolean hasNavigationBar) {
         mConfig = config;
         mMetrics = metrics;
         mRotation = rotation;
+        mHasSystemNavBar = hasSystemNavBar;
+        mHasNavigationBar = hasNavigationBar;
     }
 
     // custom API.
@@ -70,14 +74,18 @@
         return mRotation;
     }
 
-    // ---- unused implementation of IWindowManager ----
+    @Override
+    public boolean hasNavigationBar() {
+        return mHasNavigationBar;
+    }
 
     @Override
     public boolean hasSystemNavBar() throws RemoteException {
-        // TODO Auto-generated method stub
-        return false;
+        return mHasSystemNavBar;
     }
 
+    // ---- unused implementation of IWindowManager ----
+
     @Override
     public void addAppToken(int arg0, IApplicationToken arg1, int arg2, int arg3, boolean arg4,
                             boolean arg5)
@@ -435,11 +443,6 @@
     }
 
     @Override
-    public boolean hasNavigationBar() {
-        return false; // should this return something else?
-    }
-
-    @Override
     public void lockNow(Bundle options) {
         // TODO Auto-generated method stub
     }
diff --git a/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
new file mode 100644
index 0000000..2606e55
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/view/WindowManagerGlobal_Delegate.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of
+ * {@link WindowManagerGlobal}
+ *
+ * Through the layoutlib_create tool, the original  methods of WindowManagerGlobal have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ */
+public class WindowManagerGlobal_Delegate {
+
+    private static IWindowManager sService;
+
+    @LayoutlibDelegate
+    public static IWindowManager getWindowManagerService() {
+        return sService;
+    }
+
+    // ---- internal implementation stuff ----
+
+    public static void setWindowManagerService(IWindowManager service) {
+        sService = service;
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 80478ba..e2fced6 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -25,6 +25,7 @@
 import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.android.view.WindowManagerImpl;
 import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.Stack;
 import com.android.resources.ResourceType;
@@ -68,9 +69,9 @@
 import android.view.BridgeInflater;
 import android.view.CompatibilityInfoHolder;
 import android.view.Display;
-import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.view.textservice.TextServicesManager;
 
 import java.io.File;
@@ -98,7 +99,7 @@
     private final Configuration mConfig;
     private final ApplicationInfo mApplicationInfo;
     private final IProjectCallback mProjectCallback;
-    private final BridgeWindowManager mIWindowManager;
+    private final WindowManager mWindowManager;
 
     private Resources.Theme mTheme;
 
@@ -139,10 +140,10 @@
         mRenderResources = renderResources;
         mConfig = config;
 
-        mIWindowManager = new BridgeWindowManager(mConfig, metrics, Surface.ROTATION_0);
-
         mApplicationInfo = new ApplicationInfo();
         mApplicationInfo.targetSdkVersion = targetSdkVersion;
+
+        mWindowManager = new WindowManagerImpl(mMetrics);
     }
 
     /**
@@ -198,14 +199,14 @@
         return mRenderResources;
     }
 
-    public BridgeWindowManager getIWindowManager() {
-        return mIWindowManager;
-    }
-
     public Map<String, String> getDefaultPropMap(Object key) {
         return mDefaultPropMaps.get(key);
     }
 
+    public Configuration getConfiguration() {
+        return mConfig;
+    }
+
     /**
      * Adds a parser to the stack.
      * @param parser the parser to add.
@@ -431,10 +432,8 @@
             return TextServicesManager.getInstance();
         }
 
-        // AutoCompleteTextView and MultiAutoCompleteTextView want a window
-        // service. We don't have any but it's not worth an exception.
         if (WINDOW_SERVICE.equals(service)) {
-            return null;
+            return mWindowManager;
         }
 
         // needed by SearchView
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
new file mode 100644
index 0000000..9a633bf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/view/WindowManagerImpl.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.layoutlib.bridge.android.view;
+
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.View;
+import android.view.WindowManager;
+
+public class WindowManagerImpl implements WindowManager {
+
+    private final DisplayMetrics mMetrics;
+    private final Display mDisplay;
+
+    public WindowManagerImpl(DisplayMetrics metrics) {
+        mMetrics = metrics;
+
+        DisplayInfo info = new DisplayInfo();
+        info.logicalHeight = mMetrics.heightPixels;
+        info.logicalWidth = mMetrics.widthPixels;
+        mDisplay = new Display(null, Display.DEFAULT_DISPLAY, info, null);
+    }
+
+    @Override
+    public Display getDefaultDisplay() {
+        return mDisplay;
+    }
+
+
+    @Override
+    public void addView(View arg0, android.view.ViewGroup.LayoutParams arg1) {
+        // pass
+    }
+
+    @Override
+    public void removeView(View arg0) {
+        // pass
+    }
+
+    @Override
+    public void updateViewLayout(View arg0, android.view.ViewGroup.LayoutParams arg1) {
+        // pass
+    }
+
+
+    @Override
+    public void removeViewImmediate(View arg0) {
+        // pass
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index e93b41d..cc0f077 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -68,11 +68,15 @@
 import android.util.TypedValue;
 import android.view.AttachInfo_Accessor;
 import android.view.BridgeInflater;
+import android.view.IWindowManagerImpl;
+import android.view.IWindowManager;
+import android.view.Surface;
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
+import android.view.WindowManagerGlobal_Delegate;
 import android.widget.AbsListView;
 import android.widget.AbsSpinner;
 import android.widget.AdapterView;
@@ -185,6 +189,14 @@
         findActionBar(resources, metrics);
         findSystemBar(resources, metrics);
 
+        // FIXME: find those out, and possibly add them to the render params
+        boolean hasSystemNavBar = true;
+        boolean hasNavigationBar = true;
+        IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(),
+                metrics, Surface.ROTATION_0,
+                hasSystemNavBar, hasNavigationBar);
+        WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
+
         // build the inflater and parser.
         mInflater = new BridgeInflater(context, params.getProjectCallback());
         context.setBridgeInflater(mInflater);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 5109810..80a1a60 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -110,11 +110,13 @@
         "android.os.Handler#sendMessageAtTime",
         "android.os.HandlerThread#run",
         "android.os.Build#getString",
-        "android.view.Display#getWindowManager",
+        "android.view.Choreographer#getRefreshRate",
+        "android.view.Display#updateDisplayInfoLocked",
         "android.view.LayoutInflater#rInflate",
         "android.view.LayoutInflater#parseInclude",
         "android.view.View#isInEditMode",
         "android.view.ViewRootImpl#isInTouchMode",
+        "android.view.WindowManagerGlobal#getWindowManagerService",
         "android.view.inputmethod.InputMethodManager#getInstance",
         "com.android.internal.util.XmlUtils#convertValueToInt",
         "com.android.internal.textservice.ITextServicesManager$Stub#asInterface",
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 75b8bcf..e913d10 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1274,6 +1274,7 @@
                     // This will cause all further async API calls on the WifiManager
                     // to fail and throw an exception
                     mAsyncChannel = null;
+                    getLooper().quit();
                     break;
                     /* ActionListeners grouped together */
                 case WifiManager.CONNECT_NETWORK_FAILED:
@@ -1979,4 +1980,12 @@
             mService.captivePortalCheckComplete();
         } catch (RemoteException e) {}
     }
+
+    protected void finalize() throws Throwable {
+        try {
+            mHandler.getLooper().quit();
+        } finally {
+            super.finalize();
+        }
+    }
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index 2093bda..f14c305 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -114,6 +114,15 @@
         return mDevices.remove(device.deviceAddress) != null;
     }
 
+    /** Returns true if any device the list was removed @hide */
+    public boolean remove(WifiP2pDeviceList list) {
+        boolean ret = false;
+        for (WifiP2pDevice d : list.mDevices.values()) {
+            if (remove(d)) ret = true;
+        }
+        return ret;
+    }
+
     /** Get the list of devices */
     public Collection<WifiP2pDevice> getDeviceList() {
         return Collections.unmodifiableCollection(mDevices.values());
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index ca329e6..70baf13 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -355,6 +355,15 @@
         private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
 
         private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
+        /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
+         * perspective, the discovery stops during connection and it purges device since it does
+         * not get latest updates about the device without being in discovery state.
+         *
+         * From the framework perspective, the device is still there since we are connecting or
+         * connected to it. so we keep these devices in a seperate list, so that they are removed
+         * when connection is cancelled or lost
+         */
+        private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
         private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
                 new GroupDeleteListener() {
             @Override
@@ -746,6 +755,10 @@
         public boolean processMessage(Message message) {
             if (DBG) logd(getName() + message.toString());
             switch (message.what) {
+                case WifiMonitor.SUP_DISCONNECTION_EVENT:
+                    loge("Unexpected loss of p2p socket connection");
+                    transitionTo(mP2pDisabledState);
+                    break;
                 case WifiStateMachine.CMD_ENABLE_P2P:
                     //Nothing to do
                     break;
@@ -1066,7 +1079,8 @@
                         break;
                     }
                     // Do nothing
-                    if (DBG) logd("Retain connecting device " + device);
+                    if (DBG) logd("Add device to lost list " + device);
+                    mPeersLostDuringConnection.update(device);
                     break;
                 case WifiP2pManager.DISCOVER_PEERS:
                     /* Discovery will break negotiation */
@@ -1401,7 +1415,8 @@
                     device = (WifiP2pDevice) message.obj;
                     //Device loss for a connected device indicates it is not in discovery any more
                     if (mGroup.contains(device)) {
-                        if (DBG) logd("Lost " + device +" , do nothing");
+                        if (DBG) logd("Add device to lost list " + device);
+                        mPeersLostDuringConnection.update(device);
                         return HANDLED;
                     }
                     // Do the regular device lost handling
@@ -1853,7 +1868,7 @@
     private int connect(WifiP2pConfig config, boolean tryInvocation) {
 
         if (config == null) {
-            loge("invalid argument.");
+            loge("config is null");
             return CONNECT_FAILURE;
         }
 
@@ -1863,7 +1878,7 @@
 
         WifiP2pDevice dev = mPeers.get(config.deviceAddress);
         if (dev == null) {
-            loge("target device is not found.");
+            loge("target device not found " + config.deviceAddress);
             return CONNECT_FAILURE;
         }
 
@@ -2142,6 +2157,8 @@
         /* After cancelling group formation, new connections on existing peers can fail
          * at supplicant. Flush and restart discovery */
         mWifiNative.p2pFlush();
+        if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
+        mPeersLostDuringConnection.clear();
         mServiceDiscReqId = null;
         sendMessage(WifiP2pManager.DISCOVER_PEERS);
     }
@@ -2174,6 +2191,8 @@
 
         mGroup = null;
         mWifiNative.p2pFlush();
+        if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast();
+        mPeersLostDuringConnection.clear();
         mServiceDiscReqId = null;
         if (changed) sendP2pPeersChangedBroadcast();
     }