Merge "Start really collecting PSS data for process stats."
diff --git a/api/current.txt b/api/current.txt
index 92aa494..c163d55 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2697,6 +2697,7 @@
     method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void closeContextMenu();
     method public void closeOptionsMenu();
+    method public void convertToOpaque();
     method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
     method public final deprecated void dismissDialog(int);
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
@@ -2889,6 +2890,7 @@
   }
 
   public class ActivityManager {
+    method public boolean clearApplicationUserData();
     method public void dumpPackageState(java.io.FileDescriptor, java.lang.String);
     method public android.content.pm.ConfigurationInfo getDeviceConfigurationInfo();
     method public int getLargeMemoryClass();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7f2f744..e87d805 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4862,6 +4862,25 @@
     }
 
     /**
+     * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
+     * fullscreen opaque Activity.
+     *
+     * Call this whenever the background of a translucent Activity has changed to become opaque.
+     * Doing so will allow the previously visible Activity behind this one to be stopped. Stopped
+     * apps consume no CPU cycles and are eligible for removal when reclaiming memory.
+     *
+     * This call has no effect on non-translucent activities or on activities with the
+     * {@link android.R.attr#windowIsFloating} attribute.
+     */
+    public void convertToOpaque() {
+        try {
+            ActivityManagerNative.getDefault().convertToOpaque(mToken);
+        } catch (RemoteException e) {
+            // pass
+        }
+    }
+
+    /**
      * Adjust the current immersive mode setting.
      *
      * Note that changing this value will have no effect on the activity's
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 780b522..6f75f7f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1400,7 +1400,18 @@
             return false;
         }
     }
-    
+
+    /**
+     * Permits an application to erase its own data from disk.  This is equivalent to
+     * the user choosing to clear the app's data from within the device settings UI.
+     *
+     * @return {@code true} if the application successfully requested that the application's
+     *     data be erased; {@code false} otherwise.
+     */
+    public boolean clearApplicationUserData() {
+        return clearApplicationUserData(mContext.getPackageName(), null);
+    }
+
     /**
      * Information you can retrieve about any processes that are in an error condition.
      */
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 1573398..b966d6d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1499,6 +1499,14 @@
             return true;
         }
 
+        case CONVERT_TO_OPAQUE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            convertToOpaque(token);
+            reply.writeNoException();
+            return true;
+        }
+
         case SET_IMMERSIVE_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             IBinder token = data.readStrongBinder();
@@ -3823,7 +3831,19 @@
         data.recycle();
         reply.recycle();
     }
