Merge "Fix default preferred network." into honeycomb-LTE
diff --git a/api/current.xml b/api/current.xml
index acea195..4841d01 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -15714,6 +15714,28 @@
  visibility="public"
 >
 </field>
+<field name="Theme_Holo_Light_NoActionBar"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="Theme_Holo_Light_NoActionBar_Fullscreen"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974065"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Theme_Holo_Light_Panel"
  type="int"
  transient="false"
@@ -114476,6 +114498,28 @@
  visibility="public"
 >
 </field>
+<field name="TYPE_BLUETOOTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_ETHERNET"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TYPE_MOBILE"
  type="int"
  transient="false"
@@ -184515,6 +184559,17 @@
  visibility="public"
 >
 </field>
+<field name="NETWORK_TYPE_HSPAP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="15"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="NETWORK_TYPE_HSUPA"
  type="int"
  transient="false"
@@ -267731,7 +267786,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index b541ec3..eaf9191 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -165,14 +165,12 @@
 
     /**
      * The Default Mobile data connection.  When active, all data traffic
-     * will use this connection by default.  Should not coexist with other
-     * default connections.
+     * will use this connection by default.
      */
     public static final int TYPE_MOBILE      = 0;
     /**
      * The Default WIFI data connection.  When active, all data traffic
-     * will use this connection by default.  Should not coexist with other
-     * default connections.
+     * will use this connection by default.
      */
     public static final int TYPE_WIFI        = 1;
     /**
@@ -208,21 +206,23 @@
     public static final int TYPE_MOBILE_HIPRI = 5;
     /**
      * The Default WiMAX data connection.  When active, all data traffic
-     * will use this connection by default.  Should not coexist with other
-     * default connections.
+     * will use this connection by default.
      */
     public static final int TYPE_WIMAX       = 6;
 
     /**
-     * Bluetooth data connection. This is used for Bluetooth reverse tethering.
-     * @hide
+     * The Default Bluetooth data connection. When active, all data traffic
+     * will use this connection by default.
      */
     public static final int TYPE_BLUETOOTH   = 7;
 
     /** {@hide} */
     public static final int TYPE_DUMMY       = 8;
 