-    
+
+    public void convertToOpaque(IBinder token)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(CONVERT_TO_OPAQUE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     public void setImmersive(IBinder token, boolean immersive)
             throws RemoteException {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c8791a4..39f4cfa 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -301,6 +301,8 @@
 
     public void finishHeavyWeightApp() throws RemoteException;
 
+    public void convertToOpaque(IBinder token) throws RemoteException;
+
     public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
     public boolean isImmersive(IBinder token) throws RemoteException;
     public boolean isTopActivityImmersive() throws RemoteException;
@@ -666,4 +668,5 @@
     int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
     int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
     int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
+    int CONVERT_TO_OPAQUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
 }
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index 37f04d3..31c8edb 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -89,6 +89,7 @@
     private TrustManager[] mTrustManagers = null;
     private KeyManager[] mKeyManagers = null;
     private byte[] mNpnProtocols = null;
+    private byte[] mAlpnProtocols = null;
     private PrivateKey mChannelIdPrivateKey = null;
 
     private final int mHandshakeTimeoutMillis;
@@ -268,19 +269,42 @@
      *     must be non-empty and of length less than 256.
      */
     public void setNpnProtocols(byte[][] npnProtocols) {
-        this.mNpnProtocols = toNpnProtocolsList(npnProtocols);
+        this.mNpnProtocols = toLengthPrefixedList(npnProtocols);
+    }
+
+    /**
+     * Sets the
+     * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01">
+     * Application Layer Protocol Negotiation (ALPN)</a> protocols that this peer
+     * is interested in.
+     *
+     * <p>For servers this is the sequence of protocols to advertise as
+     * supported, in order of preference. This list is sent unencrypted to
+     * all clients that support ALPN.
+     *
+     * <p>For clients this is a list of supported protocols to match against the
+     * server's list. If there is no protocol supported by both client and
+     * server then the first protocol in the client's list will be selected.
+     * The order of the client's protocols is otherwise insignificant.
+     *
+     * @param protocols a non-empty list of protocol byte arrays. All arrays
+     *     must be non-empty and of length less than 256.
+     * @hide
+     */
+    public void setAlpnProtocols(byte[][] protocols) {
+        this.mAlpnProtocols = toLengthPrefixedList(protocols);
     }
 
     /**
      * Returns an array containing the concatenation of length-prefixed byte
      * strings.
      */
-    static byte[] toNpnProtocolsList(byte[]... npnProtocols) {
-        if (npnProtocols.length == 0) {
-            throw new IllegalArgumentException("npnProtocols.length == 0");
+    static byte[] toLengthPrefixedList(byte[]... items) {
+        if (items.length == 0) {
+            throw new IllegalArgumentException("items.length == 0");
         }
         int totalLength = 0;
-        for (byte[] s : npnProtocols) {
+        for (byte[] s : items) {
             if (s.length == 0 || s.length > 255) {
                 throw new IllegalArgumentException("s.length == 0 || s.length > 255: " + s.length);
             }
@@ -288,7 +312,7 @@
         }
         byte[] result = new byte[totalLength];
         int pos = 0;
-        for (byte[] s : npnProtocols) {
+        for (byte[] s : items) {
             result[pos++] = (byte) s.length;
             for (byte b : s) {
                 result[pos++] = b;
@@ -310,6 +334,20 @@
     }
 
     /**
+     * Returns the
+     * <a href="http://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-01">Application
+     * Layer Protocol Negotiation (ALPN)</a> protocol selected by client and server, or null
+     * if no protocol was negotiated.
+     *
+     * @param socket a socket created by this factory.
+     * @throws IllegalArgumentException if the socket was not created by this factory.
+     * @hide
+     */
+    public byte[] getAlpnSelectedProtocol(Socket socket) {
+        return castToOpenSSLSocket(socket).getAlpnSelectedProtocol();
+    }
+
+    /**
      * Sets the {@link KeyManager}s to be used for connections made by this factory.
      */
     public void setKeyManagers(KeyManager[] keyManagers) {
@@ -393,6 +431,7 @@
     public Socket createSocket(Socket k, String host, int port, boolean close) throws IOException {
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(k, host, port, close);
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         if (mSecure) {
@@ -413,6 +452,7 @@
     public Socket createSocket() throws IOException {
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket();
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         return s;
@@ -431,6 +471,7 @@
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
                 addr, port, localAddr, localPort);
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         return s;
@@ -447,6 +488,7 @@
     public Socket createSocket(InetAddress addr, int port) throws IOException {
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(addr, port);
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         return s;
@@ -464,6 +506,7 @@
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(
                 host, port, localAddr, localPort);
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         if (mSecure) {
@@ -482,6 +525,7 @@
     public Socket createSocket(String host, int port) throws IOException {
         OpenSSLSocketImpl s = (OpenSSLSocketImpl) getDelegate().createSocket(host, port);
         s.setNpnProtocols(mNpnProtocols);
+        s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
         if (mSecure) {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index f0acba1..52ad76d 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -108,6 +108,7 @@
     private HardwareLayer mLayer;
     private SurfaceTexture mSurface;
     private SurfaceTextureListener mListener;
+    private boolean mHadSurface;
 
     private boolean mOpaque = true;
 
@@ -202,6 +203,11 @@
             Log.w(LOG_TAG, "A TextureView or a subclass can only be "
                     + "used with hardware acceleration enabled.");
         }
+
+        if (mHadSurface) {
+            invalidate(true);
+            mHadSurface = false;
+        }
     }
 
     @Override
@@ -241,6 +247,8 @@
             if (shouldRelease) mSurface.release();
             mSurface = null;
             mLayer = null;
+
+            mHadSurface = true;
         }
     }
 
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 880464d..d1f7fa3 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -30,8 +30,6 @@
     oneway void keyguardDone(boolean authenticated, boolean wakeup);
     oneway void setHidden(boolean isHidden);
     oneway void dismiss();
-    oneway void onWakeKeyWhenKeyguardShowing(int keyCode);
-    oneway void onWakeMotionWhenKeyguardShowing();
     oneway void onDreamingStarted();
     oneway void onDreamingStopped();
     oneway void onScreenTurnedOff(int reason);
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index df579c6..464ae2f 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -26,48 +26,41 @@
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
-import android.widget.LinearLayout;
 import android.widget.RadioButton;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 /**
  * The item view for each item in the ListView-based MenuViews.
  */
-public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
-    private static final String TAG = "ListMenuItemView";
-    private MenuItemImpl mItemData; 
-    
+public class ListMenuItemView extends RelativeLayout implements MenuView.ItemView {
+    private final Drawable mBackground;
+    private final int mTextAppearance;
+
+    private MenuItemImpl mItemData;
+
     private ImageView mIconView;
     private RadioButton mRadioButton;
     private TextView mTitleView;
     private CheckBox mCheckBox;
     private TextView mShortcutView;
-    
-    private Drawable mBackground;
-    private int mTextAppearance;
-    private Context mTextAppearanceContext;
-    private boolean mPreserveIconSpacing;
-    
-    private int mMenuType;
-    
+
     private LayoutInflater mInflater;
 
+    private boolean mPreserveIconSpacing;
     private boolean mForceShowIcon;
 
     public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs);
-    
-        TypedArray a =
-            context.obtainStyledAttributes(
+
+        final TypedArray a = context.obtainStyledAttributes(
                 attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
-        
         mBackground = a.getDrawable(com.android.internal.R.styleable.MenuView_itemBackground);
-        mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
-                                          MenuView_itemTextAppearance, -1);
+        mTextAppearance = a.getResourceId(
+                com.android.internal.R.styleable.MenuView_itemTextAppearance, 0);
         mPreserveIconSpacing = a.getBoolean(
                 com.android.internal.R.styleable.MenuView_preserveIconSpacing, false);
-        mTextAppearanceContext = context;
-        
+
         a.recycle();
     }
 
@@ -78,24 +71,22 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        
-        setBackgroundDrawable(mBackground);
-        
+
+        setBackground(mBackground);
+
         mTitleView = (TextView) findViewById(com.android.internal.R.id.title);
-        if (mTextAppearance != -1) {
-            mTitleView.setTextAppearance(mTextAppearanceContext,
-                                         mTextAppearance);
+        if (mTextAppearance != 0) {
+            mTitleView.setTextAppearance(mContext, mTextAppearance);
         }
-        
+
         mShortcutView = (TextView) findViewById(com.android.internal.R.id.shortcut);
     }
 
+    @Override
     public void initialize(MenuItemImpl itemData, int menuType) {
         mItemData = itemData;
-        mMenuType = menuType;
 
         setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
-        
         setTitle(itemData.getTitleForItemView(this));
         setCheckable(itemData.isCheckable());
         setShortcut(itemData.shouldShowShortcut(), itemData.getShortcut());
@@ -107,29 +98,36 @@
         mPreserveIconSpacing = mForceShowIcon = forceShow;
     }
 
+    @Override
     public void setTitle(CharSequence title) {
         if (title != null) {
             mTitleView.setText(title);
-            
-            if (mTitleView.getVisibility() != VISIBLE) mTitleView.setVisibility(VISIBLE);
+
+            if (mTitleView.getVisibility() != VISIBLE) {
+                mTitleView.setVisibility(VISIBLE);
+            }
         } else {
-            if (mTitleView.getVisibility() != GONE) mTitleView.setVisibility(GONE);
+            if (mTitleView.getVisibility() != GONE) {
+                mTitleView.setVisibility(GONE);
+            }
         }
     }
-    
+
+    @Override
     public MenuItemImpl getItemData() {
         return mItemData;
     }
 
+    @Override
     public void setCheckable(boolean checkable) {
         if (!checkable && mRadioButton == null && mCheckBox == null) {
             return;
         }
-        
+
         // Depending on whether its exclusive check or not, the checkbox or
         // radio button will be the one in use (and the other will be otherCompoundButton)
         final CompoundButton compoundButton;
-        final CompoundButton otherCompoundButton; 
+        final CompoundButton otherCompoundButton;
 
         if (mItemData.isExclusiveCheckable()) {
             if (mRadioButton == null) {
@@ -144,28 +142,36 @@
             compoundButton = mCheckBox;
             otherCompoundButton = mRadioButton;
         }
-        
+
         if (checkable) {
             compoundButton.setChecked(mItemData.isChecked());
-            
+
             final int newVisibility = checkable ? VISIBLE : GONE;
             if (compoundButton.getVisibility() != newVisibility) {
                 compoundButton.setVisibility(newVisibility);
             }
-            
+
+            // Align text to the start of the visible compound button.
+            alignTextToStartOf(compoundButton);
+
             // Make sure the other compound button isn't visible
             if (otherCompoundButton != null && otherCompoundButton.getVisibility() != GONE) {
                 otherCompoundButton.setVisibility(GONE);
             }
         } else {
-            if (mCheckBox != null) mCheckBox.setVisibility(GONE);
-            if (mRadioButton != null) mRadioButton.setVisibility(GONE);
+            if (mCheckBox != null) {
+                mCheckBox.setVisibility(GONE);
+            }
+            if (mRadioButton != null) {
+                mRadioButton.setVisibility(GONE);
+            }
         }
     }
-    
+
+    @Override
     public void setChecked(boolean checked) {
         CompoundButton compoundButton;
-        
+
         if (mItemData.isExclusiveCheckable()) {
             if (mRadioButton == null) {
                 insertRadioButton();
@@ -177,13 +183,13 @@
             }
             compoundButton = mCheckBox;
         }
-        
+
         compoundButton.setChecked(checked);
     }
 
+    @Override
     public void setShortcut(boolean showShortcut, char shortcutKey) {
-        final int newVisibility = (showShortcut && mItemData.shouldShowShortcut())
-                ? VISIBLE : GONE;
+        final int newVisibility = (showShortcut && mItemData.shouldShowShortcut()) ? VISIBLE : GONE;
 
         if (newVisibility == VISIBLE) {
             mShortcutView.setText(mItemData.getShortcutLabel());
@@ -193,21 +199,22 @@
             mShortcutView.setVisibility(newVisibility);
         }
     }
-    
+
+    @Override
     public void setIcon(Drawable icon) {
         final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
         if (!showIcon && !mPreserveIconSpacing) {
             return;
         }
-        
+
         if (mIconView == null && icon == null && !mPreserveIconSpacing) {
             return;
         }
-        
+
         if (mIconView == null) {
             insertIconView();
         }
-        
+
         if (icon != null || mPreserveIconSpacing) {
             mIconView.setImageDrawable(showIcon ? icon : null);
 
@@ -218,51 +225,52 @@
             mIconView.setVisibility(GONE);
         }
     }
-    
+
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (mIconView != null && mPreserveIconSpacing) {
             // Enforce minimum icon spacing
-            ViewGroup.LayoutParams lp = getLayoutParams();
-            LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+            final ViewGroup.LayoutParams lp = getLayoutParams();
+            final LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
             if (lp.height > 0 && iconLp.width <= 0) {
                 iconLp.width = lp.height;
             }
         }
+
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
     private void insertIconView() {
-        LayoutInflater inflater = getInflater();
-        mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
-                this, false);
-        addView(mIconView, 0);
-    }
-    
-    private void insertRadioButton() {
-        LayoutInflater inflater = getInflater();
-        mRadioButton =
-                (RadioButton) inflater.inflate(com.android.internal.R.layout.list_menu_item_radio,
-                this, false);
-        addView(mRadioButton);
-    }
-    
-    private void insertCheckBox() {
-        LayoutInflater inflater = getInflater();
-        mCheckBox =
-                (CheckBox) inflater.inflate(com.android.internal.R.layout.list_menu_item_checkbox,
-                this, false);
-        addView(mCheckBox);
+        mIconView = (ImageView) getInflater()
+                .inflate(com.android.internal.R.layout.list_menu_item_icon, this, true);
     }
 
+    private void insertRadioButton() {
+        mRadioButton = (RadioButton) getInflater()
+                .inflate(com.android.internal.R.layout.list_menu_item_radio, this, true);
+    }
+
+    private void insertCheckBox() {
+        mCheckBox = (CheckBox) getInflater()
+                .inflate(com.android.internal.R.layout.list_menu_item_checkbox, this, true);
+    }
+
+    private void alignTextToStartOf(View v) {
+        final LayoutParams params = (LayoutParams) mTitleView.getLayoutParams();
+        params.addRule(RelativeLayout.START_OF, v.getId());
+        mTitleView.setLayoutParams(params);
+    }
+
+    @Override
     public boolean prefersCondensedTitle() {
         return false;
     }
 
+    @Override
     public boolean showsIcon() {
         return mForceShowIcon;
     }
-    
+
     private LayoutInflater getInflater() {
         if (mInflater == null) {
             mInflater = LayoutInflater.from(mContext);
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index cacc86b..6d39860 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.database.DataSetObserver;
 import android.os.Parcelable;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -47,23 +46,28 @@
 
     static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout;
 
-    private Context mContext;
-    private LayoutInflater mInflater;
-    private ListPopupWindow mPopup;
-    private MenuBuilder mMenu;
-    private int mPopupMaxWidth;
+    private final Context mContext;
+    private final LayoutInflater mInflater;
+    private final MenuBuilder mMenu;
+    private final MenuAdapter mAdapter;
+    private final boolean mOverflowOnly;
+    private final int mPopupMaxWidth;
+
     private View mAnchorView;
-    private boolean mOverflowOnly;
+    private ListPopupWindow mPopup;
     private ViewTreeObserver mTreeObserver;
-
-    private MenuAdapter mAdapter;
-
     private Callback mPresenterCallback;
 
     boolean mForceShowIcon;
 
     private ViewGroup mMeasureParent;
 
+    /** Whether the cached content width value is valid. */
+    private boolean mHasContentWidth;
+
+    /** Cached content width from {@link #measureContentWidth}. */
+    private int mContentWidth;
+
     public MenuPopupHelper(Context context, MenuBuilder menu) {
         this(context, menu, null, false);
     }
@@ -77,6 +81,7 @@
         mContext = context;
         mInflater = LayoutInflater.from(context);
         mMenu = menu;
+        mAdapter = new MenuAdapter(mMenu);
         mOverflowOnly = overflowOnly;
 
         final Resources res = context.getResources();
@@ -106,8 +111,6 @@
         mPopup = new ListPopupWindow(mContext, null, com.android.internal.R.attr.popupMenuStyle);
         mPopup.setOnDismissListener(this);
         mPopup.setOnItemClickListener(this);
-
-        mAdapter = new MenuAdapter(mMenu);
         mPopup.setAdapter(mAdapter);
         mPopup.setModal(true);
 
@@ -122,7 +125,12 @@
             return false;
         }
 
-        mPopup.setContentWidth(Math.min(measureContentWidth(mAdapter), mPopupMaxWidth));
+        if (!mHasContentWidth) {
+            mContentWidth = measureContentWidth();
+            mHasContentWidth = true;
+        }
+
+        mPopup.setContentWidth(mContentWidth);
         mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
         mPopup.show();
         mPopup.getListView().setOnKeyListener(this);
@@ -164,15 +172,15 @@
         return false;
     }
 
-    private int measureContentWidth(ListAdapter adapter) {
+    private int measureContentWidth() {
         // Menus don't tend to be long, so this is more sane than it looks.
-        int width = 0;
+        int maxWidth = 0;
         View itemView = null;
         int itemType = 0;
-        final int widthMeasureSpec =
-            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec =
-            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+
+        final ListAdapter adapter = mAdapter;
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
         final int count = adapter.getCount();
         for (int i = 0; i < count; i++) {
             final int positionType = adapter.getItemViewType(i);
@@ -180,14 +188,23 @@
                 itemType = positionType;
                 itemView = null;
             }
+
             if (mMeasureParent == null) {
                 mMeasureParent = new FrameLayout(mContext);
             }
+
             itemView = adapter.getView(i, itemView, mMeasureParent);
             itemView.measure(widthMeasureSpec, heightMeasureSpec);
-            width = Math.max(width, itemView.getMeasuredWidth());
+
+            final int itemWidth = itemView.getMeasuredWidth();
+            if (itemWidth >= mPopupMaxWidth) {
+                return mPopupMaxWidth;
+            } else if (itemWidth > maxWidth) {
+                maxWidth = itemWidth;
+            }
         }
-        return width;
+
+        return maxWidth;
     }
 
     @Override
@@ -228,7 +245,11 @@
 
     @Override
     public void updateMenuView(boolean cleared) {
-        if (mAdapter != null) mAdapter.notifyDataSetChanged();
+        mHasContentWidth = false;
+
+        if (mAdapter != null) {
+            mAdapter.notifyDataSetChanged();
+        }
     }
 
     @Override
diff --git a/core/res/res/layout/list_menu_item_checkbox.xml b/core/res/res/layout/list_menu_item_checkbox.xml
index dc02a1e..02febc4 100644
--- a/core/res/res/layout/list_menu_item_checkbox.xml
+++ b/core/res/res/layout/list_menu_item_checkbox.xml
@@ -4,9 +4,9 @@
      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.
@@ -18,9 +18,8 @@
     android:id="@+id/checkbox"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
+    android:layout_alignParentEnd="true"
+    android:layout_centerVertical="true"
     android:focusable="false"
     android:clickable="false"
     android:duplicateParentState="true" />
-
-
diff --git a/core/res/res/layout/list_menu_item_icon.xml b/core/res/res/layout/list_menu_item_icon.xml
index a30be6a..89b6b09 100644
--- a/core/res/res/layout/list_menu_item_icon.xml
+++ b/core/res/res/layout/list_menu_item_icon.xml
@@ -4,9 +4,9 @@
      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.
@@ -18,11 +18,12 @@
     android:id="@+id/icon"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
+    android:layout_centerVertical="true"
+    android:layout_alignParentStart="true"
     android:layout_marginStart="8dip"
     android:layout_marginEnd="-8dip"
     android:layout_marginTop="8dip"
     android:layout_marginBottom="8dip"
     android:scaleType="centerInside"
-    android:duplicateParentState="true" />
-
+    android:duplicateParentState="true"
+    android:contentDescription="@null" />
diff --git a/core/res/res/layout/list_menu_item_layout.xml b/core/res/res/layout/list_menu_item_layout.xml
index e8d4983..3130215 100644
--- a/core/res/res/layout/list_menu_item_layout.xml
+++ b/core/res/res/layout/list_menu_item_layout.xml
@@ -4,9 +4,9 @@
      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.
@@ -16,46 +16,38 @@
 
 <com.android.internal.view.menu.ListMenuItemView xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="?android:attr/listPreferredItemHeightSmall">
-    
+    android:layout_height="?android:attr/listPreferredItemHeightSmall"
+    android:gravity="start|center_vertical">
+
     <!-- Icon will be inserted here. -->
-    
-    <!-- The title and summary have some gap between them, and this 'group' should be centered vertically. -->
-    <RelativeLayout
-        android:layout_width="0dip"
-        android:layout_weight="1"
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
+        android:layout_alignWithParentIfMissing="true"
         android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
         android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
-        android:duplicateParentState="true">
-        
-        <TextView 
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:textAppearance="?android:attr/textAppearanceListItemSmall"
-            android:singleLine="true"
-            android:duplicateParentState="true"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal"
-            android:textAlignment="viewStart" />
+        android:layout_toEndOf="@id/icon"
+        android:textAppearance="?android:attr/textAppearanceListItemSmall"
+        android:singleLine="true"
+        android:duplicateParentState="true"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal"
+        android:textAlignment="viewStart" />
 
-        <TextView
-            android:id="@+id/shortcut"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/title"
-            android:layout_alignParentStart="true"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:singleLine="true"
-            android:duplicateParentState="true"
-            android:textAlignment="viewStart" />
-
-    </RelativeLayout>
+    <TextView
+        android:id="@+id/shortcut"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/title"
+        android:layout_alignStart="@id/title"
+        android:layout_alignWithParentIfMissing="true"
+        android:textAppearance="?android:attr/textAppearanceSmall"
+        android:singleLine="true"
+        android:duplicateParentState="true"
+        android:textAlignment="viewStart" />
 
     <!-- Checkbox, and/or radio button will be inserted here. -->
-    
+
 </com.android.internal.view.menu.ListMenuItemView>
diff --git a/core/res/res/layout/list_menu_item_radio.xml b/core/res/res/layout/list_menu_item_radio.xml
index ac4459e..74564ad 100644
--- a/core/res/res/layout/list_menu_item_radio.xml
+++ b/core/res/res/layout/list_menu_item_radio.xml
@@ -4,9 +4,9 @@
      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.
@@ -18,7 +18,8 @@
     android:id="@+id/radio"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
+    android:layout_alignParentEnd="true"
+    android:layout_centerVertical="true"
     android:focusable="false"
     android:clickable="false"
     android:duplicateParentState="true" />
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index 452f85d..aff3779 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -4,9 +4,9 @@
      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.
@@ -18,45 +18,37 @@
     android:layout_width="match_parent"
     android:layout_height="?android:attr/dropdownListPreferredItemHeight"
     android:minWidth="196dip"
-    android:paddingEnd="16dip">
-    
+    android:paddingEnd="16dip"
+    android:gravity="start|center_vertical">
+
     <!-- Icon will be inserted here. -->
-    
-    <!-- The title and summary have some gap between them, and this 'group' should be centered vertically. -->
-    <RelativeLayout
-        android:layout_width="0dip"
-        android:layout_weight="1"
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
+        android:layout_alignWithParentIfMissing="true"
         android:layout_marginStart="16dip"
-        android:duplicateParentState="true">
-        
-        <TextView 
-            android:id="@+id/title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentTop="true"
-            android:layout_alignParentStart="true"
-            android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
-            android:singleLine="true"
-            android:duplicateParentState="true"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal"
-            android:textAlignment="viewStart" />
+        android:layout_toEndOf="@id/icon"
+        android:textAppearance="?android:attr/textAppearanceLargePopupMenu"
+        android:singleLine="true"
+        android:duplicateParentState="true"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal"
+        android:textAlignment="viewStart" />
 
-        <TextView
-            android:id="@+id/shortcut"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_below="@id/title"
-            android:layout_alignParentStart="true"
-            android:textAppearance="?android:attr/textAppearanceSmallPopupMenu"
-            android:singleLine="true"
-            android:duplicateParentState="true"
-            android:textAlignment="viewStart" />
-
-    </RelativeLayout>
+    <TextView
+        android:id="@+id/shortcut"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/title"
+        android:layout_alignStart="@id/title"
+        android:layout_alignWithParentIfMissing="true"
+        android:textAppearance="?android:attr/textAppearanceSmallPopupMenu"
+        android:singleLine="true"
+        android:duplicateParentState="true"
+        android:textAlignment="viewStart" />
 
     <!-- Checkbox, and/or radio button will be inserted here. -->
-    
+
 </com.android.internal.view.menu.ListMenuItemView>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 75ff8b2..0080ad9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2069,7 +2069,7 @@
     <!-- QQ IM protocol type -->
     <string name="imProtocolQq">QQ</string>
     <!-- Google Talk IM protocol type -->
-    <string name="imProtocolGoogleTalk">Google Talk</string>
+    <string name="imProtocolGoogleTalk">Hangouts</string>
     <!-- ICQ IM protocol type -->
     <string name="imProtocolIcq">ICQ</string>
     <!-- Jabber IM protocol type -->
diff --git a/core/tests/coretests/src/android/net/SSLTest.java b/core/tests/coretests/src/android/net/SSLTest.java
index 27b699d..45d28ae 100644
--- a/core/tests/coretests/src/android/net/SSLTest.java
+++ b/core/tests/coretests/src/android/net/SSLTest.java
@@ -49,35 +49,35 @@
         // System.out.println(new String(b));
     }
 
-    public void testStringsToNpnBytes() {
+    public void testStringsToLengthPrefixedBytes() {
         byte[] expected = {
                 6, 's', 'p', 'd', 'y', '/', '2',
                 8, 'h', 't', 't', 'p', '/', '1', '.', '1',
         };
-        assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toNpnProtocolsList(
+        assertTrue(Arrays.equals(expected, SSLCertificateSocketFactory.toLengthPrefixedList(
                 new byte[] { 's', 'p', 'd', 'y', '/', '2' },
                 new byte[] { 'h', 't', 't', 'p', '/', '1', '.', '1' })));
     }
 
-    public void testStringsToNpnBytesEmptyArray() {
+    public void testStringsToLengthPrefixedBytesEmptyArray() {
         try {
-            SSLCertificateSocketFactory.toNpnProtocolsList();
+            SSLCertificateSocketFactory.toLengthPrefixedList();
             fail();
         } catch (IllegalArgumentException expected) {
         }
     }
 
-    public void testStringsToNpnBytesEmptyByteArray() {
+    public void testStringsToLengthPrefixedBytesEmptyByteArray() {
         try {
-            SSLCertificateSocketFactory.toNpnProtocolsList(new byte[0]);
+            SSLCertificateSocketFactory.toLengthPrefixedList(new byte[0]);
             fail();
         } catch (IllegalArgumentException expected) {
         }
     }
 
-    public void testStringsToNpnBytesOversizedInput() {
+    public void testStringsToLengthPrefixedBytesOversizedInput() {
         try {
-            SSLCertificateSocketFactory.toNpnProtocolsList(new byte[256]);
+            SSLCertificateSocketFactory.toLengthPrefixedList(new byte[256]);
             fail();
         } catch (IllegalArgumentException expected) {
         }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index d54b675..5d3c1d3 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -31,7 +31,10 @@
     }
 
     /**
-     * Supported elements types are {@link Element#U8_4}
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}
      *
      * The default coefficients are.
      *
@@ -49,8 +52,12 @@
     public static ScriptIntrinsicConvolve3x3 create(RenderScript rs, Element e) {
         float f[] = { 0, 0, 0, 0, 1, 0, 0, 0, 0};
         if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
             !e.isCompatible(Element.U8_4(rs)) &&
             !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
             !e.isCompatible(Element.F32_4(rs))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
diff --git a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index da4d5a2..ad09f95 100644
--- a/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/graphics/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -31,7 +31,10 @@
     }
 
     /**
-     * Supported elements types are {@link Element#U8_4}
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}
      *
      * The default coefficients are.
      * <code>
@@ -49,8 +52,12 @@
      */
     public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
         if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
             !e.isCompatible(Element.U8_4(rs)) &&
             !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
             !e.isCompatible(Element.F32_4(rs))) {
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index 782c052..d98a538 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "OpenGLRenderer"
+
 #include "AssetAtlas.h"
 #include "Caches.h"
 
@@ -49,6 +51,8 @@
         mImage = NULL;
         mTexture = NULL;
     }
+
+    mGenerationId++;
 }
 
 void AssetAtlas::terminate() {
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 2624907..9afc54d 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -97,7 +97,7 @@
         friend class AssetAtlas;
     };
 
-    AssetAtlas(): mTexture(NULL), mImage(NULL) { }
+    AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0) { }
     ~AssetAtlas() { terminate(); }
 
     /**
@@ -158,12 +158,21 @@
      */
     Texture* getEntryTexture(SkBitmap* const bitmap) const;
 
+    /**
+     * Returns the current generation id of the atlas.
+     */
+    uint32_t getGenerationId() const {
+        return mGenerationId;
+    }
+
 private:
     void createEntries(Caches& caches, int* map, int count);
 
     Texture* mTexture;
     Image* mImage;
 
+    uint32_t mGenerationId;
+
     KeyedVector<SkBitmap*, Entry*> mEntries;
 }; // class AssetAtlas
 
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 6099f5d..2b6f4cd 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -732,14 +732,12 @@
 public:
     DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
             : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
-            mBitmap(bitmap), mAtlasEntry(NULL) {
-    }
-
-    DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint,
-            const AssetAtlas::Entry* entry)
-            : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
-            mBitmap(bitmap), mAtlasEntry(entry) {
-        if (entry) mUvMapper = entry->uvMapper;
+            mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
+        mEntry = mAtlas.getEntry(bitmap);
+        if (mEntry) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mUvMapper = mEntry->uvMapper;
+        }
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -747,6 +745,16 @@
                 getPaint(renderer));
     }
 
+    AssetAtlas::Entry* getAtlasEntry() {
+        // The atlas entry is stale, let's get a new one
+        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mEntry = mAtlas.getEntry(mBitmap);
+            mUvMapper = mEntry->uvMapper;
+        }
+        return mEntry;
+    }
+
 #define SET_TEXTURE(ptr, posRect, offsetRect, texCoordsRect, xDim, yDim) \
     TextureVertex::set(ptr++, posRect.xDim - offsetRect.left, posRect.yDim - offsetRect.top, \
             texCoordsRect.xDim, texCoordsRect.yDim)
@@ -791,7 +799,7 @@
             }
         }
 
-        return renderer.drawBitmaps(mBitmap, ops.size(), &vertices[0],
+        return renderer.drawBitmaps(mBitmap, mEntry, ops.size(), &vertices[0],
                 transformed, bounds, mPaint);
     }
 
@@ -803,7 +811,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Bitmap;
-        deferInfo.mergeId = mAtlasEntry ? (mergeid_t) &mAtlasEntry->atlas : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
 
         // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in
         // MergingDrawBatch::canMergeWith()
@@ -816,7 +824,9 @@
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
     SkBitmap* mBitmap;
-    const AssetAtlas::Entry* mAtlasEntry;
+    const AssetAtlas& mAtlas;
+    uint32_t mEntryGenerationId;
+    AssetAtlas::Entry* mEntry;
     UvMapper mUvMapper;
 };
 
@@ -934,14 +944,27 @@
     DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch,
             float left, float top, float right, float bottom, SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
-            mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL) {
-        mEntry = Caches::getInstance().assetAtlas.getEntry(bitmap);
+            mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
+            mAtlas(Caches::getInstance().assetAtlas) {
+        mEntry = mAtlas.getEntry(bitmap);
+        if (mEntry) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+        }
     };
 
+    AssetAtlas::Entry* getAtlasEntry() {
+        // The atlas entry is stale, let's get a new one
+        if (mEntry && mEntryGenerationId != mAtlas.getGenerationId()) {
+            mEntryGenerationId = mAtlas.getGenerationId();
+            mEntry = mAtlas.getEntry(mBitmap);
+        }
+        return mEntry;
+    }
+
     const Patch* getMesh(OpenGLRenderer& renderer) {
         if (!mMesh || renderer.getCaches().patchCache.getGenerationId() != mGenerationId) {
             PatchCache& cache = renderer.getCaches().patchCache;
-            mMesh = cache.get(mEntry, mBitmap->width(), mBitmap->height(),
+            mMesh = cache.get(getAtlasEntry(), mBitmap->width(), mBitmap->height(),
                     mLocalBounds.getWidth(), mLocalBounds.getHeight(), mPatch);
             mGenerationId = cache.getGenerationId();
         }
@@ -1021,13 +1044,14 @@
             indexCount += opMesh->indexCount;
         }
 
-        return renderer.drawPatches(mBitmap, mEntry, &vertices[0], indexCount, getPaint(renderer));
+        return renderer.drawPatches(mBitmap, getAtlasEntry(),
+                &vertices[0], indexCount, getPaint(renderer));
     }
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         // We're not calling the public variant of drawPatch() here
         // This method won't perform the quickReject() since we've already done it at this point
-        return renderer.drawPatch(mBitmap, getMesh(renderer), mEntry,
+        return renderer.drawPatch(mBitmap, getMesh(renderer), getAtlasEntry(),
                 mLocalBounds.left, mLocalBounds.top, mLocalBounds.right, mLocalBounds.bottom,
                 getPaint(renderer));
     }
@@ -1040,7 +1064,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo) {
         deferInfo.batchId = DeferredDisplayList::kOpBatch_Patch;
-        deferInfo.mergeId = mEntry ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
+        deferInfo.mergeId = getAtlasEntry() ? (mergeid_t) &mEntry->atlas : (mergeid_t) mBitmap;
         deferInfo.mergeable = state.mMatrix.isPureTranslate() &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode;
         deferInfo.opaqueOverBounds = isOpaqueOverBounds() && mBitmap->isOpaque();
@@ -1053,6 +1077,8 @@
     uint32_t mGenerationId;
     const Patch* mMesh;
 
+    const AssetAtlas& mAtlas;
+    uint32_t mEntryGenerationId;
     AssetAtlas::Entry* mEntry;
 };
 
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 9113092..ba4c2a0 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -262,8 +262,7 @@
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
-    const AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
-    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint, entry));
+    addDrawOp(new (alloc()) DrawBitmapOp(bitmap, left, top, paint));
     return DrawGlInfo::kStatusDone;
 }
 
@@ -287,8 +286,7 @@
             (srcBottom - srcTop == dstBottom - dstTop) &&
             (srcRight - srcLeft == dstRight - dstLeft)) {
         // transform simple rect to rect drawing case into position bitmap ops, since they merge
-        const AssetAtlas::Entry* entry = mCaches.assetAtlas.getEntry(bitmap);
-        addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint, entry));
+        addDrawOp(new (alloc()) DrawBitmapOp(bitmap, dstLeft, dstTop, paint));
         return DrawGlInfo::kStatusDone;
     }
 
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 6f1dc6f..73c0453 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1168,8 +1168,6 @@
         return;
     }
 
-    // TODO: See LayerRenderer.cpp::generateMesh() for important
-    //       information about this implementation
     if (CC_LIKELY(!layer->region.isEmpty())) {
         size_t count;
         const android::Rect* rects;
@@ -2055,10 +2053,10 @@
  * will not set the scissor enable or dirty the current layer, if any.
  * The caller is responsible for properly dirtying the current layer.
  */
-status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
-        bool transformed, const Rect& bounds, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+        TextureVertex* vertices, bool transformed, const Rect& bounds, SkPaint* paint) {
     mCaches.activeTexture(0);
-    Texture* texture = getTexture(bitmap);
+    Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
 
     const AutoTexture autoCleanup(texture);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index aa0f9fc..5e731b4 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -288,8 +288,8 @@
     virtual void outputDisplayList(DisplayList* displayList);
     virtual status_t drawLayer(Layer* layer, float x, float y);
     virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
-    status_t drawBitmaps(SkBitmap* bitmap, int bitmapCount, TextureVertex* vertices,
-            bool transformed, const Rect& bounds, SkPaint* paint);
+    status_t drawBitmaps(SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+            TextureVertex* vertices, bool transformed, const Rect& bounds, SkPaint* paint);
     virtual status_t drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
     virtual status_t drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 0970248..2904f4c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -119,6 +119,8 @@
 
     protected int mClientGeneration;
 
+    protected boolean mShowSecurityWhenReturn;
+
     /*package*/ interface UserSwitcherCallback {
         void hideSecurityView(int duration);
         void showSecurityView();
@@ -872,14 +874,6 @@
         }
     };
 