-    /** {@hide} */
+    /**
+     * The Default Ethernet data connection.  When active, all data traffic
+     * will use this connection by default.
+     */
     public static final int TYPE_ETHERNET    = 9;
     /**
      * Over the air Adminstration.
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index d638e70..6a21b5a 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -329,6 +329,15 @@
                         // Set focus point to the remaining finger
                         final int index = event.findPointerIndex(actionId == mActiveId0 ?
                                 mActiveId1 : mActiveId0);
+                        if (index < 0) {
+                            mInvalidGesture = true;
+                            Log.e(TAG, "Invalid MotionEvent stream detected.", new Throwable());
+                            if (mGestureInProgress) {
+                                mListener.onScaleEnd(this);
+                            }
+                            return false;
+                        }
+
                         mActiveId0 = event.getPointerId(index);
 
                         mActive0MostRecent = true;
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 0dc0422..682ebc4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -33,6 +33,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
 import android.widget.Button;
 
 import java.io.File;
@@ -775,6 +776,16 @@
         setBoolean(LOCKOUT_PERMANENT_KEY, locked);
     }
 
+    public boolean isEmergencyCallCapable() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_voice_capable);
+    }
+
+    public boolean isPukUnlockScreenEnable() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_enable_puk_unlock_screen);
+    }
+
     /**
      * @return A formatted string of the next alarm (for showing on the lock screen),
      *   or null if there is no next alarm.
@@ -827,11 +838,22 @@
     }
 
     /**
-     * Sets the text on the emergency button to indicate what action will be taken.
+     * Sets the emergency button visibility based on isEmergencyCallCapable().
+     *
+     * If the emergency button is visible, sets the text on the emergency button
+     * to indicate what action will be taken.
+     *
      * If there's currently a call in progress, the button will take them to the call
      * @param button the button to update
      */
     public void updateEmergencyCallButtonState(Button button) {
+        if (isEmergencyCallCapable()) {
+            button.setVisibility(View.VISIBLE);
+        } else {
+            button.setVisibility(View.GONE);
+            return;
+        }
+
         int newState = TelephonyManager.getDefault().getCallState();
         int textId;
         if (newState == TelephonyManager.CALL_STATE_OFFHOOK) {
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
new file mode 100644
index 0000000..d58fb23
--- /dev/null
+++ b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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.
+*/
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/background_dark"
+        >
+
+    <LinearLayout android:id="@+id/topDisplayGroup"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <!-- header text ('Enter Puk Code') -->
+        <TextView android:id="@+id/headerText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+        <!-- Carrier info -->
+        <TextView android:id="@+id/carrier"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="9dip"
+            android:gravity="center"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginRight="10dip"
+                android:layout_marginLeft="10dip">
+                <TextView android:id="@+id/enter_puk"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:text="@android:string/keyguard_password_enter_puk_prompt"
+                    android:textSize="30sp"
+                    android:layout_marginBottom="10dip"/>
+                <TextView android:id="@+id/enter_pin"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:text="@android:string/keyguard_password_enter_pin_prompt"
+                    android:textSize="30sp"
+                    android:layout_marginTop="10dip"/>
+            </LinearLayout>
+
+            <LinearLayout
+                  android:orientation="vertical"
+                  android:layout_width="wrap_content"
+                  android:layout_weight="1"
+                  android:layout_height="match_parent"
+                  android:paddingRight="0dip"
+                  android:layout_marginRight="10dip"
+                  android:layout_marginLeft="10dip">
+
+                  <LinearLayout
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="horizontal"
+                      android:layout_marginRight="6dip"
+                      android:layout_marginLeft="6dip"
+                      android:gravity="center_vertical"
+                      android:background="@android:drawable/edit_text">
+
+                      <!-- displays dots as user enters puk -->
+                      <TextView android:id="@+id/pukDisplay"
+                          android:layout_width="0dip"
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:maxLines="1"
+                          android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                          android:textStyle="bold"
+                          android:inputType="textPassword"
+                      />
+
+                      <ImageButton android:id="@+id/pukDel"
+                          android:src="@android:drawable/ic_input_delete"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:layout_marginRight="-3dip"
+                          android:layout_marginBottom="-3dip"
+                      />
+                  </LinearLayout>
+
+
+                  <LinearLayout
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="horizontal"
+                      android:layout_marginRight="6dip"
+                      android:layout_marginLeft="6dip"
+                      android:gravity="center_vertical"
+                      android:background="@android:drawable/edit_text">
+
+                      <!-- displays dots as user enters new pin -->
+                      <TextView android:id="@+id/pinDisplay"
+                          android:layout_width="0dip"
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:maxLines="1"
+                          android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                          android:textStyle="bold"
+                          android:inputType="textPassword"
+                      />
+
+                      <ImageButton android:id="@+id/pinDel"
+                          android:src="@android:drawable/ic_input_delete"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:layout_marginRight="-3dip"
+                          android:layout_marginBottom="-3dip"
+                      />
+                  </LinearLayout>
+              </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_alignParentBottom="true"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="8dip"
+        android:layout_marginLeft="8dip"
+        android:layout_marginRight="8dip">
+
+        <Button android:id="@+id/ok"
+            android:text="@android:string/ok"
+            android:layout_alignParentBottom="true"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.0"
+            android:layout_marginBottom="8dip"
+            android:layout_marginRight="8dip"
+            android:textSize="18sp"
+            />
+
+        <Button android:id="@+id/emergencyCall"
+            android:text="@android:string/lockscreen_emergency_call"
+            android:layout_alignParentBottom="true"
+            android:layout_centerHorizontal="true"
+            android:layout_width="0dip"
+            android:layout_height="wrap_content"
+            android:layout_weight="1.0"
+            android:layout_marginBottom="8dip"
+            android:layout_marginLeft="8dip"
+            android:textSize="18sp"
+            android:drawableLeft="@drawable/ic_emergency"
+            android:drawablePadding="8dip"
+        />
+    </LinearLayout>
+
+</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml b/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml
new file mode 100644
index 0000000..5e392ef
--- /dev/null
+++ b/core/res/res/layout/keyguard_screen_sim_puk_portrait.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2008, 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:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:background="@android:color/background_dark"
+    android:gravity="center_horizontal">
+
+    <LinearLayout android:id="@+id/topDisplayGroup"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <!-- header text ('Enter Puk Code') -->
+        <TextView android:id="@+id/headerText"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+
+        <!-- Carrier info -->
+        <TextView android:id="@+id/carrier"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="9dip"
+            android:gravity="center"
+            android:singleLine="true"
+            android:ellipsize="marquee"
+            android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:layout_marginRight="10dip"
+                android:layout_marginLeft="10dip">
+                <TextView android:id="@+id/enter_puk"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:text="@android:string/keyguard_password_enter_puk_prompt"
+                    android:textSize="30sp"
+                    android:layout_marginBottom="10dip"/>
+                <TextView android:id="@+id/enter_pin"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_vertical"
+                    android:text="@android:string/keyguard_password_enter_pin_prompt"
+                    android:textSize="30sp"
+                    android:layout_marginTop="10dip"/>
+            </LinearLayout>
+
+            <LinearLayout
+                  android:orientation="vertical"
+                  android:layout_width="wrap_content"
+                  android:layout_weight="1"
+                  android:layout_height="match_parent"
+                  android:paddingRight="0dip"
+                  android:layout_marginRight="10dip"
+                  android:layout_marginLeft="10dip">
+
+                  <LinearLayout
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="horizontal"
+                      android:layout_marginRight="6dip"
+                      android:layout_marginLeft="6dip"
+                      android:gravity="center_vertical"
+                      android:background="@android:drawable/edit_text">
+
+                      <!-- displays dots as user enters puk -->
+                      <TextView android:id="@+id/pukDisplay"
+                          android:layout_width="0dip"
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:maxLines="1"
+                          android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                          android:textStyle="bold"
+                          android:inputType="textPassword"
+                      />
+
+                      <ImageButton android:id="@+id/pukDel"
+                          android:src="@android:drawable/ic_input_delete"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:layout_marginRight="-3dip"
+                          android:layout_marginBottom="-3dip"
+                      />
+                  </LinearLayout>
+
+
+                  <LinearLayout
+                      android:layout_width="match_parent"
+                      android:layout_height="wrap_content"
+                      android:orientation="horizontal"
+                      android:layout_marginRight="6dip"
+                      android:layout_marginLeft="6dip"
+                      android:gravity="center_vertical"
+                      android:background="@android:drawable/edit_text">
+
+                      <!-- displays dots as user enters new pin -->
+                      <TextView android:id="@+id/pinDisplay"
+                          android:layout_width="0dip"
+                          android:layout_height="wrap_content"
+                          android:layout_weight="1"
+                          android:maxLines="1"
+                          android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                          android:textStyle="bold"
+                          android:inputType="textPassword"
+                      />
+
+                      <ImageButton android:id="@+id/pinDel"
+                          android:src="@android:drawable/ic_input_delete"
+                          android:layout_width="wrap_content"
+                          android:layout_height="wrap_content"
+                          android:layout_marginRight="-3dip"
+                          android:layout_marginBottom="-3dip"
+                      />
+                  </LinearLayout>
+              </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+    <include
+        android:id="@+id/keyPad"
+        layout="@android:layout/twelve_key_entry"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/topDisplayGroup"
+        android:layout_marginTop="10dip"
+    />
+
+    <!-- spacer below keypad -->
+    <View
+        android:id="@+id/spacerBottom"
+        android:layout_width="match_parent"
+        android:layout_height="1dip"
+        android:layout_marginTop="6dip"
+        android:layout_above="@id/emergencyCall"
+        android:background="@android:drawable/divider_horizontal_dark"
+    />
+
+    <!-- The emergency button should take the rest of the space and be centered vertically -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dip"
+        android:layout_weight="1"
+        android:gravity="center"
+        android:orientation="vertical">
+
+        <!-- emergency call button -->
+        <Button
+            android:id="@+id/emergencyCall"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:drawableLeft="@android:drawable/ic_emergency"
+            android:drawablePadding="8dip"
+            android:text="@android:string/lockscreen_emergency_call"
+        />
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4bcdac1..60f11ce 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -369,6 +369,10 @@
     <!-- Diable lockscreen rotation by default -->
     <bool name="config_enableLockScreenRotation">false</bool>
 
+    <!-- Diable puk unlockscreen by default.
+         If unlock screen is disabled, the puk should be unlocked through Emergency Dialer -->
+    <bool name="config_enable_puk_unlock_screen">false</bool>
+
     <!-- Control the behavior when the user long presses the power button.
             0 - Nothing
             1 - Recent apps dialog
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 85884b1..47b5c60 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1657,4 +1657,8 @@
   <public type="attr" name="requiresSmallestWidthDp" id="0x01010364" />
   <public type="attr" name="compatibleWidthLimitDp" />
   <public type="attr" name="largestWidthLimitDp" />
+
+  <public type="style" name="Theme.Holo.Light.NoActionBar" />
+  <public type="style" name="Theme.Holo.Light.NoActionBar.Fullscreen" />
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f7f2606..20ee8ff 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -87,6 +87,8 @@
     <string name="mismatchPin">The PINs you entered do not match.</string>
     <!-- Displayed when a SIM PIN password is too long or too short. -->
     <string name="invalidPin">Type a PIN that is 4 to 8 numbers.</string>
+    <!-- Displayed when a SIM PUK password is too short. -->
+    <string name="invalidPuk">Type a PUK that is 8 numbers or longer.</string>
     <!-- Displayed to prompt the user to type the PUK password to unlock
          the SIM card. -->
     <string name="needPuk">Your SIM card is PUK-locked. Type the PUK code to unlock it.</string>
@@ -1644,6 +1646,15 @@
          Displayed in one line in a large font.  -->
     <string name="keyguard_password_enter_pin_code">Enter PIN code</string>
 
+    <!-- Instructions telling the user to enter their SIM PUK to unlock the keyguard.
+         Displayed in one line in a large font.  -->
+    <string name="keyguard_password_enter_puk_code">Enter PUK and new PIN code</string>
+
+    <!-- Prompt to enter SIM PUK in Edit Text Box in unlock screen -->
+    <string name="keyguard_password_enter_puk_prompt">PUK code</string>
+    <!-- Prompt to enter New SIM PIN in Edit Text Box in unlock screen -->
+    <string name="keyguard_password_enter_pin_prompt">New Pin Code</string>
+
     <!-- Displayed as hint in passwordEntry EditText on PasswordUnlockScreen [CHAR LIMIT=30]-->
     <string name="keyguard_password_entry_touch_hint"><font size="17">Touch to enter password</font></string>
 
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_default.png
new file mode 100644
index 0000000..e2584e3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_pressed.png
new file mode 100644
index 0000000..58b8510
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_zoom_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_default.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_default.png
new file mode 100644
index 0000000..2795c34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_pressed.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_pressed.png
new file mode 100644
index 0000000..bbed6a6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_zoom_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml b/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml
new file mode 100644
index 0000000..977e002
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_zoom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_zoom_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_zoom_default" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index d9f3f23..707a8cb 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -75,6 +75,13 @@
                     systemui:keyCode="82"
                     android:visibility="invisible"
                     />
+                <com.android.systemui.statusbar.policy.CompatModeButton
+                    android:id="@+id/compat_button"
+                    android:layout_width="80dip"
+                    android:layout_height="match_parent"
+                    android:src="@drawable/ic_sysbar_zoom"
+                    android:visibility="invisible"
+                    />
             </LinearLayout>
 
             <!-- fake space bar zone -->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
new file mode 100644
index 0000000..9b44f78
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CompatModeButton.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 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.systemui.statusbar.policy;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.RemoteException;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+public class CompatModeButton extends ImageView implements View.OnClickListener {
+    private static final String TAG = "StatusBar.CompatModeButton";
+
+    private ActivityManager mAM;
+
+    public CompatModeButton(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CompatModeButton(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs);
+
+        setClickable(true);
+
+        mAM = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+
+        setOnClickListener(this);
+
+        refresh();
+    }
+
+    @Override
+    public void onClick(View v) {
+        mAM.setFrontActivityScreenCompatMode(ActivityManager.COMPAT_MODE_TOGGLE);
+    }
+
+    public void refresh() {
+        setVisibility(
+                (mAM.getFrontActivityScreenCompatMode() == ActivityManager.COMPAT_MODE_NEVER)
+                ? View.GONE
+                : View.VISIBLE
+            );
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 1b73e29..4e10770 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -69,6 +69,7 @@
 import com.android.systemui.statusbar.*;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
+import com.android.systemui.statusbar.policy.CompatModeButton;
 import com.android.systemui.statusbar.policy.LocationController;
 import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.statusbar.policy.Prefs;
@@ -962,6 +963,10 @@
 
         // See above re: lights-out policy for legacy apps.
         if (visible) setLightsOn(true);
+
+        // XXX: HACK: not sure if this is the best way to catch a new activity that might require a
+        // change in compatibility features, but it's a start.
+        ((CompatModeButton) mBarContents.findViewById(R.id.compat_button)).refresh();
     }
 
     public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 5ed67a9..72209f6 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -480,11 +480,11 @@
     }
 
     /**
-     * Report that the user succesfully entered the sim pin so we
+     * Report that the user succesfully entered the sim pin or puk so we
      * have the information earlier than waiting for the intent
      * broadcast from the telephony code.
      */
-    public void reportSimPinUnlocked() {
+    public void reportSimUnlocked() {
         mSimState = IccCard.State.READY;
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 2fda3aa..874acd0 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -116,6 +116,11 @@
         SimPin,
 
         /**
+         * Unlock by entering a sim puk.
+         */
+        SimPuk,
+
+        /**
          * Unlock by entering an account's login and password.
          */
         Account,
@@ -222,8 +227,10 @@
             public void goToUnlockScreen() {
                 final IccCard.State simState = mUpdateMonitor.getSimState();
                 if (stuckOnLockScreenBecauseSimMissing()
-                         || (simState == IccCard.State.PUK_REQUIRED)){
-                    // stuck on lock screen when sim missing or puk'd
+                         || (simState == IccCard.State.PUK_REQUIRED
+                             && !mLockPatternUtils.isPukUnlockScreenEnable())){
+                    // stuck on lock screen when sim missing or
+                    // puk'd but puk unlock screen is disabled
                     return;
                 }
                 if (!isSecure()) {
@@ -522,8 +529,10 @@
                 secure = mLockPatternUtils.isLockPatternEnabled();
                 break;
             case SimPin:
-                secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED
-                            || mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
+                secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED;
+                break;
+            case SimPuk:
+                secure = mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED;
                 break;
             case Account:
                 secure = true;
@@ -592,6 +601,10 @@
 
     View createUnlockScreenFor(UnlockMode unlockMode) {
         View unlockView = null;
+
+        if (DEBUG) Log.d(TAG,
+                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
+
         if (unlockMode == UnlockMode.Pattern) {
             PatternUnlockScreen view = new PatternUnlockScreen(
                     mContext,
@@ -600,10 +613,15 @@
                     mUpdateMonitor,
                     mKeyguardScreenCallback,
                     mUpdateMonitor.getFailedAttempts());
-            if (DEBUG) Log.d(TAG,
-                "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback);
             view.setEnableFallback(mEnableFallback);
             unlockView = view;
+        } else if (unlockMode == UnlockMode.SimPuk) {
+            unlockView = new SimPukUnlockScreen(
+                    mContext,
+                    mConfiguration,
+                    mUpdateMonitor,
+                    mKeyguardScreenCallback,
+                    mLockPatternUtils);
         } else if (unlockMode == UnlockMode.SimPin) {
             unlockView = new SimUnlockScreen(
                     mContext,
@@ -654,7 +672,9 @@
      */
     private Mode getInitialMode() {
         final IccCard.State simState = mUpdateMonitor.getSimState();
-        if (stuckOnLockScreenBecauseSimMissing() || (simState == IccCard.State.PUK_REQUIRED)) {
+        if (stuckOnLockScreenBecauseSimMissing() ||
+                (simState == IccCard.State.PUK_REQUIRED &&
+                        !mLockPatternUtils.isPukUnlockScreenEnable())) {
             return Mode.LockScreen;
         } else {
             // Show LockScreen first for any screen other than Pattern unlock.
@@ -676,8 +696,10 @@
     private UnlockMode getUnlockMode() {
         final IccCard.State simState = mUpdateMonitor.getSimState();
         UnlockMode currentMode;
-        if (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED) {
+        if (simState == IccCard.State.PIN_REQUIRED) {
             currentMode = UnlockMode.SimPin;
+        } else if (simState == IccCard.State.PUK_REQUIRED) {
+            currentMode = UnlockMode.SimPuk;
         } else {
             final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality();
             switch (mode) {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index a9d5ce4..7331bda 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -232,7 +232,7 @@
 
         /** {@inheritDoc} */
         public void onGrabbedStateChange(View v, int grabbedState) {
-            if (DBG) Log.v(TAG, "*** LockScreen accel is " 
+            if (DBG) Log.v(TAG, "*** LockScreen accel is "
                     + (mEnergyWave.isHardwareAccelerated() ? "on":"off"));
             // Don't poke the wake lock when returning to a state where the handle is
             // not grabbed since that can happen when the system (instead of the user)
@@ -579,10 +579,16 @@
                 mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions);
 
                 // layout
-                mScreenLocked.setVisibility(View.VISIBLE);
-                mEmergencyCallText.setVisibility(View.VISIBLE);
-                mEmergencyCallButton.setVisibility(View.VISIBLE);
-                disableUnlock();
+                if (mLockPatternUtils.isPukUnlockScreenEnable()) {
+                    mScreenLocked.setVisibility(View.INVISIBLE);
+                    mEmergencyCallText.setVisibility(View.GONE);
+                    enableUnlock();
+                } else {
+                    mScreenLocked.setVisibility(View.VISIBLE);
+                    mEmergencyCallText.setVisibility(View.VISIBLE);
+                    mEmergencyCallButton.setVisibility(View.VISIBLE);
+                    disableUnlock();
+                }
                 break;
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
new file mode 100644
index 0000000..544bb3d
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.widget.LockPatternUtils;
+
+import android.text.Editable;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.android.internal.R;
+
+/**
+ * Displays a dialer like interface to unlock the SIM PUK.
+ */
+public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
+    View.OnClickListener, KeyguardUpdateMonitor.InfoCallback {
+
+    private static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+
+    private final KeyguardUpdateMonitor mUpdateMonitor;
+    private final KeyguardScreenCallback mCallback;
+
+    private TextView mHeaderText;
+    private TextView mPukText;
+    private TextView mPinText;
+
+    private TextView mFocusedEntry;
+
+    private TextView mOkButton;
+    private Button mEmergencyCallButton;
+
+    private View mDelPukButton;
+    private View mDelPinButton;
+
+    private ProgressDialog mSimUnlockProgressDialog = null;
+
+    private LockPatternUtils mLockPatternUtils;
+
+    private int mCreationOrientation;
+
+    private int mKeyboardHidden;
+
+    private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+    public SimPukUnlockScreen(Context context, Configuration configuration,
+            KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback,
+            LockPatternUtils lockpatternutils) {
+        super(context);
+        mUpdateMonitor = updateMonitor;
+        mCallback = callback;;
+
+        mCreationOrientation = configuration.orientation;
+        mKeyboardHidden = configuration.hardKeyboardHidden;
+        mLockPatternUtils = lockpatternutils;
+
+        LayoutInflater inflater = LayoutInflater.from(context);
+        if (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
+            inflater.inflate(
+                    R.layout.keyguard_screen_sim_puk_landscape, this, true);
+        } else {
+            inflater.inflate(
+                    R.layout.keyguard_screen_sim_puk_portrait, this, true);
+            new TouchInput();
+        }
+
+        mHeaderText = (TextView) findViewById(R.id.headerText);
+        mPukText = (TextView) findViewById(R.id.pukDisplay);
+        mPukText.setOnClickListener(new OnClickListener() {
+           public void onClick(View v) {
+               requestFocus(mPukText);
+               mCallback.pokeWakelock();
+           }
+        });
+        mPinText = (TextView) findViewById(R.id.pinDisplay);
+        mPinText.setOnClickListener(this);
+
+        mDelPukButton = findViewById(R.id.pukDel);
+        mDelPukButton.setOnClickListener(this);
+        mDelPinButton = findViewById(R.id.pinDel);
+        mDelPinButton.setOnClickListener(this);
+
+
+        mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
+        mOkButton = (TextView) findViewById(R.id.ok);
+
+        mHeaderText.setText(R.string.keyguard_password_enter_puk_code);
+        mPukText.setFocusable(false);
+        mPinText.setFocusable(false);
+        mOkButton.setOnClickListener(this);
+
+        requestFocus(mPukText);
+
+        if (mLockPatternUtils.isEmergencyCallCapable()) {
+            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
+            mEmergencyCallButton.setOnClickListener(this);
+        } else {
+            mEmergencyCallButton.setVisibility(View.GONE);
+        }
+
+        setFocusableInTouchMode(true);
+    }
+
+    private void requestFocus(TextView entry) {
+        mFocusedEntry = entry;
+        mFocusedEntry.setText("");
+    }
+
+    /** {@inheritDoc} */
+    public boolean needsInput() {
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    public void onPause() {
+
+    }
+
+    /** {@inheritDoc} */
+    public void onResume() {
+        // start fresh
+        mHeaderText.setText(R.string.keyguard_password_enter_puk_code);
+        requestFocus(mPukText);
+        mPinText.setText("");
+
+        if (mLockPatternUtils.isEmergencyCallCapable()) {
+            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void cleanUp() {
+        // dismiss the dialog.
+        if (mSimUnlockProgressDialog != null) {
+            mSimUnlockProgressDialog.dismiss();
+            mSimUnlockProgressDialog = null;
+        }
+        mUpdateMonitor.removeCallback(this);
+    }
+
+
+    /**
+     * Since the IPC can block, we want to run the request in a separate thread
+     * with a callback.
+     */
+    private abstract class CheckSimPuk extends Thread {
+
+        private final String mPin, mPuk;
+
+        protected CheckSimPuk(String puk, String pin) {
+            mPuk = puk;
+            mPin = pin;
+        }
+
+        abstract void onSimLockChangedResponse(boolean success);
+
+        @Override
+        public void run() {
+            try {
+                final boolean result = ITelephony.Stub.asInterface(ServiceManager
+                        .checkService("phone")).supplyPuk(mPuk, mPin);
+
+                post(new Runnable() {
+                    public void run() {
+                        onSimLockChangedResponse(result);
+                    }
+                });
+            } catch (RemoteException e) {
+                post(new Runnable() {
+                    public void run() {
+                        onSimLockChangedResponse(false);
+                    }
+                });
+            }
+        }
+    }
+
+    public void onClick(View v) {
+        if (v == mDelPukButton) {
+            final Editable digits = mPukText.getEditableText();
+            final int len = digits.length();
+            if (len > 0) {
+                digits.delete(len-1, len);
+            }
+            mCallback.pokeWakelock();
+        } else if (v == mDelPinButton) {
+            final Editable digits = mPinText.getEditableText();
+            final int len = digits.length();
+            if (len > 0) {
+                digits.delete(len-1, len);
+            }
+            mCallback.pokeWakelock();
+        } else if (v == mPinText) {
+            requestFocus(mPinText);
+            mCallback.pokeWakelock();
+        } else if (v == mEmergencyCallButton) {
+            mCallback.takeEmergencyCallAction();
+        } else if (v == mOkButton) {
+            checkPuk();
+        }
+    }
+
+    private Dialog getSimUnlockProgressDialog() {
+        if (mSimUnlockProgressDialog == null) {
+            mSimUnlockProgressDialog = new ProgressDialog(mContext);
+            mSimUnlockProgressDialog.setMessage(
+                    mContext.getString(R.string.lockscreen_sim_unlock_progress_dialog_message));
+            mSimUnlockProgressDialog.setIndeterminate(true);
+            mSimUnlockProgressDialog.setCancelable(false);
+            mSimUnlockProgressDialog.getWindow().setType(
+                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            if (!mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_sf_slowBlur)) {
+                mSimUnlockProgressDialog.getWindow().setFlags(
+                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
+                        WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+            }
+        }
+        return mSimUnlockProgressDialog;
+    }
+
+    private void checkPuk() {
+        // make sure that the puk is at least 8 digits long.
+        if (mPukText.getText().length() < 8) {
+            // otherwise, display a message to the user, and don't submit.
+            mHeaderText.setText(R.string.invalidPuk);
+            mPukText.setText("");
+            mCallback.pokeWakelock();
+            return;
+        }
+
+        if (mPinText.getText().length() < 4
+                || mPinText.getText().length() > 8) {
+            // otherwise, display a message to the user, and don't submit.
+            mHeaderText.setText(R.string.invalidPin);
+            mPinText.setText("");
+            mCallback.pokeWakelock();
+            return;
+        }
+
+        getSimUnlockProgressDialog().show();
+
+        new CheckSimPuk(mPukText.getText().toString(),
+                mPinText.getText().toString()) {
+            void onSimLockChangedResponse(boolean success) {
+                if (mSimUnlockProgressDialog != null) {
+                    mSimUnlockProgressDialog.hide();
+                }
+                if (success) {
+                    // before closing the keyguard, report back that
+                    // the sim is unlocked so it knows right away
+                    mUpdateMonitor.reportSimUnlocked();
+                    mCallback.goToUnlockScreen();
+                } else {
+                    mHeaderText.setText(R.string.badPuk);
+                    mPukText.setText("");
+                    mPinText.setText("");
+                }
+                mCallback.pokeWakelock();
+            }
+        }.start();
+    }
+
+
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            mCallback.goToLockScreen();
+            return true;
+        }
+        final char match = event.getMatch(DIGITS);
+        if (match != 0) {
+            reportDigit(match - '0');
+            return true;
+        }
+        if (keyCode == KeyEvent.KEYCODE_DEL) {
+            mFocusedEntry.onKeyDown(keyCode, event);
+            final Editable digits = mFocusedEntry.getEditableText();
+            final int len = digits.length();
+            if (len > 0) {
+                digits.delete(len-1, len);
+            }
+            mCallback.pokeWakelock();
+            return true;
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_ENTER) {
+            checkPuk();
+            return true;
+        }
+
+        return false;
+    }
+
+    private void reportDigit(int digit) {
+        mFocusedEntry.append(Integer.toString(digit));
+    }
+
+    void updateConfiguration() {
+        Configuration newConfig = getResources().getConfiguration();
+        if (newConfig.orientation != mCreationOrientation) {
+            mCallback.recreateMe(newConfig);
+        } else if (newConfig.hardKeyboardHidden != mKeyboardHidden) {
+            mKeyboardHidden = newConfig.hardKeyboardHidden;
+            final boolean isKeyboardOpen =
+                (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO);
+            if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) {
+                mCallback.goToUnlockScreen();
+            }
+        }
+
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        updateConfiguration();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        updateConfiguration();
+    }
+
+    /**
+     * Helper class to handle input from touch dialer.  Only relevant when
+     * the keyboard is shut.
+     */
+    private class TouchInput implements View.OnClickListener {
+        private TextView mZero;
+        private TextView mOne;
+        private TextView mTwo;
+        private TextView mThree;
+        private TextView mFour;
+        private TextView mFive;
+        private TextView mSix;
+        private TextView mSeven;
+        private TextView mEight;
+        private TextView mNine;
+        private TextView mCancelButton;
+
+        private TouchInput() {
+            mZero = (TextView) findViewById(R.id.zero);
+            mOne = (TextView) findViewById(R.id.one);
+            mTwo = (TextView) findViewById(R.id.two);
+            mThree = (TextView) findViewById(R.id.three);
+            mFour = (TextView) findViewById(R.id.four);
+            mFive = (TextView) findViewById(R.id.five);
+            mSix = (TextView) findViewById(R.id.six);
+            mSeven = (TextView) findViewById(R.id.seven);
+            mEight = (TextView) findViewById(R.id.eight);
+            mNine = (TextView) findViewById(R.id.nine);
+            mCancelButton = (TextView) findViewById(R.id.cancel);
+
+            mZero.setText("0");
+            mOne.setText("1");
+            mTwo.setText("2");
+            mThree.setText("3");
+            mFour.setText("4");
+            mFive.setText("5");
+            mSix.setText("6");
+            mSeven.setText("7");
+            mEight.setText("8");
+            mNine.setText("9");
+
+            mZero.setOnClickListener(this);
+            mOne.setOnClickListener(this);
+            mTwo.setOnClickListener(this);
+            mThree.setOnClickListener(this);
+            mFour.setOnClickListener(this);
+            mFive.setOnClickListener(this);
+            mSix.setOnClickListener(this);
+            mSeven.setOnClickListener(this);
+            mEight.setOnClickListener(this);
+            mNine.setOnClickListener(this);
+            mCancelButton.setOnClickListener(this);
+        }
+
+
+        public void onClick(View v) {
+            if (v == mCancelButton) {
+                mCallback.goToLockScreen();
+                return;
+            }
+
+            final int digit = checkDigit(v);
+            if (digit >= 0) {
+                mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS);
+                reportDigit(digit);
+            }
+        }
+
+        private int checkDigit(View v) {
+            int digit = -1;
+            if (v == mZero) {
+                digit = 0;
+            } else if (v == mOne) {
+                digit = 1;
+            } else if (v == mTwo) {
+                digit = 2;
+            } else if (v == mThree) {
+                digit = 3;
+            } else if (v == mFour) {
+                digit = 4;
+            } else if (v == mFive) {
+                digit = 5;
+            } else if (v == mSix) {
+                digit = 6;
+            } else if (v == mSeven) {
+                digit = 7;
+            } else if (v == mEight) {
+                digit = 8;
+            } else if (v == mNine) {
+                digit = 9;
+            }
+            return digit;
+        }
+    }
+
+    public void onPhoneStateChanged(String newState) {
+        if (mLockPatternUtils.isEmergencyCallCapable()) {
+            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
+        }
+    }
+
+    public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+
+    }
+
+    public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
+
+    }
+
+    public void onRingerModeChanged(int state) {
+
+    }
+
+    public void onTimeChanged() {
+
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
index 486e7aa..7255c27 100644
--- a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
@@ -92,16 +92,17 @@
         mBackSpaceButton = findViewById(R.id.backspace);
         mBackSpaceButton.setOnClickListener(this);
 
-        mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
-        mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
         mOkButton = (TextView) findViewById(R.id.ok);
 
         mHeaderText.setText(R.string.keyguard_password_enter_pin_code);
         mPinText.setFocusable(false);
 
-        mEmergencyCallButton.setOnClickListener(this);
         mOkButton.setOnClickListener(this);
 
+        mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
+        mEmergencyCallButton.setOnClickListener(this);
+        mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
+
         setFocusableInTouchMode(true);
     }
 
@@ -229,7 +230,7 @@
                 if (success) {
                     // before closing the keyguard, report back that
                     // the sim is unlocked so it knows right away
-                    mUpdateMonitor.reportSimPinUnlocked();
+                    mUpdateMonitor.reportSimUnlocked();
                     mCallback.goToUnlockScreen();
                 } else {
                     mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
@@ -291,9 +292,8 @@
                 mCallback.goToUnlockScreen();
             }
         }
-        
     }
-    
+
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
@@ -403,7 +403,7 @@
     }
 
     public void onPhoneStateChanged(String newState) {
-        mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
+            mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
     }
 
     public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c503fb8..1a333ba 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1286,7 +1286,7 @@
                         mCompatModeDialog.dismiss();
                         mCompatModeDialog = null;
                     }
-                    if (ar != null) {
+                    if (ar != null && false) {
                         if (mCompatModePackages.getPackageAskCompatModeLocked(
                                 ar.packageName)) {
                             int mode = mCompatModePackages.computeCompatModeLocked(
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9a312a7..a7b5857 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1389,6 +1389,14 @@
     if (l != NULL) {
         Mutex::Autolock _l(mStateLock);
         err = removeLayer_l(l);
+        if (err == NAME_NOT_FOUND) {
+            // The surface wasn't in the current list, which means it was
+            // removed already, which means it is in the purgatory,
+            // and need to be removed from there.
+            ssize_t idx = mLayerPurgatory.remove(l);
+            LOGE_IF(idx < 0,
+                    "layer=%p is not in the purgatory list", l.get());
+        }
         LOGE_IF(err<0 && err != NAME_NOT_FOUND,
                 "error removing layer=%p (%s)", l.get(), strerror(-err));
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8732e21..36e0202 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -191,6 +191,10 @@
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
     public String getDeviceId() {
+        if (!isVoiceCapable()) {
+            return null;
+        }
+
         try {
             return getSubscriberInfo().getDeviceId();
         } catch (RemoteException ex) {
@@ -426,8 +430,7 @@
     public static final int NETWORK_TYPE_LTE = 13;
     /** Current network is eHRPD */
     public static final int NETWORK_TYPE_EHRPD = 14;
-    /** Current network is HSPA+
-     * @hide */
+    /** Current network is HSPA+ */
     public static final int NETWORK_TYPE_HSPAP = 15;
 
     /**
@@ -450,6 +453,7 @@
      * @see #NETWORK_TYPE_IDEN
      * @see #NETWORK_TYPE_LTE
      * @see #NETWORK_TYPE_EHRPD
+     * @see #NETWORK_TYPE_HSPAP
      */
     public int getNetworkType() {
         try{
@@ -506,6 +510,8 @@
                 return "CDMA - eHRPD";
             case NETWORK_TYPE_IDEN:
                 return "iDEN";
+            case NETWORK_TYPE_HSPAP:
+                return "HSPA+";
             default:
                 return "UNKNOWN";
         }
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 7f9fc31..d83b968 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -478,6 +478,21 @@
         }
     }
 
+    /**
+     * clear IP configuration for a given network id
+     */
+    static void clearIpConfiguration(int netId) {
+        synchronized (sConfiguredNetworks) {
+            WifiConfiguration config = sConfiguredNetworks.get(netId);
+            if (config != null && config.linkProperties != null) {
+                // Clear everything except proxy
+                ProxyProperties proxy = config.linkProperties.getHttpProxy();
+                config.linkProperties.clear();
+                config.linkProperties.setHttpProxy(proxy);
+            }
+        }
+    }
+
 
     /**
      * Fetch the proxy properties for a given network id
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index e03680f..3cbf726 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1440,10 +1440,13 @@
 
         /* Clear network properties */
         mLinkProperties.clear();
+        /* Clear IP settings if the network used DHCP */
+        if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
+            WifiConfigStore.clearIpConfiguration(mLastNetworkId);
+        }
 
         mLastBssid= null;
         mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-
     }
 
     void handlePreDhcpSetup() {