-    protected boolean mShowSecurityWhenReturn;
-
-    @Override
-    public void reset() {
-        mIsVerifyUnlockOnly = false;
-        mAppWidgetContainer.setCurrentPage(getWidgetPosition(R.id.keyguard_status_view));
-    }
-
     /**
      * Sets an action to perform when keyguard is dismissed.
      * @param action
@@ -1029,39 +1023,6 @@
         showPrimarySecurityScreen(false);
     }
 
-    private boolean isSecure() {
-        SecurityMode mode = mSecurityModel.getSecurityMode();
-        switch (mode) {
-            case Pattern:
-                return mLockPatternUtils.isLockPatternEnabled();
-            case Password:
-            case PIN:
-                return mLockPatternUtils.isLockPasswordEnabled();
-            case SimPin:
-            case SimPuk:
-            case Account:
-                return true;
-            case None:
-                return false;
-            default:
-                throw new IllegalStateException("Unknown security mode " + mode);
-        }
-    }
-
-    @Override
-    public void wakeWhenReadyTq(int keyCode) {
-        if (DEBUG) Log.d(TAG, "onWakeKey");
-        if (keyCode == KeyEvent.KEYCODE_MENU && isSecure()) {
-            if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU");
-            showSecurityScreen(SecurityMode.None);
-        } else {
-            if (DEBUG) Log.d(TAG, "poking wake lock immediately");
-        }
-        if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.wakeUp();
-        }
-    }
-
     @Override
     public void verifyUnlock() {
         SecurityMode securityMode = mSecurityModel.getSecurityMode();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
index f89ad65..a70e5bd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardService.java
@@ -93,14 +93,6 @@
         public void dismiss() {
             mKeyguardViewMediator.dismiss();
         }
-        public void onWakeKeyWhenKeyguardShowing(int keyCode) {
-            checkPermission();
-            mKeyguardViewMediator.onWakeKeyWhenKeyguardShowing(keyCode);
-        }
-        public void onWakeMotionWhenKeyguardShowing() {
-            checkPermission();
-            mKeyguardViewMediator.onWakeMotionWhenKeyguardShowing();
-        }
         public void onDreamingStarted() {
             checkPermission();
             mKeyguardViewMediator.onDreamingStarted();
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index 200fb3c..714dfbd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -90,11 +90,6 @@
     }
 
     /**
-     * Called when you need to reset the state of your view.
-     */
-    abstract public void reset();
-
-    /**
      * Called when the screen turned off.
      */
     abstract public void onScreenTurnedOff();
@@ -110,21 +105,6 @@
     abstract public void show();
 
     /**
-     * Called when a key has woken the device to give us a chance to adjust our
-     * state according the the key.  We are responsible for waking the device
-     * (by poking the wake lock) once we are ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The wake key, which may be relevant for configuring the
-     *   keyguard.  May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking for a reason
-     *   other than a key press.
-     */
-    abstract public void wakeWhenReadyTq(int keyCode);
-
-    /**
      * Verify that the user can get past the keyguard securely.  This is called,
      * for example, when the phone disables the keyguard but then wants to launch
      * something else that requires secure access.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index b6c35bd..a1d11cd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -384,27 +384,6 @@
     }
 
     /**
-     * A key has woken the device.  We use this to potentially adjust the state
-     * of the lock screen based on the key.
-     *
-     * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The wake key.  May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking
-     * for a reason other than a key press.
-     */
-    public boolean wakeWhenReadyTq(int keyCode) {
-        if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
-        if (mKeyguardView != null) {
-            mKeyguardView.wakeWhenReadyTq(keyCode);
-            return true;
-        }
-        Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
-        return false;
-    }
-
-    /**
      * Hides the keyguard view
      */
     public synchronized void hide() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 4ce0dcd..597fb3b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -114,7 +114,6 @@
     private static final int VERIFY_UNLOCK = 5;
     private static final int NOTIFY_SCREEN_OFF = 6;
     private static final int NOTIFY_SCREEN_ON = 7;
-    private static final int WAKE_WHEN_READY = 8;
     private static final int KEYGUARD_DONE = 9;
     private static final int KEYGUARD_DONE_DRAWING = 10;
     private static final int KEYGUARD_DONE_AUTHENTICATING = 11;
@@ -180,14 +179,6 @@
      */
     private PowerManager.WakeLock mShowKeyguardWakeLock;
 
-    /**
-     * Does not turn on screen, held while a call to {@link KeyguardViewManager#wakeWhenReadyTq(int)}
-     * is called to make sure the device doesn't sleep before it has a chance to poke
-     * the wake lock.
-     * @see #wakeWhenReady(int)
-     */
-    private PowerManager.WakeLock mWakeAndHandOff;
-
     private KeyguardViewManager mKeyguardViewManager;
 
     // these are protected by synchronized (this)
@@ -268,12 +259,6 @@
      * various things.
      */
     public interface ViewMediatorCallback {
-
-        /**
-         * Wake the device immediately.
-         */
-        void wakeUp();
-
         /**
          * Reports user activity and requests that the screen stay on.
          */
@@ -439,10 +424,6 @@
     };
 
     ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
-        public void wakeUp() {
-            KeyguardViewMediator.this.wakeUp();
-        }
-
         public void userActivity() {
             KeyguardViewMediator.this.userActivity();
         }
@@ -475,10 +456,6 @@
         }
     };
 
-    public void wakeUp() {
-        mPM.wakeUp(SystemClock.uptimeMillis());
-    }
-
     private void userActivity() {
         userActivity(AWAKE_INTERVAL_DEFAULT_MS);
     }
@@ -501,9 +478,6 @@
         mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
         mShowKeyguardWakeLock.setReferenceCounted(false);
 
-        mWakeAndHandOff = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "keyguardWakeAndHandOff");
-        mWakeAndHandOff.setReferenceCounted(false);
-
         mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
 
         mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
@@ -981,27 +955,6 @@
     }
 
     /**
-     * Send message to keyguard telling it about a wake key so it can adjust
-     * its state accordingly and then poke the wake lock when it is ready.
-     * @param keyCode The wake key.
-     * @see #handleWakeWhenReady
-     * @see #onWakeKeyWhenKeyguardShowing(int)
-     */
-    private void wakeWhenReady(int keyCode) {
-        if (DBG_WAKE) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
-
-        /**
-         * acquire the handoff lock that will keep the cpu running.  this will
-         * be released once the keyguard has set itself up and poked the other wakelock
-         * in {@link #handleWakeWhenReady(int)}
-         */
-        mWakeAndHandOff.acquire();
-
-        Message msg = mHandler.obtainMessage(WAKE_WHEN_READY, keyCode, 0);
-        mHandler.sendMessage(msg);
-    }
-
-    /**
      * Send message to keyguard telling it to show itself
      * @see #handleShow()
      */
@@ -1056,74 +1009,14 @@
         }
     };
 
-    /**
-     * When a key is received when the screen is off and the keyguard is showing,
-     * we need to decide whether to actually turn on the screen, and if so, tell
-     * the keyguard to prepare itself and poke the wake lock when it is ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     *
-     * @param keyCode The keycode of the key that woke the device
-     */
-    public void onWakeKeyWhenKeyguardShowing(int keyCode) {
-        if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")");
-
-        // give the keyguard view manager a chance to adjust the state of the
-        // keyguard based on the key that woke the device before poking
-        // the wake lock
-        wakeWhenReady(keyCode);
-    }
-
-    /**
-     * When a wake motion such as an external mouse movement is received when the screen
-     * is off and the keyguard is showing, we need to decide whether to actually turn
-     * on the screen, and if so, tell the keyguard to prepare itself and poke the wake
-     * lock when it is ready.
-     *
-     * The 'Tq' suffix is per the documentation in {@link WindowManagerPolicy}.
-     * Be sure not to take any action that takes a long time; any significant
-     * action should be posted to a handler.
-     */
-    public void onWakeMotionWhenKeyguardShowing() {
-        if (DEBUG) Log.d(TAG, "onWakeMotionWhenKeyguardShowing()");
-
-        // give the keyguard view manager a chance to adjust the state of the
-        // keyguard based on the key that woke the device before poking
-        // the wake lock
-        wakeWhenReady(KeyEvent.KEYCODE_UNKNOWN);
-    }
-
     public void keyguardDone(boolean authenticated, boolean wakeup) {
         mKeyguardDonePending = false;
         synchronized (this) {
             EventLog.writeEvent(70000, 2);
             if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")");
-            Message msg = mHandler.obtainMessage(KEYGUARD_DONE);
-            msg.arg1 = wakeup ? 1 : 0;
+            Message msg = mHandler.obtainMessage(KEYGUARD_DONE, authenticated ? 1 : 0,
+                    wakeup ? 1 : 0);
             mHandler.sendMessage(msg);
-
-            if (authenticated) {
-                mUpdateMonitor.clearFailedUnlockAttempts();
-            }
-
-            if (mExitSecureCallback != null) {
-                try {
-                    mExitSecureCallback.onKeyguardExitResult(authenticated);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
-                }
-
-                mExitSecureCallback = null;
-
-                if (authenticated) {
-                    // after succesfully exiting securely, no need to reshow
-                    // the keyguard when they've released the lock
-                    mExternallyEnabled = true;
-                    mNeedToReshowWhenReenabled = false;
-                }
-            }
         }
     }
 
@@ -1156,11 +1049,8 @@
                 case NOTIFY_SCREEN_ON:
                     handleNotifyScreenOn((IKeyguardShowCallback) msg.obj);
                     return;
-                case WAKE_WHEN_READY:
-                    handleWakeWhenReady(msg.arg1);
-                    return;
                 case KEYGUARD_DONE:
-                    handleKeyguardDone(msg.arg1 != 0);
+                    handleKeyguardDone(msg.arg1 != 0, msg.arg2 != 0);
                     return;
                 case KEYGUARD_DONE_DRAWING:
                     handleKeyguardDoneDrawing();
@@ -1187,13 +1077,31 @@
      * @see #keyguardDone
      * @see #KEYGUARD_DONE
      */
-    private void handleKeyguardDone(boolean wakeup) {
+    private void handleKeyguardDone(boolean authenticated, boolean wakeup) {
         if (DEBUG) Log.d(TAG, "handleKeyguardDone");
-        handleHide();
-        if (wakeup) {
-            wakeUp();
+
+        if (authenticated) {
+            mUpdateMonitor.clearFailedUnlockAttempts();
         }
 
+        if (mExitSecureCallback != null) {
+            try {
+                mExitSecureCallback.onKeyguardExitResult(authenticated);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to call onKeyguardExitResult(" + authenticated + ")", e);
+            }
+
+            mExitSecureCallback = null;
+
+            if (authenticated) {
+                // after succesfully exiting securely, no need to reshow
+                // the keyguard when they've released the lock
+                mExternallyEnabled = true;
+                mNeedToReshowWhenReenabled = false;
+            }
+        }
+
+        handleHide();
         sendUserPresentBroadcast();
     }
 
@@ -1296,10 +1204,6 @@
     private void handleHide() {
         synchronized (KeyguardViewMediator.this) {
             if (DEBUG) Log.d(TAG, "handleHide");
-            if (mWakeAndHandOff.isHeld()) {
-                Log.w(TAG, "attempt to hide the keyguard while waking, ignored");
-                return;
-            }
 
             // only play "unlock" noises if not on a call (since the incall UI
             // disables the keyguard)
@@ -1375,31 +1279,6 @@
     }
 
     /**
-     * Handle message sent by {@link #wakeWhenReady(int)}
-     * @param keyCode The key that woke the device.
-     * @see #WAKE_WHEN_READY
-     */
-    private void handleWakeWhenReady(int keyCode) {
-        synchronized (KeyguardViewMediator.this) {
-            if (DBG_WAKE) Log.d(TAG, "handleWakeWhenReady(" + keyCode + ")");
-
-            // this should result in a call to 'poke wakelock' which will set a timeout
-            // on releasing the wakelock
-            if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) {
-                // poke wakelock ourselves if keyguard is no longer active
-                Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves");
-                userActivity();
-            }
-
-            /**
-             * Now that the keyguard is ready and has poked the wake lock, we can
-             * release the handoff wakelock
-             */
-            mWakeAndHandOff.release();
-        }
-    }
-
-    /**
      * Handle message sent by {@link #resetStateLocked(Bundle)}
      * @see #RESET
      */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 56d0ec0..0b8b028 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3523,11 +3523,7 @@
         updateRotation(true);
 
         if (lidOpen) {
-            if (keyguardIsShowingTq()) {
-                mKeyguardDelegate.onWakeKeyWhenKeyguardShowingTq(KeyEvent.KEYCODE_POWER);
-            } else {
-                mPowerManager.wakeUp(SystemClock.uptimeMillis());
-            }
+            mPowerManager.wakeUp(SystemClock.uptimeMillis());
         } else if (!mLidControlsSleep) {
             mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
@@ -3745,13 +3741,7 @@
             // to wake the device but don't pass the key to the application.
             result = 0;
             if (down && isWakeKey && isWakeKeyWhenScreenOff(keyCode)) {
-                if (keyguardActive) {
-                    // If the keyguard is showing, let it wake the device when ready.
-                    mKeyguardDelegate.onWakeKeyWhenKeyguardShowingTq(keyCode);
-                } else {
-                    // Otherwise, wake the device ourselves.
-                    result |= ACTION_WAKE_UP;
-                }
+                result |= ACTION_WAKE_UP;
             }
         }
 
@@ -4017,13 +4007,7 @@
         final boolean isWakeMotion = (policyFlags
                 & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
         if (isWakeMotion) {
-            if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
-                // If the keyguard is showing, let it decide what to do with the wake motion.
-                mKeyguardDelegate.onWakeMotionWhenKeyguardShowing();
-            } else {
-                // Otherwise, wake the device ourselves.
-                result |= ACTION_WAKE_UP;
-            }
+            result |= ACTION_WAKE_UP;
         }
         return result;
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 2bb94be..874076a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -12,6 +12,7 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.util.Slog;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
@@ -21,7 +22,6 @@
 import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.policy.IKeyguardService;
 import com.android.internal.widget.LockPatternUtils;
-import com.android.internal.policy.impl.KeyguardServiceWrapper;
 
 /**
  * A local class that keeps a cache of keyguard state that can be restored in the event
@@ -178,18 +178,6 @@
         return mKeyguardState.secure;
     }
 
-    public void onWakeKeyWhenKeyguardShowingTq(int keycodePower) {
-        if (mKeyguardService != null) {
-            mKeyguardService.onWakeKeyWhenKeyguardShowing(keycodePower);
-        }
-    }
-
-    public void onWakeMotionWhenKeyguardShowing() {
-        if (mKeyguardService != null) {
-            mKeyguardService.onWakeMotionWhenKeyguardShowing();
-        }
-    }
-
     public void onDreamingStarted() {
         if (mKeyguardService != null) {
             mKeyguardService.onDreamingStarted();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
similarity index 91%
rename from policy/src/com/android/internal/policy/impl/KeyguardServiceWrapper.java
rename to policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
index e649125..6b9c7df 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.policy.impl;
+package com.android.internal.policy.impl.keyguard;
 
 import android.os.Bundle;
 import android.os.IBinder;
@@ -115,22 +115,6 @@
         }
     }
 
-    public void onWakeKeyWhenKeyguardShowing(int keyCode) {
-        try {
-            mService.onWakeKeyWhenKeyguardShowing(keyCode);
-        } catch (RemoteException e) {
-            Slog.w(TAG , "Remote Exception", e);
-        }
-    }
-
-    public void onWakeMotionWhenKeyguardShowing() {
-        try {
-            mService.onWakeMotionWhenKeyguardShowing();
-        } catch (RemoteException e) {
-            Slog.w(TAG , "Remote Exception", e);
-        }
-    }
-
     public void onDreamingStarted() {
         try {
             mService.onDreamingStarted();
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f201563..ed9416e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8022,12 +8022,33 @@
         }
     }
 
+    @Override
     public void unregisterProcessObserver(IProcessObserver observer) {
         synchronized (this) {
             mProcessObservers.unregister(observer);
         }
     }
 
+    @Override
+    public void convertToOpaque(IBinder token) {
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return;
+                }
+                if (r.convertToOpaque()) {
+                    mWindowManager.setAppFullscreen(token);
+                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
     public void setImmersive(IBinder token, boolean immersive) {
         synchronized(this) {
             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
@@ -8046,6 +8067,7 @@
         }
     }
 
+    @Override
     public boolean isImmersive(IBinder token) {
         synchronized (this) {
             ActivityRecord r = ActivityRecord.isInStackLocked(token);
@@ -8118,7 +8140,7 @@
         String reason = (pReason == null) ? "Unknown" : pReason;
         // XXX Note: don't acquire main activity lock here, because the window
         // manager calls in with its locks held.
-        
+
         boolean killed = false;
         synchronized (mPidsSelfLocked) {
             int[] types = new int[pids.length];
@@ -8133,7 +8155,7 @@
                     }
                 }
             }
-            
+
             // If the worst oom_adj is somewhere in the cached proc LRU range,
             // then constrain it so we will kill all cached procs.
             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
@@ -8300,7 +8322,7 @@
         // no need to synchronize(this) just to read & return the value
         return mSystemReady;
     }
-    
+
     private static File getCalledPreBootReceiversFile() {
         File dataDir = Environment.getDataDirectory();
         File systemDir = new File(dataDir, "system");
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 44b61d0..973b9aa 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -71,7 +71,7 @@
     final String processName; // process where this component wants to run
     final String taskAffinity; // as per ActivityInfo.taskAffinity
     final boolean stateNotNeeded; // As per ActivityInfo.flags
-    final boolean fullscreen; // covers the full screen?
+    boolean fullscreen; // covers the full screen?
     final boolean noDisplay;  // activity is not displayed?
     final boolean componentSpecified;  // did caller specifiy an explicit component?
 
@@ -503,6 +503,21 @@
         }
     }
 
+    boolean convertToOpaque() {
+        if (fullscreen) {
+            return false;
+        }
+
+        AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+                realTheme, com.android.internal.R.styleable.Window);
+        if (ent != null && !ent.array.getBoolean(
+                com.android.internal.R.styleable.Window_windowIsFloating, false)) {
+            fullscreen = true;
+            ++task.numFullscreen;
+        }
+        return fullscreen;
+    }
+
     void putInHistory() {
         if (!inHistory) {
             inHistory = true;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a9ab53d..8e8bb55 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1088,11 +1088,25 @@
                         r.visible = false;
                         try {
                             mWindowManager.setAppVisibility(r.appToken, false);
-                            if ((r.state == ActivityState.STOPPING
-                                    || r.state == ActivityState.STOPPED)
-                                    && r.app != null && r.app.thread != null) {
-                                if (DEBUG_VISBILITY) Slog.v(TAG, "Scheduling invisibility: " + r);
-                                r.app.thread.scheduleWindowVisibility(r.appToken, false);
+                            switch (r.state) {
+                                case STOPPING:
+                                case STOPPED:
+                                    if (r.app != null && r.app.thread != null) {
+                                        if (DEBUG_VISBILITY) Slog.v(
+                                                TAG, "Scheduling invisibility: " + r);
+                                        r.app.thread.scheduleWindowVisibility(r.appToken, false);
+                                    }
+                                    break;
+
+                                case INITIALIZING:
+                                case RESUMED:
+                                case PAUSING:
+                                case PAUSED:
+                                    stopActivityLocked(r);
+                                    break;
+
+                                default:
+                                    break;
                             }
                         } catch (Exception e) {
                             // Just skip on any failure; we'll make it
diff --git a/services/java/com/android/server/net/LockdownVpnTracker.java b/services/java/com/android/server/net/LockdownVpnTracker.java
index e251925..13e400f 100644
--- a/services/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/java/com/android/server/net/LockdownVpnTracker.java
@@ -148,8 +148,13 @@
                 showNotification(R.string.vpn_lockdown_connecting, R.drawable.vpn_disconnected);
 
                 mAcceptedEgressIface = egressProp.getInterfaceName();
-                mVpn.startLegacyVpn(mProfile, KeyStore.getInstance(), egressProp);
-
+                try {
+                    mVpn.startLegacyVpn(mProfile, KeyStore.getInstance(), egressProp);
+                } catch (IllegalStateException e) {
+                    mAcceptedEgressIface = null;
+                    Slog.e(TAG, "Failed to start VPN", e);
+                    showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
+                }
             } else {
                 Slog.e(TAG, "Invalid VPN profile; requires IP-based server and DNS");
                 showNotification(R.string.vpn_lockdown_error, R.drawable.vpn_disconnected);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0babeea..ee2ef37 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -98,7 +98,6 @@
 import android.util.TypedValue;
 import android.view.Choreographer;
 import android.view.Display;
-import android.view.DisplayAdjustments;
 import android.view.DisplayInfo;
 import android.view.Gravity;
 import android.view.IApplicationToken;
@@ -4118,6 +4117,13 @@
         }
     }
 
+    public void setAppFullscreen(IBinder token) {
+        AppWindowToken atoken = findAppWindowToken(token);
+        if (atoken != null) {
+            atoken.appFullscreen = true;
+        }
+    }
+
     boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
             boolean visible, int transit, boolean performLayout) {
         boolean delayed = false;
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index 61180a0..3b49819 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -86,15 +86,17 @@
 LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
 LOCAL_CFLAGS += -Wno-non-virtual-dtor
 
+LOCAL_SHARED_LIBRARIES := \
+        libpng \
+        libz
+
 LOCAL_STATIC_LIBRARIES := \
         libstlport_static \
         libandroidfw \
         libutils \
         libcutils \
         libexpat_static \
-        libpng \
-        liblog \
-        libz
+        liblog
 
 include $(BUILD_EXECUTABLE)
 endif