Merge "Fix 3339257: Update lockscreen keyboard to fit Holo theme" into honeycomb
diff --git a/Android.mk b/Android.mk
index f581515..61d74ad 100644
--- a/Android.mk
+++ b/Android.mk
@@ -167,6 +167,7 @@
 	core/java/com/android/internal/view/IInputMethodManager.aidl \
 	core/java/com/android/internal/view/IInputMethodSession.aidl \
 	core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
+	core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
 	location/java/android/location/ICountryDetector.aidl \
 	location/java/android/location/ICountryListener.aidl \
 	location/java/android/location/IGeocodeProvider.aidl \
@@ -399,6 +400,8 @@
                             resources/samples/CubeLiveWallpaper "Live Wallpaper" \
 		-samplecode $(sample_dir)/Home \
 		            resources/samples/Home "Home" \
+                -samplecode $(sample_dir)/Honeycomb-Gallery \
+                            resources/samples/Honeycomb-Gallery "Honeycomb Gallery" \
 		-samplecode $(sample_dir)/JetBoy \
 		            resources/samples/JetBoy "JetBoy" \
 		-samplecode $(sample_dir)/LunarLander \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1acb620..337b30f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -89,6 +89,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_aacdec_intermediates)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_mp3dec_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/11.xml b/api/11.xml
index 5087eca..7db0328 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -188,6 +188,17 @@
  visibility="public"
 >
 </field>
+<field name="BIND_REMOTEVIEWS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.permission.BIND_REMOTEVIEWS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="BIND_WALLPAPER"
  type="java.lang.String"
  transient="false"
@@ -2710,6 +2721,17 @@
  visibility="public"
 >
 </field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="candidatesTextStyleSpans"
  type="int"
  transient="false"
@@ -3271,6 +3293,17 @@
  visibility="public"
 >
 </field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="dateTextAppearance"
  type="int"
  transient="false"
@@ -8716,17 +8749,6 @@
  visibility="public"
 >
 </field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="soundEffectsEnabled"
  type="int"
  transient="false"
@@ -10894,6 +10916,17 @@
  visibility="public"
 >
 </field>
+<field name="windowCloseOnTouchOutside"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843611"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="windowContentOverlay"
  type="int"
  transient="false"
@@ -15971,7 +16004,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974069"
+ value="16974060"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16022,6 +16055,17 @@
  visibility="public"
 >
 </field>
+<field name="Widget_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974063"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Widget_DropDownItem"
  type="int"
  transient="false"
@@ -16055,17 +16099,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974061"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_ExpandableListView"
  type="int"
  transient="false"
@@ -16257,7 +16290,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974070"
+ value="16974061"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16297,6 +16330,17 @@
  visibility="public"
 >
 </field>
+<field name="Widget_Holo_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Widget_Holo_DropDownItem"
  type="int"
  transient="false"
@@ -16330,17 +16374,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974064"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_ExpandableListView"
  type="int"
  transient="false"
@@ -16385,28 +16418,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light"
  type="int"
  transient="false"
@@ -16532,7 +16543,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974071"
+ value="16974062"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16605,17 +16616,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light_ExpandableListView"
  type="int"
  transient="false"
@@ -16660,28 +16660,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light_ListPopupWindow"
  type="int"
  transient="false"
@@ -17210,28 +17188,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_ImageWell"
  type="int"
  transient="false"
@@ -24300,6 +24256,19 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
+<method name="setFinishOnTouchOutside"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finish" type="boolean">
+</parameter>
+</method>
 <method name="setIntent"
  return="void"
  abstract="false"
@@ -136088,6 +136057,17 @@
  visibility="public"
 >
 </method>
+<method name="getPreserveEGLContextOnPause"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getRenderMode"
  return="int"
  abstract="false"
@@ -136259,6 +136239,19 @@
 <parameter name="glWrapper" type="android.opengl.GLSurfaceView.GLWrapper">
 </parameter>
 </method>
+<method name="setPreserveEGLContextOnPause"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="preserveOnPause" type="boolean">
+</parameter>
+</method>
 <method name="setRenderMode"
  return="void"
  abstract="false"
@@ -146691,6 +146684,16 @@
  visibility="public"
 >
 </constructor>
+<constructor name="StrictMode.VmPolicy.Builder"
+ type="android.os.StrictMode.VmPolicy.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="base" type="android.os.StrictMode.VmPolicy">
+</parameter>
+</constructor>
 <method name="build"
  return="android.os.StrictMode.VmPolicy"
  abstract="false"
@@ -146768,6 +146771,21 @@
  visibility="public"
 >
 </method>
+<method name="setClassInstanceLimit"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="klass" type="java.lang.Class">
+</parameter>
+<parameter name="instanceLimit" type="int">
+</parameter>
+</method>
 </class>
 <class name="SystemClock"
  extends="java.lang.Object"
@@ -160195,17 +160213,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_VIDEO_CAPTURE"
  type="java.lang.String"
  transient="false"
@@ -166475,6 +166482,74 @@
 <parameter name="d" type="float[]">
 </parameter>
 </method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
 <method name="copy2DRangeFrom"
  return="void"
  abstract="false"
@@ -166654,6 +166729,58 @@
 <parameter name="b" type="android.graphics.Bitmap">
 </parameter>
 </method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
 <method name="copyTo"
  return="void"
  abstract="false"
@@ -175623,6 +175750,17 @@
  visibility="public"
 >
 </field>
+<field name="KEY_PARAM_PAN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;pan&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KEY_PARAM_STREAM"
  type="java.lang.String"
  transient="false"
@@ -175645,6 +175783,17 @@
  visibility="public"
 >
 </field>
+<field name="KEY_PARAM_VOLUME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;volume&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <interface name="TextToSpeech.OnInitListener"
  abstract="true"
@@ -206236,25 +206385,6 @@
 >
 </field>
 </class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
 <class name="KeyCharacterMap.KeyData"
  extends="java.lang.Object"
  abstract="false"
@@ -206314,6 +206444,25 @@
 >
 </field>
 </class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
 <class name="KeyEvent"
  extends="android.view.InputEvent"
  abstract="false"
@@ -219385,6 +219534,14 @@
 <parameter name="view" type="android.view.View">
 </parameter>
 </constructor>
+<constructor name="View.DragShadowBuilder"
+ type="android.view.View.DragShadowBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
 <method name="getView"
  return="android.view.View"
  abstract="false"
@@ -236035,6 +236192,48 @@
 </parameter>
 </method>
 </class>
+<class name="WebStorage.Origin"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getOrigin"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQuota"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUsage"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
 <interface name="WebStorage.QuotaUpdater"
  abstract="true"
  static="true"
@@ -252327,6 +252526,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="appWidgetId" type="int">
+</parameter>
 <parameter name="viewId" type="int">
 </parameter>
 <parameter name="intent" type="android.content.Intent">
diff --git a/api/current.xml b/api/current.xml
index 4f566f6..75b1dc2 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -188,6 +188,17 @@
  visibility="public"
 >
 </field>
+<field name="BIND_REMOTEVIEWS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.permission.BIND_REMOTEVIEWS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="BIND_WALLPAPER"
  type="java.lang.String"
  transient="false"
@@ -2710,6 +2721,17 @@
  visibility="public"
 >
 </field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="candidatesTextStyleSpans"
  type="int"
  transient="false"
@@ -3271,6 +3293,17 @@
  visibility="public"
 >
 </field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="dateTextAppearance"
  type="int"
  transient="false"
@@ -8716,17 +8749,6 @@
  visibility="public"
 >
 </field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="soundEffectsEnabled"
  type="int"
  transient="false"
@@ -10894,6 +10916,17 @@
  visibility="public"
 >
 </field>
+<field name="windowCloseOnTouchOutside"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843611"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="windowContentOverlay"
  type="int"
  transient="false"
@@ -15971,7 +16004,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974069"
+ value="16974060"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16022,6 +16055,17 @@
  visibility="public"
 >
 </field>
+<field name="Widget_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974063"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Widget_DropDownItem"
  type="int"
  transient="false"
@@ -16055,17 +16099,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974061"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_ExpandableListView"
  type="int"
  transient="false"
@@ -16257,7 +16290,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974070"
+ value="16974061"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16297,6 +16330,17 @@
  visibility="public"
 >
 </field>
+<field name="Widget_Holo_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Widget_Holo_DropDownItem"
  type="int"
  transient="false"
@@ -16330,17 +16374,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974064"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_ExpandableListView"
  type="int"
  transient="false"
@@ -16385,28 +16418,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light"
  type="int"
  transient="false"
@@ -16532,7 +16543,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16974071"
+ value="16974062"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -16605,17 +16616,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light_ExpandableListView"
  type="int"
  transient="false"
@@ -16660,28 +16660,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_Holo_Light_ListPopupWindow"
  type="int"
  transient="false"
@@ -17210,28 +17188,6 @@
  visibility="public"
 >
 </field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="Widget_ImageWell"
  type="int"
  transient="false"
@@ -24300,6 +24256,19 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
+<method name="setFinishOnTouchOutside"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finish" type="boolean">
+</parameter>
+</method>
 <method name="setIntent"
  return="void"
  abstract="false"
@@ -136088,6 +136057,17 @@
  visibility="public"
 >
 </method>
+<method name="getPreserveEGLContextOnPause"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getRenderMode"
  return="int"
  abstract="false"
@@ -136259,6 +136239,19 @@
 <parameter name="glWrapper" type="android.opengl.GLSurfaceView.GLWrapper">
 </parameter>
 </method>
+<method name="setPreserveEGLContextOnPause"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="preserveOnPause" type="boolean">
+</parameter>
+</method>
 <method name="setRenderMode"
  return="void"
  abstract="false"
@@ -146712,6 +146705,17 @@
  visibility="public"
 >
 </method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="detectAll"
  return="android.os.StrictMode.VmPolicy.Builder"
  abstract="false"
@@ -160220,17 +160224,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.provider.action.MTP_SESSION_END&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_VIDEO_CAPTURE"
  type="java.lang.String"
  transient="false"
@@ -166500,6 +166493,74 @@
 <parameter name="d" type="float[]">
 </parameter>
 </method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
 <method name="copy2DRangeFrom"
  return="void"
  abstract="false"
@@ -166679,6 +166740,58 @@
 <parameter name="b" type="android.graphics.Bitmap">
 </parameter>
 </method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
 <method name="copyTo"
  return="void"
  abstract="false"
@@ -175648,6 +175761,17 @@
  visibility="public"
 >
 </field>
+<field name="KEY_PARAM_PAN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;pan&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KEY_PARAM_STREAM"
  type="java.lang.String"
  transient="false"
@@ -175670,6 +175794,17 @@
  visibility="public"
 >
 </field>
+<field name="KEY_PARAM_VOLUME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;volume&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <interface name="TextToSpeech.OnInitListener"
  abstract="true"
@@ -206261,25 +206396,6 @@
 >
 </field>
 </class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
 <class name="KeyCharacterMap.KeyData"
  extends="java.lang.Object"
  abstract="false"
@@ -206339,6 +206455,25 @@
 >
 </field>
 </class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
 <class name="KeyEvent"
  extends="android.view.InputEvent"
  abstract="false"
@@ -219410,6 +219545,14 @@
 <parameter name="view" type="android.view.View">
 </parameter>
 </constructor>
+<constructor name="View.DragShadowBuilder"
+ type="android.view.View.DragShadowBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
 <method name="getView"
  return="android.view.View"
  abstract="false"
@@ -252394,6 +252537,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="appWidgetId" type="int">
+</parameter>
 <parameter name="viewId" type="int">
 </parameter>
 <parameter name="intent" type="android.content.Intent">
diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk
index afc45ee..630cf03 100644
--- a/build/phone-hdpi-512-dalvik-heap.mk
+++ b/build/phone-hdpi-512-dalvik-heap.mk
@@ -19,5 +19,5 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=32m \
-    dalvik.vm.heapsize=32m
+    dalvik.vm.growthlimit=32m \
+    dalvik.vm.heapsize=128m
diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk
index ee30b92..ab33b96 100644
--- a/build/phone-hdpi-dalvik-heap.mk
+++ b/build/phone-hdpi-dalvik-heap.mk
@@ -18,5 +18,4 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=32m \
     dalvik.vm.heapsize=32m
diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk
index 9cb2f6b..37c3ec5 100644
--- a/build/tablet-dalvik-heap.mk
+++ b/build/tablet-dalvik-heap.mk
@@ -18,5 +18,5 @@
 
 PRODUCT_PROPERTY_OVERRIDES += \
     dalvik.vm.heapstartsize=5m \
-    dalvik.vm.smallheapsize=48m \
-    dalvik.vm.heapsize=48m
+    dalvik.vm.growthlimit=48m \
+    dalvik.vm.heapsize=256m
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 9cbc7be..2c99f14 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -722,6 +722,9 @@
                 final String[] argsAccountId = {String.valueOf(accountId)};
                 db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
                 db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
+                synchronized (mCacheLock) {
+                    mAuthTokenCache.remove(account);
+                }
                 db.setTransactionSuccessful();
             }
         } finally {
@@ -1019,6 +1022,10 @@
             AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
 
         Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
+        // See FLAT_ACTIVITY_NEW_TASK docs for limitations and benefits of the flag.
+        // Since it was set in Eclair+ we can't change it without breaking apps using
+        // the intent from a non-Activity context.
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.addCategory(
                 String.valueOf(getCredentialPermissionNotificationId(account, authTokenType, uid)));
 
@@ -1808,6 +1815,11 @@
                 try {
                     db.execSQL("DELETE from " + TABLE_AUTHTOKENS);
                     db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''");
+
+                    synchronized (mCacheLock) {
+                        mAuthTokenCache = new HashMap<Account, HashMap<String, String>>();
+                    }
+
                     db.setTransactionSuccessful();
                 } finally {
                     db.endTransaction();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 93ad17e..ec6eaaa 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1808,6 +1808,14 @@
     }
 
     /**
+     * Sets whether this activity is finished when touched outside its window's
+     * bounds.
+     */
+    public void setFinishOnTouchOutside(boolean finish) {
+        mWindow.setCloseOnTouchOutside(finish);
+    }
+    
+    /**
      * Use with {@link #setDefaultKeyMode} to turn off default handling of
      * keys.
      * 
@@ -2063,6 +2071,11 @@
      * The default implementation always returns false.
      */
     public boolean onTouchEvent(MotionEvent event) {
+        if (mWindow.shouldCloseOnTouch(this, event)) {
+            finish();
+            return true;
+        }
+        
         return false;
     }
     
@@ -4420,6 +4433,9 @@
             mStopped = true;
         }
         mResumed = false;
+
+        // Check for Activity leaks, if enabled.
+        StrictMode.conditionallyCheckInstanceCounts();
     }
 
     final void performDestroy() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d5aa961..133a7d0 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -64,8 +64,11 @@
     static public int staticGetMemoryClass() {
         // Really brain dead right now -- just take this from the configured
         // vm heap size, and assume it is in megabytes and thus ends with "m".
-        String vmHeapSize = SystemProperties.get("dalvik.vm.smallheapsize", "16m");
-        return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        String vmHeapSize = SystemProperties.get("dalvik.vm.growthlimit", "");
+        if (vmHeapSize != null && !"".equals(vmHeapSize)) {
+            return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+        }
+        return staticGetLargeMemoryClass();
     }
     
     /**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index db046ef..7cf60f9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3463,7 +3463,7 @@
         }
 
         if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
-            // XXX bump up Dalvik's heap.
+            dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
         }
 
         // If the app is being launched for full backup or restore, bring it up in
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 70e3616..428f4e3 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -64,11 +64,13 @@
 
     protected AlertDialog(Context context, int theme) {
         super(context, theme == 0 ? getDefaultDialogTheme(context) : theme);
+        mWindow.alwaysReadCloseOnTouchAttr();
         mAlert = new AlertController(context, this, getWindow());
     }
 
     protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
         super(context, getDefaultDialogTheme(context));
+        mWindow.alwaysReadCloseOnTouchAttr();
         setCancelable(cancelable);
         setOnCancelListener(cancelListener);
         mAlert = new AlertController(context, this, getWindow());
@@ -81,25 +83,6 @@
         return outValue.resourceId;
     }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (mCancelable) {
-            final View decor = mWindow.getDecorView();
-            final int width = decor.getWidth();
-            final int height = decor.getHeight();
-            final float x = ev.getX();
-            final float y = ev.getY();
-
-            if (mCancelable && (x < 0 || x > width || y < 0 || y > height)
-                    &&  mDecor != null && isShowing()) {
-                cancel();
-                return true;
-            }
-        }
-
-        return super.onTouchEvent(ev);
-    }
-
     /**
      * Gets one of the buttons used in the dialog.
      * <p>
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 6791400..7365670 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -41,7 +41,6 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnCreateContextMenuListener;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
 import android.view.Window;
@@ -90,12 +89,6 @@
     private Message mDismissMessage;
     private Message mShowMessage;
 
-    /**
-     * Whether to cancel the dialog when a touch is received outside of the
-     * window's bounds.
-     */
-    private boolean mCanceledOnTouchOutside = false;
-    
     private OnKeyListener mOnKeyListener;
 
     private boolean mCreated = false;
@@ -597,8 +590,7 @@
      *         happens outside of the window bounds.
      */
     public boolean onTouchEvent(MotionEvent event) {
-        if (mCancelable && mCanceledOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
-                && isOutOfBounds(event) && mDecor != null && mShowing) {
+        if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
             cancel();
             return true;
         }
@@ -606,16 +598,6 @@
         return false;
     }
 
-    private boolean isOutOfBounds(MotionEvent event) {
-        final int x = (int) event.getX();
-        final int y = (int) event.getY();
-        final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
-        final View decorView = getWindow().getDecorView();
-        return (x < -slop) || (y < -slop)
-                || (x > (decorView.getWidth()+slop))
-                || (y > (decorView.getHeight()+slop));
-    }
-    
     /**
      * Called when the trackball was moved and not handled by any of the
      * views inside of the activity.  So, for example, if the trackball moves
@@ -1021,7 +1003,7 @@
             mCancelable = true;
         }
         
-        mCanceledOnTouchOutside = cancel;
+        mWindow.setCloseOnTouchOutside(cancel);
     }
     
     /**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0243b02..de84c56 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -34,6 +34,9 @@
  * A class that represents how a persistent notification is to be presented to
  * the user using the {@link android.app.NotificationManager}.
  *
+ * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
+ * easier to construct Notifications.</p>
+ *
  * <p>For a guide to creating notifications, see the
  * <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status 
  * Bar Notifications</a> document in the Dev Guide.</p>
@@ -119,15 +122,8 @@
 
     /**
      * An intent to launch instead of posting the notification to the status bar.
-     * Only for use with extremely high-priority notifications demanding the user's
-     * <strong>immediate</strong> attention, such as an incoming phone call or
-     * alarm clock that the user has explicitly set to a particular time.
-     * If this facility is used for something else, please give the user an option
-     * to turn it off and use a normal notification, as this can be extremely
-     * disruptive.
-     * 
-     * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
-     * will reach the user even when other notifications are suppressed.
+     *
+     * @see Notification.Builder#setFullScreenIntent
      */
     public PendingIntent fullScreenIntent;
 
@@ -278,7 +274,7 @@
     /**
      * Bit to be bitwise-ored into the {@link #flags} field that should be
      * set if the notification should be canceled when it is clicked by the
-     * user. 
+     * user.  On tablets, the 
      */
     public static final int FLAG_AUTO_CANCEL        = 0x00000010;
 
@@ -618,6 +614,10 @@
         return sb.toString();
     }
 
+    /**
+     * Builder class for {@link Notification} objects.  Allows easier control over
+     * all the flags, as well as help constructing the typical notification layouts.
+     */
     public static class Builder {
         private Context mContext;
 
@@ -644,6 +644,16 @@
         private int mDefaults;
         private int mFlags;
 
+        /**
+         * Constructor.
+         *
+         * Automatically sets the when field to {@link System#currentTimeMillis()
+         * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
+         *
+         * @param context A {@link Context} that will be used to construct the
+         *      RemoteViews. The Context will not be held past the lifetime of this
+         *      Builder object.
+         */
         public Builder(Context context) {
             mContext = context;
 
@@ -652,96 +662,192 @@
             mAudioStreamType = STREAM_DEFAULT;
         }
 
+        /**
+         * Set the time that the event occurred.  Notifications in the panel are
+         * sorted by this time.
+         */
         public Builder setWhen(long when) {
             mWhen = when;
             return this;
         }
 
+        /**
+         * Set the small icon to use in the notification layouts.  Different classes of devices
+         * may return different sizes.  See the UX guidelines for more information on how to
+         * design these icons.
+         *
+         * @param icon A resource ID in the application's package of the drawble to use.
+         */
         public Builder setSmallIcon(int icon) {
             mSmallIcon = icon;
             return this;
         }
 
+        /**
+         * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
+         * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
+         * LevelListDrawable}.
+         *
+         * @param icon A resource ID in the application's package of the drawble to use.
+         * @param level The level to use for the icon.
+         *
+         * @see android.graphics.drawable.LevelListDrawable
+         */
         public Builder setSmallIcon(int icon, int level) {
             mSmallIcon = icon;
             mSmallIconLevel = level;
             return this;
         }
 
+        /**
+         * Set the title (first row) of the notification, in a standard notification.
+         */
         public Builder setContentTitle(CharSequence title) {
             mContentTitle = title;
             return this;
         }
 
+        /**
+         * Set the text (second row) of the notification, in a standard notification.
+         */
         public Builder setContentText(CharSequence text) {
             mContentText = text;
             return this;
         }
 
+        /**
+         * Set the large number at the right-hand side of the notification.  This is
+         * equivalent to setContentInfo, although it might show the number in a different
+         * font size for readability.
+         */
         public Builder setNumber(int number) {
             mNumber = number;
             return this;
         }
 
+        /**
+         * Set the large text at the right-hand side of the notification.
+         */
         public Builder setContentInfo(CharSequence info) {
             mContentInfo = info;
             return this;
         }
 
+        /**
+         * Supply a custom RemoteViews to use instead of the standard one.
+         */
         public Builder setContent(RemoteViews views) {
             mContentView = views;
             return this;
         }
 
+        /**
+         * Supply a {@link PendingIntent} to send when the notification is clicked.
+         * If you do not supply an intent, you can now add PendingIntents to individual
+         * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
+         * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+         */
         public Builder setContentIntent(PendingIntent intent) {
             mContentIntent = intent;
             return this;
         }
 
+        /**
+         * Supply a {@link PendingIntent} to send when the notification is cleared by the user
+         * directly from the notification panel.  For example, this intent is sent when the user
+         * clicks the "Clear all" button, or the individual "X" buttons on notifications.  This
+         * intent is not sent when the application calls {@link NotificationManager#cancel
+         * NotificationManager.cancel(int)}.
+         */
         public Builder setDeleteIntent(PendingIntent intent) {
             mDeleteIntent = intent;
             return this;
         }
 
+        /**
+         * An intent to launch instead of posting the notification to the status bar.
+         * Only for use with extremely high-priority notifications demanding the user's
+         * <strong>immediate</strong> attention, such as an incoming phone call or
+         * alarm clock that the user has explicitly set to a particular time.
+         * If this facility is used for something else, please give the user an option
+         * to turn it off and use a normal notification, as this can be extremely
+         * disruptive.
+         *
+         * @param intent The pending intent to launch.
+         * @param highPriority Passing true will cause this notification to be sent
+         *          even if other notifications are suppressed.
+         */
         public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
             mFullScreenIntent = intent;
             setFlag(FLAG_HIGH_PRIORITY, highPriority);
             return this;
         }
 
+        /**
+         * Set the text that is displayed in the status bar when the notification first
+         * arrives.
+         */
         public Builder setTicker(CharSequence tickerText) {
             mTickerText = tickerText;
             return this;
         }
 
+        /**
+         * Set the text that is displayed in the status bar when the notification first
+         * arrives, and also a RemoteViews object that may be displayed instead on some
+         * devices.
+         */
         public Builder setTicker(CharSequence tickerText, RemoteViews views) {
             mTickerText = tickerText;
             mTickerView = views;
             return this;
         }
 
+        /**
+         * Set the large icon that is shown in the ticker and notification.
+         */
         public Builder setLargeIcon(Bitmap icon) {
             mLargeIcon = icon;
             return this;
         }
 
+        /**
+         * Set the sound to play.  It will play on the default stream.
+         */
         public Builder setSound(Uri sound) {
             mSound = sound;
             mAudioStreamType = STREAM_DEFAULT;
             return this;
         }
 
+        /**
+         * Set the sound to play.  It will play on the stream you supply.
+         *
+         * @see #STREAM_DEFAULT
+         * @see AudioManager for the <code>STREAM_</code> constants.
+         */
         public Builder setSound(Uri sound, int streamType) {
             mSound = sound;
             mAudioStreamType = streamType;
             return this;
         }
 
+        /**
+         * Set the vibration pattern to use.
+         *
+         * @see android.os.Vibrator for a discussion of the <code>pattern</code>
+         * parameter.
+         */
         public Builder setVibrate(long[] pattern) {
             mVibrate = pattern;
             return this;
         }
 
+        /**
+         * Set the argb value that you would like the LED on the device to blnk, as well as the
+         * rate.  The rate is specified in terms of the number of milliseconds to be on
+         * and then the number of milliseconds to be off.
+         */
         public Builder setLights(int argb, int onMs, int offMs) {
             mLedArgb = argb;
             mLedOnMs = onMs;
@@ -749,21 +855,51 @@
             return this;
         }
 
+        /**
+         * Set whether this is an ongoing notification.
+         *
+         * <p>Ongoing notifications differ from regular notifications in the following ways:
+         * <ul>
+         *   <li>Ongoing notifications are sorted above the regular notifications in the
+         *   notification panel.</li>
+         *   <li>Ongoing notifications do not have an 'X' close button, and are not affected
+         *   by the "Clear all" button.
+         * </ul>
+         */
         public Builder setOngoing(boolean ongoing) {
             setFlag(FLAG_ONGOING_EVENT, ongoing);
             return this;
         }
 
+        /**
+         * Set this flag if you would only like the sound, vibrate
+         * and ticker to be played if the notification is not already showing.
+         */
         public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
             setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
             return this;
         }
 
+        /**
+         * Setting this flag will make it so the notification is automatically
+         * canceled when the user clicks it in the panel.  The PendingIntent
+         * set with {@link #setDeleteIntent} will be broadcast when the notification
+         * is canceled.
+         */
         public Builder setAutoCancel(boolean autoCancel) {
             setFlag(FLAG_AUTO_CANCEL, autoCancel);
             return this;
         }
 
+        /**
+         * Set the default notification options that will be used.
+         * <p>
+         * The value should be one or more of the following fields combined with
+         * bitwise-or:
+         * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
+         * <p>
+         * For all default values, use {@link #DEFAULT_ALL}.
+         */
         public Builder setDefaults(int defaults) {
             mDefaults = defaults;
             return this;
@@ -834,6 +970,10 @@
             }
         }
 
+        /**
+         * Combine all of the options that have been set and return a new {@link Notification}
+         * object.
+         */
         public Notification getNotification() {
             Notification n = new Notification();
             n.when = mWhen;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 2a583c1..019652c 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -18,6 +18,7 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -438,6 +439,47 @@
     }
 
     /**
+     * Binds the RemoteViewsService for a given appWidgetId and intent.
+     *
+     * The appWidgetId specified must already be bound to the calling AppWidgetHost via
+     * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
+     *
+     * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
+     * @param intent        The intent of the service which will be providing the data to the
+     *                      RemoteViewsAdapter.
+     * @param connection    The callback interface to be notified when a connection is made or lost.
+     * @hide
+     */
+    public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
+        try {
+            sService.bindRemoteViewsService(appWidgetId, intent, connection);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Unbinds the RemoteViewsService for a given appWidgetId and intent.
+     *
+     * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
+     * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
+     *
+     * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
+     * @param intent        The intent of the service which will be providing the data to the
+     *                      RemoteViewsAdapter.
+     * @hide
+     */
+    public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
+        try {
+            sService.unbindRemoteViewsService(appWidgetId, intent);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
      * Get the list of appWidgetIds that have been bound to the given AppWidget
      * provider.
      *
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index bc8a836..a70de59 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -85,6 +85,19 @@
      */
     public static final int PRIORITY_UNDEFINED = -1;
 
+    /**
+     * Return codes for the connect and disconnect Bluez / Dbus calls.
+     */
+    public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+
+    public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+
+    public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+
+    public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+
+    public static final int INPUT_OPERATION_SUCCESS = 5004;
+
     private final IBluetooth mService;
     private final Context mContext;
 
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7dee25e..1f07349 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -70,6 +70,19 @@
     public static final int STATE_CONNECTED    = 2;
     public static final int STATE_DISCONNECTING = 3;
 
+    /**
+     * Return codes for the connect and disconnect Bluez / Dbus calls.
+     */
+    public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
+
+    public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001;
+
+    public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002;
+
+    public static final int PAN_OPERATION_GENERIC_FAILURE = 1003;
+
+    public static final int PAN_OPERATION_SUCCESS = 1004;
+
     private final IBluetooth mService;
     private final Context mContext;
 
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index af7b28b..35f1c58 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -211,6 +211,12 @@
          *      {@link android.R.style#Theme_Holo}.
          * <li> The activity lifecycle has changed slightly as per
          * {@link android.app.Activity}.
+         * <li> When an application requires a permission to access on of
+         * its components (activity, receiver, service, provider), this
+         * permission is no longer enforced when the application wants to
+         * access its own component.  This means it can require a permission
+         * on a component that it does not itself hold and still access that
+         * component.
          * </ul>
          */
         public static final int HONEYCOMB = CUR_DEVELOPMENT;
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 904b2e9..ec5030c 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -416,6 +416,7 @@
      * <p>See {@link #getExternalStorageDirectory()} for more information.
      */
     public static boolean isExternalStorageRemovable() {
+        if (isExternalStorageEmulated()) return false;
         return Resources.getSystem().getBoolean(
                 com.android.internal.R.bool.config_externalStorageRemovable);
     }
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 997ea53..ae92b09 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -30,6 +30,7 @@
 
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
@@ -184,6 +185,15 @@
     /**
      * @hide
      */
+    private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000;  // for VmPolicy
+
+    private static final int ALL_VM_DETECT_BITS =
+            DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
+            DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS;
+
+    /**
+     * @hide
+     */
     public static final int PENALTY_LOG = 0x10;  // normal android.util.Log
 
     // Used for both process and thread policy:
@@ -573,11 +583,15 @@
                 } else if (mClassInstanceLimit == null) {
                     mClassInstanceLimit = new HashMap<Class, Integer>();
                 }
+                mMask |= DETECT_VM_INSTANCE_LEAKS;
                 mClassInstanceLimit.put(klass, instanceLimit);
                 return this;
             }
 
-            private Builder detectActivityLeaks() {
+            /**
+             * Detect leaks of {@link android.app.Activity} subclasses.
+             */
+            public Builder detectActivityLeaks() {
                 return enable(DETECT_VM_ACTIVITY_LEAKS);
             }
 
@@ -585,8 +599,8 @@
              * Detect everything that's potentially suspect.
              *
              * <p>In the Honeycomb release this includes leaks of
-             * SQLite cursors and other closable objects but will
-             * likely expand in future releases.
+             * SQLite cursors, Activities, and other closable objects
+             * but will likely expand in future releases.
              */
             public Builder detectAll() {
                 return enable(DETECT_VM_ACTIVITY_LEAKS |
@@ -1347,6 +1361,41 @@
     }
 
     /**
+     * @hide
+     */
+    public static void conditionallyCheckInstanceCounts() {
+        VmPolicy policy = getVmPolicy();
+        if (policy.classInstanceLimit.size() == 0) {
+            return;
+        }
+        Runtime.getRuntime().gc();
+        // Note: classInstanceLimit is immutable, so this is lock-free
+        for (Class klass : policy.classInstanceLimit.keySet()) {
+            int limit = policy.classInstanceLimit.get(klass);
+            long instances = VMDebug.countInstancesOfClass(klass, false);
+            if (instances <= limit) {
+                continue;
+            }
+            Throwable tr = new InstanceCountViolation(klass, instances, limit);
+            onVmPolicyViolation(tr.getMessage(), tr);
+        }
+    }
+
+    private static long sLastInstanceCountCheckMillis = 0;
+    private static boolean sIsIdlerRegistered = false;  // guarded by sProcessIdleHandler
+    private static final MessageQueue.IdleHandler sProcessIdleHandler =
+            new MessageQueue.IdleHandler() {
+                public boolean queueIdle() {
+                    long now = SystemClock.uptimeMillis();
+                    if (now - sLastInstanceCountCheckMillis > 30 * 1000) {
+                        sLastInstanceCountCheckMillis = now;
+                        conditionallyCheckInstanceCounts();
+                    }
+                    return true;
+                }
+            };
+
+    /**
      * Sets the policy for what actions in the VM process (on any
      * thread) should be detected, as well as the penalty if such
      * actions occur.
@@ -1357,6 +1406,19 @@
         sVmPolicy = policy;
         sVmPolicyMask = policy.mask;
         setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+
+        Looper looper = Looper.getMainLooper();
+        if (looper != null) {
+            MessageQueue mq = looper.mQueue;
+            synchronized (sProcessIdleHandler) {
+                if (policy.classInstanceLimit.size() == 0) {
+                    mq.removeIdleHandler(sProcessIdleHandler);
+                } else if (!sIsIdlerRegistered) {
+                    mq.addIdleHandler(sProcessIdleHandler);
+                    sIsIdlerRegistered = true;
+                }
+            }
+        }
     }
 
     /**
@@ -1406,19 +1468,39 @@
         onVmPolicyViolation(message, originStack);
     }
 
+    // Map from VM violation fingerprint to uptime millis.
+    private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
+
     /**
      * @hide
      */
     public static void onVmPolicyViolation(String message, Throwable originStack) {
-        if ((sVmPolicyMask & PENALTY_LOG) != 0) {
+        final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+        final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+        final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0;
+        final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+        final Integer fingerprint = info.hashCode();
+        final long now = SystemClock.uptimeMillis();
+        long lastViolationTime = 0;
+        long timeSinceLastViolationMillis = Long.MAX_VALUE;
+        synchronized (sLastVmViolationTime) {
+            if (sLastVmViolationTime.containsKey(fingerprint)) {
+                lastViolationTime = sLastVmViolationTime.get(fingerprint);
+                timeSinceLastViolationMillis = now - lastViolationTime;
+            }
+            if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
+                sLastVmViolationTime.put(fingerprint, now);
+            }
+        }
+
+        Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis);
+
+        if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
             Log.e(TAG, message, originStack);
         }
 
-        boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
-        boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
-
-        int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
-        ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+        int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask);
 
         if (penaltyDropbox && !penaltyDeath) {
             // Common case for userdebug/eng builds.  If no death and
@@ -1428,7 +1510,7 @@
             return;
         }
 
-        if (penaltyDropbox) {
+        if (penaltyDropbox && lastViolationTime == 0) {
             // The violationMask, passed to ActivityManager, is a
             // subset of the original StrictMode policy bitmask, with
             // only the bit violated and penalty bits to be executed
@@ -1786,6 +1868,12 @@
         public String broadcastIntentAction;
 
         /**
+         * If this is a instance count violation, the number of instances in memory,
+         * else -1.
+         */
+        public long numInstances = -1;
+
+        /**
          * Create an uninitialized instance of ViolationInfo
          */
         public ViolationInfo() {
@@ -1806,6 +1894,9 @@
                 broadcastIntentAction = broadcastIntent.getAction();
             }
             ThreadSpanState state = sThisThreadSpanState.get();
+            if (tr instanceof InstanceCountViolation) {
+                this.numInstances = ((InstanceCountViolation) tr).mInstances;
+            }
             synchronized (state) {
                 int spanActiveCount = state.mActiveSize;
                 if (spanActiveCount > MAX_SPAN_TAGS) {
@@ -1867,6 +1958,7 @@
             violationNumThisLoop = in.readInt();
             numAnimationsRunning = in.readInt();
             violationUptimeMillis = in.readLong();
+            numInstances = in.readLong();
             broadcastIntentAction = in.readString();
             tags = in.readStringArray();
         }
@@ -1881,6 +1973,7 @@
             dest.writeInt(violationNumThisLoop);
             dest.writeInt(numAnimationsRunning);
             dest.writeLong(violationUptimeMillis);
+            dest.writeLong(numInstances);
             dest.writeString(broadcastIntentAction);
             dest.writeStringArray(tags);
         }
@@ -1895,6 +1988,9 @@
             if (durationMillis != -1) {
                 pw.println(prefix + "durationMillis: " + durationMillis);
             }
+            if (numInstances != -1) {
+                pw.println(prefix + "numInstances: " + numInstances);
+            }
             if (violationNumThisLoop != 0) {
                 pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
             }
@@ -1914,4 +2010,29 @@
         }
 
     }
+
+    // Dummy throwable, for now, since we don't know when or where the
+    // leaked instances came from.  We might in the future, but for
+    // now we suppress the stack trace because it's useless and/or
+    // misleading.
+    private static class InstanceCountViolation extends Throwable {
+        final Class mClass;
+        final long mInstances;
+        final int mLimit;
+
+        private static final StackTraceElement[] FAKE_STACK = new StackTraceElement[1];
+        static {
+            FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit",
+                                                  "StrictMode.java", 1);
+        }
+
+        public InstanceCountViolation(Class klass, long instances, int limit) {
+            // Note: now including instances here, otherwise signatures would all be different.
+            super(klass.toString() + "; limit=" + limit);
+            setStackTrace(FAKE_STACK);
+            mClass = klass;
+            mInstances = instances;
+            mLimit = limit;
+        }
+    }
 }
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index c7f8ab2..45e3a4c 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -80,6 +80,8 @@
     private ListAdapter mRootAdapter;
     
     private Dialog mDialog;
+
+    private ListView mListView;
     
     /**
      * Do NOT use this constructor, use {@link PreferenceManager#createPreferenceScreen(Context)}.
@@ -146,15 +148,18 @@
     
     private void showDialog(Bundle state) {
         Context context = getContext();
-        ListView listView = new ListView(context);
-        bind(listView);
+        if (mListView != null) {
+            mListView.setAdapter(null);
+        }
+        mListView = new ListView(context);
+        bind(mListView);
 
         // Set the title bar if title is available, else no title bar
         final CharSequence title = getTitle();
         Dialog dialog = mDialog = new Dialog(context, TextUtils.isEmpty(title)
                 ? com.android.internal.R.style.Theme_NoTitleBar
                 : com.android.internal.R.style.Theme);
-        dialog.setContentView(listView);
+        dialog.setContentView(mListView);
         if (!TextUtils.isEmpty(title)) {
             dialog.setTitle(title);
         }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9f0ea32..82fe7de 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -57,6 +57,8 @@
      * Broadcast Action:  A broadcast to indicate the end of an MTP session with the host.
      * This broadcast is only sent if MTP activity has modified the media database during the
      * most recent MTP session.
+     *
+     * @hide
      */
     public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
 
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 539a696..cd3bc3e 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -748,9 +748,9 @@
         }
     }
 
-    private void onInputDeviceConnectionResult(String path, boolean result) {
+    private void onInputDeviceConnectionResult(String path, int result) {
         // Success case gets handled by Property Change signal
-        if (!result) {
+        if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
             String address = mBluetoothService.getAddressFromObjectPath(path);
             if (address == null) return;
 
@@ -758,9 +758,18 @@
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             int state = mBluetoothService.getInputDeviceState(device);
             if (state == BluetoothInputDevice.STATE_CONNECTING) {
-                connected = false;
+                if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
+                    connected = true;
+                } else {
+                    connected = false;
+                }
             } else if (state == BluetoothInputDevice.STATE_DISCONNECTING) {
-                connected = true;
+                if (result == BluetoothInputDevice.INPUT_DISCONNECT_FAILED_NOT_CONNECTED) {
+                    connected = false;
+                } else {
+                    // There is no better way to handle this, this shouldn't happen
+                    connected = true;
+                }
             } else {
                 Log.e(TAG, "Error onInputDeviceConnectionResult. State is:" + state);
             }
@@ -768,10 +777,10 @@
         }
     }
 
-    private void onPanDeviceConnectionResult(String path, boolean result) {
+    private void onPanDeviceConnectionResult(String path, int result) {
         log ("onPanDeviceConnectionResult " + path + " " + result);
         // Success case gets handled by Property Change signal
-        if (!result) {
+        if (result != BluetoothPan.PAN_OPERATION_SUCCESS) {
             String address = mBluetoothService.getAddressFromObjectPath(path);
             if (address == null) return;
 
@@ -779,9 +788,18 @@
             BluetoothDevice device = mAdapter.getRemoteDevice(address);
             int state = mBluetoothService.getPanDeviceState(device);
             if (state == BluetoothPan.STATE_CONNECTING) {
-                connected = false;
+                if (result == BluetoothPan.PAN_CONNECT_FAILED_ALREADY_CONNECTED) {
+                    connected = true;
+                } else {
+                    connected = false;
+                }
             } else if (state == BluetoothPan.STATE_DISCONNECTING) {
-                connected = true;
+                if (result == BluetoothPan.PAN_DISCONNECT_FAILED_NOT_CONNECTED) {
+                    connected = false;
+                } else {
+                    // There is no better way to handle this, this shouldn't happen
+                    connected = true;
+                }
             } else {
                 Log.e(TAG, "Error onPanDeviceConnectionResult. State is: "
                         + state + " result: "+ result);
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index f010076..c46d2c5 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -349,19 +349,17 @@
          */
         public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
         /**
-         * {@hide}
          * Parameter key to specify the speech volume relative to the current stream type
          * volume used when speaking text. Volume is specified as a float ranging from 0 to 1
-         * where 0 is silence, and 1 is the maximum volume.
+         * where 0 is silence, and 1 is the maximum volume (the default behavior).
          * @see TextToSpeech#speak(String, int, HashMap)
          * @see TextToSpeech#playEarcon(String, int, HashMap)
          */
         public static final String KEY_PARAM_VOLUME = "volume";
         /**
-         * {@hide}
          * Parameter key to specify how the speech is panned from left to right when speaking text.
          * Pan is specified as a float ranging from -1 to +1 where -1 maps to a hard-left pan,
-         * 0 to center, and +1 to hard-right.
+         * 0 to center (the default behavior), and +1 to hard-right.
          * @see TextToSpeech#speak(String, int, HashMap)
          * @see TextToSpeech#playEarcon(String, int, HashMap)
          */
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 6634f00..25b680e6 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -274,7 +274,7 @@
     public String toString() {
         return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
         + " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
-        + " data=" + mClipData + " result=" + mDragResult
+        + " data=" + mClipData + " local=" + mLocalState + " result=" + mDragResult
         + "}";
     }
 
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 99b686e..f480554 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -452,11 +452,14 @@
     @Override
     public int saveLayer(float left, float top, float right, float bottom, Paint paint,
             int saveFlags) {
-        boolean hasColorFilter = paint != null && setupColorFilter(paint);
-        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-        int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
-        if (hasColorFilter) nResetModifiers(mRenderer);
-        return count;
+        if (left < right && top < bottom) {
+            boolean hasColorFilter = paint != null && setupColorFilter(paint);
+            final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+            int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
+            if (hasColorFilter) nResetModifiers(mRenderer);
+            return count;
+        }
+        return save(saveFlags);
     }
 
     private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
@@ -471,7 +474,10 @@
     @Override
     public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
             int saveFlags) {
-        return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+        if (left < right && top < bottom) {
+            return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+        }
+        return save(saveFlags);
     }
 
     private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f9a6c1b..addd1b3 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -84,6 +84,13 @@
      * @return True if the initialization was successful, false otherwise.
      */
     abstract boolean initialize(SurfaceHolder holder);
+    
+    /**
+     * Updates the hardware renderer for the specified surface.
+     * 
+     * @param holder The holder for the surface to hardware accelerate.
+     */
+    abstract void updateSurface(SurfaceHolder holder);
 
     /**
      * Setup the hardware renderer for drawing. This is called for every
@@ -330,6 +337,13 @@
             }
             return false;
         }
+        
+        @Override
+        void updateSurface(SurfaceHolder holder) {
+            if (isRequested() && isEnabled()) {
+                createEglSurface(holder);
+            }
+        }
 
         abstract GLES20Canvas createCanvas();
 
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 7ca5a19..3ff7fcd 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -170,7 +170,7 @@
      *
      * @param deviceId The device id of the keyboard.
      * @return The associated key character map.
-     * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+     * @throws {@link UnavailableException} if the key character map
      * could not be loaded because it was malformed or the default key character map
      * is missing from the system.
      */
@@ -692,8 +692,8 @@
     /**
      * Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
      */
-    public static class KeyCharacterMapUnavailableException extends AndroidRuntimeException {
-        public KeyCharacterMapUnavailableException(String msg) {
+    public static class UnavailableException extends AndroidRuntimeException {
+        public UnavailableException(String msg) {
             super(msg);
         }
     }
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ecf1aef..941331a 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2163,7 +2163,7 @@
      * Gets the {@link KeyCharacterMap} associated with the keyboard device.
      *
      * @return The associated key character map.
-     * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+     * @throws {@link UnavailableException} if the key character map
      * could not be loaded because it was malformed or the default key character map
      * is missing from the system.
      *
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index e203355..0326a8f 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -159,6 +159,8 @@
     private Canvas mCanvas;
     @SuppressWarnings("unused")
     private int mNativeSurface;
+    @SuppressWarnings("unused")
+    private int mSurfaceGenerationId;
     private String mName;
 
     // The display metrics used to provide the pseudo canvas size for applications
@@ -308,6 +310,13 @@
      * returns false.
      */
     public native   boolean isValid();
+
+    /**
+     * @hide
+     */
+    public int getGenerationId() {
+        return mSurfaceGenerationId;
+    }
     
     /** Free all server-side state associated with this surface and
      * release this object's reference. {@hide} */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 53fc0c0..2447f8c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -58,7 +58,6 @@
 import android.util.Pools;
 import android.util.SparseArray;
 import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -10606,13 +10605,38 @@
         private final WeakReference<View> mView;
 
         /**
-         * Construct a shadow builder object for use with the given view.
-         * @param view
+         * Construct a shadow builder object for use with the given View object.  The
+         * default implementation will construct a drag shadow the same size and
+         * appearance as the supplied View.
+         *
+         * @param view A view within the application's layout whose appearance
+         *        should be replicated as the drag shadow.
          */
         public DragShadowBuilder(View view) {
             mView = new WeakReference<View>(view);
         }
 
+        /**
+         * Construct a shadow builder object with no associated View.  This
+         * constructor variant is only useful when the {@link #onProvideShadowMetrics(Point, Point)}
+         * and {@link #onDrawShadow(Canvas)} methods are also overridden in order
+         * to supply the drag shadow's dimensions and appearance without
+         * reference to any View object.
+         */
+        public DragShadowBuilder() {
+            mView = new WeakReference<View>(null);
+        }
+
+        /**
+         * Returns the View object that had been passed to the
+         * {@link #View.DragShadowBuilder(View)}
+         * constructor.  If that View parameter was {@code null} or if the
+         * {@link #View.DragShadowBuilder()}
+         * constructor was used to instantiate the builder object, this method will return
+         * null.
+         *
+         * @return The View object associate with this builder object.
+         */
         final public View getView() {
             return mView.get();
         }
@@ -10623,8 +10647,10 @@
          * be centered under the touch location while dragging.
          * <p>
          * The default implementation sets the dimensions of the shadow to be the
-         * same as the dimensions of the View itself and centers the shadow under
-         * the touch point.
+         * same as the dimensions of the View object that had been supplied to the
+         * {@link #View.DragShadowBuilder(View)} constructor
+         * when the builder object was instantiated, and centers the shadow under the touch
+         * point.
          *
          * @param shadowSize The application should set the {@code x} member of this
          *        parameter to the desired shadow width, and the {@code y} member to
@@ -10647,6 +10673,11 @@
          * Draw the shadow image for the upcoming drag.  The shadow canvas was
          * created with the dimensions supplied by the
          * {@link #onProvideShadowMetrics(Point, Point)} callback.
+         * <p>
+         * The default implementation replicates the appearance of the View object
+         * that had been supplied to the
+         * {@link #View.DragShadowBuilder(View)}
+         * constructor when the builder object was instantiated.
          *
          * @param canvas
          */
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d1781cc..115431e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -935,15 +935,17 @@
         } break;
 
         case DragEvent.ACTION_DRAG_ENDED: {
-            // If a child was notified about an ongoing drag, it's told that it's over
-            for (View child : mDragNotifiedChildren) {
-                child.dispatchDragEvent(event);
-            }
-
             // Release the bookkeeping now that the drag lifecycle has ended
-            mDragNotifiedChildren.clear();
-            mCurrentDrag.recycle();
-            mCurrentDrag = null;
+            if (mDragNotifiedChildren != null) {
+                for (View child : mDragNotifiedChildren) {
+                    // If a child was notified about an ongoing drag, it's told that it's over
+                    child.dispatchDragEvent(event);
+                }
+
+                mDragNotifiedChildren.clear();
+                mCurrentDrag.recycle();
+                mCurrentDrag = null;
+            }
 
             // We consider drag-ended to have been handled if one of our children
             // had offered to handle the drag.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 96f8cdc..1f15628 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -983,6 +983,8 @@
                     Log.i(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" +
                             host.getMeasuredHeight() + ", params=" + params);
                 }
+
+                final int surfaceGenerationId = mSurface.getGenerationId();
                 relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
 
                 if (params != null) {
@@ -1043,6 +1045,9 @@
                         mScroller.abortAnimation();
                     }
                     disposeResizeBitmap();
+                } else if (surfaceGenerationId != mSurface.getGenerationId() &&
+                        mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
+                    mAttachInfo.mHardwareRenderer.updateSurface(mHolder);
                 }
             } catch (RemoteException e) {
             }
@@ -2798,6 +2803,7 @@
 
                 // Report the drop result when we're done
                 if (what == DragEvent.ACTION_DROP) {
+                    mDragDescription = null;
                     try {
                         Log.i(TAG, "Reporting drop result: " + result);
                         sWindowSession.reportDropResult(mWindow, result);
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index e21824e..e447dbb 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -284,10 +284,11 @@
 
         synchronized (this) {
             ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
-            toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+            if (toneGen != null) {
+                toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+                sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
+            }
         }
-
-        sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
     }
 
     protected void onStopSounds() {
@@ -319,10 +320,16 @@
     private ToneGenerator getOrCreateToneGenerator(int streamType) {
         synchronized (this) {
             if (mToneGenerators[streamType] == null) {
-                return mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
-            } else {
-                return mToneGenerators[streamType];
+                try {
+                    mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
+                } catch (RuntimeException e) {
+                    if (LOGD) {
+                        Log.d(TAG, "ToneGenerator constructor failed with "
+                                + "RuntimeException: " + e);
+                    }
+                }
             }
+            return mToneGenerators[streamType];
         }
     }
 
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 2f27935..217e731 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -116,6 +116,8 @@
     private Window mActiveChild;
     private boolean mIsActive = false;
     private boolean mHasChildren = false;
+    private boolean mCloseOnTouchOutside = false;
+    private boolean mSetCloseOnTouchOutside = false;
     private int mForcedWindowFlags = 0;
 
     private int mFeatures = DEFAULT_FEATURES;
@@ -786,6 +788,42 @@
         return mHasSoftInputMode;
     }
     
+    /** @hide */
+    public void setCloseOnTouchOutside(boolean close) {
+        mCloseOnTouchOutside = close;
+        mSetCloseOnTouchOutside = true;
+    }
+    
+    /** @hide */
+    public void setCloseOnTouchOutsideIfNotSet(boolean close) {
+        if (!mSetCloseOnTouchOutside) {
+            mCloseOnTouchOutside = close;
+            mSetCloseOnTouchOutside = true;
+        }
+    }
+    
+    /** @hide */
+    public abstract void alwaysReadCloseOnTouchAttr();
+    
+    /** @hide */
+    public boolean shouldCloseOnTouch(Context context, MotionEvent event) {
+        if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN
+                && isOutOfBounds(context, event) && peekDecorView() != null) {
+            return true;
+        }
+        return false;
+    }
+    
+    private boolean isOutOfBounds(Context context, MotionEvent event) {
+        final int x = (int) event.getX();
+        final int y = (int) event.getY();
+        final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();
+        final View decorView = getDecorView();
+        return (x < -slop) || (y < -slop)
+                || (x > (decorView.getWidth()+slop))
+                || (y > (decorView.getHeight()+slop));
+    }
+    
     /**
      * Enable extended screen features.  This must be called before
      * setContentView().  May be called as many times as desired as long as it
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c54a3cf..8eb4269 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -817,7 +817,7 @@
         public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
 
         /**
-         * Desired operating mode for any soft input area.  May any combination
+         * Desired operating mode for any soft input area.  May be any combination
          * of:
          * 
          * <ul>
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 85bff4f..d8f34e0 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -495,6 +495,7 @@
                         break;
                     }
                     case ENDED:
+                        mSeekPosition = 0;
                         nativeOnEnded(mNativePointer);
                         break;
                     case PAUSED:
@@ -538,10 +539,15 @@
      * Play a video stream.
      * @param url is the URL of the video stream.
      */
-    public void play(String url) {
+    public void play(String url, int position) {
         if (url == null) {
             return;
         }
+
+        if (position > 0) {
+            seek(position);
+        }
+
         Message message = obtainMessage(PLAY);
         message.obj = url;
         sendMessage(message);
diff --git a/core/java/android/webkit/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java
index bb9ec48..54dfab3 100644
--- a/core/java/android/webkit/WebIconDatabase.java
+++ b/core/java/android/webkit/WebIconDatabase.java
@@ -24,6 +24,7 @@
 import android.provider.Browser;
 import android.util.Log;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.Vector;
 
@@ -194,13 +195,16 @@
     /**
      * Open a the icon database and store the icons in the given path.
      * @param path The directory path where the icon database will be stored.
-     * @return True if the database was successfully opened or created in
-     *         the given path.
      */
     public void open(String path) {
         if (path != null) {
+            // Make the directories and parents if they don't exist
+            File db = new File(path);
+            if (!db.exists()) {
+                db.mkdirs();
+            }
             mEventHandler.postMessage(
-                    Message.obtain(null, EventHandler.OPEN, path));
+                    Message.obtain(null, EventHandler.OPEN, db.getAbsolutePath()));
         }
     }
 
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 2f96782..518ba69 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1569,6 +1569,7 @@
     public void setCacheMode(int mode) {
         if (mode != mOverrideCacheMode) {
             mOverrideCacheMode = mode;
+            postSync();
         }
     }
 
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 1313fcc..72b0023 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -132,6 +132,10 @@
     private boolean mAutoFillable; // Is this textview part of an autofillable form?
     private int mQueryId;
     private boolean mAutoFillProfileIsSet;
+    // Used to determine whether onFocusChanged was called as a result of
+    // calling remove().
+    private boolean mInsideRemove;
+    private boolean mInPassword;
 
     // Types used with setType.  Keep in sync with CachedInput.h
     private static final int NORMAL_TEXT_FIELD = 0;
@@ -540,6 +544,11 @@
             Rect previouslyFocusedRect) {
         mFromFocusChange = true;
         super.onFocusChanged(focused, direction, previouslyFocusedRect);
+        if (focused) {
+            mWebView.setActive(true);
+        } else if (!mInsideRemove) {
+            mWebView.setActive(false);
+        }
         mFromFocusChange = false;
     }
 
@@ -770,26 +779,17 @@
         if (imm.isActive(this)) {
             imm.hideSoftInputFromWindow(getWindowToken(), 0);
         }
+        mInsideRemove = true;
         mWebView.removeView(this);
         mWebView.requestFocus();
-    }
-
-    /**
-     * Move the caret/selection into view.
-     */
-    /* package */ void bringIntoView() {
-        bringPointIntoView(Selection.getSelectionEnd(getText()));
+        mInsideRemove = false;
     }
 
     @Override
     public boolean bringPointIntoView(int offset) {
-        if (mWebView == null) return false;
-        if (mWebView.nativeFocusCandidateIsPassword()) {
+        if (mInPassword) {
             return getLayout() != null && super.bringPointIntoView(offset);
         }
-        // For non password text input, tell webkit to move the caret/selection
-        // on screen, since webkit draws them.
-        mWebView.revealSelection();
         return true;
     }
 
@@ -904,6 +904,7 @@
      * @param   inPassword  True if the textfield is a password field.
      */
     /* package */ void setInPassword(boolean inPassword) {
+        mInPassword = inPassword;
         if (inPassword) {
             setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.
                 TYPE_TEXT_VARIATION_WEB_PASSWORD);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 78d4cd2..82e6964 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -408,10 +408,13 @@
     PluginFullScreenHolder mFullScreenHolder;
 
     /**
-     * Position of the last touch event.
+     * Position of the last touch event in pixels.
+     * Use integer to prevent loss of dragging delta calculation accuracy;
+     * which was done in float and converted to integer, and resulted in gradual
+     * and compounding touch position and view dragging mismatch.
      */
-    private float mLastTouchX;
-    private float mLastTouchY;
+    private int mLastTouchX;
+    private int mLastTouchY;
 
     /**
      * Time of the last touch event.
@@ -496,6 +499,15 @@
     // if true, multi-touch events will be passed to webkit directly before UI
     private boolean mDeferMultitouch = false;
 
+    // Currently, multi-touch events are sent to WebKit first then back to
+    // WebView while single-touch events are handled in WebView first.
+    // So there is a chance that a single-touch move event is handled in WebView
+    // before multi-touch events are finished.
+    // if mIsHandlingMultiTouch is true, which means multi-touch event handling
+    // is not finished, then any single-touch move event will be skipped.
+    // FIXME: send single-touch events to WebKit first then back to WebView.
+    private boolean mIsHandlingMultiTouch = false;
+
     // to avoid interfering with the current touch events, track them
     // separately. Currently no snapping or fling in the deferred process mode
     private int mDeferTouchMode = TOUCH_DONE_MODE;
@@ -2218,8 +2230,8 @@
         if (type == HitTestResult.UNKNOWN_TYPE
                 || type == HitTestResult.SRC_ANCHOR_TYPE) {
             // Now check to see if it is an image.
-            int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-            int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+            int contentX = viewToContentX(mLastTouchX + mScrollX);
+            int contentY = viewToContentY(mLastTouchY + mScrollY);
             String text = nativeImageURI(contentX, contentY);
             if (text != null) {
                 result.setType(type == HitTestResult.UNKNOWN_TYPE ?
@@ -2256,8 +2268,8 @@
         if (hrefMsg == null) {
             return;
         }
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
                 contentX, contentY, hrefMsg);
     }
@@ -2271,8 +2283,8 @@
      */
     public void requestImageRef(Message msg) {
         if (0 == mNativeClass) return; // client isn't initialized
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         String ref = nativeImageURI(contentX, contentY);
         Bundle data = msg.getData();
         data.putString("url", ref);
@@ -3856,8 +3868,8 @@
      * @hide pending API council approval
      */
     public boolean selectText() {
-        int x = viewToContentX((int) mLastTouchX + mScrollX);
-        int y = viewToContentY((int) mLastTouchY + mScrollY);
+        int x = viewToContentX(mLastTouchX + mScrollX);
+        int y = viewToContentY(mLastTouchY + mScrollY);
         return selectText(x, y);
     }
 
@@ -4268,7 +4280,7 @@
         Rect vBox = contentToViewRect(bounds);
         mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
         if (!Rect.intersects(bounds, visibleRect)) {
-            mWebTextView.bringIntoView();
+            revealSelection();
         }
         String text = nativeFocusCandidateText();
         int nodePointer = nativeFocusCandidatePointer();
@@ -4858,8 +4870,8 @@
             mSelectX = contentToViewX(rect.left);
             mSelectY = contentToViewY(rect.top);
         } else if (mLastTouchY > getVisibleTitleHeight()) {
-            mSelectX = mScrollX + (int) mLastTouchX;
-            mSelectY = mScrollY + (int) mLastTouchY;
+            mSelectX = mScrollX + mLastTouchX;
+            mSelectY = mScrollY + mLastTouchY;
         } else {
             mSelectX = mScrollX + getViewWidth() / 2;
             mSelectY = mScrollY + getViewHeightWithTitle() / 2;
@@ -5050,7 +5062,7 @@
     public void onGlobalFocusChanged(View oldFocus, View newFocus) {
     }
 
-    private void setActive(boolean active) {
+    void setActive(boolean active) {
         if (active) {
             if (hasFocus()) {
                 // If our window regained focus, and we have focus, then begin
@@ -5235,7 +5247,7 @@
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 mGotKeyDown = true;
             } else {
-                if (!mGotKeyDown) {
+                if (!mGotKeyDown && event.getAction() != KeyEvent.ACTION_MULTIPLE) {
                     /*
                      * We got a key up for which we were not the recipient of
                      * the original key down. Don't give it to the view.
@@ -5353,11 +5365,19 @@
             if (DebugFlags.WEB_VIEW) {
                 Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit");
             }
+            if (!mIsHandlingMultiTouch) {
+                mIsHandlingMultiTouch = true;
+            }
             passMultiTouchToWebKit(ev);
             return true;
+        } else {
+            // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
+            if (mIsHandlingMultiTouch && ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
+                return false;
+            }
         }
 
-        return handleTouchEventCommon(ev, ev.getX(), ev.getY());
+        return handleTouchEventCommon(ev, ev.getActionMasked(), Math.round(ev.getX()), Math.round(ev.getY()));
     }
 
     /*
@@ -5365,8 +5385,7 @@
      * (x, y) denotes current focus point, which is the touch point for single touch
      * and the middle point for multi-touch.
      */
-    private boolean handleTouchEventCommon(MotionEvent ev, float x, float y) {
-        int action = ev.getAction();
+    private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
         long eventTime = ev.getEventTime();
 
 
@@ -5377,12 +5396,10 @@
         x = Math.min(x, getViewWidth() - 1);
         y = Math.min(y, getViewHeightWithTitle() - 1);
 
-        float fDeltaX = mLastTouchX - x;
-        float fDeltaY = mLastTouchY - y;
-        int deltaX = (int) fDeltaX;
-        int deltaY = (int) fDeltaY;
-        int contentX = viewToContentX((int) x + mScrollX);
-        int contentY = viewToContentY((int) y + mScrollY);
+        int deltaX = mLastTouchX - x;
+        int deltaY = mLastTouchY - y;
+        int contentX = viewToContentX(x + mScrollX);
+        int contentY = viewToContentY(y + mScrollY);
 
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
@@ -5607,8 +5624,6 @@
                     mTouchMode = TOUCH_DRAG_MODE;
                     mLastTouchX = x;
                     mLastTouchY = y;
-                    fDeltaX = 0.0f;
-                    fDeltaY = 0.0f;
                     deltaX = 0;
                     deltaY = 0;
 
@@ -5619,9 +5634,7 @@
                 // do pan
                 boolean done = false;
                 boolean keepScrollBarsVisible = false;
-                if (Math.abs(fDeltaX) < 1.0f && Math.abs(fDeltaY) < 1.0f) {
-                    mLastTouchX = x;
-                    mLastTouchY = y;
+                if (deltaX == 0 && deltaY == 0) {
                     keepScrollBarsVisible = done = true;
                 } else {
                     if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
@@ -5670,12 +5683,6 @@
                             mLastTouchY = y;
                         }
                         mHeldMotionless = MOTIONLESS_FALSE;
-                    } else {
-                        // keep the scrollbar on the screen even there is no
-                        // scroll
-                        mLastTouchX = x;
-                        mLastTouchY = y;
-                        keepScrollBarsVisible = true;
                     }
                     mLastTouchTime = eventTime;
                     mUserScroll = true;
@@ -5856,7 +5863,7 @@
 
     private void passMultiTouchToWebKit(MotionEvent ev) {
         TouchEventData ted = new TouchEventData();
-        ted.mAction = ev.getAction() & MotionEvent.ACTION_MASK;
+        ted.mAction = ev.getActionMasked();
         final int count = ev.getPointerCount();
         ted.mIds = new int[count];
         ted.mPoints = new Point[count];
@@ -5875,7 +5882,7 @@
         mPreventDefault = PREVENT_DEFAULT_IGNORE;
     }
 
-    private boolean handleMultiTouchInWebView(MotionEvent ev) {
+    private void handleMultiTouchInWebView(MotionEvent ev) {
         if (DebugFlags.WEB_VIEW) {
             Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
                 + " mTouchMode=" + mTouchMode
@@ -5888,7 +5895,7 @@
 
         // A few apps use WebView but don't instantiate gesture detector.
         // We don't need to support multi touch for them.
-        if (detector == null) return false;
+        if (detector == null) return;
 
         float x = ev.getX();
         float y = ev.getY();
@@ -5923,7 +5930,7 @@
             cancelLongPress();
             mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
             if (!mZoomManager.supportsPanDuringZoom()) {
-                return false;
+                return;
             }
             mTouchMode = TOUCH_DRAG_MODE;
             if (mVelocityTracker == null) {
@@ -5937,16 +5944,17 @@
             action = MotionEvent.ACTION_DOWN;
         } else if (action == MotionEvent.ACTION_POINTER_UP) {
             // set mLastTouchX/Y to the remaining point
-            mLastTouchX = x;
-            mLastTouchY = y;
+            mLastTouchX = Math.round(x);
+            mLastTouchY = Math.round(y);
+            mIsHandlingMultiTouch = false;
         } else if (action == MotionEvent.ACTION_MOVE) {
             // negative x or y indicate it is on the edge, skip it.
             if (x < 0 || y < 0) {
-                return false;
+                return;
             }
         }
 
-        return handleTouchEventCommon(ev, x, y);
+        handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
     }
 
     private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
@@ -5967,8 +5975,8 @@
 
     private void startTouch(float x, float y, long eventTime) {
         // Remember where the motion event started
-        mLastTouchX = x;
-        mLastTouchY = y;
+        mLastTouchX = Math.round(x);
+        mLastTouchY = Math.round(y);
         mLastTouchTime = eventTime;
         mVelocityTracker = VelocityTracker.obtain();
         mSnapScrollMode = SNAP_NONE;
@@ -6598,8 +6606,8 @@
             return;
         }
         // mLastTouchX and mLastTouchY are the point in the current viewport
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
                 contentX + mNavSlop, contentY + mNavSlop);
         nativeSelectBestAt(rect);
@@ -6630,8 +6638,8 @@
         if (!inEditingMode()) {
             return;
         }
-        mLastTouchX = x + (float) (mWebTextView.getLeft() - mScrollX);
-        mLastTouchY = y + (float) (mWebTextView.getTop() - mScrollY);
+        mLastTouchX = Math.round(x + mWebTextView.getLeft() - mScrollX);
+        mLastTouchY = Math.round(y + mWebTextView.getTop() - mScrollY);
         mLastTouchTime = eventTime;
         if (!mScroller.isFinished()) {
             abortAnimation();
@@ -6690,8 +6698,8 @@
         mTouchMode = TOUCH_DONE_MODE;
         switchOutDrawHistory();
         // mLastTouchX and mLastTouchY are the point in the current viewport
-        int contentX = viewToContentX((int) mLastTouchX + mScrollX);
-        int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+        int contentX = viewToContentX(mLastTouchX + mScrollX);
+        int contentY = viewToContentY(mLastTouchY + mScrollY);
         if (getSettings().supportTouchOnly()) {
             removeTouchHighlight(false);
             WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -7052,8 +7060,8 @@
                             || (msg.arg1 == MotionEvent.ACTION_MOVE
                             && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
                         cancelWebCoreTouchEvent(
-                                viewToContentX((int) mLastTouchX + mScrollX),
-                                viewToContentY((int) mLastTouchY + mScrollY),
+                                viewToContentX(mLastTouchX + mScrollX),
+                                viewToContentY(mLastTouchY + mScrollY),
                                 true);
                     }
                     break;
@@ -7104,8 +7112,8 @@
                         ted.mIds = new int[1];
                         ted.mIds[0] = 0;
                         ted.mPoints = new Point[1];
-                        ted.mPoints[0] = new Point(viewToContentX((int) mLastTouchX + mScrollX),
-                                                   viewToContentY((int) mLastTouchY + mScrollY));
+                        ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + mScrollX),
+                                                   viewToContentY(mLastTouchY + mScrollY));
                         // metaState for long press is tricky. Should it be the
                         // state when the press started or when the press was
                         // released? Or some intermediary key state? For
@@ -7274,7 +7282,6 @@
                     // this is sent after finishing resize in WebViewCore. Make
                     // sure the text edit box is still on the  screen.
                     if (inEditingMode() && nativeCursorIsTextInput()) {
-                        mWebTextView.bringIntoView();
                         rebuildWebTextView();
                     }
                     break;
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 88a54ea..9a050c5 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -148,13 +148,13 @@
      */
     private float mInitialScale;
 
-    private static float MINIMUM_SCALE_INCREMENT = 0.01f;
+    private static float MINIMUM_SCALE_INCREMENT = 0.007f;
 
     /*
      *  The touch points could be changed even the fingers stop moving.
      *  We use the following to filter out the zooming jitters.
      */
-    private static float MINIMUM_SCALE_WITHOUT_JITTER = 0.05f;
+    private static float MINIMUM_SCALE_WITHOUT_JITTER = 0.007f;
 
     /*
      * The following member variables are only to be used for animating zoom. If
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index d8f5972..a65de13 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2439,8 +2439,12 @@
             if (adapter != null && mItemCount > 0 &&
                     motionPosition != INVALID_POSITION &&
                     motionPosition < adapter.getCount() && sameWindow()) {
-                performItemClick(getChildAt(motionPosition - mFirstPosition), motionPosition,
-                        adapter.getItemId(motionPosition));
+                final View view = getChildAt(motionPosition - mFirstPosition);
+                // If there is no view, something bad happened (the view scrolled off the
+                // screen, etc.) and we should cancel the click
+                if (view != null) {
+                    performItemClick(view, motionPosition, adapter.getItemId(motionPosition));
+                }
             }
         }
     }
@@ -5315,6 +5319,24 @@
         mRecycler.mRecyclerListener = listener;
     }
 
+    class AdapterDataSetObserver extends AdapterView<ListAdapter>.AdapterDataSetObserver {
+        @Override
+        public void onChanged() {
+            super.onChanged();
+            if (mFastScroller != null) {
+                mFastScroller.onSectionsChanged();
+            }
+        }
+
+        @Override
+        public void onInvalidated() {
+            super.onInvalidated();
+            if (mFastScroller != null) {
+                mFastScroller.onSectionsChanged();
+            }
+        }
+    }
+
     /**
      * A MultiChoiceModeListener receives events for {@link AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.
      * It acts as the {@link ActionMode.Callback} for the selection mode and also receives
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index b4ece24..593cb59 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,9 +25,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.List;
-import java.util.Comparator;
 import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 
 /**
  * A concrete BaseAdapter that is backed by an array of arbitrary
@@ -86,6 +86,8 @@
 
     private Context mContext;
 
+    // A copy of the original mObjects array, initialized from and then used instead as soon as
+    // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
     private ArrayList<T> mOriginalValues;
     private ArrayFilter mFilter;
 
@@ -170,15 +172,14 @@
      * @param object The object to add at the end of the array.
      */
     public void add(T object) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.add(object);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.add(object);
             }
-        } else {
-            mObjects.add(object);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -187,15 +188,14 @@
      * @param collection The Collection to add at the end of the array.
      */
     public void addAll(Collection<? extends T> collection) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.addAll(collection);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.addAll(collection);
             }
-        } else {
-            mObjects.addAll(collection);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -204,19 +204,18 @@
      * @param items The items to add at the end of the array.
      */
     public void addAll(T ... items) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 for (T item : items) {
                     mOriginalValues.add(item);
                 }
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                for (T item : items) {
+                    mObjects.add(item);
+                }
             }
-        } else {
-            for (T item : items) {
-                mObjects.add(item);
-            }
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -226,15 +225,14 @@
      * @param index The index at which the object must be inserted.
      */
     public void insert(T object, int index) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.add(index, object);
-                if (mNotifyOnChange) notifyDataSetChanged();
+            } else {
+                mObjects.add(index, object);
             }
-        } else {
-            mObjects.add(index, object);
-            if (mNotifyOnChange) notifyDataSetChanged();
         }
+        if (mNotifyOnChange) notifyDataSetChanged();
     }
 
     /**
@@ -243,12 +241,12 @@
      * @param object The object to remove.
      */
     public void remove(T object) {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.remove(object);
+            } else {
+                mObjects.remove(object);
             }
-        } else {
-            mObjects.remove(object);
         }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
@@ -257,12 +255,12 @@
      * Remove all elements from the list.
      */
     public void clear() {
-        if (mOriginalValues != null) {
-            synchronized (mLock) {
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
                 mOriginalValues.clear();
+            } else {
+                mObjects.clear();
             }
-        } else {
-            mObjects.clear();
         }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
@@ -274,7 +272,13 @@
      *        in this adapter.
      */
     public void sort(Comparator<? super T> comparator) {
-        Collections.sort(mObjects, comparator);
+        synchronized (mLock) {
+            if (mOriginalValues != null) {
+                Collections.sort(mOriginalValues, comparator);
+            } else {
+                Collections.sort(mObjects, comparator);
+            }
+        }
         if (mNotifyOnChange) notifyDataSetChanged();
     }
 
@@ -482,6 +486,7 @@
                         final String[] words = valueText.split(" ");
                         final int wordCount = words.length;
 
+                        // Start at index 0, in case valueText starts with space(s)
                         for (int k = 0; k < wordCount; k++) {
                             if (words[k].startsWith(prefixString)) {
                                 newValues.add(value);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4d8d21f..707b92d 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
@@ -36,8 +38,6 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
-import com.android.internal.R;
-
 
 /**
  * <p>An editable text view that shows completion suggestions automatically
@@ -113,6 +113,7 @@
 
     private Validator mValidator = null;
 
+    // Set to true when text is set directly and no filtering shall be performed
     private boolean mBlockCompletion;
 
     private PassThroughClickListener mPassThroughClickListener;
@@ -721,6 +722,10 @@
             return;
         }
 
+        updateList();
+    }
+
+    private void updateList() {
         // the drop down is shown only when a minimum number of characters
         // was typed in the text view
         if (enoughToFilter()) {
@@ -840,7 +845,7 @@
 
             mBlockCompletion = true;
             replaceText(convertSelectionToString(selectedItem));
-            mBlockCompletion = false;            
+            mBlockCompletion = false;
 
             if (mItemClickListener != null) {
                 final ListPopupWindow list = mPopup;
@@ -903,10 +908,10 @@
 
     /** {@inheritDoc} */
     public void onFilterComplete(int count) {
-        updateDropDownForFilter(count);
+        updateDropDownForFilter(count, true);
     }
 
-    private void updateDropDownForFilter(int count) {
+    private void updateDropDownForFilter(int count, boolean forceShow) {
         // Not attached to window, don't update drop-down
         if (getWindowVisibility() == View.GONE) return;
 
@@ -919,7 +924,7 @@
 
         final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
         if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
-            if (hasFocus() && hasWindowFocus()) {
+            if (hasFocus() && hasWindowFocus() && (forceShow || isPopupShowing())) {
                 showDropDown();
             }
         } else if (!dropDownAlwaysVisible) {
@@ -1182,12 +1187,14 @@
                 // If the popup is not showing already, showing it will cause
                 // the list of data set observers attached to the adapter to
                 // change. We can't do it from here, because we are in the middle
-                // of iterating throught he list of observers.
+                // of iterating through the list of observers.
                 post(new Runnable() {
                     public void run() {
                         final ListAdapter adapter = mAdapter;
                         if (adapter != null) {
-                            updateDropDownForFilter(adapter.getCount());
+                            // This will re-layout, thus resetting mDataChanged, so that the
+                            // listView click listener stays responsive
+                            updateDropDownForFilter(adapter.getCount(), false);
                         }
                     }
                 });
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 2c53005..af5de8a 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -129,27 +129,30 @@
     }
 
     public DatePicker(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+        this(context, attrs, R.attr.datePickerStyle);
     }
 
     public DatePicker(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
+        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
+                defStyle, 0);
         boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
                 DEFAULT_SPINNERS_SHOWN);
         boolean calendarViewShown = attributesArray.getBoolean(
                 R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
-        int startYear = attributesArray
-                .getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+        int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
+                DEFAULT_START_YEAR);
         int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
         String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
         String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
+        int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_layout,
+                R.layout.date_picker);
         attributesArray.recycle();
 
         LayoutInflater inflater = (LayoutInflater) context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(R.layout.date_picker, this, true);
+        inflater.inflate(layoutResourceId, this, true);
 
         OnValueChangedListener onChangeListener = new OnValueChangedListener() {
             public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index dfa94c7..200c870 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -476,6 +476,10 @@
         }
     }
 
+    public void onSectionsChanged() {
+        mListAdapter = null;
+    }
+
     private void scrollTo(float position) {
         int count = mList.getCount();
         mScrollCompleted = false;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index f6b1dbc..db22a0c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -511,8 +511,10 @@
 
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
-                final float x = ev.getX();
-                mIsBeingDragged = true;
+                mIsBeingDragged = getChildCount() != 0;
+                if (!mIsBeingDragged) {
+                    return false;
+                }
 
                 /*
                  * If being flinged and user touches, stop the fling. isFinished
@@ -523,7 +525,7 @@
                 }
 
                 // Remember where the motion event started
-                mLastMotionX = x;
+                mLastMotionX = ev.getX();
                 mActivePointerId = ev.getPointerId(0);
                 break;
             }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 63dbfbf..ba1c0ec 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -62,8 +62,6 @@
  * <p>
  * For an example of using this widget, see {@link android.widget.TimePicker}.
  * </p>
- *
- * @attr ref android.R.styleable#NumberPicker_solidColor
  */
 @Widget
 public class NumberPicker extends LinearLayout {
@@ -325,6 +323,11 @@
     private final int mSolidColor;
 
     /**
+     * Flag indicating if this widget supports flinging.
+     */
+    private final boolean mFlingable;
+
+    /**
      * Reusable {@link Rect} instance.
      */
     private final Rect mTempRect = new Rect();
@@ -427,9 +430,8 @@
         // process style attributes
         TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                 R.styleable.NumberPicker, defStyle, 0);
-        int orientation = attributesArray.getInt(R.styleable.NumberPicker_orientation, VERTICAL);
-        setOrientation(orientation);
         mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);
+        mFlingable = attributesArray.getBoolean(R.styleable.NumberPicker_flingable, true);
         attributesArray.recycle();
 
         // By default Linearlayout that we extend is not drawn. This is
@@ -563,7 +565,7 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (!isEnabled()) {
+        if (!isEnabled() || !mFlingable) {
             return false;
         }
         switch (event.getActionMasked()) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8f25311..482ce56 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -59,6 +59,12 @@
     private static final String LOG_TAG = "RemoteViews";
     
     /**
+     * The intent extra that contains the appWidgetId.
+     * @hide
+     */
+    static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
+
+    /**
      * The package name of the package containing the layout 
      * resource. (Added to the parcel)
      */
@@ -1271,11 +1277,15 @@
     /**
      * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
      *
+     * @param appWidgetId The id of the app widget which contains the specified view
      * @param viewId The id of the view whose text should change
      * @param intent The intent of the service which will be
      *            providing data to the RemoteViewsAdapter
      */
-    public void setRemoteAdapter(int viewId, Intent intent) {
+    public void setRemoteAdapter(int appWidgetId, int viewId, Intent intent) {
+        // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
+        // RemoteViewsService
+        intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, appWidgetId);
         setIntent(viewId, "setRemoteViewsAdapter", intent);
     }
 
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index ab69725..f329a3e 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -22,20 +22,21 @@
 import java.util.LinkedList;
 import java.util.Map;
 
-import android.content.ComponentName;
+import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.Intent;
-import android.content.ServiceConnection;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Message;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.View.MeasureSpec;
 
+import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
 
 /**
@@ -43,11 +44,22 @@
  * to be later inflated as child views.
  */
 /** @hide */
-public class RemoteViewsAdapter extends BaseAdapter {
+public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback {
     private static final String TAG = "RemoteViewsAdapter";
 
-    private Context mContext;
-    private Intent mIntent;
+    // The max number of items in the cache
+    private static final int sDefaultCacheSize = 36;
+    // The delay (in millis) to wait until attempting to unbind from a service after a request.
+    // This ensures that we don't stay continually bound to the service and that it can be destroyed
+    // if we need the memory elsewhere in the system.
+    private static final int sUnbindServiceDelay = 5000;
+    // Type defs for controlling different messages across the main and worker message queues
+    private static final int sDefaultMessageType = 0;
+    private static final int sUnbindServiceMessageType = 1;
+
+    private final Context mContext;
+    private final Intent mIntent;
+    private final int mAppWidgetId;
     private LayoutInflater mLayoutInflater;
     private RemoteViewsAdapterServiceConnection mServiceConnection;
     private WeakReference<RemoteAdapterConnectionCallback> mCallback;
@@ -79,7 +91,8 @@
      * garbage collected, and would cause us to leak activities due to the caching mechanism for
      * FrameLayouts in the adapter).
      */
-    private static class RemoteViewsAdapterServiceConnection implements ServiceConnection {
+    private static class RemoteViewsAdapterServiceConnection extends
+            IRemoteViewsAdapterConnection.Stub {
         private boolean mConnected;
         private WeakReference<RemoteViewsAdapter> mAdapter;
         private IRemoteViewsFactory mRemoteViewsFactory;
@@ -88,8 +101,7 @@
             mAdapter = new WeakReference<RemoteViewsAdapter>(adapter);
         }
 
-        public void onServiceConnected(ComponentName name,
-                IBinder service) {
+        public void onServiceConnected(IBinder service) {
             mRemoteViewsFactory = IRemoteViewsFactory.Stub.asInterface(service);
             mConnected = true;
 
@@ -137,7 +149,7 @@
             });
         }
 
-        public void onServiceDisconnected(ComponentName name) {
+        public void onServiceDisconnected() {
             mConnected = false;
             mRemoteViewsFactory = null;
 
@@ -145,8 +157,9 @@
             if (adapter == null) return;
             
             // Clear the main/worker queues
-            adapter.mMainQueue.removeMessages(0);
-            adapter.mWorkerQueue.removeMessages(0);
+            adapter.mMainQueue.removeMessages(sUnbindServiceMessageType);
+            adapter.mMainQueue.removeMessages(sDefaultMessageType);
+            adapter.mWorkerQueue.removeMessages(sDefaultMessageType);
 
             final RemoteAdapterConnectionCallback callback = adapter.mCallback.get();
             if (callback != null) {
@@ -574,20 +587,26 @@
     public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectionCallback callback) {
         mContext = context;
         mIntent = intent;
+        mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
         mLayoutInflater = LayoutInflater.from(context);
         if (mIntent == null) {
             throw new IllegalArgumentException("Non-null Intent must be specified.");
         }
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
 
-        // initialize the worker thread
+        // Strip the previously injected app widget id from service intent
+        if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
+            intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
+        }
+
+        // Initialize the worker thread
         mWorkerThread = new HandlerThread("RemoteViewsCache-loader");
         mWorkerThread.start();
         mWorkerQueue = new Handler(mWorkerThread.getLooper());
-        mMainQueue = new Handler(Looper.myLooper());
+        mMainQueue = new Handler(Looper.myLooper(), this);
 
-        // initialize the cache and the service connection on startup
-        mCache = new FixedSizeRemoteViewsCache(50);
+        // Initialize the cache and the service connection on startup
+        mCache = new FixedSizeRemoteViewsCache(sDefaultCacheSize);
         mCallback = new WeakReference<RemoteAdapterConnectionCallback>(callback);
         mServiceConnection = new RemoteViewsAdapterServiceConnection(this);
         requestBindService();
@@ -687,6 +706,7 @@
                     @Override
                     public void run() {
                         mRequestedViews.notifyOnRemoteViewsLoaded(position, rv, typeId);
+                        enqueueDeferredUnbindServiceMessage();
                     }
                 });
             }
@@ -879,10 +899,36 @@
         super.notifyDataSetChanged();
     }
 
+    @Override
+    public boolean handleMessage(Message msg) {
+        boolean result = false;
+        switch (msg.what) {
+        case sUnbindServiceMessageType:
+            final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
+            if (mServiceConnection.isConnected()) {
+                mgr.unbindRemoteViewsService(mAppWidgetId, mIntent);
+            }
+            result = true;
+            break;
+        default:
+            break;
+        }
+        return result;
+    }
+
+    private void enqueueDeferredUnbindServiceMessage() {
+        /* Temporarily disable delayed service unbinding
+        // Remove any existing deferred-unbind messages
+        mMainQueue.removeMessages(sUnbindServiceMessageType);
+        mMainQueue.sendEmptyMessageDelayed(sUnbindServiceMessageType, sUnbindServiceDelay);
+        */
+    }
+
     private boolean requestBindService() {
-        // try binding the service (which will start it if it's not already running)
+        // Try binding the service (which will start it if it's not already running)
         if (!mServiceConnection.isConnected()) {
-            mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+            final AppWidgetManager mgr = AppWidgetManager.getInstance(mContext);
+            mgr.bindRemoteViewsService(mAppWidgetId, mIntent, mServiceConnection.asBinder());
         }
 
         return mServiceConnection.isConnected();
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 8558c70..ce6da72 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -521,8 +521,10 @@
 
         switch (action & MotionEvent.ACTION_MASK) {
             case MotionEvent.ACTION_DOWN: {
-                final float y = ev.getY();
-                mIsBeingDragged = true;
+                mIsBeingDragged = getChildCount() != 0;
+                if (!mIsBeingDragged) {
+                    return false;
+                }
 
                 /*
                  * If being flinged and user touches, stop the fling. isFinished
@@ -537,7 +539,7 @@
                 }
 
                 // Remember where the motion event started
-                mLastMotionY = y;
+                mLastMotionY = ev.getY();
                 mActivePointerId = ev.getPointerId(0);
                 break;
             }
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 0baddcb..e38a69f 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -23,13 +23,14 @@
 import android.content.DialogInterface.OnClickListener;
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 
 
 /**
@@ -69,6 +70,8 @@
 
     private int mGravity;
 
+    private LayoutObserver mLayoutObserver;
+
     /**
      * Construct a new spinner with the given context's theme.
      *
@@ -169,6 +172,7 @@
                     com.android.internal.R.styleable.Spinner_dropDownHorizontalOffset, 0));
 
             mPopup = popup;
+            mLayoutObserver = new LayoutObserver();
             break;
         }
         }
@@ -421,6 +425,11 @@
             handled = true;
 
             if (!mPopup.isShowing()) {
+                if (mLayoutObserver != null) {
+                    final ViewTreeObserver vto = getViewTreeObserver();
+                    vto.addOnGlobalLayoutListener(mLayoutObserver);
+                    vto.addOnScrollChangedListener(mLayoutObserver);
+                }
                 mPopup.show();
             }
         }
@@ -668,6 +677,7 @@
             super.show();
             getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
             setSelection(Spinner.this.getSelectedItemPosition());
+            setOnDismissListener(mLayoutObserver);
         }
 
         @Override
@@ -718,4 +728,28 @@
                     ViewGroup.LayoutParams.WRAP_CONTENT);
         }
     }
+
+    private class LayoutObserver implements ViewTreeObserver.OnGlobalLayoutListener,
+            ViewTreeObserver.OnScrollChangedListener, PopupWindow.OnDismissListener {
+        @Override
+        public void onScrollChanged() {
+            if (mPopup != null && mPopup.isShowing()) {
+                mPopup.show();
+            }
+        }
+
+        @Override
+        public void onGlobalLayout() {
+            if (mPopup != null && mPopup.isShowing()) {
+                mPopup.show();
+            }
+        }
+
+        @Override
+        public void onDismiss() {
+            ViewTreeObserver vto = getViewTreeObserver();
+            vto.removeGlobalOnLayoutListener(mLayoutObserver);
+            vto.removeOnScrollChangedListener(mLayoutObserver);
+        }
+    }
 }
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 1ebe622..2cfc016 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -78,15 +78,15 @@
     // URL color
     private ColorStateList mUrlColor;
 
-    // Cached column indexes, updated when the cursor changes.
-    private int mText1Col;
-    private int mText2Col;
-    private int mText2UrlCol;
-    private int mIconName1Col;
-    private int mIconName2Col;
-    private int mFlagsCol;
+    static final int INVALID_INDEX = -1;
 
-    static final int NONE = -1;
+    // Cached column indexes, updated when the cursor changes.
+    private int mText1Col = INVALID_INDEX;
+    private int mText2Col = INVALID_INDEX;
+    private int mText2UrlCol = INVALID_INDEX;
+    private int mIconName1Col = INVALID_INDEX;
+    private int mIconName2Col = INVALID_INDEX;
+    private int mFlagsCol = INVALID_INDEX;
 
     private final Runnable mStartSpinnerRunnable;
     private final Runnable mStopSpinnerRunnable;
@@ -308,7 +308,7 @@
         ChildViewCache views = (ChildViewCache) view.getTag();
 
         int flags = 0;
-        if (mFlagsCol != -1) {
+        if (mFlagsCol != INVALID_INDEX) {
             flags = cursor.getInt(mFlagsCol);
         }
         if (views.mText1 != null) {
@@ -391,7 +391,7 @@
     }
 
     private Drawable getIcon1(Cursor cursor) {
-        if (mIconName1Col < 0) {
+        if (mIconName1Col == INVALID_INDEX) {
             return null;
         }
         String value = cursor.getString(mIconName1Col);
@@ -403,7 +403,7 @@
     }
 
     private Drawable getIcon2(Cursor cursor) {
-        if (mIconName2Col < 0) {
+        if (mIconName2Col == INVALID_INDEX) {
             return null;
         }
         String value = cursor.getString(mIconName2Col);
@@ -687,7 +687,7 @@
     }
 
     private static String getStringOrNull(Cursor cursor, int col) {
-        if (col == NONE) {
+        if (col == INVALID_INDEX) {
             return null;
         }
         try {
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 8f3442e..26fbbbd 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -20,6 +20,7 @@
 
 import android.annotation.Widget;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
@@ -31,50 +32,55 @@
 import java.util.Calendar;
 
 /**
- * A view for selecting the time of day, in either 24 hour or AM/PM mode.
- *
- * The hour, each minute digit, and AM/PM (if applicable) can be conrolled by
- * vertical spinners.
- *
- * The hour can be entered by keyboard input.  Entering in two digit hours
- * can be accomplished by hitting two digits within a timeout of about a
- * second (e.g. '1' then '2' to select 12).
- *
- * The minutes can be entered by entering single digits.
- *
- * Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick.
- *
- * For a dialog using this view, see {@link android.app.TimePickerDialog}.
- *
- * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
- * tutorial</a>.</p>
+ * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
+ * hour, each minute digit, and AM/PM (if applicable) can be conrolled by
+ * vertical spinners. The hour can be entered by keyboard input. Entering in two
+ * digit hours can be accomplished by hitting two digits within a timeout of
+ * about a second (e.g. '1' then '2' to select 12). The minutes can be entered
+ * by entering single digits. Under AM/PM mode, the user can hit 'a', 'A", 'p'
+ * or 'P' to pick. For a dialog using this view, see
+ * {@link android.app.TimePickerDialog}.
+ *<p>
+ * See the <a href="{@docRoot}
+ * resources/tutorials/views/hello-timepicker.html">Time Picker tutorial</a>.
+ * </p>
  */
 @Widget
 public class TimePicker extends FrameLayout {
 
     private static final boolean DEFAULT_ENABLED_STATE = true;
 
+    private static final int HOURS_IN_HALF_DAY = 12;
+
     /**
-     * A no-op callback used in the constructor to avoid null checks
-     * later in the code.
+     * A no-op callback used in the constructor to avoid null checks later in
+     * the code.
      */
     private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
         public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
         }
     };
-    
+
     // state
-    private int mCurrentHour = 0; // 0-23
-    private int mCurrentMinute = 0; // 0-59
-    private Boolean mIs24HourView = false;
+    private boolean mIs24HourView;
+
     private boolean mIsAm;
 
     // ui components
     private final NumberPicker mHourSpinner;
+
     private final NumberPicker mMinuteSpinner;
+
     private final NumberPicker mAmPmSpinner;
+
     private final TextView mDivider;
 
+    // Note that the legacy implementation of the TimePicker is
+    // using a button for toggling between AM/PM while the new
+    // version uses a NumberPicker spinner. Therefore the code
+    // accommodates these two cases to be backwards compatible.
+    private final Button mAmPmButton;
+
     private final String[] mAmPmStrings;
 
     private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
@@ -98,45 +104,51 @@
     public TimePicker(Context context) {
         this(context, null);
     }
-    
+
     public TimePicker(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+        this(context, attrs, R.attr.timePickerStyle);
     }
 
     public TimePicker(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        LayoutInflater inflater =
-                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(R.layout.time_picker,
-            this, // we are the parent
-            true);
+        // process style attributes
+        TypedArray attributesArray = context.obtainStyledAttributes(
+                attrs, R.styleable.TimePicker, defStyle, 0);
+        int layoutResourceId = attributesArray.getResourceId(
+                R.styleable.TimePicker_layout, R.layout.time_picker);
+        attributesArray.recycle();
+
+        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(layoutResourceId, this, true);
 
         // hour
         mHourSpinner = (NumberPicker) findViewById(R.id.hour);
         mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                mCurrentHour = newVal;
-                if (!mIs24HourView) {
-                    // adjust from [1-12] to [0-11] internally, with the times
-                    // written "12:xx" being the start of the half-day
-                    if (mCurrentHour == 12) {
-                        mCurrentHour = 0;
-                    }
-                    if (!mIsAm) {
-                        // PM means 12 hours later than nominal
-                        mCurrentHour += 12;
+                if (!is24HourView()) {
+                    int minValue = mHourSpinner.getMinValue();
+                    int maxValue = mHourSpinner.getMaxValue();
+                    // toggle AM/PM if the spinner has wrapped and not in 24
+                    // format
+                    if ((oldVal == maxValue && newVal == minValue)
+                            || (oldVal == minValue && newVal == maxValue)) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
                     }
                 }
                 onTimeChanged();
             }
         });
 
-        // divider
+        // divider (only for the new widget style)
         mDivider = (TextView) findViewById(R.id.divider);
-        mDivider.setText(R.string.time_picker_separator);
+        if (mDivider != null) {
+            mDivider.setText(R.string.time_picker_separator);
+        }
 
-        // digits of minute
+        // minute
         mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
         mMinuteSpinner.setMinValue(0);
         mMinuteSpinner.setMaxValue(59);
@@ -144,28 +156,25 @@
         mMinuteSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                mCurrentMinute = newVal;
-                onTimeChanged();
-            }
-        });
-
-        // am/pm
-        mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
-        mAmPmSpinner.setOnValueChangedListener(new OnValueChangedListener() {
-            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
-                picker.requestFocus();
-                if (mIsAm) {
-                    // Currently AM switching to PM
-                    if (mCurrentHour < 12) {
-                        mCurrentHour += 12;
+                int minValue = mMinuteSpinner.getMinValue();
+                int maxValue = mMinuteSpinner.getMaxValue();
+                if (oldVal == maxValue && newVal == minValue) {
+                    int currentHour = mHourSpinner.getValue();
+                    // toggle AM/PM if the spinner is about to wrap
+                    if (!is24HourView() && currentHour == mHourSpinner.getMaxValue()) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
                     }
-                } else {
-                    // Currently PM switching to AM
-                    if (mCurrentHour >= 12) {
-                        mCurrentHour -= 12;
+                    mHourSpinner.setValue(currentHour + 1);
+                } else if (oldVal == minValue && newVal == maxValue) {
+                    int currentHour = mHourSpinner.getValue();
+                    // toggle AM/PM if the spinner is about to wrap
+                    if (!is24HourView() && currentHour == mHourSpinner.getMinValue()) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
                     }
+                    mHourSpinner.setValue(currentHour - 1);
                 }
-                mIsAm = !mIsAm;
                 onTimeChanged();
             }
         });
@@ -173,17 +182,44 @@
         /* Get the localized am/pm strings and use them in the spinner */
         mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
 
-        // now that the hour/minute picker objects have been initialized, set
-        // the hour range properly based on the 12/24 hour display mode.
-        configurePickerRanges();
+        // am/pm
+        View amPmView = findViewById(R.id.amPm);
+        if (amPmView instanceof Button) {
+            mAmPmSpinner = null;
+            mAmPmButton = (Button) amPmView;
+            mAmPmButton.setOnClickListener(new OnClickListener() {
+                public void onClick(View button) {
+                    button.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                }
+            });
+        } else {
+            mAmPmButton = null;
+            mAmPmSpinner = (NumberPicker) amPmView;
+            mAmPmSpinner.setMinValue(0);
+            mAmPmSpinner.setMaxValue(1);
+            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+            mAmPmSpinner.setOnValueChangedListener(new OnValueChangedListener() {
+                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    picker.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                }
+            });
+        }
+
+        // update controls to initial state
+        updateHourControl();
+        updateAmPmControl();
 
         // initialize to current time
-        Calendar cal = Calendar.getInstance();
+        Calendar calendar = Calendar.getInstance();
         setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
 
-        // by default we're not in 24 hour mode
-        setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
-        setCurrentMinute(cal.get(Calendar.MINUTE));
+        // set to current time
+        setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
+        setCurrentMinute(calendar.get(Calendar.MINUTE));
 
         if (!isEnabled()) {
             setEnabled(false);
@@ -197,9 +233,15 @@
         }
         super.setEnabled(enabled);
         mMinuteSpinner.setEnabled(enabled);
-        mDivider.setEnabled(enabled);
+        if (mDivider != null) {
+            mDivider.setEnabled(enabled);
+        }
         mHourSpinner.setEnabled(enabled);
-        mAmPmSpinner.setEnabled(enabled);
+        if (mAmPmSpinner != null) {
+            mAmPmSpinner.setEnabled(enabled);
+        } else {
+            mAmPmButton.setEnabled(enabled);
+        }
         mIsEnabled = enabled;
     }
 
@@ -214,6 +256,7 @@
     private static class SavedState extends BaseSavedState {
 
         private final int mHour;
+
         private final int mMinute;
 
         private SavedState(Parcelable superState, int hour, int minute) {
@@ -221,7 +264,7 @@
             mHour = hour;
             mMinute = minute;
         }
-        
+
         private SavedState(Parcel in) {
             super(in);
             mHour = in.readInt();
@@ -244,8 +287,7 @@
         }
 
         @SuppressWarnings("unused")
-        public static final Parcelable.Creator<SavedState> CREATOR
-                = new Creator<SavedState>() {
+        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
             public SavedState createFromParcel(Parcel in) {
                 return new SavedState(in);
             }
@@ -259,7 +301,7 @@
     @Override
     protected Parcelable onSaveInstanceState() {
         Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, mCurrentHour, mCurrentMinute);
+        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
     }
 
     @Override
@@ -272,6 +314,7 @@
 
     /**
      * Set the callback that indicates the time has been adjusted by the user.
+     *
      * @param onTimeChangedListener the callback, should not be null.
      */
     public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
@@ -279,30 +322,58 @@
     }
 
     /**
-     * @return The current hour (0-23).
+     * @return The current hour in the range (0-23).
      */
     public Integer getCurrentHour() {
-        return mCurrentHour;
+        int currentHour = mHourSpinner.getValue();
+        if (is24HourView() || mIsAm) {
+            return currentHour;
+        } else {
+            return (currentHour == HOURS_IN_HALF_DAY) ? 0 : currentHour + HOURS_IN_HALF_DAY;
+        }
     }
 
     /**
      * Set the current hour.
      */
     public void setCurrentHour(Integer currentHour) {
-        this.mCurrentHour = currentHour;
-        updateHourDisplay();
+        // why was Integer used in the first place?
+        if (currentHour == null || currentHour == getCurrentHour()) {
+            return;
+        }
+        if (!is24HourView()) {
+            // convert [0,23] ordinal to wall clock display
+            if (currentHour > HOURS_IN_HALF_DAY) {
+                currentHour -= HOURS_IN_HALF_DAY;
+                mIsAm = false;
+            } else {
+                if (currentHour == 0) {
+                    currentHour = HOURS_IN_HALF_DAY;
+                }
+                mIsAm = true;
+            }
+            updateAmPmControl();
+        }
+        mHourSpinner.setValue(currentHour);
+        onTimeChanged();
     }
 
     /**
      * Set whether in 24 hour or AM/PM mode.
+     *
      * @param is24HourView True = 24 hour mode. False = AM/PM.
      */
     public void setIs24HourView(Boolean is24HourView) {
-        if (mIs24HourView != is24HourView) {
-            mIs24HourView = is24HourView;
-            configurePickerRanges();
-            updateHourDisplay();
+        if (mIs24HourView == is24HourView) {
+            return;
         }
+        mIs24HourView = is24HourView;
+        // cache the current hour since spinner range changes
+        int currentHour = getCurrentHour();
+        updateHourControl();
+        // set value after spinner range is updated
+        setCurrentHour(currentHour);
+        updateAmPmControl();
     }
 
     /**
@@ -311,20 +382,23 @@
     public boolean is24HourView() {
         return mIs24HourView;
     }
-    
+
     /**
      * @return The current minute.
      */
     public Integer getCurrentMinute() {
-        return mCurrentMinute;
+        return mMinuteSpinner.getValue();
     }
 
     /**
      * Set the current minute (0-59).
      */
     public void setCurrentMinute(Integer currentMinute) {
-        this.mCurrentMinute = currentMinute;
-        updateMinuteDisplay();
+        if (currentMinute == getCurrentMinute()) {
+            return;
+        }
+        mMinuteSpinner.setValue(currentMinute);
+        onTimeChanged();
     }
 
     @Override
@@ -332,39 +406,34 @@
         return mHourSpinner.getBaseline();
     }
 
-    /**
-     * Set the state of the spinners appropriate to the current hour.
-     */
-    private void updateHourDisplay() {
-        int currentHour = mCurrentHour;
-        if (!mIs24HourView) {
-            // convert [0,23] ordinal to wall clock display
-            if (currentHour > 12) {
-                currentHour -= 12;
-            } else if (currentHour == 0) {
-                currentHour = 12;
-            }
-        }
-        mHourSpinner.setValue(currentHour);
-        mIsAm = mCurrentHour < 12;
-        mAmPmSpinner.setValue(mIsAm ? Calendar.AM : Calendar.PM);
-        onTimeChanged();
-    }
-
-    private void configurePickerRanges() {
-        if (mIs24HourView) {
+    private void updateHourControl() {
+        if (is24HourView()) {
             mHourSpinner.setMinValue(0);
             mHourSpinner.setMaxValue(23);
             mHourSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
-            mAmPmSpinner.setVisibility(View.GONE);
         } else {
             mHourSpinner.setMinValue(1);
             mHourSpinner.setMaxValue(12);
             mHourSpinner.setFormatter(null);
-            mAmPmSpinner.setVisibility(View.VISIBLE);
-            mAmPmSpinner.setMinValue(0);
-            mAmPmSpinner.setMaxValue(1);
-            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+        }
+    }
+
+    private void updateAmPmControl() {
+        if (is24HourView()) {
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setVisibility(View.GONE);
+            } else {
+                mAmPmButton.setVisibility(View.GONE);
+            }
+        } else {
+            int index = mIsAm ? Calendar.AM : Calendar.PM;
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setValue(index);
+                mAmPmSpinner.setVisibility(View.VISIBLE);
+            } else {
+                mAmPmButton.setText(mAmPmStrings[index]);
+                mAmPmButton.setVisibility(View.VISIBLE);
+            }
         }
     }
 
@@ -373,12 +442,4 @@
             mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());
         }
     }
-
-    /**
-     * Set the state of the spinners appropriate to the current minute.
-     */
-    private void updateMinuteDisplay() {
-        mMinuteSpinner.setValue(mCurrentMinute);
-        onTimeChanged();
-    }
 }
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 29ca49a..6a7db1f0 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -67,15 +67,9 @@
      */
     public static final int LENGTH_LONG = 1;
 
-    final Handler mHandler = new Handler();    
     final Context mContext;
     final TN mTN;
     int mDuration;
-    int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-    int mX, mY;
-    float mHorizontalMargin;
-    float mVerticalMargin;
-    View mView;
     View mNextView;
 
     /**
@@ -88,7 +82,7 @@
     public Toast(Context context) {
         mContext = context;
         mTN = new TN();
-        mY = context.getResources().getDimensionPixelSize(
+        mTN.mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
     }
     
@@ -101,10 +95,9 @@
         }
 
         INotificationManager service = getService();
-
         String pkg = mContext.getPackageName();
-
         TN tn = mTN;
+        tn.mNextView = mNextView;
 
         try {
             service.enqueueToast(pkg, tn, mDuration);
@@ -167,22 +160,22 @@
      *        notification
      */
     public void setMargin(float horizontalMargin, float verticalMargin) {
-        mHorizontalMargin = horizontalMargin;
-        mVerticalMargin = verticalMargin;
+        mTN.mHorizontalMargin = horizontalMargin;
+        mTN.mVerticalMargin = verticalMargin;
     }
 
     /**
      * Return the horizontal margin.
      */
     public float getHorizontalMargin() {
-        return mHorizontalMargin;
+        return mTN.mHorizontalMargin;
     }
 
     /**
      * Return the vertical margin.
      */
     public float getVerticalMargin() {
-        return mVerticalMargin;
+        return mTN.mVerticalMargin;
     }
 
     /**
@@ -191,9 +184,9 @@
      * @see #getGravity
      */
     public void setGravity(int gravity, int xOffset, int yOffset) {
-        mGravity = gravity;
-        mX = xOffset;
-        mY = yOffset;
+        mTN.mGravity = gravity;
+        mTN.mX = xOffset;
+        mTN.mY = yOffset;
     }
 
      /**
@@ -202,21 +195,21 @@
      * @see #getGravity
      */
     public int getGravity() {
-        return mGravity;
+        return mTN.mGravity;
     }
 
     /**
      * Return the X offset in pixels to apply to the gravity's location.
      */
     public int getXOffset() {
-        return mX;
+        return mTN.mX;
     }
     
     /**
      * Return the Y offset in pixels to apply to the gravity's location.
      */
     public int getYOffset() {
-        return mY;
+        return mTN.mY;
     }
     
     /**
@@ -283,21 +276,6 @@
         tv.setText(s);
     }
 
-    private void trySendAccessibilityEvent() {
-        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
-        if (!accessibilityManager.isEnabled()) {
-            return;
-        }
-        // treat toasts as notifications since they are used to
-        // announce a transient piece of information to the user
-        AccessibilityEvent event = AccessibilityEvent.obtain(
-                AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
-        event.setClassName(getClass().getName());
-        event.setPackageName(mContext.getPackageName());
-        mView.dispatchPopulateAccessibilityEvent(event);
-        accessibilityManager.sendAccessibilityEvent(event);
-    }
-
     // =======================================================================================
     // All the gunk below is the interaction with the Notification Service, which handles
     // the proper ordering of these system-wide.
@@ -313,7 +291,7 @@
         return sService;
     }
 
-    private class TN extends ITransientNotification.Stub {
+    private static class TN extends ITransientNotification.Stub {
         final Runnable mShow = new Runnable() {
             public void run() {
                 handleShow();
@@ -327,6 +305,16 @@
         };
 
         private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+        final Handler mHandler = new Handler();    
+
+        int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+        int mX, mY;
+        float mHorizontalMargin;
+        float mVerticalMargin;
+
+       
+        View mView;
+        View mNextView;
         
         WindowManagerImpl mWM;
 
@@ -382,8 +370,7 @@
                 mParams.verticalMargin = mVerticalMargin;
                 mParams.horizontalMargin = mHorizontalMargin;
                 if (mView.getParent() != null) {
-                    if (localLOGV) Log.v(
-                            TAG, "REMOVE! " + mView + " in " + this);
+                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                     mWM.removeView(mView);
                 }
                 if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
@@ -392,6 +379,22 @@
             }
         }
 
+        private void trySendAccessibilityEvent() {
+            AccessibilityManager accessibilityManager =
+                    AccessibilityManager.getInstance(mView.getContext());
+            if (!accessibilityManager.isEnabled()) {
+                return;
+            }
+            // treat toasts as notifications since they are used to
+            // announce a transient piece of information to the user
+            AccessibilityEvent event = AccessibilityEvent.obtain(
+                    AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+            event.setClassName(getClass().getName());
+            event.setPackageName(mView.getContext().getPackageName());
+            mView.dispatchPopulateAccessibilityEvent(event);
+            accessibilityManager.sendAccessibilityEvent(event);
+        }        
+
         public void handleHide() {
             if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
             if (mView != null) {
@@ -399,12 +402,12 @@
                 // been added...  i have seen cases where we get here when
                 // the view isn't yet added, so let's try not to crash.
                 if (mView.getParent() != null) {
-                    if (localLOGV) Log.v(
-                            TAG, "REMOVE! " + mView + " in " + this);
+                    if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
                     mWM.removeView(mView);
                 }
 
                 mView = null;
+                mNextView = null;
             }
         }
     }
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 0e31fef..a8eb6fe 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -388,6 +388,7 @@
             mActionMode.finish();
         }
 
+        mUpperContextView.killMode();
         ActionMode mode = new ActionModeImpl(callback);
         if (callback.onCreateActionMode(mode, mode.getMenu())) {
             mode.invalidate();
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index a139d31..71a7a52 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -391,6 +391,7 @@
         View buttonPanel = mWindow.findViewById(R.id.buttonPanel);
         if (!hasButtons) {
             buttonPanel.setVisibility(View.GONE);
+            mWindow.setCloseOnTouchOutsideIfNotSet(true);
         }
 
         FrameLayout customPanel = null;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9ed4dd8..38ac37d 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -17,7 +17,6 @@
 package com.android.internal.app;
 
 import android.content.Intent;
-import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.util.Log;
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index e1c5564..9fbbb3d 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -29,11 +29,11 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         
-        mToast = Toast.makeText(this, "Zombie art by Jack Larson", Toast.LENGTH_SHORT);
+        mToast = Toast.makeText(this, "REZZZZZZZ...", Toast.LENGTH_SHORT);
 
         ImageView content = new ImageView(this);
         content.setImageResource(com.android.internal.R.drawable.platlogo);
-        content.setScaleType(ImageView.ScaleType.FIT_CENTER);
+        content.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
         
         setContentView(content);
     }
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 4d56745..fa0873d 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * 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.
@@ -17,8 +17,10 @@
 package com.android.internal.appwidget;
 
 import android.content.ComponentName;
+import android.content.Intent;
 import android.appwidget.AppWidgetProviderInfo;
 import com.android.internal.appwidget.IAppWidgetHost;
+import android.os.IBinder;
 import android.widget.RemoteViews;
 
 /** {@hide} */
@@ -46,6 +48,8 @@
     List<AppWidgetProviderInfo> getInstalledProviders();
     AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId);
     void bindAppWidgetId(int appWidgetId, in ComponentName provider);
+    void bindRemoteViewsService(int appWidgetId, in Intent intent, in IBinder connection);
+    void unbindRemoteViewsService(int appWidgetId, in Intent intent);
     int[] getAppWidgetIds(in ComponentName provider);
 
 }
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 31e7bab..bb0c752 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -160,10 +160,6 @@
     }
 
     public void initForMode(final ActionMode mode) {
-        if (mAnimationMode != ANIMATE_IDLE || mAnimateInOnLayout) {
-            killMode();
-        }
-
         if (mClose == null) {
             LayoutInflater inflater = LayoutInflater.from(mContext);
             mClose = inflater.inflate(R.layout.action_mode_close_item, this, false);
@@ -198,15 +194,15 @@
             return;
         }
 
-        mAnimationMode = ANIMATE_OUT;
         finishAnimation();
+        mAnimationMode = ANIMATE_OUT;
         mCurrentAnimation = makeOutAnimation();
         mCurrentAnimation.start();
     }
 
     private void finishAnimation() {
         final Animator a = mCurrentAnimation;
-        if (a != null && a.isRunning()) {
+        if (a != null) {
             mCurrentAnimation = null;
             a.end();
         }
@@ -448,7 +444,7 @@
 
     @Override
     public void onAnimationEnd(Animator animation) {
-        if (mAnimationMode != ANIMATE_IN) {
+        if (mAnimationMode == ANIMATE_OUT) {
             killMode();
         }
         mAnimationMode = ANIMATE_IDLE;
diff --git a/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl b/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl
new file mode 100644
index 0000000..7eb2aef
--- /dev/null
+++ b/core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.widget;
+
+import android.os.IBinder;
+
+/** {@hide} */
+interface IRemoteViewsAdapterConnection {
+    void onServiceConnected(IBinder service);
+    void onServiceDisconnected();
+}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f023e94..342b884 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -568,6 +568,7 @@
     char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
     char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
     char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
+    char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
     char extraOptsBuf[PROPERTY_VALUE_MAX];
     char* stackTraceFile = NULL;
     bool checkJni = false;
@@ -659,6 +660,13 @@
     opt.optionString = heapsizeOptsBuf;
     mOptions.add(opt);
 
+    strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
+    property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
+    if (heapgrowthlimitOptsBuf[20] != '\0') {
+        opt.optionString = heapgrowthlimitOptsBuf;
+        mOptions.add(opt);
+    }
+
     /*
      * Enable or disable dexopt features, such as bytecode verification and
      * calculation of register maps for precise GC.
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index c43b5ce..2445229 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -154,6 +154,16 @@
         scale_rgn(rgn, *rgn, scale);
 }
 
+static jstring Region_toString(JNIEnv* env, jobject clazz, SkRegion* region) {
+    char* str = region->toString();
+    if (str == NULL) {
+        return NULL;
+    }
+    jstring result = env->NewStringUTF(str);
+    free(str);
+    return result;
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
@@ -262,6 +272,7 @@
     { "quickReject",            "(Landroid/graphics/Region;)Z",     (void*)Region_quickRejectRgn    },
     { "scale",                  "(FLandroid/graphics/Region;)V",    (void*)Region_scale             },
     { "translate",              "(IILandroid/graphics/Region;)V",   (void*)Region_translate         },
+    { "nativeToString",         "(I)Ljava/lang/String;",            (void*)Region_toString          },
     // parceling methods
     { "nativeCreateFromParcel", "(Landroid/os/Parcel;)I",           (void*)Region_createFromParcel  },
     { "nativeWriteToParcel",    "(ILandroid/os/Parcel;)Z",          (void*)Region_writeToParcel     },
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index 9222e1a..3364703 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -38,6 +38,7 @@
 #ifdef HAVE_BLUETOOTH
 #define BLUEZ_DBUS_BASE_PATH      "/org/bluez"
 #define BLUEZ_DBUS_BASE_IFC       "org.bluez"
+#define BLUEZ_ERROR_IFC           "org.bluez.Error"
 
 // It would be nicer to retrieve this from bluez using GetDefaultAdapter,
 // but this is only possible when the adapter is up (and hcid is running).
@@ -171,6 +172,30 @@
 
 bool debug_no_encrypt();
 
+
+// Result codes from Bluez DBus calls
+#define BOND_RESULT_ERROR                      -1
+#define BOND_RESULT_SUCCESS                     0
+#define BOND_RESULT_AUTH_FAILED                 1
+#define BOND_RESULT_AUTH_REJECTED               2
+#define BOND_RESULT_AUTH_CANCELED               3
+#define BOND_RESULT_REMOTE_DEVICE_DOWN          4
+#define BOND_RESULT_DISCOVERY_IN_PROGRESS       5
+#define BOND_RESULT_AUTH_TIMEOUT                6
+#define BOND_RESULT_REPEATED_ATTEMPTS           7
+
+#define PAN_DISCONNECT_FAILED_NOT_CONNECTED  1000
+#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
+#define PAN_CONNECT_FAILED_ATTEMPT_FAILED    1002
+#define PAN_OPERATION_GENERIC_FAILURE        1003
+#define PAN_OPERATION_SUCCESS                1004
+
+#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED  5000
+#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
+#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED    5002
+#define INPUT_OPERATION_GENERIC_FAILURE        5003
+#define INPUT_OPERATION_SUCCESS                5004
+
 #endif
 } /* namespace android */
 
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index b0ba695..fd12c2d7 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -134,11 +134,11 @@
     method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
                                                "(Ljava/lang/String;[Ljava/lang/String;)V");
     method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
-                                               "(Ljava/lang/String;Z)V");
+                                               "(Ljava/lang/String;I)V");
     method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
                                                "(Ljava/lang/String;[Ljava/lang/String;)V");
     method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
-                                               "(Ljava/lang/String;Z)V");
+                                               "(Ljava/lang/String;I)V");
     method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
                                                "(Ljava/lang/String;I)V");
 
@@ -1227,16 +1227,6 @@
 
 
 #ifdef HAVE_BLUETOOTH
-//TODO: Unify result codes in a header
-#define BOND_RESULT_ERROR -1000
-#define BOND_RESULT_SUCCESS 0
-#define BOND_RESULT_AUTH_FAILED 1
-#define BOND_RESULT_AUTH_REJECTED 2
-#define BOND_RESULT_AUTH_CANCELED 3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-#define BOND_RESULT_AUTH_TIMEOUT 6
-#define BOND_RESULT_REPEATED_ATTEMPTS 7
 
 void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
     LOGV(__FUNCTION__);
@@ -1406,11 +1396,25 @@
     JNIEnv *env;
     nat->vm->GetEnv((void**)&env, nat->envVer);
 
-    bool result = JNI_TRUE;
+    jint result = INPUT_OPERATION_SUCCESS;
     if (dbus_set_error_from_message(&err, msg)) {
+        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+            result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
+            result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+            // TODO():This is flaky, need to change Bluez to add new error codes
+            if (!strcmp(err.message, "Transport endpoint is not connected")) {
+              result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
+            } else {
+              result = INPUT_OPERATION_GENERIC_FAILURE;
+            }
+        } else {
+            result = INPUT_OPERATION_GENERIC_FAILURE;
+        }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
     }
+
     LOGV("... Device Path = %s, result = %d", path, result);
     jstring jPath = env->NewStringUTF(path);
     env->CallVoidMethod(nat->me,
@@ -1431,11 +1435,25 @@
     JNIEnv *env;
     nat->vm->GetEnv((void**)&env, nat->envVer);
 
-    bool result = JNI_TRUE;
+    jint result = PAN_OPERATION_SUCCESS;
     if (dbus_set_error_from_message(&err, msg)) {
+        if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+            result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
+        } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+            // TODO():This is flaky, need to change Bluez to add new error codes
+            if (!strcmp(err.message, "Device already connected")) {
+                result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
+            } else if (!strcmp(err.message, "Device not connected")) {
+                result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
+            } else {
+                result = PAN_OPERATION_GENERIC_FAILURE;
+            }
+        } else {
+            result = PAN_OPERATION_GENERIC_FAILURE;
+        }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = JNI_FALSE;
     }
+
     LOGV("... Pan Device Path = %s, result = %d", path, result);
     jstring jPath = env->NewStringUTF(path);
     env->CallVoidMethod(nat->me,
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 8c30987..e4af33f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -61,6 +61,7 @@
 
 struct so_t {
     jfieldID surfaceControl;
+    jfieldID surfaceGenerationId;
     jfieldID surface;
     jfieldID saveCount;
     jfieldID canvas;
@@ -189,6 +190,12 @@
         p->decStrong(clazz);
     }
     env->SetIntField(clazz, so.surface, (int)surface.get());
+    // This test is conservative and it would be better to compare the ISurfaces
+    if (p && p != surface.get()) {
+        jint generationId = env->GetIntField(clazz, so.surfaceGenerationId);
+        generationId++;
+        env->SetIntField(clazz, so.surfaceGenerationId, generationId);
+    }
 }
 
 // ----------------------------------------------------------------------------
@@ -785,6 +792,7 @@
 void nativeClassInit(JNIEnv* env, jclass clazz)
 {
     so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
+    so.surfaceGenerationId = env->GetFieldID(clazz, "mSurfaceGenerationId", "I");
     so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I");
     so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I");
     so.canvas    = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 41c911a..9b890fa 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1210,6 +1210,13 @@
         android:description="@string/permdesc_backup"
         android:protectionLevel="signatureOrSystem" />
 
+    <!-- Must be required by a {@link android.widget.RemoteViewsService},
+         to ensure that only the system can bind to it. -->
+    <permission android:name="android.permission.BIND_REMOTEVIEWS"
+        android:label="@string/permlab_bindRemoteViews"
+        android:description="@string/permdesc_bindRemoteViews"
+        android:protectionLevel="signatureOrSystem" />
+
     <!-- Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
          picks an AppWidget to go into a particular host, thereby giving that
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
deleted file mode 100644
index 3ecaa9d..0000000
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
deleted file mode 100644
index 40009af..0000000
--- a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
deleted file mode 100644
index c369e6f..0000000
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
deleted file mode 100644
index a4df2bf..0000000
--- a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_focused_holo_light.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index e5af356..67e6ac3 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
index 4691edf..f2b846a 100644
--- a/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_dark.xml
@@ -14,6 +14,5 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_dark" />
     <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_dark" />
 </selector>
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
index 5c52ff4..34afa71 100644
--- a/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
+++ b/core/res/res/drawable/ic_menu_moreoverflow_holo_light.xml
@@ -14,6 +14,5 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_focused="true" android:drawable="@drawable/ic_menu_moreoverflow_focused_holo_light" />
     <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_light" />
 </selector>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
index 4f5beff..9779074 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_glogin_unlock.xml
@@ -100,6 +100,16 @@
                 android:text="@android:string/lockscreen_glogin_submit_button"
                 />
 
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_below="@id/ok"
+                android:layout_marginTop="50dip"
+                android:text="@android:string/lockscreen_glogin_account_recovery_hint"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center_horizontal"
+                />
+
         </RelativeLayout>
     </ScrollView>
 
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index e9663b1..1649466 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -40,10 +40,10 @@
         <!-- Month -->
         <NumberPicker
             android:id="@+id/month"
-            android:layout_width="48dip"
+            android:layout_width="80dip"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="22dip"
-            android:layout_marginRight="22dip"
+            android:layout_marginLeft="1dip"
+            android:layout_marginRight="1dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -51,10 +51,10 @@
         <!-- Day -->
         <NumberPicker
             android:id="@+id/day"
-            android:layout_width="48dip"
+            android:layout_width="80dip"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="22dip"
-            android:layout_marginRight="22dip"
+            android:layout_marginLeft="1dip"
+            android:layout_marginRight="1dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -62,10 +62,10 @@
         <!-- Year -->
         <NumberPicker
             android:id="@+id/year"
-            android:layout_width="48dip"
+            android:layout_width="95dip"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="22dip"
-            android:layout_marginRight="22dip"
+            android:layout_marginLeft="1dip"
+            android:layout_marginRight="1dip"
             android:focusable="true"
             android:focusableInTouchMode="true"
             />
@@ -81,6 +81,7 @@
         android:layout_weight="1"
         android:focusable="true"
         android:focusableInTouchMode="true"
+        android:visibility="gone"
         />
 
 </LinearLayout>
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_holo.xml
new file mode 100644
index 0000000..026cbfb
--- /dev/null
+++ b/core/res/res/layout/date_picker_holo.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Layout of date picker-->
+
+<!-- Warning: everything within the "pickers" layout is removed and re-ordered
+     depending on the date format selected by the user.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:layout_gravity="center_horizontal"
+    android:orientation="horizontal"
+    android:gravity="center">
+
+    <LinearLayout android:id="@+id/pickers"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginRight="22dip"
+        android:layout_weight="1"
+        android:orientation="horizontal"
+        android:gravity="center">
+
+        <!-- Month -->
+        <NumberPicker
+            android:id="@+id/month"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="22dip"
+            android:layout_marginRight="22dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+        <!-- Day -->
+        <NumberPicker
+            android:id="@+id/day"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="22dip"
+            android:layout_marginRight="22dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+        <!-- Year -->
+        <NumberPicker
+            android:id="@+id/year"
+            android:layout_width="48dip"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="22dip"
+            android:layout_marginRight="22dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+    </LinearLayout>
+
+    <!-- calendar view -->
+    <CalendarView
+        android:id="@+id/calendar_view"
+        android:layout_width="245dip"
+        android:layout_height="280dip"
+        android:layout_marginLeft="22dip"
+        android:layout_weight="1"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+</LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index 382b2f6..df46db4 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -28,42 +28,33 @@
     <!-- hour -->
     <NumberPicker
         android:id="@+id/hour"
-        android:layout_width="48dip"
+        android:layout_width="70dip"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="22dip"
-        android:layout_marginRight="20dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
 
-    <!-- divider -->
-    <TextView
-        android:id="@+id/divider"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        />
-
     <!-- minute -->
     <NumberPicker
         android:id="@+id/minute"
-        android:layout_width="48dip"
+        android:layout_width="70dip"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="20dip"
-        android:layout_marginRight="22dip"
+        android:layout_marginLeft="5dip"
         android:focusable="true"
         android:focusableInTouchMode="true"
         />
 
     <!-- AM / PM -->
-    <NumberPicker
+    <Button
         android:id="@+id/amPm"
-        android:layout_width="48dip"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginLeft="22dip"
-        android:layout_marginRight="22dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
+        android:layout_marginTop="43dip"
+        android:layout_marginLeft="5dip"
+        android:paddingLeft="20dip"
+        android:paddingRight="20dip"
+        style="?android:attr/textAppearanceLargeInverse"
+        android:textColor="@android:color/primary_text_light_nodisable"
         />
 
 </LinearLayout>
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
new file mode 100644
index 0000000..ca6fe2d
--- /dev/null
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- Layout of time picker -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_gravity="center_horizontal"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <!-- hour -->
+    <NumberPicker
+        android:id="@+id/hour"
+        android:layout_width="48dip"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="22dip"
+        android:layout_marginRight="20dip"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+    <!-- divider -->
+    <TextView
+        android:id="@+id/divider"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        />
+
+    <!-- minute -->
+    <NumberPicker
+        android:id="@+id/minute"
+        android:layout_width="48dip"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="22dip"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+    <!-- AM / PM -->
+    <NumberPicker
+        android:id="@+id/amPm"
+        android:layout_width="48dip"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="22dip"
+        android:layout_marginRight="22dip"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+</LinearLayout>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 080d66d..8a506a3 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"تعيين الخادم الوكيل العمومي للجهاز لكي يتم استخدامه أثناء تمكين السياسة. يعين مشرف الجهاز الأول فقط الخادم الوكيل العمومي الفعال."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"تعيين انتهاء صلاحية كلمة المرور"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"التحكم في الوقت المستغرق قبل الحاجة إلى تغيير كلمة مرور شاشة التوقف"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"الرئيسية"</item>
     <item msgid="869923650527136615">"الجوال"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"تم توصيل تصحيح أخطاء USB"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"اختيار تعطيل تصحيح أخطاء USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"تحديد طريقة الإرسال"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d1176b8..2736269 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Задаване на глобалния прокси сървър, който да се използва, когато правилото е активирано. Само първият администратор на устройството задава действителния глобален прокси сървър."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Срок на валидност на паролата"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролирайте след колко време трябва да се променя паролата при заключване на екрана"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Домашен"</item>
     <item msgid="869923650527136615">"Мобилен"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняването на грешки през USB е свързано"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Изберете, за да деактивирате отстраняването на грешки през USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Избиране на метод на въвеждане"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index e352fc0..ba93303 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Defineix el servidor intermediari global del dispositiu que cal utilitzar mentre la política estigui activada. Només el primer administrador del dispositiu pot definir el servidor intermediari global efectiu."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Defineix la caducitat de la contrasenya"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controla quant de temps abans de la pantalla de bloqueig cal canviar la contrasenya"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Casa"</item>
     <item msgid="869923650527136615">"Mòbil"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració d\'USB connectada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccioneu-ho per desactivar la depuració d\'USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Selecció del mètode d\'entrada"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 441ad01..7495a66 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globální proxy server, který se bude používat, když jsou zásady aktivní. Aktuální globální proxy server nastavuje pouze první správce zařízení."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavit konec platnosti hesla"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládání doby, po jejímž uplynutí je nutné změnit heslo pro odemknutí obrazovky"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Domů"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, chcete-li zakázat ladění USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Výběr metody zadávání dat"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0242ee9..0c9aefd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angiv enhedens globale proxy, der skal bruges, mens politikken er aktiveret. Kun den første enhedsadministrator angiver den effektive globale proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Indstil udløb for adgangskode"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontroller, hvor lang tid der skal gå, før adgangskoden til skærmlåsen skal ændres."</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Hjem"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Vælg for at deaktivere USB-fejlretning."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Vælg indtastningsmetode"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 87f14c5..7856aaf 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Den globalen Proxy des Geräts zur Verwendung während der Aktivierung der Richtlinie festlegen. Nur der erste Geräteadministrator kann den gültigen globalen Proxy festlegen."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Ablauf des Passworts festlegen"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Zeitraum bis zur Änderung des Passworts für die Bildschirmsperre festlegen"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Privat"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging verbunden"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Auswählen, um USB-Debugging zu deaktivieren."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Eingabemethode auswählen"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6b8db1e..7dc9747 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ορίστε τη χρήση του γενικού διακομιστή μεσολάβησης της συσκευής όταν είναι ενεργοποιημένη η πολιτική. Μόνο ο διαχειριστής της πρώτης συσκευής ορίζει τον ισχύοντα γενικό διακομιστή μεσολάβησης."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Ορισμός λήξης κωδ. πρόσβασης"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ελέγξτε πόσος χρόνος απομένει προτού πρέπει να αλλάξετε τον κωδικό πρόσβασης κλειδώματος της οθόνης"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Οικία"</item>
     <item msgid="869923650527136615">"Κινητό"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Επιλογή για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Επιλογή μεθόδου εισόδου"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index a981ed6..a63e2c4 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Set the device\'s global proxy to be used while policy is enabled. Only the first device admin sets the effective global proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Set password expiry"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Control how long before lock-screen password needs to be changed"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Home"</item>
     <item msgid="869923650527136615">"Mobile"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB debugging connected"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Select to disable USB debugging."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Select input method"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string>
diff --git a/core/res/res/values-es-rUS-xlarge/strings.xml b/core/res/res/values-es-rUS-xlarge/strings.xml
index b1409ba..81b3f1a 100644
--- a/core/res/res/values-es-rUS-xlarge/strings.xml
+++ b/core/res/res/values-es-rUS-xlarge/strings.xml
@@ -288,6 +288,8 @@
     <!-- XL -->
     <string name="capital_on" msgid="5705918046896729554">"ENCENDIDO"</string>
     <!-- XL -->
+    <string name="capital_off" msgid="6734525950925281617">"APAGADO"</string>
+    <!-- XL -->
     <string name="wait" msgid="8036803866051401072">"Espera"</string>
     <!-- XL -->
     <string name="heavy_weight_notification" msgid="5762367358298413602">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando"</string>
@@ -311,6 +313,10 @@
     <!-- XL -->
     <string name="permdesc_mediaStorageWrite" product="default" msgid="2372999661142345443">"Permite que una aplicación modifique los contenidos del almacenamiento interno de medios."</string>
     <!-- XL -->
+    <string name="policylab_encryptedStorage" msgid="488196329176602372">"Establecer la encriptación del almacenamiento"</string>
+    <!-- XL -->
+    <string name="policydesc_encryptedStorage" msgid="6111889605506443825">"Requiere que los datos almacenados de la aplicación estén encriptados"</string>
+    <!-- XL -->
     <string name="autofill_address_summary_name_format" msgid="7531610259426153850">"$1$2$3"</string>
     <!-- XL -->
     <string name="autofill_address_summary_format" msgid="8398158823767723887">"$1$2$3"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5e6645d..5d1a25f 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -489,6 +489,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configuración del proxy global de dispositivo que se utilizará mientras se habilita la política. Sólo la primera administración de dispositivo configura el proxy global efectivo."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Establecer la caducidad de la contraseña"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Verifica cuánto tiempo antes debes cambiar la contraseña de la pantalla de bloqueo"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Casa"</item>
     <item msgid="869923650527136615">"Celular"</item>
@@ -809,8 +813,8 @@
     <string name="no" msgid="5141531044935541497">"Cancelar"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
     <string name="loading" msgid="1760724998928255250">"Cargando..."</string>
-    <string name="capital_on" msgid="1544682755514494298">"Encendido"</string>
-    <string name="capital_off" msgid="6815870386972805832">"APAGADO"</string>
+    <string name="capital_on" msgid="1544682755514494298">"Sí"</string>
+    <string name="capital_off" msgid="6815870386972805832">"No"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Completar la acción mediante"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utilizar de manera predeterminada en esta acción."</string>
     <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar la predeterminación en Configuración de la página principal &gt; Aplicaciones &gt; Administrar aplicaciones."</string>
@@ -904,6 +908,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para desactivar la depuración de USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4f02c4b..a4d6545 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Define el servidor proxy global que se debe utilizar mientras la política esté habilitada. Solo el primer administrador de dispositivos define el servidor proxy global efectivo."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir caducidad contraseña"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Permite controlar cuándo se debe cambiar la contraseña de bloqueo de la pantalla."</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Casa"</item>
     <item msgid="869923650527136615">"Móvil"</item>
@@ -501,7 +505,7 @@
     <item msgid="9192514806975898961">"Personalizar"</item>
   </string-array>
   <string-array name="emailAddressTypes">
-    <item msgid="8073994352956129127">"Personal"</item>
+    <item msgid="8073994352956129127">"Casa"</item>
     <item msgid="7084237356602625604">"Trabajo"</item>
     <item msgid="1112044410659011023">"Otra"</item>
     <item msgid="2374913952870110618">"Personalizar"</item>
@@ -810,8 +814,8 @@
     <string name="no" msgid="5141531044935541497">"Cancelar"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
     <string name="loading" msgid="1760724998928255250">"Cargando…"</string>
-    <string name="capital_on" msgid="1544682755514494298">"Activado"</string>
-    <string name="capital_off" msgid="6815870386972805832">"Desconectado"</string>
+    <string name="capital_on" msgid="1544682755514494298">"SÍ"</string>
+    <string name="capital_off" msgid="6815870386972805832">"NO"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Completar acción utilizando"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utilizar de forma predeterminada para esta acción"</string>
     <string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar valores predeterminados en la página de configuración de la pantalla de inicio del teléfono &gt; Aplicaciones &gt; Administrar aplicaciones\"."</string>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccionar para inhabilitar la depuración USB"</string>
     <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de introducción de texto"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 95871a4..767655d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"پروکسی جهانی دستگاه مورد نظر را جهت استفاده هنگام فعال بودن خط مشی تنظیم کنید. فقط اولین سرپرست دستگاه پروکسی جهانی مفید را تنظیم می کند."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"تنظیم زمان انقضای رمز ورود"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"کنترل مدت زمانی که رمز ورود صفحه قفل قبل از تغییر یافتن لازم دارد"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"خانه"</item>
     <item msgid="869923650527136615">"تلفن همراه"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"رفع عیب USB متصل شد"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"انتخاب کنید تا رفع عیب USB غیرفعال شود."</string>
     <string name="select_input_method" msgid="6865512749462072765">"انتخاب روش ورودی"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1392ebb..d8d13ef 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Aseta laitteen yleinen välityspalvelin käyttöön, kun käytäntö on käytössä. Vain ensimmäinen laitteen järjestelmänhallitsija voi asettaa käytettävän yleisen välityspalvelimen."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Aseta salasanan umpeutuminen"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Valitse, kuinka pian ruudunlukituksen poiston salasana tulee vaihtaa"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Puhelinnumero (koti)"</item>
     <item msgid="869923650527136615">"Mobiili"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Poista USB-vianetsintä käytöstä valitsemalla tämä."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Valitse syöttötapa"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 361d193..c3fb6eb 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Indiquez le proxy global à utiliser pour ce mobile lorsque les règles sont activées. Seul l\'administrateur principal du mobile peut définir le proxy global utilisé."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Définir date exp. mot de passe"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Définir la fréquence de changement du mot de passe de verrouillage d\'écran"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Domicile"</item>
     <item msgid="869923650527136615">"Mobile"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Sélectionnez cette option pour désactiver le débogage USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Sélectionner un mode de saisie"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index befb526..fe9f319 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Postavi globalni proxy uređaja za upotrebu dok su pravila omogućena. Samo prvi administrator uređaja postavlja djelotvoran globalni proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Postavi istek zaporke"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Nadzirite za koliko vremena zaporka za zaključani zaslon treba biti promijenjena"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Početna"</item>
     <item msgid="869923650527136615">"Mobilni"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje programske pogreške USB-a"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Odaberite da biste onemogućili rješavanje programske pogreške na USB-u."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Odaberite način unosa"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 0ee1bbc..a090f0b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Az eszköz globális proxyja lesz használatban, amíg az irányelv engedélyezve van. Csak az eszköz első rendszergazdája állíthatja be a tényleges globális proxyt."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Jelszó lejáratának beállítása"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Azt vezérli, mennyi időnként kell módosítani a képernyőt zároló jelszót"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Otthoni"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Válassza ezt az USB hibakeresés kikapcsolásához."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Válassza ki a beviteli módszert"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 304ef90..8f738d6 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setel proxy global perangkat yang akandigunakan ketika kebijakan diaktifkan. Hanya admin perangkat pertama yang menyetel procy global yang berlaku."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Setel kedaluwarsa sandi"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrol berapa lama sebelum sandi penguncian layar perlu diubah"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Rumah"</item>
     <item msgid="869923650527136615">"Seluler"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB terhubung"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Pilih untuk menonaktifkan debugging USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Pilih metode masukan"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 282d375..887a96d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Imposta il proxy globale del dispositivo in modo da utilizzarlo mentre la norma è attiva. Il proxy globale effettivo è impostabile solo dal primo amministratore del dispositivo."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Imposta scadenza password"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Stabilisci la scadenza della password di blocco dello schermo"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Casa"</item>
     <item msgid="869923650527136615">"Cellulare"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleziona per disattivare il debug USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Seleziona metodo di inserimento"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index ea48002..eab8673 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"הגדר את שרת proxy הגלובלי של ההתקן לשימוש כאשר המדיניות מופעלת. רק מנהל ההתקן הראשון מגדיר את שרת ה-proxy הגלובלי הפעיל."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"הגדר תפוגת תוקף של סיסמה"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"שלוט בפרק הזמן הדרוש לשינוי הסיסמה של נעילת המסך"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"דף הבית"</item>
     <item msgid="869923650527136615">"נייד"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"ניקוי באגים של USB מחובר"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"בחר כדי להשבית ניקוי באגים ב-USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"בחר שיטת קלט"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZאבגדהוזחטיכלמנסעפצקרשת"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ  0123456789אבגדהוזחטיכלמנסעפצקרשת"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 6df5f3d..c1b9f5d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ポリシーが有効になっている場合は端末のグローバルプロキシが使用されるように設定します。有効なグローバルプロキシを設定できるのは最初のデバイス管理者だけです。"</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"パスワードの有効期限の設定"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"画面ロックパスワードの変更が必要になるまでの期間を指定します"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"自宅"</item>
     <item msgid="869923650527136615">"携帯"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"USBデバッグを無効にする場合に選択します。"</string>
     <string name="select_input_method" msgid="6865512749462072765">"入力方法の選択"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -969,7 +975,7 @@
     <string name="no_file_chosen" msgid="6363648562170759465">"ファイルが選択されていません"</string>
     <string name="reset" msgid="2448168080964209908">"リセット"</string>
     <string name="submit" msgid="1602335572089911941">"送信"</string>
-    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードを有効にする"</string>
+    <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードになっています"</string>
     <string name="car_mode_disable_notification_message" msgid="668663626721675614">"運転モードを終了するには選択してください。"</string>
     <string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
     <string name="tethered_notification_message" msgid="3067108323903048927">"タップして設定する"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 10eba59..eda018d 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"정책이 사용 설정되어 있는 동안 사용될 기기 전체 프록시를 설정합니다. 첫 번째 기기 관리자가 설정한 전체 프록시만 유효합니다."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"비밀번호 만료 설정"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"화면 잠금 비밀번호를 변경해야 하는 기간 변경"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"집"</item>
     <item msgid="869923650527136615">"모바일"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
     <string name="select_input_method" msgid="6865512749462072765">"입력 방법 선택"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index bbb629d..f9f01e4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nustatyti įrenginio bendrąjį tarpinį serverį, kad būtų naudojamas, kol įgalinta politika. Tik pirmasis įrenginio administratorius nustato efektyvų bendrąjį tarpinį serverį."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Nust. slaptaž. galiojimo pab."</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Valdyti, per kiek laiko iki ekrano užrakinimo turi būti pakeistas slaptažodis"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Pagrindinis"</item>
     <item msgid="869923650527136615">"Mobilusis"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Pasirinkite, kas išjungtumėte USB derinimą."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Pasirinkti įvesties būdą"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7ef1e0a..6d25c54 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Iestatiet izmantojamo ierīces globālo starpniekserveri, kad ir iespējota politika. Spēkā esošo globālo starpniekserveri iestata tikai pirmās ierīces administrators."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Paroles termiņa izb. iest."</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolē ekrāna bloķēšanas paroles maiņas intervālu"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Mājas"</item>
     <item msgid="869923650527136615">"Mobilais"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Atlasiet, lai atspējotu USB atkļūdošanu."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Atlasiet ievades metodi"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 83fd2d3c..aed9163 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Angir den globale mellomtjeneren på enheten som skal brukes når regelen er aktivert. Kun den opprinnelige administratoren av enheten kan angi den globale mellomtjeneren."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Angi utløpsdato for passordet"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Velg hvor lenge det skal gå før passordet til låseskjermen må byttes"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Hjemmenummer"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Velg for å deaktivere USB-debugging."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Velg inndatametode"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 3c03980..062caee 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Stel de algemene proxy voor het apparaat in die moet worden gebruikt terwijl het beleid is geactiveerd. Alleen de eerste apparaatbeheerder stelt de algemene proxy in."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Verval wachtwoord instellen"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Beheren hoe lang het duurt voordat het wachtwoord voor schermvergrendeling moet worden gewijzigd"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Thuis"</item>
     <item msgid="869923650527136615">"Mobiel"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Selecteer deze optie om USB-foutopsporing uit te schakelen."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Invoermethode selecteren"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index e82dbca..868f168 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ustaw globalny serwer proxy urządzenia do wykorzystywania przy włączonych zasadach. Tylko pierwszy administrator urządzenia ustawia obowiązujący globalny serwer proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Ustaw wygasanie hasła"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrola czasu, po którym należy zmienić hasło blokowania ekranu"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Dom"</item>
     <item msgid="869923650527136615">"Komórka"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Wybierz, aby wyłączyć debugowanie USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Wybierz metodę wprowadzania"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 41634f8..f306b8d 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Definir o proxy global do aparelho a ser utilizado quando a política estiver activada. Só o primeiro administrador do aparelho define o proxy global efectivo."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Def. valid. da palavra-passe"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle com que antecedência é necessário alterar a palavra-passe de bloqueio do ecrã"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Residência"</item>
     <item msgid="869923650527136615">"Móvel"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Seleccione para desactivar depuração USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Seleccionar método de entrada"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 572cbce..7cd6cc4 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Configura o proxy global do dispositivo para ser usado enquanto a política estiver ativada. Somente o primeiro administrador do dispositivo pode configurar um verdadeiro proxy global."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Definir validade da senha"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controle quanto tempo uma senha de bloqueio de tela deve ficar ativa antes de ser alterada"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Residencial"</item>
     <item msgid="869923650527136615">"Celular"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Selecione para desativar a depuração USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Selecionar método de entrada"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9a879c7..a3d8191 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -498,6 +498,10 @@
     <skip />
     <!-- no translation found for policydesc_expirePassword (7276906351852798814) -->
     <skip />
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Privat"</item>
     <item msgid="869923650527136615">"Telefonin"</item>
@@ -947,6 +951,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Debugging USB connectà"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Tscherner per deactivar il debugging USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Tscherner ina metoda d\'endataziun"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index d0e1dc6..07a6213 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Setaţi serverul proxy global pentru dispozitiv care să fie utilizat cât timp politica este activă. Numai primul administrator al dispozitivului poate seta serverul proxy global activ."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Setaţi expirarea parolei"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Controlarea duratei până când parola de blocare a ecranului trebuie modificată"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Domiciliu"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Selectaţi pentru a dezactiva depanarea USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Selectaţi metoda de intrare"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 22ee02a..dfc5d08 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Настройте глобальный прокси-сервер устройства, который будет использоваться при активной политике. Глобальный прокси-сервер должен настроить первый администратор устройства."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Задать время действия пароля"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Задать время действия пароля перед появлением экрана блокировки"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Домашний"</item>
     <item msgid="869923650527136615">"Мобильный"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отладка по USB разрешена"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Нажмите, чтобы отключить отладку USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Выберите способ ввода"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 397688d..e7bbaf6 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Vyberte globálny server proxy, ktorý sa bude používať po aktivácii pravidiel. Platný globálny server proxy nastavuje iba prvý správca zariadenia."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastav. koniec platnosti hesla"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ovládanie doby, po uplynutí ktorej treba zmeniť heslo na odomknutie obrazovky"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Domovská stránka"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez rozhranie USB pripojené"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Vyberte, ak chcete zakázať ladenie USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Výber metódy vstupu"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 91c42a8..c6b4302 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Nastavite globalni strežnik proxy naprave, ki bo v uporabi, ko je pravilnik omogočen. Samo skrbnik prve naprave lahko nastavi veljaven globalni strežnik proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Nastavitev poteka gesla"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Nastavite, koliko časa prej je treba spremeniti geslo za odklepanje zaslona"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Začetna stran"</item>
     <item msgid="869923650527136615">"Mobilni"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"iskanje in odpravljanje napak USB je povezano"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Izberite, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Izbiranje načina vnosa"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -997,8 +1003,7 @@
     <string name="media_unknown_state" msgid="729192782197290385">"Neznano stanje zunanjih nosilcev podatkov."</string>
     <string name="share" msgid="1778686618230011964">"Deli z dr."</string>
     <string name="find" msgid="4808270900322985960">"Najdi"</string>
-    <!-- no translation found for websearch (4337157977400211589) -->
-    <skip />
+    <string name="websearch" msgid="4337157977400211589">"Spletno iskanje"</string>
     <!-- no translation found for gpsNotifTicker (5622683912616496172) -->
     <skip />
     <!-- no translation found for gpsNotifTitle (5446858717157416839) -->
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index c5c1e43..0493685 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Подесите глобални прокси сервер уређаја који ће се користити док су омогућене смернице. Само први администратор уређаја поставља ефективни глобални прокси сервер."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Подеси време истека лозинке"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Контролишите време када лозинка за закључавање екрана треба да се промени"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Кућа"</item>
     <item msgid="869923650527136615">"Мобилни"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Изаберите да бисте онемогућили отклањања грешака са USB-а."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Избор методе уноса"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index bda3863..a60e7f9 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Ange vilken global proxyserver som ska användas när policyn är aktiverad. Endast den första enhetsadministratören anger den faktiska globala proxyservern."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Ange lösenordets utgångsdatum"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Se hur långt det är kvar till du måste ändra lösenordet till låsningsskärmen"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Hem"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Välj att inaktivera USB-felsökning."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Välj indatametod"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 41593f2..f192c6d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"ตั้งค่าพร็อกซีส่วนกลางของอุปกรณ์ที่จะใช้ขณะเปิดการใช้งานนโยบาย เฉพาะผู้ดูแลอุปกรณ์คนแรกเท่านั้นที่ตั้งค่าพร็อกซีส่วนกลางที่มีผลบังคับ"</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"ตั้งค่าการหมดอายุของรหัสผ่าน"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"ควบคุมระยะเวลาก่อนที่จะต้องเปลี่ยนรหัสผ่านการล็อกหน้าจอ"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"บ้าน"</item>
     <item msgid="869923650527136615">"มือถือ"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"เลือกเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string>
     <string name="select_input_method" msgid="6865512749462072765">"เลือกวิธีป้อนข้อมูล"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f65d77e..d42ef28 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Itakda ang pandaigdigang proxy ng device na gagamitin habang pinagana ang patakaran. Tanging ang unang admin ng device ang magtatakda sa may bisang pandaigdigang proxy."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Itakda pag-expire ng password"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kontrolin kung gaano katagal bago kailangang palitan ang password sa pag-lock ng screen"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Home"</item>
     <item msgid="869923650527136615">"Mobile"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Piliin upang huwag paganahin ang debugging ng USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Pumili ng pamamaraan ng pag-input"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"mga kandidato"</u></string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 762ea47..8b338dd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Politika etkin olduğunda kullanılacak cihaz genelinde geçerli proxy\'yi ayarlayın. Etkin genel proxy\'yi yalnızca ilk cihaz yöneticisi ayarlar."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Şifre süre sonu tarihi ayarla"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Ekran kilitleme şifresinin ne kadar süre sonra değiştirilmesi gerekeceğini denetleyin."</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Ev"</item>
     <item msgid="869923650527136615">"Mobil"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"USB hata ayıklamasını devre dışı bırakmak için tıklayın."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Giriş yöntemini seç"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a2ad6dc..6e5fdaa 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Устан. використ. глоб. проксі, коли ввімкнено політику. Лише адміністратор першого пристрою встановлює активний глоб. проксі."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Установити термін дії пароля"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Регулює, за скільки часу перед блокуванням екрана треба змінювати пароль"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Дом."</item>
     <item msgid="869923650527136615">"Мобільний"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB підключ."</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Вибер., щоб вимкн. налагодж. USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Виберіть метод введ-ня"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4e5220a..08c8990 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -487,6 +487,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Đặt proxy chung của điện thoại được sử dụng trong khi chính sách được bật. Chỉ quản trị viên đầu tiên của điện thoại mới có thể đặt proxy chung hiệu quả."</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"Đặt hết hạn mật khẩu"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"Kiểm soát thời lượng trước khi mật khẩu khóa màn hình cần được thay đổi"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Nhà riêng"</item>
     <item msgid="869923650527136615">"ĐT di động"</item>
@@ -900,6 +904,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"Gỡ lỗi USB đã được kết nối"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"Chọn để vô hiệu hoá gỡ lỗi USB."</string>
     <string name="select_input_method" msgid="6865512749462072765">"Chọn phương thức nhập"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1cfc5cf..ecfdd63 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"请设置在启用政策的情况下要使用的设备全局代理。只有第一设备管理员才可设置有效的全局代理。"</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"设置密码有效期"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制屏幕锁定密码的使用期限"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"住宅"</item>
     <item msgid="869923650527136615">"手机"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"选择停用 USB 调试。"</string>
     <string name="select_input_method" msgid="6865512749462072765">"选择输入法"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d0f460f..28cb8b2 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -490,6 +490,10 @@
     <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"設定政策啟用時所要使用的裝置全域 Proxy,只有第一個裝置管理員所設定的全域 Proxy 具有效力。"</string>
     <string name="policylab_expirePassword" msgid="2314569545488269564">"設定密碼到期日"</string>
     <string name="policydesc_expirePassword" msgid="7276906351852798814">"控制螢幕鎖定密碼的使用期限"</string>
+    <!-- no translation found for policylab_encryptedStorage (8901326199909132915) -->
+    <skip />
+    <!-- no translation found for policydesc_encryptedStorage (2504984732631479399) -->
+    <skip />
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"住家電話"</item>
     <item msgid="869923650527136615">"行動電話"</item>
@@ -905,6 +909,8 @@
     <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string>
     <string name="adb_active_notification_message" msgid="8470296818270110396">"選取以停用 USB 偵錯。"</string>
     <string name="select_input_method" msgid="6865512749462072765">"選取輸入方式"</string>
+    <!-- no translation found for configure_input_methods (6324843080254191535) -->
+    <skip />
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6ca42e3..457baa6 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -362,6 +362,15 @@
              pointer will go until that pointers go up thereby enabling touches
              with multiple pointers to be split across multiple windows. -->
         <attr name="windowEnableSplitTouch" format="boolean" />
+        
+        <!-- Control whether a container should automatically close itself if
+             the user touches outside of it.  This only applies to activities
+             and dialogs.
+             
+             <p>Note: this attribute will only be respected for applications
+             that are targeting {@link android.os.Build.VERSION_CODES#HONEYCOMB}
+             or later. -->
+        <attr name="windowCloseOnTouchOutside" format="boolean" />
 
         <!-- ============ -->
         <!-- Alert Dialog styles -->
@@ -525,6 +534,12 @@
         <!-- The CalndarView style. -->
         <attr name="calendarViewStyle" format="reference" />
 
+        <!-- The TimePicker style. -->
+        <attr name="timePickerStyle" format="reference" />
+
+        <!-- The DatePicker style. -->
+        <attr name="datePickerStyle" format="reference" />
+
         <!-- Fast scroller styles -->
         <eat-comment />
 
@@ -1342,6 +1357,7 @@
         <attr name="windowActionModeOverlay" />
         <attr name="windowActionBarOverlay" />
         <attr name="windowEnableSplitTouch" />
+        <attr name="windowCloseOnTouchOutside" />
         <!-- The minimum width the window is allowed to be, along the major
              axis of the screen.  That is, when in landscape.  Can be either
              an absolute dimension or a fraction of the screen size in that
@@ -2859,6 +2875,7 @@
         <!-- Gravity setting for positioning the currently selected item. -->
         <attr name="gravity" />
     </declare-styleable>
+
     <declare-styleable name="DatePicker">
         <!-- The first year (inclusive), for example "1940". -->
         <attr name="startYear" format="integer" />
@@ -2872,6 +2889,8 @@
         <attr name="minDate" format="string" />
         <!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
         <attr name="maxDate" format="string" />
+        <!-- @hide The layout of the time picker. -->
+        <attr name="layout" />
     </declare-styleable>
 
     <declare-styleable name="TwoLineListItem">
@@ -3070,9 +3089,20 @@
     </declare-styleable>
 
     <declare-styleable name="NumberPicker">
-        <attr name="orientation" />
-        <!-- Color for the solid color background if such for optimized rendering. -->
+        <!-- @hide Color for the solid color background if such for optimized rendering. -->
         <attr name="solidColor" format="color|reference" />
+        <!-- @hide Whether the number picker supports fligning. -->
+        <attr name="flingable" format="boolean" />
+    </declare-styleable>
+
+    <declare-styleable name="TimePicker">
+        <!-- @hide The layout of the time picker. -->
+        <attr name="layout" />
+    </declare-styleable>
+
+    <declare-styleable name="DatePicker">
+        <!-- @hide The layout of the time picker. -->
+        <attr name="layout" />
     </declare-styleable>
 
     <!-- ========================= -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8bb05fb..e0c26d4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -81,6 +81,10 @@
          specified for -large and -xlarge configurations. -->
     <dimen name="config_prefDialogWidth">0px</dimen>
     
+    <!-- Whether dialogs should close automatically when the user touches outside
+         of them.  This should not normally be modified. -->
+    <bool name="config_closeDialogWhenTouchOutside">false</bool>
+    
     <!-- The duration (in milliseconds) that the radio will scan for a signal
          when there's no network connection. If the scan doesn't timeout, use zero -->
     <integer name="config_radioScanningTimeout">0</integer>
@@ -433,7 +437,14 @@
          from the touch driver. This code exists for one particular device,
          and should not be enabled for any others. -->
     <bool name="config_filterJumpyTouchEvents">false</bool>
-    
+
+    <!-- Specifies the amount of time to disable virtual keys after the screen is touched
+         in order to filter out accidental virtual key presses due to swiping gestures
+         or taps near the edge of the display.  May be 0 to disable the feature.
+         It is recommended that this value be no more than 250 ms.
+         This feature should be disabled for most devices. -->
+    <integer name="config_virtualKeyQuietTimeMillis">0</integer>
+
     <!-- Component name of the default wallpaper. This will be ImageWallpaper if not 
          specified -->
     <string name="default_wallpaper_component">@null</string>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index eabd457..a30e316 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1425,6 +1425,9 @@
   <public type="attr" name="queryHint" />
   <public type="attr" name="fastScrollTextColor" />
   <public type="attr" name="largeHeap" />
+  <public type="attr" name="windowCloseOnTouchOutside" />
+  <public type="attr" name="datePickerStyle" />
+  <public type="attr" name="calendarViewStyle" />
 
   <!-- A simple fade-in animation. -->
   <public type="animator" name="fade_in" id="0x010b0000" />
@@ -1626,21 +1629,15 @@
   <public type="style" name="Holo.Light.ButtonBar.AlertDialog" />
   <public type="style" name="Holo.SegmentedButton" />
   <public type="style" name="Holo.Light.SegmentedButton" />
-  <public type="style" name="Widget.ImageButton.NumberPickerUpButton" />
-  <public type="style" name="Widget.EditText.NumberPickerInputText" />
-  <public type="style" name="Widget.ImageButton.NumberPickerDownButton" />
-  <public type="style" name="Widget.Holo.ImageButton.NumberPickerUpButton" />
-  <public type="style" name="Widget.Holo.EditText.NumberPickerInputText" />
-  <public type="style" name="Widget.Holo.ImageButton.NumberPickerDownButton" />
-  <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" />
-  <public type="style" name="Widget.Holo.Light.EditText.NumberPickerInputText" />
-  <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" />
   <public type="style" name="Widget.CalendarView" />
   <public type="style" name="Widget.Holo.CalendarView" />
   <public type="style" name="Widget.Holo.Light.CalendarView" />
+  <public type="style" name="Widget.DatePicker" />
+  <public type="style" name="Widget.Holo.DatePicker" />
 
   <public type="string" name="selectTextMode" />
 
   <!-- Default icon for applications that don't specify an icon. -->
   <public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
+
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2658b53..9a1b42d 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -681,6 +681,12 @@
         interface of a wallpaper. Should never be needed for normal applications.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindRemoteViews">bind to a widget service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindRemoteViews">Allows the holder to bind to the top-level
+        interface of a widget service. Should never be needed for normal applications.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bindDeviceAdmin">interact with a device admin</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindDeviceAdmin">Allows the holder to send intents to
@@ -1784,6 +1790,8 @@
     <string name="lockscreen_glogin_submit_button">Sign in</string>
     <!-- Displayed to the user when unlocking the phone with a username and password fails. -->
     <string name="lockscreen_glogin_invalid_input">Invalid username or password.</string>
+    <!-- Hint displayed on account unlock screen to advise the user on how to recover the account. -->
+    <string name="lockscreen_glogin_account_recovery_hint">Forgot your username or password\?\nVisit <b>google.com/accounts/recovery</b></string>
 
     <!-- Displayed in a progress dialog while a username and password are being checked. -->
     <string name="lockscreen_glogin_checking_password">Checking...</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 16c80d0..b7b43e0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -489,7 +489,16 @@
         <item name="android:orientation">vertical</item>
         <item name="android:fadingEdge">vertical</item>
         <item name="android:fadingEdgeLength">50dip</item>
-        <item name="android:solidColor">@android:color/transparent</item>
+        <item name="android:flingable">false</item>
+    </style>
+
+    <style name="Widget.TimePicker">
+        <item name="android:layout">@android:layout/time_picker</item>
+    </style>
+
+    <style name="Widget.DatePicker">
+        <item name="android:layout">@android:layout/date_picker</item>
+        <item name="android:calendarViewShown">false</item>
     </style>
 
     <style name="Widget.ImageButton.NumberPickerUpButton">
@@ -1502,6 +1511,20 @@
         <item name="android:background">@android:drawable/btn_default_holo_dark</item>
     </style>
 
+    <style name="Widget.Holo.NumberPicker" parent="Widget.NumberPicker">
+        <item name="android:solidColor">@android:color/transparent</item>
+        <item name="android:flingable">true</item>
+    </style>
+
+    <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+        <item name="android:layout">@android:layout/time_picker_holo</item>
+    </style>
+
+    <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
+        <item name="android:layout">@android:layout/date_picker_holo</item>
+        <item name="android:calendarViewShown">true</item>
+    </style>
+
     <style name="Widget.Holo.ImageButton.NumberPickerUpButton">
         <item name="android:background">@null</item>
         <item name="android:src">@android:drawable/numberpicker_up_btn_holo_dark</item>
@@ -1870,6 +1893,15 @@
         <item name="android:weekDayTextAppearance">@android:style/TextAppearance.Holo.Light.CalendarViewWeekDayView</item>
     </style>
 
+    <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker">
+    </style>
+
+    <style name="Widget.Holo.Light.TimePicker" parent="Widget.Holo.TimePicker">
+    </style>
+
+    <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
+    </style>
+
     <style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
         <item name="android:src">@android:drawable/numberpicker_up_btn_holo_light</item>
     </style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 506dd07..2f8cffc 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -138,6 +138,7 @@
         <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
         <item name="windowActionBar">false</item>
         <item name="windowActionModeOverlay">false</item>
+        <item name="windowCloseOnTouchOutside">false</item>
 
         <!-- Dialog attributes -->
         <item name="alertDialogStyle">@android:style/AlertDialog</item>
@@ -289,6 +290,12 @@
         <!-- CalendarView style-->
         <item name="calendarViewStyle">@style/Widget.CalendarView</item>
 
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.DatePicker</item>
+
         <item name="fastScrollThumbDrawable">@android:drawable/scrollbar_handle_accelerated_anim2</item>
         <item name="fastScrollTrackDrawable">@null</item>
         <item name="fastScrollPreviewBackgroundRight">@android:drawable/menu_submenu_background</item>
@@ -506,6 +513,7 @@
         <item name="android:windowContentOverlay">@null</item>
         <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
         <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
 
         <item name="android:colorBackgroundCacheHint">@null</item>
         
@@ -547,6 +555,7 @@
         <item name="android:backgroundDimEnabled">false</item>
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
     </style>
 
     <!-- Default theme for alert dialog windows, which is used by the
@@ -687,6 +696,7 @@
         <item name="windowIsFloating">true</item>
         <item name="windowContentOverlay">@null</item>
         <item name="textAppearance">@style/TextAppearance.Theme.Dialog.AppError</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
     </style>
     
     <!-- Special theme for the recent apps dialog, to allow customization
@@ -696,6 +706,7 @@
         <item name="windowBackground">@android:color/transparent</item>
         <item name="android:windowAnimationStyle">@android:style/Animation.RecentApplications</item>
         <item name="android:textColor">@android:color/secondary_text_nofocus</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
     </style>
 
     <!-- Default theme for window that looks like a toast. -->
@@ -703,6 +714,7 @@
         <item name="android:windowBackground">@android:drawable/toast_frame</item>
         <item name="android:windowAnimationStyle">@android:style/Animation.Toast</item>
         <item name="android:backgroundDimEnabled">false</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
     </style>
 
     <!-- Default theme with an Action Bar. -->
@@ -972,10 +984,17 @@
         <item name="numberPickerUpButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerUpButton</item>
         <item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
         <item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+        <item name="numberPickerStyle">@style/Widget.Holo.NumberPicker</item>
 
         <!-- CalendarView style-->
         <item name="calendarViewStyle">@style/Widget.Holo.CalendarView</item>
 
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Holo.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
+
         <item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
         <item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_dark</item>
         <item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_dark</item>
@@ -997,6 +1016,7 @@
         <item name="disabledAlpha">0.5</item>
         <item name="backgroundDimAmount">0.6</item>
 
+
         <!-- Text styles -->
         <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
         <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
@@ -1230,10 +1250,17 @@
         <item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
         <item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
         <item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+        <item name="numberPickerStyle">@style/Widget.Holo.Light.NumberPicker</item>
 
         <!-- CalendarView style-->
         <item name="calendarViewStyle">@style/Widget.Holo.Light.CalendarView</item>
 
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Holo.Light.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
+
         <item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
         <item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_light</item>
         <item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_light</item>
@@ -1291,6 +1318,7 @@
         <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowActionModeOverlay">true</item>
+        <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
 
         <item name="android:colorBackgroundCacheHint">@null</item>
 
@@ -1331,6 +1359,7 @@
         <item name="android:backgroundDimEnabled">false</item>
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowNoTitle">true</item>
+        <item name="android:windowCloseOnTouchOutside">false</item>
     </style>
 
     <!-- Holo theme for alert dialog windows, which is used by the
@@ -1377,6 +1406,7 @@
         <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
         <item name="android:windowActionBar">false</item>
         <item name="android:windowActionModeOverlay">true</item>
+        <item name="android:windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
 
         <item name="android:colorBackgroundCacheHint">@null</item>
 
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 43cf06a..96b028a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -19,6 +19,16 @@
 import android.content.Context;
 import android.test.InstrumentationTestCase;
 
+/**
+ * Stress test suite for Bluetooth related functions.
+ *
+ * Includes tests for enabling/disabling bluetooth, enabling/disabling discoverable mode,
+ * starting/stopping scans, connecting/disconnecting to HFP, A2DP, HID, PAN profiles, and verifying
+ * that remote connections/disconnections occur for the PAN profile.
+ * <p>
+ * This test suite uses {@link android.bluetooth.BluetoothTestRunner} to for parameters such as the
+ * number of iterations and the addresses of remote Bluetooth devices.
+ */
 public class BluetoothStressTest extends InstrumentationTestCase {
     private static final String TAG = "BluetoothStressTest";
     private static final String OUTPUT_FILE = "BluetoothStressTestOutput.txt";
@@ -40,6 +50,9 @@
         mTestUtils.close();
     }
 
+    /**
+     * Stress test for enabling and disabling Bluetooth.
+     */
     public void testEnable() {
         int iterations = BluetoothTestRunner.sEnableIterations;
         if (iterations == 0) {
@@ -55,6 +68,9 @@
         }
     }
 
+    /**
+     * Stress test for putting the device in and taking the device out of discoverable mode.
+     */
     public void testDiscoverable() {
         int iterations = BluetoothTestRunner.sDiscoverableIterations;
         if (iterations == 0) {
@@ -73,6 +89,9 @@
         mTestUtils.disable(adapter);
     }
 
+    /**
+     * Stress test for starting and stopping Bluetooth scans.
+     */
     public void testScan() {
         int iterations = BluetoothTestRunner.sScanIterations;
         if (iterations == 0) {
@@ -91,6 +110,30 @@
         mTestUtils.disable(adapter);
     }
 
+    /**
+     * Stress test for enabling and disabling the PAN NAP profile.
+     */
+    public void testEnablePan() {
+        int iterations = BluetoothTestRunner.sEnablePanIterations;
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        mTestUtils.enable(adapter);
+
+        for (int i = 0; i < iterations; i++) {
+            mTestUtils.writeOutput("testEnablePan iteration " + (i + 1) + " of "
+                    + iterations);
+            mTestUtils.enablePan(adapter);
+            mTestUtils.disablePan(adapter);
+        }
+
+        mTestUtils.disable(adapter);
+    }
+
+    /**
+     * Stress test for pairing and unpairing with a remote device.
+     * <p>
+     * In this test, the local device initiates pairing with a remote device, and then unpairs with
+     * the device after the pairing has successfully completed.
+     */
     public void testPair() {
         int iterations = BluetoothTestRunner.sPairIterations;
         if (iterations == 0) {
@@ -110,6 +153,12 @@
         mTestUtils.disable(adapter);
     }
 
+    /**
+     * Stress test for accepting a pairing request and unpairing with a remote device.
+     * <p>
+     * In this test, the local device waits for a pairing request from a remote device.  It accepts
+     * the request and then unpairs after the paring has successfully completed.
+     */
     public void testAcceptPair() {
         int iterations = BluetoothTestRunner.sPairIterations;
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -125,6 +174,12 @@
         mTestUtils.disable(adapter);
     }
 
+    /**
+     * Stress test for connecting and disconnecting with an A2DP source.
+     * <p>
+     * In this test, the local device plays the role of an A2DP sink, and initiates connections and
+     * disconnections with an A2DP source.
+     */
     public void testConnectA2dp() {
         int iterations = BluetoothTestRunner.sConnectA2dpIterations;
         if (iterations == 0) {
@@ -143,10 +198,16 @@
             mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.A2DP);
         }
 
-        // TODO: Unpair from device if device can accept pairing after unpairing
+        mTestUtils.unpair(adapter, device);
         mTestUtils.disable(adapter);
     }
 
+    /**
+     * Stress test for connecting and disconnecting the HFP with a hands free device.
+     * <p>
+     * In this test, the local device plays the role of an HFP audio gateway, and initiates
+     * connections and disconnections with a hands free device.
+     */
     public void testConnectHeadset() {
         int iterations = BluetoothTestRunner.sConnectHeadsetIterations;
         if (iterations == 0) {
@@ -165,7 +226,94 @@
             mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET);
         }
 
-        // TODO: Unpair from device if device can accept pairing after unpairing
+        mTestUtils.unpair(adapter, device);
+        mTestUtils.disable(adapter);
+    }
+
+    /**
+     * Stress test for connecting and disconnecting with a HID device.
+     * <p>
+     * In this test, the local device plays the role of a HID host, and initiates connections and
+     * disconnections with a HID device.
+     */
+    public void testConnectInput() {
+        int iterations = BluetoothTestRunner.sConnectInputIterations;
+        if (iterations == 0) {
+            return;
+        }
+
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sInputAddress);
+        mTestUtils.enable(adapter);
+        mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey,
+                BluetoothTestRunner.sPairPin);
+
+        for (int i = 0; i < iterations; i++) {
+            mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.connectInput(adapter, device);
+            mTestUtils.disconnectInput(adapter, device);
+        }
+
+        mTestUtils.unpair(adapter, device);
+        mTestUtils.disable(adapter);
+    }
+
+    /**
+     * Stress test for connecting and disconnecting with a PAN NAP.
+     * <p>
+     * In this test, the local device plays the role of a PANU, and initiates connections and
+     * disconnections with a NAP.
+     */
+    public void testConnectPan() {
+        int iterations = BluetoothTestRunner.sConnectPanIterations;
+        if (iterations == 0) {
+            return;
+        }
+
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sPanAddress);
+        mTestUtils.enable(adapter);
+        mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey,
+                BluetoothTestRunner.sPairPin);
+
+        for (int i = 0; i < iterations; i++) {
+            mTestUtils.writeOutput("connectPan iteration " + (i + 1) + " of " + iterations);
+            mTestUtils.connectPan(adapter, device);
+            mTestUtils.disconnectPan(adapter, device);
+        }
+
+        mTestUtils.unpair(adapter, device);
+        mTestUtils.disable(adapter);
+    }
+
+    /**
+     * Stress test for verifying a PANU connecting and disconnecting with the device.
+     * <p>
+     * In this test, the local device plays the role of a NAP which a remote PANU connects and
+     * disconnects from.
+     */
+    public void testIncomingPanConnection() {
+        int iterations = BluetoothTestRunner.sConnectPanIterations;
+        if (iterations == 0) {
+            return;
+        }
+
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sPanAddress);
+        mTestUtils.enable(adapter);
+        mTestUtils.enablePan(adapter);
+        mTestUtils.acceptPair(adapter, device, BluetoothTestRunner.sPairPasskey,
+                BluetoothTestRunner.sPairPin);
+
+        for (int i = 0; i < iterations; i++) {
+            mTestUtils.writeOutput("incomingPanConnection iteration " + (i + 1) + " of "
+                    + iterations);
+            mTestUtils.incomingPanConnection(adapter, device);
+            mTestUtils.incomingPanDisconnection(adapter, device);
+        }
+
+        mTestUtils.unpair(adapter, device);
+        mTestUtils.disablePan(adapter);
         mTestUtils.disable(adapter);
     }
 }
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
index 3e589fc..cede05a 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
@@ -23,19 +23,51 @@
 import android.test.InstrumentationTestSuite;
 import android.util.Log;
 
+/**
+ * Instrumentation test runner for Bluetooth tests.
+ * <p>
+ * To run:
+ * <pre>
+ * {@code
+ * adb shell am instrument \
+ *     [-e enable_iterations <iterations>] \
+ *     [-e discoverable_iterations <iterations>] \
+ *     [-e scan_iterations <iterations>] \
+ *     [-e enable_pan_iterations <iterations>] \
+ *     [-e pair_iterations <iterations>] \
+ *     [-e connect_a2dp_iterations <iterations>] \
+ *     [-e connect_headset_iterations <iterations>] \
+ *     [-e connect_input_iterations <iterations>] \
+ *     [-e connect_pan_iterations <iterations>] \
+ *     [-e pair_address <address>] \
+ *     [-e headset_address <address>] \
+ *     [-e a2dp_address <address>] \
+ *     [-e input_address <address>] \
+ *     [-e pan_address <address>] \
+ *     [-e pair_pin <pin>] \
+ *     [-e pair_passkey <passkey>] \
+ *     -w com.android.frameworks.coretests/android.bluetooth.BluetoothTestRunner
+ * }
+ * </pre>
+ */
 public class BluetoothTestRunner extends InstrumentationTestRunner {
     private static final String TAG = "BluetoothTestRunner";
 
     public static int sEnableIterations = 100;
     public static int sDiscoverableIterations = 1000;
     public static int sScanIterations = 1000;
+    public static int sEnablePanIterations = 1000;
     public static int sPairIterations = 100;
     public static int sConnectHeadsetIterations = 100;
     public static int sConnectA2dpIterations = 100;
+    public static int sConnectInputIterations = 100;
+    public static int sConnectPanIterations = 100;
 
     public static String sPairAddress = "";
     public static String sHeadsetAddress = "";
     public static String sA2dpAddress = "";
+    public static String sInputAddress = "";
+    public static String sPanAddress = "";
 
     public static byte[] sPairPin = {'1', '2', '3', '4'};
     public static int sPairPasskey = 123456;
@@ -81,6 +113,15 @@
             }
         }
 
+        val = arguments.getString("enable_pan_iterations");
+        if (val != null) {
+            try {
+                sEnablePanIterations = Integer.parseInt(val);
+            } catch (NumberFormatException e) {
+                // Invalid argument, fall back to default value
+            }
+        }
+
         val = arguments.getString("pair_iterations");
         if (val != null) {
             try {
@@ -108,6 +149,24 @@
             }
         }
 
+        val = arguments.getString("connect_input_iterations");
+        if (val != null) {
+            try {
+                sConnectInputIterations = Integer.parseInt(val);
+            } catch (NumberFormatException e) {
+                // Invalid argument, fall back to default value
+            }
+        }
+
+        val = arguments.getString("connect_pan_iterations");
+        if (val != null) {
+            try {
+                sConnectPanIterations = Integer.parseInt(val);
+            } catch (NumberFormatException e) {
+                // Invalid argument, fall back to default value
+            }
+        }
+
         val = arguments.getString("pair_address");
         if (val != null) {
             sPairAddress = val;
@@ -123,6 +182,16 @@
             sA2dpAddress = val;
         }
 
+        val = arguments.getString("input_address");
+        if (val != null) {
+            sInputAddress = val;
+        }
+
+        val = arguments.getString("pan_address");
+        if (val != null) {
+            sPanAddress = val;
+        }
+
         val = arguments.getString("pair_pin");
         if (val != null) {
             sPairPin = BluetoothDevice.convertPinToBytes(val);
@@ -143,9 +212,13 @@
         Log.i(TAG, String.format("pair_iterations=%d", sPairIterations));
         Log.i(TAG, String.format("connect_a2dp_iterations=%d", sConnectA2dpIterations));
         Log.i(TAG, String.format("connect_headset_iterations=%d", sConnectHeadsetIterations));
+        Log.i(TAG, String.format("connect_input_iterations=%d", sConnectInputIterations));
+        Log.i(TAG, String.format("connect_pan_iterations=%d", sConnectPanIterations));
         Log.i(TAG, String.format("pair_address=%s", sPairAddress));
         Log.i(TAG, String.format("a2dp_address=%s", sA2dpAddress));
         Log.i(TAG, String.format("headset_address=%s", sHeadsetAddress));
+        Log.i(TAG, String.format("input_address=%s", sInputAddress));
+        Log.i(TAG, String.format("pan_address=%s", sPanAddress));
         Log.i(TAG, String.format("pair_pin=%s", new String(sPairPin)));
         Log.i(TAG, String.format("pair_passkey=%d", sPairPasskey));
 
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index 6da38a7..effed76 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -35,49 +35,29 @@
 public class BluetoothTestUtils extends Assert {
 
     /**
-     * Timeout for {@link BluetoothAdapter#disable()} in ms.
+     * Timeout for enable/disable in ms.
      */
-    private static final int DISABLE_TIMEOUT = 20000;
+    private static final int ENABLE_DISABLE_TIMEOUT = 20000;
 
     /**
-     * Timeout for {@link BluetoothAdapter#enable()} in ms.
+     * Timeout for discoverable/undiscoverable in ms.
      */
-    private static final int ENABLE_TIMEOUT = 20000;
+    private static final int DISCOVERABLE_UNDISCOVERABLE_TIMEOUT = 5000;
 
     /**
-     * Timeout for {@link BluetoothAdapter#setScanMode(int)} in ms.
+     * Timeout for starting/stopping a scan in ms.
      */
-    private static final int SET_SCAN_MODE_TIMEOUT = 5000;
+    private static final int START_STOP_SCAN_TIMEOUT = 5000;
 
     /**
-     * Timeout for {@link BluetoothAdapter#startDiscovery()} in ms.
+     * Timeout for pair/unpair in ms.
      */
-    private static final int START_DISCOVERY_TIMEOUT = 5000;
+    private static final int PAIR_UNPAIR_TIMEOUT = 20000;
 
     /**
-     * Timeout for {@link BluetoothAdapter#cancelDiscovery()} in ms.
+     * Timeout for connecting/disconnecting a profile in ms.
      */
-    private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;
-
-    /**
-     * Timeout for {@link BluetoothDevice#createBond()} in ms.
-     */
-    private static final int PAIR_TIMEOUT = 20000;
-
-    /**
-     * Timeout for {@link BluetoothDevice#removeBond()} in ms.
-     */
-    private static final int UNPAIR_TIMEOUT = 20000;
-
-    /**
-     * Timeout for {@link BluetoothProfile#connect(BluetoothDevice)} in ms.
-     */
-    private static final int CONNECT_PROFILE_TIMEOUT = 20000;
-
-    /**
-     * Timeout for {@link BluetoothProfile#disconnect(BluetoothDevice)} in ms.
-     */
-    private static final int DISCONNECT_PROFILE_TIMEOUT = 20000;
+    private static final int CONNECT_DISCONNECT_PROFILE_TIMEOUT = 20000;
 
     /**
      * Timeout to connect a profile proxy in ms.
@@ -265,7 +245,6 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-
             if (mConnectionAction != null && mConnectionAction.equals(intent.getAction())) {
                 if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
                     return;
@@ -291,6 +270,91 @@
         }
     }
 
+    private class ConnectInputReceiver extends FlagReceiver {
+        private static final int STATE_DISCONNECTED_FLAG = 1;
+        private static final int STATE_CONNECTING_FLAG = 1 << 1;
+        private static final int STATE_CONNECTED_FLAG = 1 << 2;
+        private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
+
+        private BluetoothDevice mDevice;
+
+        public ConnectInputReceiver(BluetoothDevice device, int expectedFlags) {
+            super(expectedFlags);
+
+            mDevice = device;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
+                return;
+            }
+
+            if (BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED.equals(intent.getAction())) {
+                int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, -1);
+                assertNotSame(-1, state);
+                switch (state) {
+                    case BluetoothInputDevice.STATE_DISCONNECTED:
+                        setFiredFlag(STATE_DISCONNECTED_FLAG);
+                        break;
+                    case BluetoothInputDevice.STATE_CONNECTING:
+                        setFiredFlag(STATE_CONNECTING_FLAG);
+                        break;
+                    case BluetoothInputDevice.STATE_CONNECTED:
+                        setFiredFlag(STATE_CONNECTED_FLAG);
+                        break;
+                    case BluetoothInputDevice.STATE_DISCONNECTING:
+                        setFiredFlag(STATE_DISCONNECTING_FLAG);
+                        break;
+                }
+            }
+        }
+    }
+
+    private class ConnectPanReceiver extends FlagReceiver {
+        private static final int STATE_DISCONNECTED_FLAG = 1;
+        private static final int STATE_CONNECTING_FLAG = 1 << 1;
+        private static final int STATE_CONNECTED_FLAG = 1 << 2;
+        private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
+
+        private BluetoothDevice mDevice;
+        private int mRole;
+
+        public ConnectPanReceiver(BluetoothDevice device, int role, int expectedFlags) {
+            super (expectedFlags);
+
+            mDevice = device;
+            mRole = role;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))
+                    || mRole != intent.getIntExtra(BluetoothPan.EXTRA_LOCAL_ROLE, -1)) {
+                return;
+            }
+
+            if (BluetoothPan.ACTION_PAN_STATE_CHANGED.equals(intent.getAction())) {
+                int state = intent.getIntExtra(BluetoothPan.EXTRA_PAN_STATE, -1);
+                assertNotSame(-1, state);
+                switch (state) {
+                    case BluetoothPan.STATE_DISCONNECTED:
+                        setFiredFlag(STATE_DISCONNECTED_FLAG);
+                        break;
+                    case BluetoothPan.STATE_CONNECTING:
+                        setFiredFlag(STATE_CONNECTING_FLAG);
+                        break;
+                    case BluetoothPan.STATE_CONNECTED:
+                        setFiredFlag(STATE_CONNECTED_FLAG);
+                        break;
+                    case BluetoothPan.STATE_DISCONNECTING:
+                        setFiredFlag(STATE_DISCONNECTING_FLAG);
+                        break;
+                }
+            }
+        }
+    }
+
     private BluetoothProfile.ServiceListener mServiceListener =
             new BluetoothProfile.ServiceListener() {
         public void onServiceConnected(int profile, BluetoothProfile proxy) {
@@ -330,10 +394,24 @@
     private BluetoothA2dp mA2dp;
     private BluetoothHeadset mHeadset;
 
+    /**
+     * Creates a utility instance for testing Bluetooth.
+     *
+     * @param context The context of the application using the utility.
+     * @param tag The log tag of the application using the utility.
+     */
     public BluetoothTestUtils(Context context, String tag) {
         this(context, tag, null);
     }
 
+    /**
+     * Creates a utility instance for testing Bluetooth.
+     *
+     * @param context The context of the application using the utility.
+     * @param tag The log tag of the application using the utility.
+     * @param outputFile The path to an output file if the utility is to write results to a
+     *        separate file.
+     */
     public BluetoothTestUtils(Context context, String tag, String outputFile) {
         mContext = context;
         mTag = tag;
@@ -352,6 +430,9 @@
         }
     }
 
+    /**
+     * Closes the utility instance and unregisters any BroadcastReceivers.
+     */
     public void close() {
         while (!mReceivers.isEmpty()) {
             mContext.unregisterReceiver(mReceivers.remove(0));
@@ -366,6 +447,12 @@
         }
     }
 
+    /**
+     * Enables Bluetooth and checks to make sure that Bluetooth was turned on and that the correct
+     * actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void enable(BluetoothAdapter adapter) {
         int mask = (BluetoothReceiver.STATE_TURNING_ON_FLAG | BluetoothReceiver.STATE_ON_FLAG
                 | BluetoothReceiver.SCAN_MODE_CONNECTABLE_FLAG);
@@ -397,22 +484,19 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < ENABLE_TIMEOUT) {
+        while (System.currentTimeMillis() - s < ENABLE_DISABLE_TIMEOUT) {
             state = adapter.getState();
-            if (state == BluetoothAdapter.STATE_ON) {
+            if (state == BluetoothAdapter.STATE_ON
+                    && (receiver.getFiredFlags() & mask) == mask) {
                 assertTrue(adapter.isEnabled());
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("enable() completed in %d ms", (finish - start)));
-                    } else {
-                        writeOutput("enable() completed");
-                    }
-                    removeReceiver(receiver);
-                    return;
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("enable() completed in %d ms", (finish - start)));
+                } else {
+                    writeOutput("enable() completed");
                 }
-            } else {
-                assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -423,6 +507,12 @@
                 state, BluetoothAdapter.STATE_ON, firedFlags, mask));
     }
 
+    /**
+     * Disables Bluetooth and checks to make sure that Bluetooth was turned off and that the correct
+     * actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void disable(BluetoothAdapter adapter) {
         int mask = (BluetoothReceiver.STATE_TURNING_OFF_FLAG | BluetoothReceiver.STATE_OFF_FLAG
                 | BluetoothReceiver.SCAN_MODE_NONE_FLAG);
@@ -454,23 +544,19 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < DISABLE_TIMEOUT) {
+        while (System.currentTimeMillis() - s < ENABLE_DISABLE_TIMEOUT) {
             state = adapter.getState();
-            if (state == BluetoothAdapter.STATE_OFF) {
+            if (state == BluetoothAdapter.STATE_OFF
+                    && (receiver.getFiredFlags() & mask) == mask) {
                 assertFalse(adapter.isEnabled());
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("disable() completed in %d ms",
-                                (finish - start)));
-                    } else {
-                        writeOutput("disable() completed");
-                    }
-                    removeReceiver(receiver);
-                    return;
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("disable() completed in %d ms", (finish - start)));
+                } else {
+                    writeOutput("disable() completed");
                 }
-            } else {
-                assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -481,6 +567,12 @@
                 state, BluetoothAdapter.STATE_OFF, firedFlags, mask));
     }
 
+    /**
+     * Puts the local device into discoverable mode and checks to make sure that the local device
+     * is in discoverable mode and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void discoverable(BluetoothAdapter adapter) {
         int mask = BluetoothReceiver.SCAN_MODE_CONNECTABLE_DISCOVERABLE_FLAG;
 
@@ -499,17 +591,14 @@
         long start = System.currentTimeMillis();
         assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE));
 
-        while (System.currentTimeMillis() - start < SET_SCAN_MODE_TIMEOUT) {
+        while (System.currentTimeMillis() - start < DISCOVERABLE_UNDISCOVERABLE_TIMEOUT) {
             scanMode = adapter.getScanMode();
-            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    writeOutput(String.format("discoverable() completed in %d ms",
-                            (receiver.getCompletedTime() - start)));
-                    removeReceiver(receiver);
-                    return;
-                }
-            } else {
-                assertEquals(BluetoothAdapter.SCAN_MODE_CONNECTABLE, scanMode);
+            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                writeOutput(String.format("discoverable() completed in %d ms",
+                        (receiver.getCompletedTime() - start)));
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -521,6 +610,12 @@
                 firedFlags, mask));
     }
 
+    /**
+     * Puts the local device into connectable only mode and checks to make sure that the local
+     * device is in in connectable mode and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void undiscoverable(BluetoothAdapter adapter) {
         int mask = BluetoothReceiver.SCAN_MODE_CONNECTABLE_FLAG;
 
@@ -539,17 +634,14 @@
         long start = System.currentTimeMillis();
         assertTrue(adapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
 
-        while (System.currentTimeMillis() - start < SET_SCAN_MODE_TIMEOUT) {
+        while (System.currentTimeMillis() - start < DISCOVERABLE_UNDISCOVERABLE_TIMEOUT) {
             scanMode = adapter.getScanMode();
-            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    writeOutput(String.format("undiscoverable() completed in %d ms",
-                            (receiver.getCompletedTime() - start)));
-                    removeReceiver(receiver);
-                    return;
-                }
-            } else {
-                assertEquals(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, scanMode);
+            if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                writeOutput(String.format("undiscoverable() completed in %d ms",
+                        (receiver.getCompletedTime() - start)));
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -561,6 +653,12 @@
                 mask));
     }
 
+    /**
+     * Starts a scan for remote devices and checks to make sure that the local device is scanning
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void startScan(BluetoothAdapter adapter) {
         int mask = BluetoothReceiver.DISCOVERY_STARTED_FLAG;
 
@@ -577,7 +675,7 @@
         long start = System.currentTimeMillis();
         assertTrue(adapter.startDiscovery());
 
-        while (System.currentTimeMillis() - start < START_DISCOVERY_TIMEOUT) {
+        while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
             if (adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
                 writeOutput(String.format("startScan() completed in %d ms",
                         (receiver.getCompletedTime() - start)));
@@ -593,6 +691,12 @@
                 adapter.isDiscovering(), firedFlags, mask));
     }
 
+    /**
+     * Stops a scan for remote devices and checks to make sure that the local device is not scanning
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     */
     public void stopScan(BluetoothAdapter adapter) {
         int mask = BluetoothReceiver.DISCOVERY_FINISHED_FLAG;
 
@@ -610,7 +714,7 @@
         // TODO: put assertTrue() around cancelDiscovery() once it starts returning true.
         adapter.cancelDiscovery();
 
-        while (System.currentTimeMillis() - start < CANCEL_DISCOVERY_TIMEOUT) {
+        while (System.currentTimeMillis() - start < START_STOP_SCAN_TIMEOUT) {
             if (!adapter.isDiscovering() && ((receiver.getFiredFlags() & mask) == mask)) {
                 writeOutput(String.format("stopScan() completed in %d ms",
                         (receiver.getCompletedTime() - start)));
@@ -627,20 +731,84 @@
 
     }
 
+    /**
+     * Enables PAN tethering on the local device and checks to make sure that tethering is enabled.
+     *
+     * @param adapter The BT adapter.
+     */
+    public void enablePan(BluetoothAdapter adapter) {
+        BluetoothPan pan = new BluetoothPan(mContext);
+        assertNotNull(pan);
+
+        long start = System.currentTimeMillis();
+        pan.setBluetoothTethering(true);
+        long stop = System.currentTimeMillis();
+        assertTrue(pan.isTetheringOn());
+
+        writeOutput(String.format("enablePan() completed in %d ms", (stop - start)));
+    }
+
+    /**
+     * Disables PAN tethering on the local device and checks to make sure that tethering is
+     * disabled.
+     *
+     * @param adapter The BT adapter.
+     */
+    public void disablePan(BluetoothAdapter adapter) {
+        BluetoothPan pan = new BluetoothPan(mContext);
+        assertNotNull(pan);
+
+        long start = System.currentTimeMillis();
+        pan.setBluetoothTethering(false);
+        long stop = System.currentTimeMillis();
+        assertFalse(pan.isTetheringOn());
+
+        writeOutput(String.format("disablePan() completed in %d ms", (stop - start)));
+    }
+
+    /**
+     * Initiates a pairing with a remote device and checks to make sure that the devices are paired
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+     * @param pin The pairing pin if pairing requires a pin. Any value if not.
+     */
     public void pair(BluetoothAdapter adapter, BluetoothDevice device, int passkey, byte[] pin) {
         pairOrAcceptPair(adapter, device, passkey, pin, true);
     }
 
+    /**
+     * Accepts a pairing with a remote device and checks to make sure that the devices are paired
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+     * @param pin The pairing pin if pairing requires a pin. Any value if not.
+     */
     public void acceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
             byte[] pin) {
         pairOrAcceptPair(adapter, device, passkey, pin, false);
     }
 
+    /**
+     * Helper method used by {@link #pair(BluetoothAdapter, BluetoothDevice, int, byte[])} and
+     * {@link #acceptPair(BluetoothAdapter, BluetoothDevice, int, byte[])} to either pair or accept
+     * a pairing request.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param passkey The pairing passkey if pairing requires a passkey. Any value if not.
+     * @param pin The pairing pin if pairing requires a pin. Any value if not.
+     * @param shouldPair Whether to pair or accept the pair.
+     */
     private void pairOrAcceptPair(BluetoothAdapter adapter, BluetoothDevice device, int passkey,
-            byte[] pin, boolean pair) {
+            byte[] pin, boolean shouldPair) {
         int mask = PairReceiver.STATE_BONDING_FLAG | PairReceiver.STATE_BONDED_FLAG;
         long start = -1;
-        String methodName = pair ? "pair()" : "acceptPair()";
+        String methodName = shouldPair ? "pair()" : "acceptPair()";
 
         if (!adapter.isEnabled()) {
             fail(methodName + " bluetooth not enabled");
@@ -653,7 +821,7 @@
             case BluetoothDevice.BOND_NONE:
                 assertFalse(adapter.getBondedDevices().contains(device));
                 start = System.currentTimeMillis();
-                if (pair) {
+                if (shouldPair) {
                     assertTrue(device.createBond());
                 }
                 break;
@@ -670,21 +838,19 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < PAIR_TIMEOUT) {
+        while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
             state = device.getBondState();
-            if (state == BluetoothDevice.BOND_BONDED) {
+            if (state == BluetoothDevice.BOND_BONDED && (receiver.getFiredFlags() & mask) == mask) {
                 assertTrue(adapter.getBondedDevices().contains(device));
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
-                                (finish - start), device));
-                    } else {
-                        writeOutput(String.format("%s completed: device=%s", methodName, device));
-                    }
-                    removeReceiver(receiver);
-                    return;
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("%s completed: device=%s", methodName, device));
                 }
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -696,6 +862,13 @@
                 BluetoothDevice.BOND_BONDED, firedFlags, mask));
     }
 
+    /**
+     * Deletes a pairing with a remote device and checks to make sure that the devices are unpaired
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
     public void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
         int mask = PairReceiver.STATE_NONE_FLAG;
         long start = -1;
@@ -727,20 +900,19 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < UNPAIR_TIMEOUT) {
-            if (device.getBondState() == BluetoothDevice.BOND_NONE) {
+        while (System.currentTimeMillis() - s < PAIR_UNPAIR_TIMEOUT) {
+            if (device.getBondState() == BluetoothDevice.BOND_NONE
+                    && (receiver.getFiredFlags() & mask) == mask) {
                 assertFalse(adapter.getBondedDevices().contains(device));
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("unpair() completed in %d ms: device=%s",
-                                (finish - start), device));
-                    } else {
-                        writeOutput(String.format("unpair() completed: device=%s", device));
-                    }
-                    removeReceiver(receiver);
-                    return;
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("unpair() completed in %d ms: device=%s",
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("unpair() completed: device=%s", device));
                 }
+                removeReceiver(receiver);
+                return;
             }
         }
 
@@ -751,6 +923,15 @@
                 firedFlags, mask));
     }
 
+    /**
+     * Connects a profile from the local device to a remote device and checks to make sure that the
+     * profile is connected and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param profile The profile to connect. One of {@link BluetoothProfile#A2DP} or
+     *        {@link BluetoothProfile#HEADSET}.
+     */
     public void connectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile) {
         int mask = (ConnectProfileReceiver.STATE_CONNECTING_FLAG
                 | ConnectProfileReceiver.STATE_CONNECTED_FLAG);
@@ -794,21 +975,20 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < CONNECT_PROFILE_TIMEOUT) {
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
             state = proxy.getConnectionState(device);
-            if (state == BluetoothProfile.STATE_CONNECTED) {
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("connectProfile() completed in %d ms: "
-                                + "device=%s, profile=%d", (finish - start), device, profile));
-                    } else {
-                        writeOutput(String.format("connectProfile() completed: device=%s, "
-                                + "profile=%d", device, profile));
-                    }
-                    removeReceiver(receiver);
-                    return;
+            if (state == BluetoothProfile.STATE_CONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("connectProfile() completed in %d ms: "
+                            + "device=%s, profile=%d", (finish - start), device, profile));
+                } else {
+                    writeOutput(String.format("connectProfile() completed: device=%s, "
+                            + "profile=%d", device, profile));
                 }
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -820,6 +1000,15 @@
                 BluetoothProfile.STATE_CONNECTED, firedFlags, mask));
     }
 
+    /**
+     * Disconnects a profile between the local device and a remote device and checks to make sure
+     * that the profile is disconnected and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param profile The profile to disconnect. One of {@link BluetoothProfile#A2DP} or
+     *        {@link BluetoothProfile#HEADSET}.
+     */
     public void disconnectProfile(BluetoothAdapter adapter, BluetoothDevice device, int profile) {
         int mask = (ConnectProfileReceiver.STATE_DISCONNECTING_FLAG
                 | ConnectProfileReceiver.STATE_DISCONNECTED_FLAG);
@@ -863,21 +1052,20 @@
         }
 
         long s = System.currentTimeMillis();
-        while (System.currentTimeMillis() - s < DISCONNECT_PROFILE_TIMEOUT) {
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
             state = proxy.getConnectionState(device);
-            if (state == BluetoothProfile.STATE_DISCONNECTED) {
-                if ((receiver.getFiredFlags() & mask) == mask) {
-                    long finish = receiver.getCompletedTime();
-                    if (start != -1 && finish != -1) {
-                        writeOutput(String.format("disconnectProfile() completed in %d ms: "
-                                + "device=%s, profile=%d", (finish - start), device, profile));
-                    } else {
-                        writeOutput(String.format("disconnectProfile() completed: device=%s, "
-                                + "profile=%d", device, profile));
-                    }
-                    removeReceiver(receiver);
-                    return;
+            if (state == BluetoothProfile.STATE_DISCONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("disconnectProfile() completed in %d ms: "
+                            + "device=%s, profile=%d", (finish - start), device, profile));
+                } else {
+                    writeOutput(String.format("disconnectProfile() completed: device=%s, "
+                            + "profile=%d", device, profile));
                 }
+                removeReceiver(receiver);
+                return;
             }
             sleep(POLL_TIME);
         }
@@ -889,6 +1077,360 @@
                 BluetoothProfile.STATE_DISCONNECTED, firedFlags, mask));
     }
 
+    /**
+     * Connects the local device with a remote HID device and checks to make sure that the profile
+     * is connected and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void connectInput(BluetoothAdapter adapter, BluetoothDevice device) {
+        int mask = (ConnectInputReceiver.STATE_CONNECTING_FLAG
+                | ConnectInputReceiver.STATE_CONNECTED_FLAG);
+        long start = -1;
+
+        if (!adapter.isEnabled()) {
+            fail(String.format("connectInput() bluetooth not enabled: device=%s", device));
+        }
+
+        if (!adapter.getBondedDevices().contains(device)) {
+            fail(String.format("connectInput() device not paired: device=%s", device));
+        }
+
+        BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
+        assertNotNull(inputDevice);
+        ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
+
+        int state = inputDevice.getInputDeviceState(device);
+        switch (state) {
+            case BluetoothInputDevice.STATE_CONNECTED:
+                removeReceiver(receiver);
+                return;
+            case BluetoothInputDevice.STATE_CONNECTING:
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            case BluetoothInputDevice.STATE_DISCONNECTED:
+            case BluetoothInputDevice.STATE_DISCONNECTING:
+                start = System.currentTimeMillis();
+                assertTrue(inputDevice.connectInputDevice(device));
+                break;
+            default:
+                removeReceiver(receiver);
+                fail(String.format("connectInput() invalid state: device=%s, state=%d", device,
+                        state));
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+            state = inputDevice.getInputDeviceState(device);
+            if (state == BluetoothInputDevice.STATE_CONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("connectInput() completed in %d ms: device=%s",
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("connectInput() completed: device=%s", device));
+                }
+                removeReceiver(receiver);
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = receiver.getFiredFlags();
+        removeReceiver(receiver);
+        fail(String.format("connectInput() timeout: device=%s, state=%d (expected %d), "
+                + "flags=0x%x (expected 0x%s)", device, state, BluetoothInputDevice.STATE_CONNECTED,
+                firedFlags, mask));
+    }
+
+    /**
+     * Disconnects the local device with a remote HID device and checks to make sure that the
+     * profile is connected and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void disconnectInput(BluetoothAdapter adapter, BluetoothDevice device) {
+        int mask = (ConnectInputReceiver.STATE_DISCONNECTING_FLAG
+                | ConnectInputReceiver.STATE_DISCONNECTED_FLAG);
+        long start = -1;
+
+        if (!adapter.isEnabled()) {
+            fail(String.format("disconnectInput() bluetooth not enabled: device=%s", device));
+        }
+
+        if (!adapter.getBondedDevices().contains(device)) {
+            fail(String.format("disconnectInput() device not paired: device=%s", device));
+        }
+
+        BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
+        assertNotNull(inputDevice);
+        ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
+
+        int state = inputDevice.getInputDeviceState(device);
+        switch (state) {
+            case BluetoothInputDevice.STATE_CONNECTED:
+            case BluetoothInputDevice.STATE_CONNECTING:
+                start = System.currentTimeMillis();
+                assertTrue(inputDevice.disconnectInputDevice(device));
+                break;
+            case BluetoothInputDevice.STATE_DISCONNECTED:
+                removeReceiver(receiver);
+                return;
+            case BluetoothInputDevice.STATE_DISCONNECTING:
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            default:
+                removeReceiver(receiver);
+                fail(String.format("disconnectInput() invalid state: device=%s, state=%d", device,
+                        state));
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+            state = inputDevice.getInputDeviceState(device);
+            if (state == BluetoothInputDevice.STATE_DISCONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("disconnectInput() completed in %d ms: device=%s",
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("disconnectInput() completed: device=%s", device));
+                }
+                removeReceiver(receiver);
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = receiver.getFiredFlags();
+        removeReceiver(receiver);
+        fail(String.format("disconnectInput() timeout: device=%s, state=%d (expected %d), "
+                + "flags=0x%x (expected 0x%s)", device, state,
+                BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
+    }
+
+    /**
+     * Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
+     * the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void connectPan(BluetoothAdapter adapter, BluetoothDevice device) {
+        connectPanOrIncomingPanConnection(adapter, device, true);
+    }
+
+    /**
+     * Checks that a remote PANU connects to the local NAP correctly and that the correct actions
+     * were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void incomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device) {
+        connectPanOrIncomingPanConnection(adapter, device, false);
+    }
+
+    /**
+     * Helper method used by {@link #connectPan(BluetoothAdapter, BluetoothDevice)} and
+     * {@link #incomingPanConnection(BluetoothAdapter, BluetoothDevice)} to either connect to a
+     * remote NAP or verify that a remote device connected to the local NAP.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param connect If the method should initiate the connection (is PANU)
+     */
+    private void connectPanOrIncomingPanConnection(BluetoothAdapter adapter, BluetoothDevice device,
+            boolean connect) {
+        long start = -1;
+        int mask, role;
+        String methodName;
+
+        if (connect) {
+            methodName = "connectPan()";
+            mask = (ConnectPanReceiver.STATE_CONNECTED_FLAG |
+                    ConnectPanReceiver.STATE_CONNECTING_FLAG);
+            role = BluetoothPan.LOCAL_PANU_ROLE;
+        } else {
+            methodName = "incomingPanConnection()";
+            mask = ConnectPanReceiver.STATE_CONNECTED_FLAG;
+            role = BluetoothPan.LOCAL_NAP_ROLE;
+        }
+
+        if (!adapter.isEnabled()) {
+            fail(String.format("%s bluetooth not enabled: device=%s", methodName, device));
+        }
+
+        if (!adapter.getBondedDevices().contains(device)) {
+            fail(String.format("%s device not paired: device=%s", methodName, device));
+        }
+
+        BluetoothPan pan = new BluetoothPan(mContext);
+        assertNotNull(pan);
+        ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
+
+        int state = pan.getPanDeviceState(device);
+        switch (state) {
+            case BluetoothPan.STATE_CONNECTED:
+                removeReceiver(receiver);
+                return;
+            case BluetoothPan.STATE_CONNECTING:
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            case BluetoothPan.STATE_DISCONNECTED:
+            case BluetoothPan.STATE_DISCONNECTING:
+                start = System.currentTimeMillis();
+                if (role == BluetoothPan.LOCAL_PANU_ROLE) {
+                    Log.i("BT", "connect to pan");
+                    assertTrue(pan.connect(device));
+                }
+                break;
+            default:
+                removeReceiver(receiver);
+                fail(String.format("%s invalid state: device=%s, state=%d", methodName, device,
+                        state));
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+            state = pan.getPanDeviceState(device);
+            if (state == BluetoothPan.STATE_CONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("%s completed: device=%s", methodName, device));
+                }
+                removeReceiver(receiver);
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = receiver.getFiredFlags();
+        removeReceiver(receiver);
+        fail(String.format("%s timeout: device=%s, state=%d (expected %d), "
+                + "flags=0x%x (expected 0x%s)", methodName, device, state,
+                BluetoothPan.STATE_CONNECTED, firedFlags, mask));
+    }
+
+    /**
+     * Disconnects the PANU from a remote NAP and checks to make sure that the PANU is disconnected
+     * and that the correct actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void disconnectPan(BluetoothAdapter adapter, BluetoothDevice device) {
+        disconnectFromRemoteOrVerifyConnectNap(adapter, device, true);
+    }
+
+    /**
+     * Checks that a remote PANU disconnects from the local NAP correctly and that the correct
+     * actions were broadcast.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     */
+    public void incomingPanDisconnection(BluetoothAdapter adapter, BluetoothDevice device) {
+        disconnectFromRemoteOrVerifyConnectNap(adapter, device, false);
+    }
+
+    /**
+     * Helper method used by {@link #disconnectPan(BluetoothAdapter, BluetoothDevice)} and
+     * {@link #incomingPanDisconnection(BluetoothAdapter, BluetoothDevice)} to either disconnect
+     * from a remote NAP or verify that a remote device disconnected from the local NAP.
+     *
+     * @param adapter The BT adapter.
+     * @param device The remote device.
+     * @param disconnect Whether the method should connect or verify.
+     */
+    private void disconnectFromRemoteOrVerifyConnectNap(BluetoothAdapter adapter,
+            BluetoothDevice device, boolean disconnect) {
+        long start = -1;
+        int mask, role;
+        String methodName;
+
+        if (disconnect) {
+            methodName = "disconnectPan()";
+            mask = (ConnectPanReceiver.STATE_DISCONNECTED_FLAG |
+                    ConnectPanReceiver.STATE_DISCONNECTING_FLAG);
+            role = BluetoothPan.LOCAL_PANU_ROLE;
+        } else {
+            methodName = "incomingPanDisconnection()";
+            mask = ConnectPanReceiver.STATE_DISCONNECTED_FLAG;
+            role = BluetoothPan.LOCAL_NAP_ROLE;
+        }
+
+        if (!adapter.isEnabled()) {
+            fail(String.format("%s bluetooth not enabled: device=%s", methodName, device));
+        }
+
+        if (!adapter.getBondedDevices().contains(device)) {
+            fail(String.format("%s device not paired: device=%s", methodName, device));
+        }
+
+        BluetoothPan pan = new BluetoothPan(mContext);
+        assertNotNull(pan);
+        ConnectPanReceiver receiver = getConnectPanReceiver(device, role, mask);
+
+        int state = pan.getPanDeviceState(device);
+        switch (state) {
+            case BluetoothInputDevice.STATE_CONNECTED:
+            case BluetoothInputDevice.STATE_CONNECTING:
+                start = System.currentTimeMillis();
+                if (role == BluetoothPan.LOCAL_PANU_ROLE) {
+                    assertTrue(pan.disconnect(device));
+                }
+                break;
+            case BluetoothInputDevice.STATE_DISCONNECTED:
+                removeReceiver(receiver);
+                return;
+            case BluetoothInputDevice.STATE_DISCONNECTING:
+                mask = 0; // Don't check for received intents since we might have missed them.
+                break;
+            default:
+                removeReceiver(receiver);
+                fail(String.format("%s invalid state: device=%s, state=%d", methodName, device,
+                        state));
+        }
+
+        long s = System.currentTimeMillis();
+        while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
+            state = pan.getPanDeviceState(device);
+            if (state == BluetoothInputDevice.STATE_DISCONNECTED
+                    && (receiver.getFiredFlags() & mask) == mask) {
+                long finish = receiver.getCompletedTime();
+                if (start != -1 && finish != -1) {
+                    writeOutput(String.format("%s completed in %d ms: device=%s", methodName,
+                            (finish - start), device));
+                } else {
+                    writeOutput(String.format("%s completed: device=%s", methodName, device));
+                }
+                removeReceiver(receiver);
+                return;
+            }
+            sleep(POLL_TIME);
+        }
+
+        int firedFlags = receiver.getFiredFlags();
+        removeReceiver(receiver);
+        fail(String.format("%s timeout: device=%s, state=%d (expected %d), "
+                + "flags=0x%x (expected 0x%s)", methodName, device, state,
+                BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
+    }
+
+    /**
+     * Writes a string to the logcat and a file if a file has been specified in the constructor.
+     *
+     * @param s The string to be written.
+     */
     public void writeOutput(String s) {
         Log.i(mTag, s);
         if (mOutputWriter == null) {
@@ -902,38 +1444,60 @@
         }
     }
 
-    private BluetoothReceiver getBluetoothReceiver(int expectedFlags) {
-        BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags);
+    private void addReceiver(BroadcastReceiver receiver, String[] actions) {
         IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
-        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
-        filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
-        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+        for (String action: actions) {
+            filter.addAction(action);
+        }
         mContext.registerReceiver(receiver, filter);
         mReceivers.add(receiver);
+    }
+
+    private BluetoothReceiver getBluetoothReceiver(int expectedFlags) {
+        String[] actions = {
+                BluetoothAdapter.ACTION_DISCOVERY_FINISHED,
+                BluetoothAdapter.ACTION_DISCOVERY_STARTED,
+                BluetoothAdapter.ACTION_SCAN_MODE_CHANGED,
+                BluetoothAdapter.ACTION_STATE_CHANGED};
+        BluetoothReceiver receiver = new BluetoothReceiver(expectedFlags);
+        addReceiver(receiver, actions);
         return receiver;
     }
 
     private PairReceiver getPairReceiver(BluetoothDevice device, int passkey, byte[] pin,
             int expectedFlags) {
+        String[] actions = {
+                BluetoothDevice.ACTION_PAIRING_REQUEST,
+                BluetoothDevice.ACTION_BOND_STATE_CHANGED};
         PairReceiver receiver = new PairReceiver(device, passkey, pin, expectedFlags);
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
-        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        mReceivers.add(receiver);
+        addReceiver(receiver, actions);
         return receiver;
     }
 
     private ConnectProfileReceiver getConnectProfileReceiver(BluetoothDevice device, int profile,
             int expectedFlags) {
+        String[] actions = {
+                BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
+                BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED};
         ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
                 expectedFlags);
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
-        filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
-        mContext.registerReceiver(receiver, filter);
-        mReceivers.add(receiver);
+        addReceiver(receiver, actions);
+        return receiver;
+    }
+
+    private ConnectInputReceiver getConnectInputReceiver(BluetoothDevice device,
+            int expectedFlags) {
+        String[] actions = {BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED};
+        ConnectInputReceiver receiver = new ConnectInputReceiver(device, expectedFlags);
+        addReceiver(receiver, actions);
+        return receiver;
+    }
+
+    private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
+            int expectedFlags) {
+        String[] actions = {BluetoothPan.ACTION_PAN_STATE_CHANGED};
+        ConnectPanReceiver receiver = new ConnectPanReceiver(device, role, expectedFlags);
+        addReceiver(receiver, actions);
         return receiver;
     }
 
diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index 97b31cf..fe69d7d 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -8,14 +8,13 @@
 <ol>
   <li><a href="#intro">Introduction</a></li>
   <li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
-  <li><a href="#object_creation">Avoid Creating Objects</a></li>
+  <li><a href="#object_creation">Avoid Creating Unnecessary Objects</a></li>
   <li><a href="#myths">Performance Myths</a></li>
   <li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
   <li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
   <li><a href="#use_final">Use Static Final For Constants</a></li>
   <li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
-  <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
-  <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
+  <li><a href="#package_inner">Consider Package Instead of Private Access with Inner Classes</a></li>
   <li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
   <li><a href="#library">Know And Use The Libraries</a></li>
   <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
@@ -83,27 +82,31 @@
 test on that device.</p>
 
 <a name="object_creation"></a>
-<h2>Avoid Creating Objects</h2>
+<h2>Avoid Creating Unnecessary Objects</h2>
 
 <p>Object creation is never free. A generational GC with per-thread allocation
 pools for temporary objects can make allocation cheaper, but allocating memory
 is always more expensive than not allocating memory.</p>
 
 <p>If you allocate objects in a user interface loop, you will force a periodic
-garbage collection, creating little "hiccups" in the user experience.</p>
+garbage collection, creating little "hiccups" in the user experience. The
+concurrent collector introduced in Gingerbread helps, but unnecessary work
+should always be avoided.</p>
 
 <p>Thus, you should avoid creating object instances you don't need to.  Some
 examples of things that can help:</p>
 
 <ul>
-    <li>When extracting strings from a set of input data, try 
-    to return a substring of the original data, instead of creating a copy.
-    You will create a new String object, but it will share the char[]
-    with the data.</li>
     <li>If you have a method returning a string, and you know that its result
     will always be appended to a StringBuffer anyway, change your signature
     and implementation so that the function does the append directly,
     instead of creating a short-lived temporary object.</li>
+    <li>When extracting strings from a set of input data, try
+    to return a substring of the original data, instead of creating a copy.
+    You will create a new String object, but it will share the char[]
+    with the data. (The trade-off being that if you're only using a small
+    part of the original input, you'll be keeping it all around in memory
+    anyway if you go this route.)</li>
 </ul>
 
 <p>A somewhat more radical idea is to slice up multidimensional arrays into
@@ -119,7 +122,7 @@
     generally much better than a single array of custom (Foo,Bar) objects.
     (The exception to this, of course, is when you're designing an API for
     other code to access;  in those cases, it's usually better to trade
-    correct API design for a small hit in speed. But in your own internal 
+    good API design for a small hit in speed. But in your own internal
     code, you should try and be as efficient as possible.)</li>
 </ul>
 
@@ -127,6 +130,7 @@
 can.  Fewer objects created mean less-frequent garbage collection, which has
 a direct impact on user experience.</p>
 
+<a name="avoid_enums" id="avoid_enums"></a>
 <a name="myths" id="myths"></a>
 <h2>Performance Myths</h2>
 
@@ -265,43 +269,18 @@
 
 <p>(See also <em>Effective Java</em> item 46.)</p>
 
-<a name="avoid_enums" id="avoid_enums"></a>
-<h2>Avoid Enums Where You Only Need Ints</h2>
-
-<p>Enums are very convenient, but unfortunately can be painful when size
-and speed matter.  For example, this:</p>
-
-<pre>public enum Shrubbery { GROUND, CRAWLING, HANGING }</pre>
-
-<p>adds 740 bytes to your .dex file compared to the equivalent class
-with three public static final ints. On first use, the
-class initializer invokes the &lt;init&gt; method on objects representing each
-of the enumerated values. Each object gets its own static field, and the full
-set is stored in an array (a static field called "$VALUES"). That's a lot of
-code and data, just for three integers. Additionally, this:</p>
-
-<pre>Shrubbery shrub = Shrubbery.GROUND;</pre>
-
-<p>causes a static field lookup.  If "GROUND" were a static final int,
-the compiler would treat it as a known constant and inline it.</p>
-
-<p>The flip side, of course, is that with enums you get nicer APIs and
-some compile-time value checking.  So, the usual trade-off applies: you should
-by all means use enums for public APIs, but try to avoid them when performance
-matters.</p>
-
-<p>If you're using <code>Enum.ordinal</code>, that's usually a sign that you
-should be using ints instead. As a rule of thumb, if an enum doesn't have a
-constructor and doesn't define its own methods, and it's used in
-performance-critical code, you should consider <code>static final int</code>
-constants instead.</p>
-
 <a name="package_inner" id="package_inner"></a>
-<h2>Use Package Scope with Inner Classes</h2>
+<h2>Consider Package Instead of Private Access with Private Inner Classes</h2>
 
 <p>Consider the following class definition:</p>
 
 <pre>public class Foo {
+    private class Inner {
+        void stuff() {
+            Foo.this.doStuff(Foo.this.mValue);
+        }
+    }
+
     private int mValue;
 
     public void run() {
@@ -313,24 +292,19 @@
     private void doStuff(int value) {
         System.out.println("Value is " + value);
     }
-
-    private class Inner {
-        void stuff() {
-            Foo.this.doStuff(Foo.this.mValue);
-        }
-    }
 }</pre>
 
-<p>The key things to note here are that we define an inner class (Foo$Inner)
-that directly accesses a private method and a private instance field
-in the outer class.  This is legal, and the code prints "Value is 27" as
-expected.</p>
+<p>The key things to note here are that we define a private inner class
+(<code>Foo$Inner</code>) that directly accesses a private method and a private
+instance field in the outer class. This is legal, and the code prints "Value is
+27" as expected.</p>
 
-<p>The problem is that the VM considers direct access to Foo's private members
-from Foo$Inner to be illegal because Foo and Foo$Inner are different classes,
-even though the Java language allows an inner class to access an outer class'
-private members. To bridge the gap, the compiler generates a couple of
-synthetic methods:</p>
+<p>The problem is that the VM considers direct access to <code>Foo</code>'s
+private members from <code>Foo$Inner</code> to be illegal because
+<code>Foo</code> and <code>Foo$Inner</code> are different classes, even though
+the Java language allows an inner class to access an outer class' private
+members. To bridge the gap, the compiler generates a couple of synthetic
+methods:</p>
 
 <pre>/*package*/ static int Foo.access$100(Foo foo) {
     return foo.mValue;
@@ -339,22 +313,19 @@
     foo.doStuff(value);
 }</pre>
 
-<p>The inner-class code calls these static methods whenever it needs to
-access the "mValue" field or invoke the "doStuff" method in the outer
-class. What this means is that the code above really boils down to a case
-where you're accessing member fields through accessor methods instead of
-directly.  Earlier we talked about how accessors are slower than direct field
+<p>The inner class code calls these static methods whenever it needs to
+access the <code>mValue</code> field or invoke the <code>doStuff</code> method
+in the outer class. What this means is that the code above really boils down to
+a case where you're accessing member fields through accessor methods.
+Earlier we talked about how accessors are slower than direct field
 accesses, so this is an example of a certain language idiom resulting in an
 "invisible" performance hit.</p>
 
-<p>We can avoid this problem by declaring fields and methods accessed
-by inner classes to have package scope, rather than private scope.
-This runs faster and removes the overhead of the generated methods.
-(Unfortunately it also means the fields could be accessed directly by other
-classes in the same package, which runs counter to the standard
-practice of making all fields private. Once again, if you're
-designing a public API you might want to carefully consider using this
-optimization.)</p>
+<p>If you're using code like this in a performance hotspot, you can avoid the
+overhead by declaring fields and methods accessed by inner classes to have
+package access, rather than private access. Unfortunately this means the fields
+can be accessed directly by other classes in the same package, so you shouldn't
+use this in public API.</p>
 
 <a name="avoidfloat" id="avoidfloat"></a>
 <h2>Use Floating-Point Judiciously</h2>
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 221406c..233838b 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -405,6 +405,16 @@
     }
   },
   {
+    tags: ['sample', 'new'],
+    path: 'samples/Honeycomb-Gallery/index.html',
+    title: {
+      en: 'Honeycomb Gallery'
+    },
+    description: {
+      en: 'An image gallery application using Honeycomb-specific APIs.'
+    }
+  },
+  {
     tags: ['sample', 'gamedev', 'media'],
     path: 'samples/JetBoy/index.html',
     title: {
diff --git a/docs/html/resources/samples/images/hcgallery.png b/docs/html/resources/samples/images/hcgallery.png
new file mode 100644
index 0000000..9a80fd7
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery.png
Binary files differ
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 75edac6..ddbd220 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -382,7 +382,7 @@
     }
 
     data.writeInt32(playbackStatus);
-    data.writeInt32(position);
+    data.writeInt64(position);
 
     remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
     return reply.readInt32();
@@ -1111,7 +1111,7 @@
         }
 
         const status_t status
-            = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+            = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
         reply->writeInt32(status);
 
         delete handle.decryptInfo; handle.decryptInfo = NULL;
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index e540806..27ea0f0 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -287,6 +287,10 @@
                         region2.mNativeRegion, op.nativeInt);
     }
 
+    public String toString() {
+        return nativeToString(mNativeRegion);
+    }
+
     //////////////////////////////////////////////////////////////////////////
     
     public static final Parcelable.Creator<Region> CREATOR
@@ -357,6 +361,8 @@
         return mNativeRegion;
     }
 
+    private static native boolean nativeEquals(int native_r1, int native_r2);
+
     private static native int nativeConstructor();
     private static native void nativeDestructor(int native_region);
 
@@ -381,5 +387,5 @@
     private static native boolean nativeWriteToParcel(int native_region,
                                                       Parcel p);
 
-    private static native boolean nativeEquals(int native_r1, int native_r2);
+    private static native String nativeToString(int native_region);
 }
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 1789891..74cdf80 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -268,22 +268,105 @@
         }
     }
 
+    /**
+     * Copy an allocation from an array.  This variant is not type
+     * checked which allows an application to fill in structured
+     * data from an array.
+     *
+     * @param d the source data array
+     */
+    public void copyFromUnchecked(int[] d) {
+        mRS.validate();
+        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+    }
+    /**
+     * Copy an allocation from an array.  This variant is not type
+     * checked which allows an application to fill in structured
+     * data from an array.
+     *
+     * @param d the source data array
+     */
+    public void copyFromUnchecked(short[] d) {
+        mRS.validate();
+        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+    }
+    /**
+     * Copy an allocation from an array.  This variant is not type
+     * checked which allows an application to fill in structured
+     * data from an array.
+     *
+     * @param d the source data array
+     */
+    public void copyFromUnchecked(byte[] d) {
+        mRS.validate();
+        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+    }
+    /**
+     * Copy an allocation from an array.  This variant is not type
+     * checked which allows an application to fill in structured
+     * data from an array.
+     *
+     * @param d the source data array
+     */
+    public void copyFromUnchecked(float[] d) {
+        mRS.validate();
+        copy1DRangeFromUnchecked(0, mType.getCount(), d);
+    }
+
+    /**
+     * Copy an allocation from an array.  This variant is type
+     * checked and will generate exceptions if the Allocation type
+     * is not a 32 bit integer type.
+     *
+     * @param d the source data array
+     */
     public void copyFrom(int[] d) {
         mRS.validate();
         copy1DRangeFrom(0, mType.getCount(), d);
     }
+
+    /**
+     * Copy an allocation from an array.  This variant is type
+     * checked and will generate exceptions if the Allocation type
+     * is not a 16 bit integer type.
+     *
+     * @param d the source data array
+     */
     public void copyFrom(short[] d) {
         mRS.validate();
         copy1DRangeFrom(0, mType.getCount(), d);
     }
+
+    /**
+     * Copy an allocation from an array.  This variant is type
+     * checked and will generate exceptions if the Allocation type
+     * is not a 8 bit integer type.
+     *
+     * @param d the source data array
+     */
     public void copyFrom(byte[] d) {
         mRS.validate();
         copy1DRangeFrom(0, mType.getCount(), d);
     }
+
+    /**
+     * Copy an allocation from an array.  This variant is type
+     * checked and will generate exceptions if the Allocation type
+     * is not a 32 bit float type.
+     *
+     * @param d the source data array
+     */
     public void copyFrom(float[] d) {
         mRS.validate();
         copy1DRangeFrom(0, mType.getCount(), d);
     }
+
+    /**
+     * Copy an allocation from a bitmap.  The height, width, and
+     * format of the bitmap must match the existing allocation.
+     *
+     * @param b the source bitmap
+     */
     public void copyFrom(Bitmap b) {
         mRS.validate();
         validateBitmapSize(b);
@@ -369,39 +452,114 @@
         mRS.nAllocationGenerateMipmaps(getID());
     }
 
-    void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * not type checked which allows an application to fill in
+     * structured data from an array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
         mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
     }
-    void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * not type checked which allows an application to fill in
+     * structured data from an array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 2, dataSize);
         mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
     }
-    void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * not type checked which allows an application to fill in
+     * structured data from an array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length, dataSize);
         mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
     }
-    void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * not type checked which allows an application to fill in
+     * structured data from an array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
         int dataSize = mType.mElement.getSizeBytes() * count;
         data1DChecks(off, count, d.length * 4, dataSize);
         mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
     }
 
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * type checked and will generate exceptions if the Allocation
+     * type is not a 32 bit integer type.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
     public void copy1DRangeFrom(int off, int count, int[] d) {
         validateIsInt32();
         copy1DRangeFromUnchecked(off, count, d);
     }
+
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * type checked and will generate exceptions if the Allocation
+     * type is not a 16 bit integer type.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
     public void copy1DRangeFrom(int off, int count, short[] d) {
         validateIsInt16();
         copy1DRangeFromUnchecked(off, count, d);
     }
+
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * type checked and will generate exceptions if the Allocation
+     * type is not a 8 bit integer type.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
     public void copy1DRangeFrom(int off, int count, byte[] d) {
         validateIsInt8();
         copy1DRangeFromUnchecked(off, count, d);
     }
+
+    /**
+     * Copy part of an allocation from an array.  This variant is
+     * type checked and will generate exceptions if the Allocation
+     * type is not a 32 bit float type.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source data array
+     */
     public void copy1DRangeFrom(int off, int count, float[] d) {
         validateIsFloat32();
         copy1DRangeFromUnchecked(off, count, d);
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 28b32d5..bb9fb78 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -101,414 +101,515 @@
     }
     native void rsnContextDestroy(int con);
     synchronized void nContextDestroy() {
+        validate();
         rsnContextDestroy(mContext);
     }
     native void rsnContextSetSurface(int con, int w, int h, Surface sur);
     synchronized void nContextSetSurface(int w, int h, Surface sur) {
+        validate();
         rsnContextSetSurface(mContext, w, h, sur);
     }
     native void rsnContextSetPriority(int con, int p);
     synchronized void nContextSetPriority(int p) {
+        validate();
         rsnContextSetPriority(mContext, p);
     }
     native void rsnContextDump(int con, int bits);
     synchronized void nContextDump(int bits) {
+        validate();
         rsnContextDump(mContext, bits);
     }
     native void rsnContextFinish(int con);
     synchronized void nContextFinish() {
+        validate();
         rsnContextFinish(mContext);
     }
 
     native void rsnContextBindRootScript(int con, int script);
     synchronized void nContextBindRootScript(int script) {
+        validate();
         rsnContextBindRootScript(mContext, script);
     }
     native void rsnContextBindSampler(int con, int sampler, int slot);
     synchronized void nContextBindSampler(int sampler, int slot) {
+        validate();
         rsnContextBindSampler(mContext, sampler, slot);
     }
     native void rsnContextBindProgramStore(int con, int pfs);
     synchronized void nContextBindProgramStore(int pfs) {
+        validate();
         rsnContextBindProgramStore(mContext, pfs);
     }
     native void rsnContextBindProgramFragment(int con, int pf);
     synchronized void nContextBindProgramFragment(int pf) {
+        validate();
         rsnContextBindProgramFragment(mContext, pf);
     }
     native void rsnContextBindProgramVertex(int con, int pv);
     synchronized void nContextBindProgramVertex(int pv) {
+        validate();
         rsnContextBindProgramVertex(mContext, pv);
     }
     native void rsnContextBindProgramRaster(int con, int pr);
     synchronized void nContextBindProgramRaster(int pr) {
+        validate();
         rsnContextBindProgramRaster(mContext, pr);
     }
     native void rsnContextPause(int con);
     synchronized void nContextPause() {
+        validate();
         rsnContextPause(mContext);
     }
     native void rsnContextResume(int con);
     synchronized void nContextResume() {
+        validate();
         rsnContextResume(mContext);
     }
 
     native void rsnAssignName(int con, int obj, byte[] name);
     synchronized void nAssignName(int obj, byte[] name) {
+        validate();
         rsnAssignName(mContext, obj, name);
     }
     native String rsnGetName(int con, int obj);
     synchronized String nGetName(int obj) {
+        validate();
         return rsnGetName(mContext, obj);
     }
     native void rsnObjDestroy(int con, int id);
     synchronized void nObjDestroy(int id) {
-        rsnObjDestroy(mContext, id);
+        // There is a race condition here.  The calling code may be run
+        // by the gc while teardown is occuring.  This protects againts
+        // deleting dead objects.
+        if (mContext != 0) {
+            rsnObjDestroy(mContext, id);
+        }
     }
 
     native int  rsnElementCreate(int con, int type, int kind, boolean norm, int vecSize);
     synchronized int nElementCreate(int type, int kind, boolean norm, int vecSize) {
+        validate();
         return rsnElementCreate(mContext, type, kind, norm, vecSize);
     }
     native int  rsnElementCreate2(int con, int[] elements, String[] names, int[] arraySizes);
     synchronized int nElementCreate2(int[] elements, String[] names, int[] arraySizes) {
+        validate();
         return rsnElementCreate2(mContext, elements, names, arraySizes);
     }
     native void rsnElementGetNativeData(int con, int id, int[] elementData);
     synchronized void nElementGetNativeData(int id, int[] elementData) {
+        validate();
         rsnElementGetNativeData(mContext, id, elementData);
     }
     native void rsnElementGetSubElements(int con, int id, int[] IDs, String[] names);
     synchronized void nElementGetSubElements(int id, int[] IDs, String[] names) {
+        validate();
         rsnElementGetSubElements(mContext, id, IDs, names);
     }
 
     native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
     synchronized int nTypeCreate(int eid, int x, int y, int z, boolean mips, boolean faces) {
+        validate();
         return rsnTypeCreate(mContext, eid, x, y, z, mips, faces);
     }
     native void rsnTypeGetNativeData(int con, int id, int[] typeData);
     synchronized void nTypeGetNativeData(int id, int[] typeData) {
+        validate();
         rsnTypeGetNativeData(mContext, id, typeData);
     }
 
     native int  rsnAllocationCreateTyped(int con, int type, int mip, int usage);
     synchronized int nAllocationCreateTyped(int type, int mip, int usage) {
+        validate();
         return rsnAllocationCreateTyped(mContext, type, mip, usage);
     }
     native int  rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
     synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+        validate();
         return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
     }
     native int  rsnAllocationCubeCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
     synchronized int nAllocationCubeCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
+        validate();
         return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
     }
     native int  rsnAllocationCreateBitmapRef(int con, int type, Bitmap bmp);
     synchronized int nAllocationCreateBitmapRef(int type, Bitmap bmp) {
+        validate();
         return rsnAllocationCreateBitmapRef(mContext, type, bmp);
     }
     native int  rsnAllocationCreateFromAssetStream(int con, int mips, int assetStream, int usage);
     synchronized int nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
+        validate();
         return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
     }
 
     native void  rsnAllocationCopyToBitmap(int con, int alloc, Bitmap bmp);
     synchronized void nAllocationCopyToBitmap(int alloc, Bitmap bmp) {
+        validate();
         rsnAllocationCopyToBitmap(mContext, alloc, bmp);
     }
 
 
     native void rsnAllocationSyncAll(int con, int alloc, int src);
     synchronized void nAllocationSyncAll(int alloc, int src) {
+        validate();
         rsnAllocationSyncAll(mContext, alloc, src);
     }
     native void rsnAllocationGenerateMipmaps(int con, int alloc);
     synchronized void nAllocationGenerateMipmaps(int alloc) {
+        validate();
         rsnAllocationGenerateMipmaps(mContext, alloc);
     }
     native void  rsnAllocationCopyFromBitmap(int con, int alloc, Bitmap bmp);
     synchronized void nAllocationCopyFromBitmap(int alloc, Bitmap bmp) {
+        validate();
         rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
     }
 
 
     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, int[] d, int sizeBytes);
     synchronized void nAllocationData1D(int id, int off, int mip, int count, int[] d, int sizeBytes) {
+        validate();
         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
     }
     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, short[] d, int sizeBytes);
     synchronized void nAllocationData1D(int id, int off, int mip, int count, short[] d, int sizeBytes) {
+        validate();
         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
     }
     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, byte[] d, int sizeBytes);
     synchronized void nAllocationData1D(int id, int off, int mip, int count, byte[] d, int sizeBytes) {
+        validate();
         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
     }
     native void rsnAllocationData1D(int con, int id, int off, int mip, int count, float[] d, int sizeBytes);
     synchronized void nAllocationData1D(int id, int off, int mip, int count, float[] d, int sizeBytes) {
+        validate();
         rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes);
     }
 
     native void rsnAllocationElementData1D(int con, int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
     synchronized void nAllocationElementData1D(int id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+        validate();
         rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
     }
 
     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes);
     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, byte[] d, int sizeBytes) {
+        validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
     }
     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes);
     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, short[] d, int sizeBytes) {
+        validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
     }
     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes);
     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, int[] d, int sizeBytes) {
+        validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
     }
     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes);
     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, int w, int h, float[] d, int sizeBytes) {
+        validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes);
     }
     native void rsnAllocationData2D(int con, int id, int xoff, int yoff, int mip, int face, Bitmap b);
     synchronized void nAllocationData2D(int id, int xoff, int yoff, int mip, int face, Bitmap b) {
+        validate();
         rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
     }
 
     native void rsnAllocationRead(int con, int id, byte[] d);
     synchronized void nAllocationRead(int id, byte[] d) {
+        validate();
         rsnAllocationRead(mContext, id, d);
     }
     native void rsnAllocationRead(int con, int id, short[] d);
     synchronized void nAllocationRead(int id, short[] d) {
+        validate();
         rsnAllocationRead(mContext, id, d);
     }
     native void rsnAllocationRead(int con, int id, int[] d);
     synchronized void nAllocationRead(int id, int[] d) {
+        validate();
         rsnAllocationRead(mContext, id, d);
     }
     native void rsnAllocationRead(int con, int id, float[] d);
     synchronized void nAllocationRead(int id, float[] d) {
+        validate();
         rsnAllocationRead(mContext, id, d);
     }
     native int  rsnAllocationGetType(int con, int id);
     synchronized int nAllocationGetType(int id) {
+        validate();
         return rsnAllocationGetType(mContext, id);
     }
 
     native void rsnAllocationResize1D(int con, int id, int dimX);
     synchronized void nAllocationResize1D(int id, int dimX) {
+        validate();
         rsnAllocationResize1D(mContext, id, dimX);
     }
     native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
     synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
+        validate();
         rsnAllocationResize2D(mContext, id, dimX, dimY);
     }
 
     native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
     synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
+        validate();
         return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
     }
     native int  rsnFileA3DCreateFromFile(int con, String path);
     synchronized int nFileA3DCreateFromFile(String path) {
+        validate();
         return rsnFileA3DCreateFromFile(mContext, path);
     }
     native int  rsnFileA3DCreateFromAsset(int con, AssetManager mgr, String path);
     synchronized int nFileA3DCreateFromAsset(AssetManager mgr, String path) {
+        validate();
         return rsnFileA3DCreateFromAsset(mContext, mgr, path);
     }
     native int  rsnFileA3DGetNumIndexEntries(int con, int fileA3D);
     synchronized int nFileA3DGetNumIndexEntries(int fileA3D) {
+        validate();
         return rsnFileA3DGetNumIndexEntries(mContext, fileA3D);
     }
     native void rsnFileA3DGetIndexEntries(int con, int fileA3D, int numEntries, int[] IDs, String[] names);
     synchronized void nFileA3DGetIndexEntries(int fileA3D, int numEntries, int[] IDs, String[] names) {
+        validate();
         rsnFileA3DGetIndexEntries(mContext, fileA3D, numEntries, IDs, names);
     }
     native int  rsnFileA3DGetEntryByIndex(int con, int fileA3D, int index);
     synchronized int nFileA3DGetEntryByIndex(int fileA3D, int index) {
+        validate();
         return rsnFileA3DGetEntryByIndex(mContext, fileA3D, index);
     }
 
     native int  rsnFontCreateFromFile(int con, String fileName, float size, int dpi);
     synchronized int nFontCreateFromFile(String fileName, float size, int dpi) {
+        validate();
         return rsnFontCreateFromFile(mContext, fileName, size, dpi);
     }
     native int  rsnFontCreateFromAssetStream(int con, String name, float size, int dpi, int assetStream);
     synchronized int nFontCreateFromAssetStream(String name, float size, int dpi, int assetStream) {
+        validate();
         return rsnFontCreateFromAssetStream(mContext, name, size, dpi, assetStream);
     }
     native int  rsnFontCreateFromAsset(int con, AssetManager mgr, String path, float size, int dpi);
     synchronized int nFontCreateFromAsset(AssetManager mgr, String path, float size, int dpi) {
+        validate();
         return rsnFontCreateFromAsset(mContext, mgr, path, size, dpi);
     }
 
 
     native void rsnScriptBindAllocation(int con, int script, int alloc, int slot);
     synchronized void nScriptBindAllocation(int script, int alloc, int slot) {
+        validate();
         rsnScriptBindAllocation(mContext, script, alloc, slot);
     }
     native void rsnScriptSetTimeZone(int con, int script, byte[] timeZone);
     synchronized void nScriptSetTimeZone(int script, byte[] timeZone) {
+        validate();
         rsnScriptSetTimeZone(mContext, script, timeZone);
     }
     native void rsnScriptInvoke(int con, int id, int slot);
     synchronized void nScriptInvoke(int id, int slot) {
+        validate();
         rsnScriptInvoke(mContext, id, slot);
     }
     native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
     synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
+        validate();
         rsnScriptInvokeV(mContext, id, slot, params);
     }
     native void rsnScriptSetVarI(int con, int id, int slot, int val);
     synchronized void nScriptSetVarI(int id, int slot, int val) {
+        validate();
         rsnScriptSetVarI(mContext, id, slot, val);
     }
     native void rsnScriptSetVarJ(int con, int id, int slot, long val);
     synchronized void nScriptSetVarJ(int id, int slot, long val) {
+        validate();
         rsnScriptSetVarJ(mContext, id, slot, val);
     }
     native void rsnScriptSetVarF(int con, int id, int slot, float val);
     synchronized void nScriptSetVarF(int id, int slot, float val) {
+        validate();
         rsnScriptSetVarF(mContext, id, slot, val);
     }
     native void rsnScriptSetVarD(int con, int id, int slot, double val);
     synchronized void nScriptSetVarD(int id, int slot, double val) {
+        validate();
         rsnScriptSetVarD(mContext, id, slot, val);
     }
     native void rsnScriptSetVarV(int con, int id, int slot, byte[] val);
     synchronized void nScriptSetVarV(int id, int slot, byte[] val) {
+        validate();
         rsnScriptSetVarV(mContext, id, slot, val);
     }
     native void rsnScriptSetVarObj(int con, int id, int slot, int val);
     synchronized void nScriptSetVarObj(int id, int slot, int val) {
+        validate();
         rsnScriptSetVarObj(mContext, id, slot, val);
     }
 
     native void rsnScriptCBegin(int con);
     synchronized void nScriptCBegin() {
+        validate();
         rsnScriptCBegin(mContext);
     }
     native void rsnScriptCSetScript(int con, byte[] script, int offset, int length);
     synchronized void nScriptCSetScript(byte[] script, int offset, int length) {
+        validate();
         rsnScriptCSetScript(mContext, script, offset, length);
     }
     native int  rsnScriptCCreate(int con, String packageName, String resName, String cacheDir);
     synchronized int nScriptCCreate(String packageName, String resName, String cacheDir) {
+        validate();
         return rsnScriptCCreate(mContext, packageName, resName, cacheDir);
     }
 
     native void rsnSamplerBegin(int con);
     synchronized void nSamplerBegin() {
+        validate();
         rsnSamplerBegin(mContext);
     }
     native void rsnSamplerSet(int con, int param, int value);
     synchronized void nSamplerSet(int param, int value) {
+        validate();
         rsnSamplerSet(mContext, param, value);
     }
     native void rsnSamplerSet2(int con, int param, float value);
     synchronized void nSamplerSet2(int param, float value) {
+        validate();
         rsnSamplerSet2(mContext, param, value);
     }
     native int  rsnSamplerCreate(int con);
     synchronized int nSamplerCreate() {
+        validate();
         return rsnSamplerCreate(mContext);
     }
 
     native void rsnProgramStoreBegin(int con, int in, int out);
     synchronized void nProgramStoreBegin(int in, int out) {
+        validate();
         rsnProgramStoreBegin(mContext, in, out);
     }
     native void rsnProgramStoreDepthFunc(int con, int func);
     synchronized void nProgramStoreDepthFunc(int func) {
+        validate();
         rsnProgramStoreDepthFunc(mContext, func);
     }
     native void rsnProgramStoreDepthMask(int con, boolean enable);
     synchronized void nProgramStoreDepthMask(boolean enable) {
+        validate();
         rsnProgramStoreDepthMask(mContext, enable);
     }
     native void rsnProgramStoreColorMask(int con, boolean r, boolean g, boolean b, boolean a);
     synchronized void nProgramStoreColorMask(boolean r, boolean g, boolean b, boolean a) {
+        validate();
         rsnProgramStoreColorMask(mContext, r, g, b, a);
     }
     native void rsnProgramStoreBlendFunc(int con, int src, int dst);
     synchronized void nProgramStoreBlendFunc(int src, int dst) {
+        validate();
         rsnProgramStoreBlendFunc(mContext, src, dst);
     }
     native void rsnProgramStoreDither(int con, boolean enable);
     synchronized void nProgramStoreDither(boolean enable) {
+        validate();
         rsnProgramStoreDither(mContext, enable);
     }
     native int  rsnProgramStoreCreate(int con);
     synchronized int nProgramStoreCreate() {
+        validate();
         return rsnProgramStoreCreate(mContext);
     }
 
     native int  rsnProgramRasterCreate(int con, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
     synchronized int nProgramRasterCreate(boolean pointSmooth, boolean lineSmooth, boolean pointSprite) {
+        validate();
         return rsnProgramRasterCreate(mContext, pointSmooth, lineSmooth, pointSprite);
     }
     native void rsnProgramRasterSetLineWidth(int con, int pr, float v);
     synchronized void nProgramRasterSetLineWidth(int pr, float v) {
+        validate();
         rsnProgramRasterSetLineWidth(mContext, pr, v);
     }
     native void rsnProgramRasterSetCullMode(int con, int pr, int mode);
     synchronized void nProgramRasterSetCullMode(int pr, int mode) {
+        validate();
         rsnProgramRasterSetCullMode(mContext, pr, mode);
     }
 
     native void rsnProgramBindConstants(int con, int pv, int slot, int mID);
     synchronized void nProgramBindConstants(int pv, int slot, int mID) {
+        validate();
         rsnProgramBindConstants(mContext, pv, slot, mID);
     }
     native void rsnProgramBindTexture(int con, int vpf, int slot, int a);
     synchronized void nProgramBindTexture(int vpf, int slot, int a) {
+        validate();
         rsnProgramBindTexture(mContext, vpf, slot, a);
     }
     native void rsnProgramBindSampler(int con, int vpf, int slot, int s);
     synchronized void nProgramBindSampler(int vpf, int slot, int s) {
+        validate();
         rsnProgramBindSampler(mContext, vpf, slot, s);
     }
     native int  rsnProgramFragmentCreate(int con, String shader, int[] params);
     synchronized int nProgramFragmentCreate(String shader, int[] params) {
+        validate();
         return rsnProgramFragmentCreate(mContext, shader, params);
     }
     native int  rsnProgramVertexCreate(int con, String shader, int[] params);
     synchronized int nProgramVertexCreate(String shader, int[] params) {
+        validate();
         return rsnProgramVertexCreate(mContext, shader, params);
     }
 
     native int  rsnMeshCreate(int con, int vtxCount, int indexCount);
     synchronized int nMeshCreate(int vtxCount, int indexCount) {
+        validate();
         return rsnMeshCreate(mContext, vtxCount, indexCount);
     }
     native void rsnMeshBindVertex(int con, int id, int alloc, int slot);
     synchronized void nMeshBindVertex(int id, int alloc, int slot) {
+        validate();
         rsnMeshBindVertex(mContext, id, alloc, slot);
     }
     native void rsnMeshBindIndex(int con, int id, int alloc, int prim, int slot);
     synchronized void nMeshBindIndex(int id, int alloc, int prim, int slot) {
+        validate();
         rsnMeshBindIndex(mContext, id, alloc, prim, slot);
     }
     native void rsnMeshInitVertexAttribs(int con, int id);
     synchronized void nMeshInitVertexAttribs(int id) {
+        validate();
         rsnMeshInitVertexAttribs(mContext, id);
     }
     native int  rsnMeshGetVertexBufferCount(int con, int id);
     synchronized int nMeshGetVertexBufferCount(int id) {
+        validate();
         return rsnMeshGetVertexBufferCount(mContext, id);
     }
     native int  rsnMeshGetIndexCount(int con, int id);
     synchronized int nMeshGetIndexCount(int id) {
+        validate();
         return rsnMeshGetIndexCount(mContext, id);
     }
     native void rsnMeshGetVertices(int con, int id, int[] vtxIds, int vtxIdCount);
     synchronized void nMeshGetVertices(int id, int[] vtxIds, int vtxIdCount) {
+        validate();
         rsnMeshGetVertices(mContext, id, vtxIds, vtxIdCount);
     }
     native void rsnMeshGetIndices(int con, int id, int[] idxIds, int[] primitives, int vtxIdCount);
     synchronized void nMeshGetIndices(int id, int[] idxIds, int[] primitives, int vtxIdCount) {
+        validate();
         rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
     }
 
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index ff8f093..9445283 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -56,6 +56,9 @@
     protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
         super(0, rs);
         int id = internalCreate(rs, resources, resourceID);
+        if (id == 0) {
+            throw new RSRuntimeException("Loading of ScriptC script failed.");
+        }
         setID(id);
     }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 35db786..f86343a 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -991,7 +991,7 @@
     jint *paramPtr = _env->GetIntArrayElements(params, NULL);
     jint paramLen = _env->GetArrayLength(params);
 
-    LOG_API("nProgramFragmentCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
 
     jint ret = (jint)rsProgramFragmentCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
     _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
@@ -1008,7 +1008,7 @@
     jint *paramPtr = _env->GetIntArrayElements(params, NULL);
     jint paramLen = _env->GetArrayLength(params);
 
-    LOG_API("nProgramVertexCreate, con(%p), shaderLen(%i), paramLen(%i)", con, shaderLen, paramLen);
+    LOG_API("nProgramVertexCreate, con(%p), paramLen(%i)", con, paramLen);
 
     jint ret = (jint)rsProgramVertexCreate(con, shaderUTF.c_str(), shaderUTF.length(), (uint32_t *)paramPtr, paramLen);
     _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 5170a2c..18fd90e 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -30,8 +30,10 @@
 // The following keys map to int32_t data unless indicated otherwise.
 enum {
     kKeyMIMEType          = 'mime',  // cstring
-    kKeyWidth             = 'widt',  // int32_t
-    kKeyHeight            = 'heig',  // int32_t
+    kKeyWidth             = 'widt',  // int32_t, image pixel
+    kKeyHeight            = 'heig',  // int32_t, image pixel
+    kKeyDisplayWidth      = 'dWid',  // int32_t, display/presentation
+    kKeyDisplayHeight     = 'dHgt',  // int32_t, display/presentation
 
     // a rectangle, if absent assumed to be (0, 0, width - 1, height - 1)
     kKeyCropRect          = 'crop',
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 27f65bc..30b45f7 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -38,6 +38,15 @@
     AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
 };
 
+enum {
+    /*
+     * Indicates that an input device has switches.
+     * This input source flag is hidden from the API because switches are only used by the system
+     * and applications have no way to interact with them.
+     */
+    AINPUT_SOURCE_SWITCH = 0x80000000,
+};
+
 /*
  * Maximum number of pointers supported per motion event.
  * Smallest number of pointers is 1.
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index c080501..c43e40d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -298,8 +298,10 @@
 // FontRenderer
 ///////////////////////////////////////////////////////////////////////////////
 
+static bool sLogFontRendererCreate = true;
+
 FontRenderer::FontRenderer() {
-    LOGD("Creating FontRenderer");
+    if (sLogFontRendererCreate) LOGD("Creating FontRenderer");
 
     mGammaTable = NULL;
     mInitialized = false;
@@ -317,18 +319,24 @@
 
     char property[PROPERTY_VALUE_MAX];
     if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
-        LOGD("  Setting text cache width to %s pixels", property);
+        if (sLogFontRendererCreate) LOGD("  Setting text cache width to %s pixels", property);
         mCacheWidth = atoi(property);
     } else {
-        LOGD("  Using default text cache width of %i pixels", mCacheWidth);
+        if (sLogFontRendererCreate) {
+            LOGD("  Using default text cache width of %i pixels", mCacheWidth);
+        }
     }
 
     if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
-        LOGD("  Setting text cache width to %s pixels", property);
+        if (sLogFontRendererCreate) LOGD("  Setting text cache width to %s pixels", property);
         mCacheHeight = atoi(property);
     } else {
-        LOGD("  Using default text cache height of %i pixels", mCacheHeight);
+        if (sLogFontRendererCreate) {
+            LOGD("  Using default text cache height of %i pixels", mCacheHeight);
+        }
     }
+
+    sLogFontRendererCreate = false;
 }
 
 FontRenderer::~FontRenderer() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e6bea78..a167429 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -29,7 +29,6 @@
 void LayerRenderer::prepare(bool opaque) {
     LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
 
-    glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
     glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
 
     OpenGLRenderer::prepare(opaque);
@@ -37,11 +36,17 @@
 
 void LayerRenderer::finish() {
     OpenGLRenderer::finish();
-    glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
 
     generateMesh();
 
     LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo);
+
+    // No need to unbind our FBO, this will be taken care of by the caller
+    // who will invoke OpenGLRenderer::resume()
+}
+
+GLint LayerRenderer::getTargetFbo() {
+    return mLayer->fbo;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index f2fb898..1e39847 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -51,6 +51,7 @@
 
     bool hasLayer();
     Region* getRegion();
+    GLint getTargetFbo();
 
     static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
     static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
@@ -61,8 +62,6 @@
     void generateMesh();
 
     Layer* mLayer;
-    GLuint mPreviousFbo;
-
 }; // class LayerRenderer
 
 }; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2067acc1..6477eb0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -200,7 +200,7 @@
 
     glDisable(GL_DITHER);
 
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 
     mCaches.blend = true;
@@ -430,18 +430,18 @@
     } else {
         // Copy the framebuffer into the layer
         glBindTexture(GL_TEXTURE_2D, layer->texture);
-
-        if (layer->empty) {
-            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
-                    snapshot->height - bounds.bottom, layer->width, layer->height, 0);
-            layer->empty = false;
-        } else {
-            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
-                    snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+        if (!bounds.isEmpty()) {
+            if (layer->empty) {
+                glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
+                        snapshot->height - bounds.bottom, layer->width, layer->height, 0);
+                layer->empty = false;
+            } else {
+                glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
+                        snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+            }
+            // Enqueue the buffer coordinates to clear the corresponding region later
+            mLayers.push(new Rect(bounds));
         }
-
-        // Enqueue the buffer coordinates to clear the corresponding region later
-        mLayers.push(new Rect(bounds));
     }
 
     return true;
@@ -565,8 +565,10 @@
             resetColorFilter();
         }
     } else {
-        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
-        composeLayerRect(layer, rect, true);
+        if (!rect.isEmpty()) {
+            dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+            composeLayerRect(layer, rect, true);
+        }
     }
 
     if (fboLayer) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 272c5c2..4150ddc 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -145,14 +145,27 @@
         return mSnapshot;
     }
 
+    /**
+     * Returns the region of the current layer.
+     */
     virtual Region* getRegion() {
         return mSnapshot->region;
     }
 
+    /**
+     * Indicates whether rendering is currently targeted at a layer.
+     */
     virtual bool hasLayer() {
         return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
     }
 
+    /**
+     * Returns the name of the FBO this renderer is rendering into.
+     */
+    virtual GLint getTargetFbo() {
+        return 0;
+    }
+
 private:
     /**
      * Saves the current state of the renderer as a new snapshot.
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 535c0ac..11eb953 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -154,8 +154,7 @@
     float y1 = 0.0f;
     float v1 = 0.0f;
 
-    uint32_t i = 0;
-    for ( ; i < mYCount; i++) {
+    for (uint32_t i = 0; i < mYCount; i++) {
         float stepY = mYDivs[i];
 
         float y2 = 0.0f;
@@ -167,8 +166,10 @@
         }
         float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
 
-        generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
-                bitmapWidth, quadCount, i & 1);
+        if (stepY > 0.0f) {
+            generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
+                    bitmapWidth, quadCount);
+        }
 
         y1 = y2;
         v1 = (stepY + 0.5f) / bitmapHeight;
@@ -176,8 +177,10 @@
         previousStepY = stepY;
     }
 
-    generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
-            bitmapWidth, quadCount, i & 1);
+    if (previousStepY != bitmapHeight) {
+        generateRow(vertex, y1, bottom - top, v1, 1.0f, stretchX, right - left,
+                bitmapWidth, quadCount);
+    }
 
     if (verticesCount > 0) {
         Caches::getInstance().bindMeshBuffer(meshBuffer);
@@ -195,15 +198,14 @@
 }
 
 void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
-        float stretchX, float width, float bitmapWidth, uint32_t& quadCount, bool isStretch) {
+        float stretchX, float width, float bitmapWidth, uint32_t& quadCount) {
     float previousStepX = 0.0f;
 
     float x1 = 0.0f;
     float u1 = 0.0f;
 
     // Generate the row quad by quad
-    uint32_t i = 0;
-    for ( ; i < mXCount; i++) {
+    for (uint32_t i = 0; i < mXCount; i++) {
         float stepX = mXDivs[i];
 
         float x2 = 0.0f;
@@ -215,7 +217,9 @@
         }
         float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
 
-        generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount, isStretch || (i & 1));
+        if (stepX > 0.0f) {
+            generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
+        }
 
         x1 = x2;
         u1 = (stepX + 0.5f) / bitmapWidth;
@@ -223,19 +227,18 @@
         previousStepX = stepX;
     }
 
-    generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, isStretch || (i & 1));
+    if (previousStepX != bitmapWidth) {
+        generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount);
+    }
 }
 
 void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
-            float u1, float v1, float u2, float v2, uint32_t& quadCount, bool isStretch) {
+            float u1, float v1, float u2, float v2, uint32_t& quadCount) {
     const uint32_t oldQuadCount = quadCount;
-    const bool valid = isStretch || (x2 - x1 > 0.9999f && y2 - y1 > 0.9999f);
-    if (valid) {
-        quadCount++;
-    }
+    quadCount++;
 
     // Skip degenerate and transparent (empty) quads
-    if (!valid || ((mColorKey >> oldQuadCount) & 0x1) == 1) {
+    if ((mColorKey >> oldQuadCount) & 0x1) {
 #if DEBUG_PATCHES_EMPTY_VERTICES
         PATCH_LOGD("    quad %d (empty)", oldQuadCount);
         PATCH_LOGD("        left,  top    = %.2f, %.2f\t\tu1, v1 = %.2f, %.2f", x1, y1, u1, v1);
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index 4de0c76..0f0ffa2 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -70,11 +70,11 @@
 
     void generateRow(TextureVertex*& vertex, float y1, float y2,
             float v1, float v2, float stretchX, float width, float bitmapWidth,
-            uint32_t& quadCount, bool isStretch);
+            uint32_t& quadCount);
     void generateQuad(TextureVertex*& vertex,
             float x1, float y1, float x2, float y2,
             float u1, float v1, float u2, float v2,
-            uint32_t& quadCount, bool isStretch);
+            uint32_t& quadCount);
 }; // struct Patch
 
 }; // namespace uirenderer
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index fc3a065..541bf22 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -68,6 +68,7 @@
         unitTests.add(new UT_rsdebug(this, mRes, mCtx));
         unitTests.add(new UT_rstime(this, mRes, mCtx));
         unitTests.add(new UT_rstypes(this, mRes, mCtx));
+        unitTests.add(new UT_math(this, mRes, mCtx));
         unitTests.add(new UT_fp_mad(this, mRes, mCtx));
         /*
         unitTests.add(new UnitTest(null, "<Pass>", 1));
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_math.java b/libs/rs/java/tests/src/com/android/rs/test/UT_math.java
new file mode 100644
index 0000000..bf133be
--- /dev/null
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_math.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 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.rs.test;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+
+public class UT_math extends UnitTest {
+    private Resources mRes;
+
+    protected UT_math(RSTestCore rstc, Resources res, Context ctx) {
+        super(rstc, "Math", ctx);
+        mRes = res;
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        ScriptC_math s = new ScriptC_math(pRS, mRes, R.raw.math);
+        pRS.setMessageHandler(mRsMessage);
+        s.invoke_math_test(0, 0);
+        pRS.finish();
+        waitForMessage();
+        pRS.destroy();
+    }
+}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
index 4133fda..b6f2b2a6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
@@ -113,7 +113,7 @@
 
     start();
     // Do ~100 M ops
-    for (ct=0; ct < 1000 * 100; ct++) {
+    for (int ct=0; ct < 1000 * 100; ct++) {
         for (int i=0; i < (1000); i++) {
             if (data_f1[i] < -1.f) data_f1[i] = -1.f;
             if (data_f1[i] > -1.f) data_f1[i] = 1.f;
@@ -140,7 +140,8 @@
 }
 
 void fp_mad_test(uint32_t index, int test_num) {
-    for (int x=0; x < 1025; x++) {
+    int x;
+    for (x=0; x < 1025; x++) {
         data_f1[x] = (x & 0xf) * 0.1f;
         data_f4[x].x = (x & 0xf) * 0.1f;
         data_f4[x].y = (x & 0xf0) * 0.1f;
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
new file mode 100644
index 0000000..3ff7910
--- /dev/null
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -0,0 +1,182 @@
+#include "shared.rsh"
+
+// Testing math library
+
+volatile float f1;
+volatile float2 f2;
+volatile float3 f3;
+volatile float4 f4;
+
+volatile int i1;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
+
+#define TEST_FN_FUNC_FN(fnc)        \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1);                   \
+    f2 = fnc(f2);                   \
+    f3 = fnc(f3);                   \
+    f4 = fnc(f4);
+
+#define TEST_FN_FUNC_FN_PFN(fnc)    \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, (float*) &f1);     \
+    f2 = fnc(f2, (float2*) &f2);    \
+    f3 = fnc(f3, (float3*) &f3);    \
+    f4 = fnc(f4, (float4*) &f4);
+
+#define TEST_FN_FUNC_FN_FN(fnc)     \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1);               \
+    f2 = fnc(f2, f2);               \
+    f3 = fnc(f3, f3);               \
+    f4 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_F(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1);               \
+    f2 = fnc(f2, f1);               \
+    f3 = fnc(f3, f1);               \
+    f4 = fnc(f4, f1);
+
+#define TEST_FN_FUNC_FN_IN(fnc)     \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, i1);               \
+    f2 = fnc(f2, i2);               \
+    f3 = fnc(f3, i3);               \
+    f4 = fnc(f4, i4);
+
+#define TEST_FN_FUNC_FN_I(fnc)      \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, i1);               \
+    f2 = fnc(f2, i1);               \
+    f3 = fnc(f3, i1);               \
+    f4 = fnc(f4, i1);
+
+#define TEST_FN_FUNC_FN_FN_FN(fnc)  \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1, f1);           \
+    f2 = fnc(f2, f2, f2);           \
+    f3 = fnc(f3, f3, f3);           \
+    f4 = fnc(f4, f4, f4);
+
+#define TEST_FN_FUNC_FN_PIN(fnc)    \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, (int*) &i1);       \
+    f2 = fnc(f2, (int2*) &i2);      \
+    f3 = fnc(f3, (int3*) &i3);      \
+    f4 = fnc(f4, (int4*) &i4);
+
+#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
+    rsDebug("Testing " #fnc, 0);    \
+    f1 = fnc(f1, f1, (int*) &i1);   \
+    f2 = fnc(f2, f2, (int2*) &i2);  \
+    f3 = fnc(f3, f3, (int3*) &i3);  \
+    f4 = fnc(f4, f4, (int4*) &i4);
+
+#define TEST_IN_FUNC_FN(fnc)        \
+    rsDebug("Testing " #fnc, 0);    \
+    i1 = fnc(f1);                   \
+    i2 = fnc(f2);                   \
+    i3 = fnc(f3);                   \
+    i4 = fnc(f4);
+
+
+static bool test_math(uint32_t index) {
+    bool failed = false;
+    start();
+
+    TEST_FN_FUNC_FN(acos);
+    TEST_FN_FUNC_FN(acosh);
+    TEST_FN_FUNC_FN(acospi);
+    TEST_FN_FUNC_FN(asin);
+    TEST_FN_FUNC_FN(asinh);
+    TEST_FN_FUNC_FN(asinpi);
+    TEST_FN_FUNC_FN(atan);
+    TEST_FN_FUNC_FN_FN(atan2);
+    TEST_FN_FUNC_FN(atanh);
+    TEST_FN_FUNC_FN(atanpi);
+    TEST_FN_FUNC_FN_FN(atan2pi);
+    TEST_FN_FUNC_FN(cbrt);
+    TEST_FN_FUNC_FN(ceil);
+    TEST_FN_FUNC_FN_FN(copysign);
+    TEST_FN_FUNC_FN(cos);
+    TEST_FN_FUNC_FN(cosh);
+    TEST_FN_FUNC_FN(cospi);
+    TEST_FN_FUNC_FN(erfc);
+    TEST_FN_FUNC_FN(erf);
+    TEST_FN_FUNC_FN(exp);
+    TEST_FN_FUNC_FN(exp2);
+    TEST_FN_FUNC_FN(exp10);
+    TEST_FN_FUNC_FN(expm1);
+    TEST_FN_FUNC_FN(fabs);
+    TEST_FN_FUNC_FN_FN(fdim);
+    TEST_FN_FUNC_FN(floor);
+    TEST_FN_FUNC_FN_FN_FN(fma);
+    TEST_FN_FUNC_FN_FN(fmax);
+    TEST_FN_FUNC_FN_F(fmax);
+    TEST_FN_FUNC_FN_FN(fmin);
+    TEST_FN_FUNC_FN_F(fmin);
+    TEST_FN_FUNC_FN_FN(fmod);
+    TEST_FN_FUNC_FN_PFN(fract);
+    TEST_FN_FUNC_FN_PIN(frexp);
+    TEST_FN_FUNC_FN_FN(hypot);
+    TEST_IN_FUNC_FN(ilogb);
+    TEST_FN_FUNC_FN_IN(ldexp);
+    TEST_FN_FUNC_FN_I(ldexp);
+    TEST_FN_FUNC_FN(lgamma);
+    TEST_FN_FUNC_FN_PIN(lgamma);
+    TEST_FN_FUNC_FN(log);
+    TEST_FN_FUNC_FN(log2);
+    TEST_FN_FUNC_FN(log10);
+    TEST_FN_FUNC_FN(log1p);
+    TEST_FN_FUNC_FN(logb);
+    TEST_FN_FUNC_FN_FN_FN(mad);
+    TEST_FN_FUNC_FN_PFN(modf);
+    // nan
+    TEST_FN_FUNC_FN_FN(nextafter);
+    TEST_FN_FUNC_FN_FN(pow);
+    TEST_FN_FUNC_FN_IN(pown);
+    TEST_FN_FUNC_FN_FN(powr);
+    TEST_FN_FUNC_FN_FN(remainder);
+    TEST_FN_FUNC_FN_FN_PIN(remquo);
+    TEST_FN_FUNC_FN(rint);
+    TEST_FN_FUNC_FN_IN(rootn);
+    TEST_FN_FUNC_FN(round);
+    TEST_FN_FUNC_FN(rsqrt);
+    TEST_FN_FUNC_FN(sin);
+    TEST_FN_FUNC_FN_PFN(sincos);
+    TEST_FN_FUNC_FN(sinh);
+    TEST_FN_FUNC_FN(sinpi);
+    TEST_FN_FUNC_FN(sqrt);
+    TEST_FN_FUNC_FN(tan);
+    TEST_FN_FUNC_FN(tanh);
+    TEST_FN_FUNC_FN(tanpi);
+    TEST_FN_FUNC_FN(tgamma);
+    TEST_FN_FUNC_FN(trunc);
+
+    float time = end(index);
+
+    if (failed) {
+        rsDebug("test_math FAILED", time);
+    }
+    else {
+        rsDebug("test_math PASSED", time);
+    }
+
+    return failed;
+}
+
+void math_test(uint32_t index, int test_num) {
+    bool failed = false;
+    failed |= test_math(index);
+
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2e0c491..3acb624 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -253,7 +253,11 @@
     LOGV("%p, deinitEGL", this);
 
     if (mEGL.mContext != EGL_NO_CONTEXT) {
-        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
+        eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        eglDestroySurface(mEGL.mDisplay, mEGL.mSurfaceDefault);
+        if (mEGL.mSurface != EGL_NO_SURFACE) {
+            eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+        }
         eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
         checkEglError("eglDestroyContext");
     }
@@ -1035,9 +1039,7 @@
 }
 
 void rsi_ContextDestroyWorker(Context *rsc) {
-    LOGE("rsi_ContextDestroyWorker 1");
     rsc->destroyWorkerThreadResources();;
-    LOGE("rsi_ContextDestroyWorker 2");
 }
 
 }
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index 804c767..eb2af1c 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -210,3 +210,19 @@
 void LocklessCommandFifo::dumpState(const char *s) const {
     LOGV("%s %p  put %p, get %p,  buf %p,  end %p", s, this, mPut, mGet, mBuffer, mEnd);
 }
+
+void LocklessCommandFifo::printDebugData() const {
+    dumpState("printing fifo debug");
+    const uint32_t *pptr = (const uint32_t *)mGet;
+    pptr -= 8 * 4;
+    if (mGet < mBuffer) {
+        pptr = (const uint32_t *)mBuffer;
+    }
+
+
+    for (int ct=0; ct < 16; ct++) {
+        LOGV("fifo %p = 0x%08x  0x%08x  0x%08x  0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
+        pptr += 4;
+    }
+
+}
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
index c963963..eabdc3e 100644
--- a/libs/rs/rsLocklessFifo.h
+++ b/libs/rs/rsLocklessFifo.h
@@ -35,6 +35,8 @@
     bool init(uint32_t size);
     void shutdown();
 
+    void printDebugData() const;
+
     LocklessCommandFifo();
     ~LocklessCommandFifo();
 
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 042f6c7..1fceb66 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -467,7 +467,7 @@
 extern unsigned rs_runtime_lib_bc_size;
 #endif
 
-void ScriptCState::runCompiler(Context *rsc,
+bool ScriptCState::runCompiler(Context *rsc,
                                ScriptC *s,
                                const char *resName,
                                const char *cacheDir) {
@@ -482,7 +482,7 @@
                   s->mEnviroment.mScriptText,
                   s->mEnviroment.mScriptTextLength, 0) != 0) {
         LOGE("bcc: FAILS to read bitcode");
-        // Handle Fatal Error
+        return false;
     }
 
 #if 1
@@ -493,14 +493,14 @@
                     /*"1" means skip buffer here, and let libbcc decide*/,
                   0) != 0) {
         LOGE("bcc: FAILS to link bitcode");
-        // Handle Fatal Error
+        return false;
     }
 #endif
     char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
 
     if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
         LOGE("bcc: FAILS to prepare executable");
-        // Handle Fatal Error
+        return false;
     }
 
     free(cachePath);
@@ -543,8 +543,11 @@
     for (size_t i=0; i < pragmaCount; ++i) {
         //LOGE("pragma %s %s", keys[i], values[i]);
         if (!strcmp(keys[i], "version")) {
-            // TODO: Verify that version is correct
-            continue;
+            if (!strcmp(values[i], "1")) {
+                continue;
+            }
+            LOGE("Invalid version pragma value: %s\n", values[i]);
+            return false;
         }
 
         if (!strcmp(keys[i], "stateVertex")) {
@@ -555,7 +558,8 @@
                 s->mEnviroment.mVertex.clear();
                 continue;
             }
-            LOGE("Unreconized value %s passed to stateVertex", values[i]);
+            LOGE("Unrecognized value %s passed to stateVertex", values[i]);
+            return false;
         }
 
         if (!strcmp(keys[i], "stateRaster")) {
@@ -566,7 +570,8 @@
                 s->mEnviroment.mRaster.clear();
                 continue;
             }
-            LOGE("Unreconized value %s passed to stateRaster", values[i]);
+            LOGE("Unrecognized value %s passed to stateRaster", values[i]);
+            return false;
         }
 
         if (!strcmp(keys[i], "stateFragment")) {
@@ -577,7 +582,8 @@
                 s->mEnviroment.mFragment.clear();
                 continue;
             }
-            LOGE("Unreconized value %s passed to stateFragment", values[i]);
+            LOGE("Unrecognized value %s passed to stateFragment", values[i]);
+            return false;
         }
 
         if (!strcmp(keys[i], "stateStore")) {
@@ -588,9 +594,11 @@
                 s->mEnviroment.mFragmentStore.clear();
                 continue;
             }
-            LOGE("Unreconized value %s passed to stateStore", values[i]);
+            LOGE("Unrecognized value %s passed to stateStore", values[i]);
+            return false;
         }
     }
+    return true;
 }
 
 namespace android {
@@ -623,7 +631,11 @@
     ss->mScript.clear();
     s->incUserRef();
 
-    ss->runCompiler(rsc, s.get(), resName, cacheDir);
+    if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) {
+        // Error during compile, destroy s and return null.
+        s->zeroUserRef();
+        return NULL;
+    }
     ss->clear(rsc);
     return s.get();
 }
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 483481e8..612e38a 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -81,7 +81,7 @@
     void init(Context *rsc);
 
     void clear(Context *rsc);
-    void runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
+    bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
 
     struct SymbolTable_t {
         const char * mName;
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 0b21669..f550d98 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -226,51 +226,51 @@
 }
 
 static void SC_debugF(const char *s, float f) {
-    LOGE("%s %f, 0x%08x", s, f, *((int *) (&f)));
+    LOGD("%s %f, 0x%08x", s, f, *((int *) (&f)));
 }
 static void SC_debugFv2(const char *s, float f1, float f2) {
-    LOGE("%s {%f, %f}", s, f1, f2);
+    LOGD("%s {%f, %f}", s, f1, f2);
 }
 static void SC_debugFv3(const char *s, float f1, float f2, float f3) {
-    LOGE("%s {%f, %f, %f}", s, f1, f2, f3);
+    LOGD("%s {%f, %f, %f}", s, f1, f2, f3);
 }
 static void SC_debugFv4(const char *s, float f1, float f2, float f3, float f4) {
-    LOGE("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
+    LOGD("%s {%f, %f, %f, %f}", s, f1, f2, f3, f4);
 }
 static void SC_debugD(const char *s, double d) {
-    LOGE("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
+    LOGD("%s %f, 0x%08llx", s, d, *((long long *) (&d)));
 }
 static void SC_debugFM4v4(const char *s, const float *f) {
-    LOGE("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
-    LOGE("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
-    LOGE("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
-    LOGE("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
+    LOGD("%s {%f, %f, %f, %f", s, f[0], f[4], f[8], f[12]);
+    LOGD("%s  %f, %f, %f, %f", s, f[1], f[5], f[9], f[13]);
+    LOGD("%s  %f, %f, %f, %f", s, f[2], f[6], f[10], f[14]);
+    LOGD("%s  %f, %f, %f, %f}", s, f[3], f[7], f[11], f[15]);
 }
 static void SC_debugFM3v3(const char *s, const float *f) {
-    LOGE("%s {%f, %f, %f", s, f[0], f[3], f[6]);
-    LOGE("%s  %f, %f, %f", s, f[1], f[4], f[7]);
-    LOGE("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
+    LOGD("%s {%f, %f, %f", s, f[0], f[3], f[6]);
+    LOGD("%s  %f, %f, %f", s, f[1], f[4], f[7]);
+    LOGD("%s  %f, %f, %f}",s, f[2], f[5], f[8]);
 }
 static void SC_debugFM2v2(const char *s, const float *f) {
-    LOGE("%s {%f, %f", s, f[0], f[2]);
-    LOGE("%s  %f, %f}",s, f[1], f[3]);
+    LOGD("%s {%f, %f", s, f[0], f[2]);
+    LOGD("%s  %f, %f}",s, f[1], f[3]);
 }
 
 static void SC_debugI32(const char *s, int32_t i) {
-    LOGE("%s %i  0x%x", s, i, i);
+    LOGD("%s %i  0x%x", s, i, i);
 }
 static void SC_debugU32(const char *s, uint32_t i) {
-    LOGE("%s %u  0x%x", s, i, i);
+    LOGD("%s %u  0x%x", s, i, i);
 }
 static void SC_debugLL64(const char *s, long long ll) {
-    LOGE("%s %lld  0x%llx", s, ll, ll);
+    LOGD("%s %lld  0x%llx", s, ll, ll);
 }
 static void SC_debugULL64(const char *s, unsigned long long ll) {
-    LOGE("%s %llu  0x%llx", s, ll, ll);
+    LOGD("%s %llu  0x%llx", s, ll, ll);
 }
 
 static void SC_debugP(const char *s, const void *p) {
-    LOGE("%s %p", s, p);
+    LOGD("%s %p", s, p);
 }
 
 static uint32_t SC_toClient2(int cmdID, void *data, int len) {
diff --git a/libs/rs/rsScriptC_LibCL.cpp b/libs/rs/rsScriptC_LibCL.cpp
index 6c0e164..65b5ff4 100644
--- a/libs/rs/rsScriptC_LibCL.cpp
+++ b/libs/rs/rsScriptC_LibCL.cpp
@@ -58,6 +58,10 @@
     return log10(v) / log10(2.f);
 }
 
+static float SC_mad(float v1, float v2, float v3) {
+    return v1 * v2 + v3;
+}
+
 static float SC_pown(float v, int p) {
     return powf(v, (float)p);
 }
@@ -188,6 +192,7 @@
     { "_Z6asinpif", (void *)&SC_asinpi, true },
     { "_Z4atanf", (void *)&atanf, true },
     { "_Z5atan2ff", (void *)&atan2f, true },
+    { "_Z5atanhf", (void *)&atanhf, true },
     { "_Z6atanpif", (void *)&SC_atanpi, true },
     { "_Z7atan2piff", (void *)&SC_atan2pi, true },
     { "_Z4cbrtf", (void *)&cbrtf, true },
@@ -215,33 +220,32 @@
     { "_Z5ilogbf", (void *)&ilogbf, true },
     { "_Z5ldexpfi", (void *)&ldexpf, true },
     { "_Z6lgammaf", (void *)&lgammaf, true },
+    { "_Z6lgammafPi", (void *)&lgammaf_r, true },
     { "_Z3logf", (void *)&logf, true },
     { "_Z4log2f", (void *)&SC_log2, true },
     { "_Z5log10f", (void *)&log10f, true },
     { "_Z5log1pf", (void *)&log1pf, true },
-    //{ "logb", (void *)&, true },
-    //{ "mad", (void *)&, true },
-    { "modf", (void *)&modff, true },
+    { "_Z4logbf", (void *)&logbf, true },
+    { "_Z3madfff", (void *)&SC_mad, true },
+    { "_Z4modffPf", (void *)&modff, true },
     //{ "nan", (void *)&, true },
     { "_Z9nextafterff", (void *)&nextafterf, true },
     { "_Z3powff", (void *)&powf, true },
-    { "_Z4pownfi", (void *)&SC_pown, true },
-    { "_Z4powrff", (void *)&SC_powr, true },
     { "_Z9remainderff", (void *)&remainderf, true },
-    { "remquo", (void *)&remquof, true },
+    { "_Z6remquoffPi", (void *)&remquof, true },
     { "_Z4rintf", (void *)&rintf, true },
     { "_Z5rootnfi", (void *)&SC_rootn, true },
     { "_Z5roundf", (void *)&roundf, true },
     { "_Z5rsqrtf", (void *)&SC_rsqrt, true },
     { "_Z3sinf", (void *)&sinf, true },
-    { "sincos", (void *)&SC_sincos, true },
+    { "_Z6sincosfPf", (void *)&SC_sincos, true },
     { "_Z4sinhf", (void *)&sinhf, true },
     { "_Z5sinpif", (void *)&SC_sinpi, true },
     { "_Z4sqrtf", (void *)&sqrtf, true },
     { "_Z3tanf", (void *)&tanf, true },
     { "_Z4tanhf", (void *)&tanhf, true },
     { "_Z5tanpif", (void *)&SC_tanpi, true },
-    //{ "tgamma", (void *)&, true },
+    { "_Z6tgammaf", (void *)&lgammaf, true }, // FIXME!!! NEEDS TO USE tgammaf
     { "_Z5truncf", (void *)&truncf, true },
 
     // OpenCL Int
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 001ac55..6cf07de7 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -56,6 +56,7 @@
         if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
             rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
             LOGE("playCoreCommands error con %p, cmd %i", con, cmdID);
+            mToCore.printDebugData();
         }
         gPlaybackFuncs[cmdID](con, data);
         mToCore.next();
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index b9bb1f7..a7e46d8 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -1,20 +1,23 @@
 #ifndef __RS_CL_RSH__
 #define __RS_CL_RSH__
 
-#define M_PI        3.14159265358979323846264338327950288f   /* pi */
-
+#ifdef BCC_PREPARE_BC
+#define _RS_STATIC  extern
+#else
+#define _RS_STATIC  static
+#endif
 
 // Conversions
 #define CVT_FUNC_2(typeout, typein) \
-static typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
+_RS_STATIC typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
     typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
     return r; \
 } \
-static typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
+_RS_STATIC typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
     typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
     return r; \
 } \
-static typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
+_RS_STATIC typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
     typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, (typeout)v.w}; \
     return r; \
 }
@@ -39,21 +42,21 @@
 
 // Float ops, 6.11.2
 
-#define DEF_FUNC_1(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v) { \
+#define FN_FUNC_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v) { \
     float2 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
     return r; \
 } \
-static float3 __attribute__((overloadable)) fnc(float3 v) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v) { \
     float3 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
     r.z = fnc(v.z); \
     return r; \
 } \
-static float4 __attribute__((overloadable)) fnc(float4 v) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v) { \
     float4 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
@@ -62,21 +65,21 @@
     return r; \
 }
 
-#define DEF_FUNC_1_RI(fnc) \
-static int2 __attribute__((overloadable)) fnc(float2 v) { \
+#define IN_FUNC_FN(fnc) \
+_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
     int2 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
     return r; \
 } \
-static int3 __attribute__((overloadable)) fnc(float3 v) { \
+_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
     int3 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
     r.z = fnc(v.z); \
     return r; \
 } \
-static int4 __attribute__((overloadable)) fnc(float4 v) { \
+_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
     int4 r; \
     r.x = fnc(v.x); \
     r.y = fnc(v.y); \
@@ -85,44 +88,44 @@
     return r; \
 }
 
-#define DEF_FUNC_2(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
+#define FN_FUNC_FN_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
     float2 r; \
     r.x = fnc(v1.x, v2.x); \
     r.y = fnc(v1.y, v2.y); \
     return r; \
 } \
-static float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
     float3 r; \
     r.x = fnc(v1.x, v2.x); \
     r.y = fnc(v1.y, v2.y); \
     r.z = fnc(v1.z, v2.z); \
     return r; \
 } \
-static float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
     float4 r; \
     r.x = fnc(v1.x, v2.x); \
     r.y = fnc(v1.y, v2.y); \
     r.z = fnc(v1.z, v2.z); \
-    r.w = fnc(v1.w, v2.z); \
+    r.w = fnc(v1.w, v2.w); \
     return r; \
 }
 
-#define DEF_FUNC_2F(fnc) \
-static float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
+#define FN_FUNC_FN_F(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
     float2 r; \
     r.x = fnc(v1.x, v2); \
     r.y = fnc(v1.y, v2); \
     return r; \
 } \
-static float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
     float3 r; \
     r.x = fnc(v1.x, v2); \
     r.y = fnc(v1.y, v2); \
     r.z = fnc(v1.z, v2); \
     return r; \
 } \
-static float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
     float4 r; \
     r.x = fnc(v1.x, v2); \
     r.y = fnc(v1.y, v2); \
@@ -131,120 +134,293 @@
     return r; \
 }
 
+#define FN_FUNC_FN_IN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    r.z = fnc(v1.z, v2.z); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2.x); \
+    r.y = fnc(v1.y, v2.y); \
+    r.z = fnc(v1.z, v2.z); \
+    r.w = fnc(v1.w, v2.w); \
+    return r; \
+}
+
+#define FN_FUNC_FN_I(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int v2) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int v2) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    r.z = fnc(v1.z, v2); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int v2) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2); \
+    r.y = fnc(v1.y, v2); \
+    r.z = fnc(v1.z, v2); \
+    r.w = fnc(v1.w, v2); \
+    return r; \
+}
+
+#define FN_FUNC_FN_PFN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 *v2) { \
+    float2 r; \
+    float q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 *v2) { \
+    float3 r; \
+    float q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 *v2) { \
+    float4 r; \
+    float q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    r.w = fnc(v1.w, &q); \
+    v2->w = q; \
+    return r; \
+}
+
+#define FN_FUNC_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) { \
+    float2 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) { \
+    float3 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) { \
+    float4 r; \
+    int q; \
+    r.x = fnc(v1.x, &q); \
+    v2->x = q; \
+    r.y = fnc(v1.y, &q); \
+    v2->y = q; \
+    r.z = fnc(v1.z, &q); \
+    v2->z = q; \
+    r.w = fnc(v1.w, &q); \
+    v2->w = q; \
+    return r; \
+}
+
+#define FN_FUNC_FN_FN_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2, float2 v3) { \
+    float2 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2, float3 v3) { \
+    float3 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    r.z = fnc(v1.z, v2.z, v3.z); \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2, float4 v3) { \
+    float4 r; \
+    r.x = fnc(v1.x, v2.x, v3.x); \
+    r.y = fnc(v1.y, v2.y, v3.y); \
+    r.z = fnc(v1.z, v2.z, v3.z); \
+    r.w = fnc(v1.w, v2.w, v3.w); \
+    return r; \
+}
+
+#define FN_FUNC_FN_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2, int2 *v3) { \
+    float2 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2, int3 *v3) { \
+    float3 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    r.z = fnc(v1.z, v2.z, &q); \
+    v3->z = q; \
+    return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2, int4 *v3) { \
+    float4 r; \
+    int q; \
+    r.x = fnc(v1.x, v2.x, &q); \
+    v3->x = q; \
+    r.y = fnc(v1.y, v2.y, &q); \
+    v3->y = q; \
+    r.z = fnc(v1.z, v2.z, &q); \
+    v3->z = q; \
+    r.w = fnc(v1.w, v2.w, &q); \
+    v3->w = q; \
+    return r; \
+}
+
+
 
 extern float __attribute__((overloadable)) acos(float);
-DEF_FUNC_1(acos)
+FN_FUNC_FN(acos)
 
 extern float __attribute__((overloadable)) acosh(float);
-DEF_FUNC_1(acosh)
+FN_FUNC_FN(acosh)
 
-static float __attribute__((overloadable)) acospi(float v) {
+_RS_STATIC float __attribute__((overloadable)) acospi(float v) {
     return acos(v) / M_PI;
 }
-DEF_FUNC_1(acospi)
+FN_FUNC_FN(acospi)
 
 extern float __attribute__((overloadable)) asin(float);
-DEF_FUNC_1(asin)
+FN_FUNC_FN(asin)
 
 extern float __attribute__((overloadable)) asinh(float);
-DEF_FUNC_1(asinh)
+FN_FUNC_FN(asinh)
 
-static float __attribute__((overloadable)) asinpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) asinpi(float v) {
     return asin(v) / M_PI;
 }
-DEF_FUNC_1(asinpi)
+FN_FUNC_FN(asinpi)
 
 extern float __attribute__((overloadable)) atan(float);
-DEF_FUNC_1(atan)
+FN_FUNC_FN(atan)
 
 extern float __attribute__((overloadable)) atan2(float, float);
-DEF_FUNC_2(atan2)
+FN_FUNC_FN_FN(atan2)
 
 extern float __attribute__((overloadable)) atanh(float);
-DEF_FUNC_1(atanh)
+FN_FUNC_FN(atanh)
 
-static float __attribute__((overloadable)) atanpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) atanpi(float v) {
     return atan(v) / M_PI;
 }
-DEF_FUNC_1(atanpi)
+FN_FUNC_FN(atanpi)
 
-static float __attribute__((overloadable)) atan2pi(float y, float x) {
+_RS_STATIC float __attribute__((overloadable)) atan2pi(float y, float x) {
     return atan2(y, x) / M_PI;
 }
-DEF_FUNC_2(atan2pi)
+FN_FUNC_FN_FN(atan2pi)
 
 extern float __attribute__((overloadable)) cbrt(float);
-DEF_FUNC_1(cbrt)
+FN_FUNC_FN(cbrt)
 
 extern float __attribute__((overloadable)) ceil(float);
-DEF_FUNC_1(ceil)
+FN_FUNC_FN(ceil)
 
 extern float __attribute__((overloadable)) copysign(float, float);
-DEF_FUNC_2(copysign)
+FN_FUNC_FN_FN(copysign)
 
 extern float __attribute__((overloadable)) cos(float);
-DEF_FUNC_1(cos)
+FN_FUNC_FN(cos)
 
 extern float __attribute__((overloadable)) cosh(float);
-DEF_FUNC_1(cosh)
+FN_FUNC_FN(cosh)
 
-static float __attribute__((overloadable)) cospi(float v) {
+_RS_STATIC float __attribute__((overloadable)) cospi(float v) {
     return cos(v * M_PI);
 }
-DEF_FUNC_1(cospi)
+FN_FUNC_FN(cospi)
 
 extern float __attribute__((overloadable)) erfc(float);
-DEF_FUNC_1(erfc)
+FN_FUNC_FN(erfc)
 
 extern float __attribute__((overloadable)) erf(float);
-DEF_FUNC_1(erf)
+FN_FUNC_FN(erf)
 
 extern float __attribute__((overloadable)) exp(float);
-DEF_FUNC_1(exp)
+FN_FUNC_FN(exp)
 
 extern float __attribute__((overloadable)) exp2(float);
-DEF_FUNC_1(exp2)
+FN_FUNC_FN(exp2)
 
 extern float __attribute__((overloadable)) pow(float, float);
-static float __attribute__((overloadable)) exp10(float v) {
+_RS_STATIC float __attribute__((overloadable)) exp10(float v) {
     return pow(10.f, v);
 }
-DEF_FUNC_1(exp10)
+FN_FUNC_FN(exp10)
 
 extern float __attribute__((overloadable)) expm1(float);
-DEF_FUNC_1(expm1)
+FN_FUNC_FN(expm1)
 
 extern float __attribute__((overloadable)) fabs(float);
-DEF_FUNC_1(fabs)
+FN_FUNC_FN(fabs)
 
 extern float __attribute__((overloadable)) fdim(float, float);
-DEF_FUNC_2(fdim)
+FN_FUNC_FN_FN(fdim)
 
 extern float __attribute__((overloadable)) floor(float);
-DEF_FUNC_1(floor)
+FN_FUNC_FN(floor)
 
 extern float __attribute__((overloadable)) fma(float, float, float);
-extern float2 __attribute__((overloadable)) fma(float2, float2, float2);
-extern float3 __attribute__((overloadable)) fma(float3, float3, float3);
-extern float4 __attribute__((overloadable)) fma(float4, float4, float4);
+FN_FUNC_FN_FN_FN(fma)
 
 extern float __attribute__((overloadable)) fmax(float, float);
-DEF_FUNC_2(fmax);
-DEF_FUNC_2F(fmax);
+FN_FUNC_FN_FN(fmax);
+FN_FUNC_FN_F(fmax);
 
 extern float __attribute__((overloadable)) fmin(float, float);
-DEF_FUNC_2(fmin);
-DEF_FUNC_2F(fmin);
+FN_FUNC_FN_FN(fmin);
+FN_FUNC_FN_F(fmin);
 
 extern float __attribute__((overloadable)) fmod(float, float);
-DEF_FUNC_2(fmod)
+FN_FUNC_FN_FN(fmod)
 
-static float __attribute__((overloadable)) fract(float v, float *iptr) {
+_RS_STATIC float __attribute__((overloadable)) fract(float v, float *iptr) {
     int i = (int)floor(v);
     iptr[0] = i;
     return fmin(v - i, 0x1.fffffep-1f);
 }
-static float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
+_RS_STATIC float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
     float t[2];
     float2 r;
     r.x = fract(v.x, &t[0]);
@@ -253,7 +429,7 @@
     iptr[1] = t[1];
     return r;
 }
-static float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
+_RS_STATIC float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
     float t[3];
     float3 r;
     r.x = fract(v.x, &t[0]);
@@ -264,7 +440,7 @@
     iptr[2] = t[2];
     return r;
 }
-static float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
+_RS_STATIC float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
     float t[4];
     float4 r;
     r.x = fract(v.x, &t[0]);
@@ -278,194 +454,180 @@
     return r;
 }
 
-extern float __attribute__((overloadable)) frexp(float, float *);
-extern float2 __attribute__((overloadable)) frexp(float2, float2 *);
-extern float3 __attribute__((overloadable)) frexp(float3, float3 *);
-extern float4 __attribute__((overloadable)) frexp(float4, float4 *);
+extern float __attribute__((overloadable)) frexp(float, int *);
+FN_FUNC_FN_PIN(frexp)
 
 extern float __attribute__((overloadable)) hypot(float, float);
-DEF_FUNC_2(hypot)
+FN_FUNC_FN_FN(hypot)
 
 extern int __attribute__((overloadable)) ilogb(float);
-DEF_FUNC_1_RI(ilogb)
+IN_FUNC_FN(ilogb)
 
 extern float __attribute__((overloadable)) ldexp(float, int);
-extern float2 __attribute__((overloadable)) ldexp(float2, int2);
-extern float3 __attribute__((overloadable)) ldexp(float3, int3);
-extern float4 __attribute__((overloadable)) ldexp(float4, int4);
-extern float2 __attribute__((overloadable)) ldexp(float2, int);
-extern float3 __attribute__((overloadable)) ldexp(float3, int);
-extern float4 __attribute__((overloadable)) ldexp(float4, int);
+FN_FUNC_FN_IN(ldexp)
+FN_FUNC_FN_I(ldexp)
 
 extern float __attribute__((overloadable)) lgamma(float);
-DEF_FUNC_1(lgamma)
-extern float __attribute__((overloadable)) lgamma(float, float *);
-extern float2 __attribute__((overloadable)) lgamma(float2, float2 *);
-extern float3 __attribute__((overloadable)) lgamma(float3, float3 *);
-extern float4 __attribute__((overloadable)) lgamma(float4, float4 *);
+FN_FUNC_FN(lgamma)
+extern float __attribute__((overloadable)) lgamma(float, int*);
+FN_FUNC_FN_PIN(lgamma)
 
 extern float __attribute__((overloadable)) log(float);
-DEF_FUNC_1(log)
+FN_FUNC_FN(log)
 
 
 extern float __attribute__((overloadable)) log10(float);
-DEF_FUNC_1(log10)
+FN_FUNC_FN(log10)
 
-static float __attribute__((overloadable)) log2(float v) {
+_RS_STATIC float __attribute__((overloadable)) log2(float v) {
     return log10(v) / log10(2.f);
 }
-DEF_FUNC_1(log2)
+FN_FUNC_FN(log2)
 
 extern float __attribute__((overloadable)) log1p(float);
-DEF_FUNC_1(log1p)
+FN_FUNC_FN(log1p)
 
 extern float __attribute__((overloadable)) logb(float);
-DEF_FUNC_1(logb)
+FN_FUNC_FN(logb)
 
 extern float __attribute__((overloadable)) mad(float, float, float);
-extern float2 __attribute__((overloadable)) mad(float2, float2, float2);
-extern float3 __attribute__((overloadable)) mad(float3, float3, float3);
-extern float4 __attribute__((overloadable)) mad(float4, float4, float4);
+FN_FUNC_FN_FN_FN(mad)
 
 extern float __attribute__((overloadable)) modf(float, float *);
-extern float2 __attribute__((overloadable)) modf(float2, float2 *);
-extern float3 __attribute__((overloadable)) modf(float3, float3 *);
-extern float4 __attribute__((overloadable)) modf(float4, float4 *);
+FN_FUNC_FN_PFN(modf);
 
 //extern float __attribute__((overloadable)) nan(uint);
 
 extern float __attribute__((overloadable)) nextafter(float, float);
-DEF_FUNC_2(nextafter)
+FN_FUNC_FN_FN(nextafter)
 
-DEF_FUNC_2(pow)
+FN_FUNC_FN_FN(pow)
 
-static float __attribute__((overloadable)) pown(float v, int p) {
+_RS_STATIC float __attribute__((overloadable)) pown(float v, int p) {
     return pow(v, (float)p);
 }
-static float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
+_RS_STATIC float2 __attribute__((overloadable)) pown(float2 v, int2 p) {
     return pow(v, (float2)p);
 }
-static float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
+_RS_STATIC float3 __attribute__((overloadable)) pown(float3 v, int3 p) {
     return pow(v, (float3)p);
 }
-static float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
+_RS_STATIC float4 __attribute__((overloadable)) pown(float4 v, int4 p) {
     return pow(v, (float4)p);
 }
 
-static float __attribute__((overloadable)) powr(float v, float p) {
+_RS_STATIC float __attribute__((overloadable)) powr(float v, float p) {
     return pow(v, p);
 }
-static float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
+_RS_STATIC float2 __attribute__((overloadable)) powr(float2 v, float2 p) {
     return pow(v, p);
 }
-static float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
+_RS_STATIC float3 __attribute__((overloadable)) powr(float3 v, float3 p) {
     return pow(v, p);
 }
-static float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
+_RS_STATIC float4 __attribute__((overloadable)) powr(float4 v, float4 p) {
     return pow(v, p);
 }
 
 extern float __attribute__((overloadable)) remainder(float, float);
-DEF_FUNC_2(remainder)
+FN_FUNC_FN_FN(remainder)
 
 extern float __attribute__((overloadable)) remquo(float, float, int *);
-extern float2 __attribute__((overloadable)) remquo(float2, float2, int2 *);
-extern float3 __attribute__((overloadable)) remquo(float3, float3, int3 *);
-extern float4 __attribute__((overloadable)) remquo(float4, float4, int4 *);
+FN_FUNC_FN_FN_PIN(remquo)
 
 extern float __attribute__((overloadable)) rint(float);
-DEF_FUNC_1(rint)
+FN_FUNC_FN(rint)
 
-static float __attribute__((overloadable)) rootn(float v, int r) {
+_RS_STATIC float __attribute__((overloadable)) rootn(float v, int r) {
     return pow(v, 1.f / r);
 }
-static float2 __attribute__((overloadable)) rootn(float2 v, int2 r) {
+_RS_STATIC float2 __attribute__((overloadable)) rootn(float2 v, int2 r) {
     float2 t = {1.f / r.x, 1.f / r.y};
     return pow(v, t);
 }
-static float3 __attribute__((overloadable)) rootn(float3 v, int3 r) {
+_RS_STATIC float3 __attribute__((overloadable)) rootn(float3 v, int3 r) {
     float3 t = {1.f / r.x, 1.f / r.y, 1.f / r.z};
     return pow(v, t);
 }
-static float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
+_RS_STATIC float4 __attribute__((overloadable)) rootn(float4 v, int4 r) {
     float4 t = {1.f / r.x, 1.f / r.y, 1.f / r.z, 1.f / r.w};
     return pow(v, t);
 }
 
 extern float __attribute__((overloadable)) round(float);
-DEF_FUNC_1(round)
+FN_FUNC_FN(round)
 
 extern float __attribute__((overloadable)) sqrt(float);
-static float __attribute__((overloadable)) rsqrt(float v) {
+_RS_STATIC float __attribute__((overloadable)) rsqrt(float v) {
     return 1.f / sqrt(v);
 }
-DEF_FUNC_1(rsqrt)
+FN_FUNC_FN(rsqrt)
 
 extern float __attribute__((overloadable)) sin(float);
-DEF_FUNC_1(sin)
+FN_FUNC_FN(sin)
 
-static float __attribute__((overloadable)) sincos(float v, float *cosptr) {
+_RS_STATIC float __attribute__((overloadable)) sincos(float v, float *cosptr) {
     *cosptr = cos(v);
     return sin(v);
 }
-static float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
+_RS_STATIC float2 __attribute__((overloadable)) sincos(float2 v, float2 *cosptr) {
     *cosptr = cos(v);
     return sin(v);
 }
-static float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
+_RS_STATIC float3 __attribute__((overloadable)) sincos(float3 v, float3 *cosptr) {
     *cosptr = cos(v);
     return sin(v);
 }
-static float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
+_RS_STATIC float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) {
     *cosptr = cos(v);
     return sin(v);
 }
 
 extern float __attribute__((overloadable)) sinh(float);
-DEF_FUNC_1(sinh)
+FN_FUNC_FN(sinh)
 
-static float __attribute__((overloadable)) sinpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) sinpi(float v) {
     return sin(v * M_PI);
 }
-DEF_FUNC_1(sinpi)
+FN_FUNC_FN(sinpi)
 
-DEF_FUNC_1(sqrt)
+FN_FUNC_FN(sqrt)
 
 extern float __attribute__((overloadable)) tan(float);
-DEF_FUNC_1(tan)
+FN_FUNC_FN(tan)
 
 extern float __attribute__((overloadable)) tanh(float);
-DEF_FUNC_1(tanh)
+FN_FUNC_FN(tanh)
 
-static float __attribute__((overloadable)) tanpi(float v) {
+_RS_STATIC float __attribute__((overloadable)) tanpi(float v) {
     return tan(v * M_PI);
 }
-DEF_FUNC_1(tanpi)
+FN_FUNC_FN(tanpi)
 
 extern float __attribute__((overloadable)) tgamma(float);
-DEF_FUNC_1(tgamma)
+FN_FUNC_FN(tgamma)
 
 extern float __attribute__((overloadable)) trunc(float);
-DEF_FUNC_1(trunc)
+FN_FUNC_FN(trunc)
 
 // Int ops (partial), 6.11.3
 
-#define DEF_RIFUNC_1(typeout, typein, fnc)                          \
+#define XN_FUNC_YN(typeout, fnc, typein)                            \
 extern typeout __attribute__((overloadable)) fnc(typein);           \
-static typeout##2 __attribute__((overloadable)) fnc(typein##2 v) {  \
+_RS_STATIC typeout##2 __attribute__((overloadable)) fnc(typein##2 v) {  \
     typeout##2 r;                                                   \
     r.x = fnc(v.x);                                                 \
     r.y = fnc(v.y);                                                 \
     return r;                                                       \
 }                                                                   \
-static typeout##3 __attribute__((overloadable)) fnc(typein##3 v) {  \
+_RS_STATIC typeout##3 __attribute__((overloadable)) fnc(typein##3 v) {  \
     typeout##3 r;                                                   \
     r.x = fnc(v.x);                                                 \
     r.y = fnc(v.y);                                                 \
     r.z = fnc(v.z);                                                 \
     return r;                                                       \
 }                                                                   \
-static typeout##4 __attribute__((overloadable)) fnc(typein##4 v) {  \
+_RS_STATIC typeout##4 __attribute__((overloadable)) fnc(typein##4 v) {  \
     typeout##4 r;                                                   \
     r.x = fnc(v.x);                                                 \
     r.y = fnc(v.y);                                                 \
@@ -474,37 +636,37 @@
     return r;                                                       \
 }
 
-#define DEF_UIFUNC_1(fnc)           \
-DEF_RIFUNC_1(uchar, char, fnc)      \
-DEF_RIFUNC_1(ushort, short, fnc)    \
-DEF_RIFUNC_1(uint, int, fnc)
+#define UIN_FUNC_IN(fnc)           \
+XN_FUNC_YN(uchar, fnc, char)      \
+XN_FUNC_YN(ushort, fnc, short)    \
+XN_FUNC_YN(uint, fnc, int)
 
-#define DEF_IFUNC_1(fnc)            \
-DEF_RIFUNC_1(uchar, uchar, fnc)     \
-DEF_RIFUNC_1(char, char, fnc)       \
-DEF_RIFUNC_1(ushort, ushort, fnc)   \
-DEF_RIFUNC_1(short, short, fnc)     \
-DEF_RIFUNC_1(uint, uint, fnc)       \
-DEF_RIFUNC_1(int, int, fnc)
+#define IN_FUNC_IN(fnc)            \
+XN_FUNC_YN(uchar, fnc, uchar)     \
+XN_FUNC_YN(char, fnc, char)       \
+XN_FUNC_YN(ushort, fnc, ushort)   \
+XN_FUNC_YN(short, fnc, short)     \
+XN_FUNC_YN(uint, fnc, uint)       \
+XN_FUNC_YN(int, fnc, int)
 
-#define DEF_RIFUNC_2(type, fnc, body)                                       \
-static type __attribute__((overloadable)) fnc(type v1, type v2) {           \
+#define XN_FUNC_XN_XN_BODY(type, fnc, body)                                       \
+_RS_STATIC type __attribute__((overloadable)) fnc(type v1, type v2) {           \
     return body;                                                            \
 }                                                                           \
-static type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) {  \
+_RS_STATIC type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) {  \
     type##2 r;                                                              \
     r.x = fnc(v1.x, v2.x);                                                  \
     r.y = fnc(v1.y, v2.y);                                                  \
     return r;                                                               \
 }                                                                           \
-static type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) {  \
+_RS_STATIC type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) {  \
     type##3 r;                                                              \
     r.x = fnc(v1.x, v2.x);                                                  \
     r.y = fnc(v1.y, v2.y);                                                  \
     r.z = fnc(v1.z, v2.z);                                                  \
     return r;                                                               \
 }                                                                           \
-static type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) {  \
+_RS_STATIC type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) {  \
     type##4 r;                                                              \
     r.x = fnc(v1.x, v2.x);                                                  \
     r.y = fnc(v1.y, v2.y);                                                  \
@@ -513,43 +675,43 @@
     return r;                                                               \
 }                                                                           \
 
-#define DEF_IFUNC_2(fnc, body)  \
-DEF_RIFUNC_2(uchar, fnc, body)  \
-DEF_RIFUNC_2(char, fnc, body)   \
-DEF_RIFUNC_2(ushort, fnc, body) \
-DEF_RIFUNC_2(short, fnc, body)  \
-DEF_RIFUNC_2(uint, fnc, body)   \
-DEF_RIFUNC_2(int, fnc, body)    \
-DEF_RIFUNC_2(float, fnc, body)
+#define IN_FUNC_IN_IN_BODY(fnc, body)  \
+XN_FUNC_XN_XN_BODY(uchar, fnc, body)  \
+XN_FUNC_XN_XN_BODY(char, fnc, body)   \
+XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
+XN_FUNC_XN_XN_BODY(short, fnc, body)  \
+XN_FUNC_XN_XN_BODY(uint, fnc, body)   \
+XN_FUNC_XN_XN_BODY(int, fnc, body)    \
+XN_FUNC_XN_XN_BODY(float, fnc, body)
 
-DEF_UIFUNC_1(abs)
-DEF_IFUNC_1(clz)
+UIN_FUNC_IN(abs)
+IN_FUNC_IN(clz)
 
-DEF_IFUNC_2(min, (v1 < v2 ? v1 : v2))
-DEF_FUNC_2F(min)
+IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
+FN_FUNC_FN_F(min)
 
-DEF_IFUNC_2(max, (v1 > v2 ? v1 : v2))
-DEF_FUNC_2F(max)
+IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
+FN_FUNC_FN_F(max)
 
 // 6.11.4
 
-static float __attribute__((overloadable)) clamp(float amount, float low, float high) {
+_RS_STATIC float __attribute__((overloadable)) clamp(float amount, float low, float high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-static float2 __attribute__((overloadable)) clamp(float2 amount, float2 low, float2 high) {
+_RS_STATIC float2 __attribute__((overloadable)) clamp(float2 amount, float2 low, float2 high) {
     float2 r;
     r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
     r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
     return r;
 }
-static float3 __attribute__((overloadable)) clamp(float3 amount, float3 low, float3 high) {
+_RS_STATIC float3 __attribute__((overloadable)) clamp(float3 amount, float3 low, float3 high) {
     float3 r;
     r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
     r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
     r.z = amount.z < low.z ? low.z : (amount.z > high.z ? high.z : amount.z);
     return r;
 }
-static float4 __attribute__((overloadable)) clamp(float4 amount, float4 low, float4 high) {
+_RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float4 low, float4 high) {
     float4 r;
     r.x = amount.x < low.x ? low.x : (amount.x > high.x ? high.x : amount.x);
     r.y = amount.y < low.y ? low.y : (amount.y > high.y ? high.y : amount.y);
@@ -557,20 +719,20 @@
     r.w = amount.w < low.w ? low.w : (amount.w > high.w ? high.w : amount.w);
     return r;
 }
-static float2 __attribute__((overloadable)) clamp(float2 amount, float low, float high) {
+_RS_STATIC float2 __attribute__((overloadable)) clamp(float2 amount, float low, float high) {
     float2 r;
     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
     return r;
 }
-static float3 __attribute__((overloadable)) clamp(float3 amount, float low, float high) {
+_RS_STATIC float3 __attribute__((overloadable)) clamp(float3 amount, float low, float high) {
     float3 r;
     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
     r.z = amount.z < low ? low : (amount.z > high ? high : amount.z);
     return r;
 }
-static float4 __attribute__((overloadable)) clamp(float4 amount, float low, float high) {
+_RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float low, float high) {
     float4 r;
     r.x = amount.x < low ? low : (amount.x > high ? high : amount.x);
     r.y = amount.y < low ? low : (amount.y > high ? high : amount.y);
@@ -579,55 +741,55 @@
     return r;
 }
 
-static float __attribute__((overloadable)) degrees(float radians) {
+_RS_STATIC float __attribute__((overloadable)) degrees(float radians) {
     return radians * (180.f / M_PI);
 }
-DEF_FUNC_1(degrees)
+FN_FUNC_FN(degrees)
 
-static float __attribute__((overloadable)) mix(float start, float stop, float amount) {
+_RS_STATIC float __attribute__((overloadable)) mix(float start, float stop, float amount) {
     return start + (stop - start) * amount;
 }
-static float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
+_RS_STATIC float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float2 amount) {
     return start + (stop - start) * amount;
 }
-static float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
+_RS_STATIC float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float3 amount) {
     return start + (stop - start) * amount;
 }
-static float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
+_RS_STATIC float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float4 amount) {
     return start + (stop - start) * amount;
 }
-static float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
+_RS_STATIC float2 __attribute__((overloadable)) mix(float2 start, float2 stop, float amount) {
     return start + (stop - start) * amount;
 }
-static float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
+_RS_STATIC float3 __attribute__((overloadable)) mix(float3 start, float3 stop, float amount) {
     return start + (stop - start) * amount;
 }
-static float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
+_RS_STATIC float4 __attribute__((overloadable)) mix(float4 start, float4 stop, float amount) {
     return start + (stop - start) * amount;
 }
 
-static float __attribute__((overloadable)) radians(float degrees) {
+_RS_STATIC float __attribute__((overloadable)) radians(float degrees) {
     return degrees * (M_PI / 180.f);
 }
-DEF_FUNC_1(radians)
+FN_FUNC_FN(radians)
 
-static float __attribute__((overloadable)) step(float edge, float v) {
+_RS_STATIC float __attribute__((overloadable)) step(float edge, float v) {
     return (v < edge) ? 0.f : 1.f;
 }
-static float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
+_RS_STATIC float2 __attribute__((overloadable)) step(float2 edge, float2 v) {
     float2 r;
     r.x = (v.x < edge.x) ? 0.f : 1.f;
     r.y = (v.y < edge.y) ? 0.f : 1.f;
     return r;
 }
-static float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
+_RS_STATIC float3 __attribute__((overloadable)) step(float3 edge, float3 v) {
     float3 r;
     r.x = (v.x < edge.x) ? 0.f : 1.f;
     r.y = (v.y < edge.y) ? 0.f : 1.f;
     r.z = (v.z < edge.z) ? 0.f : 1.f;
     return r;
 }
-static float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
+_RS_STATIC float4 __attribute__((overloadable)) step(float4 edge, float4 v) {
     float4 r;
     r.x = (v.x < edge.x) ? 0.f : 1.f;
     r.y = (v.y < edge.y) ? 0.f : 1.f;
@@ -635,20 +797,20 @@
     r.w = (v.w < edge.w) ? 0.f : 1.f;
     return r;
 }
-static float2 __attribute__((overloadable)) step(float2 edge, float v) {
+_RS_STATIC float2 __attribute__((overloadable)) step(float2 edge, float v) {
     float2 r;
     r.x = (v < edge.x) ? 0.f : 1.f;
     r.y = (v < edge.y) ? 0.f : 1.f;
     return r;
 }
-static float3 __attribute__((overloadable)) step(float3 edge, float v) {
+_RS_STATIC float3 __attribute__((overloadable)) step(float3 edge, float v) {
     float3 r;
     r.x = (v < edge.x) ? 0.f : 1.f;
     r.y = (v < edge.y) ? 0.f : 1.f;
     r.z = (v < edge.z) ? 0.f : 1.f;
     return r;
 }
-static float4 __attribute__((overloadable)) step(float4 edge, float v) {
+_RS_STATIC float4 __attribute__((overloadable)) step(float4 edge, float v) {
     float4 r;
     r.x = (v < edge.x) ? 0.f : 1.f;
     r.y = (v < edge.y) ? 0.f : 1.f;
@@ -665,15 +827,15 @@
 extern float3 __attribute__((overloadable)) smoothstep(float, float, float3);
 extern float4 __attribute__((overloadable)) smoothstep(float, float, float4);
 
-static float __attribute__((overloadable)) sign(float v) {
+_RS_STATIC float __attribute__((overloadable)) sign(float v) {
     if (v > 0) return 1.f;
     if (v < 0) return -1.f;
     return v;
 }
-DEF_FUNC_1(sign)
+FN_FUNC_FN(sign)
 
 // 6.11.5
-static float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
+_RS_STATIC float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
     float3 r;
     r.x = lhs.y * rhs.z  - lhs.z * rhs.y;
     r.y = lhs.z * rhs.x  - lhs.x * rhs.z;
@@ -681,7 +843,7 @@
     return r;
 }
 
-static float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
+_RS_STATIC float4 __attribute__((overloadable)) cross(float4 lhs, float4 rhs) {
     float4 r;
     r.x = lhs.y * rhs.z  - lhs.z * rhs.y;
     r.y = lhs.z * rhs.x  - lhs.x * rhs.z;
@@ -690,68 +852,75 @@
     return r;
 }
 
-static float __attribute__((overloadable)) dot(float lhs, float rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float lhs, float rhs) {
     return lhs * rhs;
 }
-static float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float2 lhs, float2 rhs) {
     return lhs.x*rhs.x + lhs.y*rhs.y;
 }
-static float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float3 lhs, float3 rhs) {
     return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
 }
-static float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
+_RS_STATIC float __attribute__((overloadable)) dot(float4 lhs, float4 rhs) {
     return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
 }
 
-static float __attribute__((overloadable)) length(float v) {
+_RS_STATIC float __attribute__((overloadable)) length(float v) {
     return v;
 }
-static float __attribute__((overloadable)) length(float2 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float2 v) {
     return sqrt(v.x*v.x + v.y*v.y);
 }
-static float __attribute__((overloadable)) length(float3 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float3 v) {
     return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
 }
-static float __attribute__((overloadable)) length(float4 v) {
+_RS_STATIC float __attribute__((overloadable)) length(float4 v) {
     return sqrt(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w);
 }
 
-static float __attribute__((overloadable)) distance(float lhs, float rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float lhs, float rhs) {
     return length(lhs - rhs);
 }
-static float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float2 lhs, float2 rhs) {
     return length(lhs - rhs);
 }
-static float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float3 lhs, float3 rhs) {
     return length(lhs - rhs);
 }
-static float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
+_RS_STATIC float __attribute__((overloadable)) distance(float4 lhs, float4 rhs) {
     return length(lhs - rhs);
 }
 
-static float __attribute__((overloadable)) normalize(float v) {
+_RS_STATIC float __attribute__((overloadable)) normalize(float v) {
     return 1.f;
 }
-static float2 __attribute__((overloadable)) normalize(float2 v) {
+_RS_STATIC float2 __attribute__((overloadable)) normalize(float2 v) {
     return v / length(v);
 }
-static float3 __attribute__((overloadable)) normalize(float3 v) {
+_RS_STATIC float3 __attribute__((overloadable)) normalize(float3 v) {
     return v / length(v);
 }
-static float4 __attribute__((overloadable)) normalize(float4 v) {
+_RS_STATIC float4 __attribute__((overloadable)) normalize(float4 v) {
     return v / length(v);
 }
 
 #undef CVT_FUNC
 #undef CVT_FUNC_2
-#undef DEF_FUNC_1
-#undef DEF_FUNC_1_RI
-#undef DEF_FUNC_2
-#undef DEF_FUNC_2F
-#undef DEF_RIFUNC_1
-#undef DEF_UIFUNC_1
-#undef DEF_IFUNC_1
-#undef DEF_RIFUNC_2
-#undef DEF_IFUNC_2
+#undef FN_FUNC_FN
+#undef IN_FUNC_FN
+#undef FN_FUNC_FN_FN
+#undef FN_FUNC_FN_F
+#undef FN_FUNC_FN_IN
+#undef FN_FUNC_FN_I
+#undef FN_FUNC_FN_PFN
+#undef FN_FUNC_FN_PIN
+#undef FN_FUNC_FN_FN_FN
+#undef FN_FUNC_FN_FN_PIN
+#undef XN_FUNC_YN
+#undef UIN_FUNC_IN
+#undef IN_FUNC_IN
+#undef XN_FUNC_XN_XN_BODY
+#undef IN_FUNC_IN_IN_BODY
+#undef _RS_STATIC
 
 #endif
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index 16482c1..f3e0ab0 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,6 +1,12 @@
 #ifndef __RS_CORE_RSH__
 #define __RS_CORE_RSH__
 
+#ifdef BCC_PREPARE_BC
+#define _RS_STATIC  extern
+#else
+#define _RS_STATIC  static
+#endif
+
 // Debugging, print to the LOG a description string and a value.
 extern void __attribute__((overloadable))
     rsDebug(const char *, float);
@@ -35,17 +41,17 @@
 #define RS_DEBUG(a) rsDebug(#a, a)
 #define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
 
-static void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float2 v) {
     rsDebug(s, v.x, v.y);
 }
-static void __attribute__((overloadable)) rsDebug(const char *s, float3 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float3 v) {
     rsDebug(s, v.x, v.y, v.z);
 }
-static void __attribute__((overloadable)) rsDebug(const char *s, float4 v) {
+_RS_STATIC void __attribute__((overloadable)) rsDebug(const char *s, float4 v) {
     rsDebug(s, v.x, v.y, v.z, v.w);
 }
 
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b)
 {
     uchar4 c;
     c.x = (uchar)(r * 255.f);
@@ -55,7 +61,7 @@
     return c;
 }
 
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a)
 {
     uchar4 c;
     c.x = (uchar)(r * 255.f);
@@ -65,21 +71,21 @@
     return c;
 }
 
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color)
 {
     color *= 255.f;
     uchar4 c = {color.x, color.y, color.z, 255};
     return c;
 }
 
-static uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
+_RS_STATIC uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color)
 {
     color *= 255.f;
     uchar4 c = {color.x, color.y, color.z, color.w};
     return c;
 }
 
-static float4 rsUnpackColor8888(uchar4 c)
+_RS_STATIC float4 rsUnpackColor8888(uchar4 c)
 {
     float4 ret = (float4)0.0039156862745f;
     ret *= convert_float4(c);
@@ -95,37 +101,37 @@
 // Matrix ops
 /////////////////////////////////////////////////////
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v) {
     m->m[row * 4 + col] = v;
 }
 
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
 rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col) {
     return m->m[row * 4 + col];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v) {
     m->m[row * 3 + col] = v;
 }
 
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
 rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col) {
     return m->m[row * 3 + col];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v) {
     m->m[row * 2 + col] = v;
 }
 
-static float __attribute__((overloadable))
+_RS_STATIC float __attribute__((overloadable))
 rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col) {
     return m->m[row * 2 + col];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadIdentity(rs_matrix4x4 *m) {
     m->m[0] = 1.f;
     m->m[1] = 0.f;
@@ -145,7 +151,7 @@
     m->m[15] = 1.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadIdentity(rs_matrix3x3 *m) {
     m->m[0] = 1.f;
     m->m[1] = 0.f;
@@ -158,7 +164,7 @@
     m->m[8] = 1.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadIdentity(rs_matrix2x2 *m) {
     m->m[0] = 1.f;
     m->m[1] = 0.f;
@@ -166,7 +172,7 @@
     m->m[3] = 1.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix4x4 *m, const float *v) {
     m->m[0] = v[0];
     m->m[1] = v[1];
@@ -186,7 +192,7 @@
     m->m[15] = v[15];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix3x3 *m, const float *v) {
     m->m[0] = v[0];
     m->m[1] = v[1];
@@ -199,7 +205,7 @@
     m->m[8] = v[8];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix2x2 *m, const float *v) {
     m->m[0] = v[0];
     m->m[1] = v[1];
@@ -207,7 +213,7 @@
     m->m[3] = v[3];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v) {
     m->m[0] = v->m[0];
     m->m[1] = v->m[1];
@@ -227,7 +233,7 @@
     m->m[15] = v->m[15];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v) {
     m->m[0] = v->m[0];
     m->m[1] = v->m[1];
@@ -247,7 +253,7 @@
     m->m[15] = 1.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v) {
     m->m[0] = v->m[0];
     m->m[1] = v->m[1];
@@ -267,7 +273,7 @@
     m->m[15] = 1.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v) {
     m->m[0] = v->m[0];
     m->m[1] = v->m[1];
@@ -280,7 +286,7 @@
     m->m[8] = v->m[8];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v) {
     m->m[0] = v->m[0];
     m->m[1] = v->m[1];
@@ -288,7 +294,7 @@
     m->m[3] = v->m[3];
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
     float c, s;
     m->m[3] = 0;
@@ -327,7 +333,7 @@
     m->m[10] = z*z*nc +  c;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z) {
     rsMatrixLoadIdentity(m);
     m->m[0] = x;
@@ -335,7 +341,7 @@
     m->m[10] = z;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z) {
     rsMatrixLoadIdentity(m);
     m->m[12] = x;
@@ -343,7 +349,7 @@
     m->m[14] = z;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs) {
     for (int i=0 ; i<4 ; i++) {
         float ri0 = 0;
@@ -364,14 +370,14 @@
     }
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs) {
     rs_matrix4x4 mt;
     rsMatrixLoadMultiply(&mt, m, rhs);
     rsMatrixLoad(m, &mt);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs) {
     for (int i=0 ; i<3 ; i++) {
         float ri0 = 0;
@@ -389,14 +395,14 @@
     }
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs) {
     rs_matrix3x3 mt;
     rsMatrixLoadMultiply(&mt, m, rhs);
     rsMatrixLoad(m, &mt);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs) {
     for (int i=0 ; i<2 ; i++) {
         float ri0 = 0;
@@ -411,35 +417,35 @@
     }
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs) {
     rs_matrix2x2 mt;
     rsMatrixLoadMultiply(&mt, m, rhs);
     rsMatrixLoad(m, &mt);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z) {
     rs_matrix4x4 m1;
     rsMatrixLoadRotate(&m1, rot, x, y, z);
     rsMatrixMultiply(m, &m1);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z) {
     rs_matrix4x4 m1;
     rsMatrixLoadScale(&m1, x, y, z);
     rsMatrixMultiply(m, &m1);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z) {
     rs_matrix4x4 m1;
     rsMatrixLoadTranslate(&m1, x, y, z);
     rsMatrixMultiply(m, &m1);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
     rsMatrixLoadIdentity(m);
     m->m[0] = 2.f / (right - left);
@@ -450,7 +456,7 @@
     m->m[14]= -(far + near) / (far - near);
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far) {
     rsMatrixLoadIdentity(m);
     m->m[0] = 2.f * near / (right - left);
@@ -463,7 +469,7 @@
     m->m[15]= 0.f;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far) {
     float top = near * tan((float) (fovy * M_PI / 360.0f));
     float bottom = -top;
@@ -472,7 +478,7 @@
     rsMatrixLoadFrustum(m, left, right, bottom, top, near, far);
 }
 
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix4x4 *m, float4 in) {
     float4 ret;
     ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + (m->m[12] * in.w);
@@ -482,7 +488,7 @@
     return ret;
 }
 
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix4x4 *m, float3 in) {
     float4 ret;
     ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + (m->m[8] * in.z) + m->m[12];
@@ -492,7 +498,7 @@
     return ret;
 }
 
-static float4 __attribute__((overloadable))
+_RS_STATIC float4 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix4x4 *m, float2 in) {
     float4 ret;
     ret.x = (m->m[0] * in.x) + (m->m[4] * in.y) + m->m[12];
@@ -502,7 +508,7 @@
     return ret;
 }
 
-static float3 __attribute__((overloadable))
+_RS_STATIC float3 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix3x3 *m, float3 in) {
     float3 ret;
     ret.x = (m->m[0] * in.x) + (m->m[3] * in.y) + (m->m[6] * in.z);
@@ -511,7 +517,7 @@
     return ret;
 }
 
-static float3 __attribute__((overloadable))
+_RS_STATIC float3 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix3x3 *m, float2 in) {
     float3 ret;
     ret.x = (m->m[0] * in.x) + (m->m[3] * in.y);
@@ -520,7 +526,7 @@
     return ret;
 }
 
-static float2 __attribute__((overloadable))
+_RS_STATIC float2 __attribute__((overloadable))
 rsMatrixMultiply(rs_matrix2x2 *m, float2 in) {
     float2 ret;
     ret.x = (m->m[0] * in.x) + (m->m[2] * in.y);
@@ -529,7 +535,7 @@
 }
 
 // Returns true if the matrix was successfully inversed
-static bool __attribute__((overloadable))
+_RS_STATIC bool __attribute__((overloadable))
 rsMatrixInverse(rs_matrix4x4 *m) {
     rs_matrix4x4 result;
 
@@ -571,7 +577,7 @@
 }
 
 // Returns true if the matrix was successfully inversed
-static bool __attribute__((overloadable))
+_RS_STATIC bool __attribute__((overloadable))
 rsMatrixInverseTranspose(rs_matrix4x4 *m) {
     rs_matrix4x4 result;
 
@@ -612,7 +618,7 @@
     return true;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixTranspose(rs_matrix4x4 *m) {
     int i, j;
     float temp;
@@ -625,7 +631,7 @@
     }
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixTranspose(rs_matrix3x3 *m) {
     int i, j;
     float temp;
@@ -638,7 +644,7 @@
     }
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsMatrixTranspose(rs_matrix2x2 *m) {
     float temp = m->m[1];
     m->m[1] = m->m[2];
@@ -649,7 +655,7 @@
 // quaternion ops
 /////////////////////////////////////////////////////
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
     q->w = w;
     q->x = x;
@@ -657,7 +663,7 @@
     q->z = z;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
     q->w = rhs->w;
     q->x = rhs->x;
@@ -665,7 +671,7 @@
     q->z = rhs->z;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsQuaternionMultiply(rs_quaternion *q, float s) {
     q->w *= s;
     q->x *= s;
@@ -673,7 +679,7 @@
     q->z *= s;
 }
 
-static void __attribute__((overloadable))
+_RS_STATIC void __attribute__((overloadable))
 rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
     q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
     q->x =  q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
@@ -681,7 +687,7 @@
     q->z =  q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
 }
 
-static void
+_RS_STATIC void
 rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
     q->w *= rhs->w;
     q->x *= rhs->x;
@@ -689,7 +695,7 @@
     q->z *= rhs->z;
 }
 
-static void
+_RS_STATIC void
 rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
     rot *= (float)(M_PI / 180.0f) * 0.5f;
     float c = cos(rot);
@@ -701,7 +707,7 @@
     q->z = z * s;
 }
 
-static void
+_RS_STATIC void
 rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
     const float len = x*x + y*y + z*z;
     if (len != 1) {
@@ -713,19 +719,19 @@
     rsQuaternionLoadRotateUnit(q, rot, x, y, z);
 }
 
-static void
+_RS_STATIC void
 rsQuaternionConjugate(rs_quaternion *q) {
     q->x = -q->x;
     q->y = -q->y;
     q->z = -q->z;
 }
 
-static float
+_RS_STATIC float
 rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
     return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
 }
 
-static void
+_RS_STATIC void
 rsQuaternionNormalize(rs_quaternion *q) {
     const float len = rsQuaternionDot(q, q);
     if (len != 1) {
@@ -734,7 +740,7 @@
     }
 }
 
-static void
+_RS_STATIC void
 rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
     if (t <= 0.0f) {
         rsQuaternionSet(q, q0);
@@ -776,7 +782,7 @@
                         tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
 }
 
-static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
+_RS_STATIC void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
     float x2 = 2.0f * q->x * q->x;
     float y2 = 2.0f * q->y * q->y;
     float z2 = 2.0f * q->z * q->z;
@@ -811,7 +817,7 @@
 /////////////////////////////////////////////////////
 // utility funcs
 /////////////////////////////////////////////////////
-__inline__ static void __attribute__((overloadable, always_inline))
+__inline__ _RS_STATIC void __attribute__((overloadable, always_inline))
 rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
                          float4 *left, float4 *right,
                          float4 *top, float4 *bottom,
@@ -861,7 +867,7 @@
     *far /= len;
 }
 
-__inline__ static bool __attribute__((overloadable, always_inline))
+__inline__ _RS_STATIC bool __attribute__((overloadable, always_inline))
 rsIsSphereInFrustum(float4 *sphere,
                       float4 *left, float4 *right,
                       float4 *top, float4 *bottom,
@@ -899,26 +905,26 @@
 // int ops
 /////////////////////////////////////////////////////
 
-__inline__ static uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
+__inline__ _RS_STATIC uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-__inline__ static int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
+__inline__ _RS_STATIC int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-__inline__ static ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
+__inline__ _RS_STATIC ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-__inline__ static short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
+__inline__ _RS_STATIC short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-__inline__ static uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
+__inline__ _RS_STATIC uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
-__inline__ static char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
+__inline__ _RS_STATIC char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high) {
     return amount < low ? low : (amount > high ? high : amount);
 }
 
-
+#undef _RS_STATIC
 
 #endif
 
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 212eb83..a010096 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -1,6 +1,9 @@
 #ifndef __RS_TYPES_RSH__
 #define __RS_TYPES_RSH__
 
+#define M_PI        3.14159265358979323846264338327950288f   /* pi */
+
+#include "stdbool.h"
 typedef char int8_t;
 typedef short int16_t;
 typedef int int32_t;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 3b2ef84..af11f97 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -261,8 +261,7 @@
     // NOTE: if stack.head is messed up, we could crash the client
     // or cause some drawing artifacts. This is okay, as long as it is
     // limited to the client.
-    return (buf != stack.index[stack.head] ||
-            (stack.queued > 0 && stack.inUse != buf));
+    return (buf != stack.index[stack.head]);
 }
 
 SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition(
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 1663313..f24a71d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -66,12 +66,6 @@
     if (outConfig == NULL)
         return BAD_VALUE;
     
-    int err;
-    PixelFormatInfo fbFormatInfo;
-    if ((err = getPixelFormatInfo(PixelFormat(format), &fbFormatInfo)) < 0) {
-        return err;
-    }
-
     // Get all the "potential match" configs...
     if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
         return BAD_VALUE;
@@ -81,23 +75,14 @@
         free(configs);
         return BAD_VALUE;
     }
-
-    const int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
-    const int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
-    const int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
-    const int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE); 
     
     int i;
     EGLConfig config = NULL;
     for (i=0 ; i<n ; i++) {
-        EGLint r,g,b,a;
-        EGLConfig curr = configs[i];
-        eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE,   &r);
-        eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
-        eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE,  &b);
-        eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
-        if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB  == b) {
-            config = curr;
+        EGLint nativeVisualId = 0;
+        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+        if (nativeVisualId>0 && format == nativeVisualId) {
+            config = configs[i];
             break;
         }
     }
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index ce84683..33ef1fc 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -61,7 +61,7 @@
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
             list.keyAt(i), rec.size/1024.0f, 
             rec.w, rec.s, rec.h, rec.format, rec.usage);
         result.append(buffer);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 10c9a9a..33c6385 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1462,22 +1462,29 @@
         if (lastSlash < 0) throw new IllegalArgumentException("bad path " + path);
         Uri uri, membersUri;
         long rowId = entry.mRowId;
-        if (rowId == 0) {
-            // Create a new playlist
 
-            int lastDot = path.lastIndexOf('.');
-            String name = (lastDot < 0 ? path.substring(lastSlash + 1) : path.substring(lastSlash + 1, lastDot));
-            values.put(MediaStore.Audio.Playlists.NAME, name);
+        // make sure we have a name
+        String name = values.getAsString(MediaStore.Audio.Playlists.NAME);
+        if (name == null) {
+            name = values.getAsString(MediaStore.MediaColumns.TITLE);
+            if (name == null) {
+                // extract name from file name
+                int lastDot = path.lastIndexOf('.');
+                name = (lastDot < 0 ? path.substring(lastSlash + 1)
+                        : path.substring(lastSlash + 1, lastDot));
+            }
+        }
+
+        values.put(MediaStore.Audio.Playlists.NAME, name);
+        values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);
+
+        if (rowId == 0) {
             values.put(MediaStore.Audio.Playlists.DATA, path);
-            values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);
             uri = mMediaProvider.insert(mPlaylistsUri, values);
             rowId = ContentUris.parseId(uri);
             membersUri = Uri.withAppendedPath(uri, Playlists.Members.CONTENT_DIRECTORY);
         } else {
             uri = ContentUris.withAppendedId(mPlaylistsUri, rowId);
-
-            // update lastModified value of existing playlist
-            values.put(MediaStore.Audio.Playlists.DATE_MODIFIED, entry.mLastModified);
             mMediaProvider.update(uri, values, null, null);
 
             // delete members of existing playlist
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index 3e54627..d3e9a49 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -150,7 +150,7 @@
      */
     public static final int ERROR = -1;
     /**
-     * Internal opreation status. Not returned by any method.
+     * Internal operation status. Not returned by any method.
      */
     public static final int ALREADY_EXISTS = -2;
     /**
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index 41309dc..bcf7b89 100755
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -95,7 +95,7 @@
      */
     public  static final int ERROR                = -1;
     /**
-     * Internal opreation status. Not returned by any method.
+     * Internal operation status. Not returned by any method.
      */
     public  static final int ALREADY_EXISTS       = -2;
     /**
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index b03588f..1c02878 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -93,29 +93,28 @@
      *
      * @throws IOException
      */
-    public MediaImageItem(VideoEditor editor, String mediaItemId,
-                         String filename, long durationMs,
-                         int renderingMode) throws IOException {
+    public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
+        int renderingMode) throws IOException {
 
         super(editor, mediaItemId, filename, renderingMode);
 
         mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
         mVideoEditor = ((VideoEditorImpl)editor);
         try {
-            final Properties properties =
-                                   mMANativeHelper.getMediaProperties(filename);
+            final Properties properties = mMANativeHelper.getMediaProperties(filename);
 
             switch (mMANativeHelper.getFileType(properties.fileType)) {
                 case MediaProperties.FILE_JPEG:
+                case MediaProperties.FILE_PNG: {
                     break;
-                case MediaProperties.FILE_PNG:
-                    break;
+                }
 
-                default:
-                throw new IllegalArgumentException("Unsupported Input File Type");
+                default: {
+                    throw new IllegalArgumentException("Unsupported Input File Type");
+                }
             }
         } catch (Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found");
+            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
         }
 
         /**
@@ -130,13 +129,13 @@
         mDurationMs = durationMs;
         mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
                 "/" + "decoded" + getId()+ ".rgb");
-        final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
-        final DataOutputStream dos = new DataOutputStream(fl);
+
         try {
             mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
         } catch(IllegalArgumentException e) {
             throw new IllegalArgumentException ("Null width and height");
         }
+
         mGeneratedClipHeight = 0;
         mGeneratedClipWidth = 0;
 
@@ -146,9 +145,12 @@
          */
         final Pair<Integer, Integer>[] resolutions =
             MediaProperties.getSupportedResolutions(mAspectRatio);
+
         /**
          *  Get the highest resolution
          */
+        final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
+        final DataOutputStream dos = new DataOutputStream(fl);
         final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
         if (mHeight > maxResolution.second) {
             /**
@@ -171,16 +173,16 @@
             int mNewHeight = 0;
             if ((mScaledWidth % 2 ) != 0) {
                 mNewWidth = mScaledWidth - 1;
-            }
-            else {
+            } else {
                 mNewWidth = mScaledWidth;
             }
+
             if ((mScaledHeight % 2 ) != 0) {
                 mNewHeight = mScaledHeight - 1;
-            }
-            else {
+            } else {
                 mNewHeight = mScaledHeight;
             }
+
             final int [] framingBuffer = new int[mNewWidth];
             final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
             IntBuffer intBuffer;
@@ -195,6 +197,7 @@
                 dos.write(array);
                 tmp += 1;
             }
+
             mScaledWidth = mNewWidth;
             mScaledHeight = mNewHeight;
             scaledImage.recycle();
@@ -204,10 +207,11 @@
                                 + "/" + "scaled" + getId()+ ".JPG");
             if (!((new File(mScaledFilename)).exists())) {
                 super.mRegenerateClip = true;
-                FileOutputStream f1 = new FileOutputStream(mScaledFilename);
+                final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
                 scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1);
                 f1.close();
             }
+
             mScaledWidth = scaledImage.getWidth();
             mScaledHeight = scaledImage.getHeight();
 
@@ -215,17 +219,17 @@
             int mNewheight = 0;
             if ((mScaledWidth % 2 ) != 0) {
                 mNewWidth = mScaledWidth - 1;
-            }
-            else {
+            } else {
                 mNewWidth = mScaledWidth;
             }
+
             if ((mScaledHeight % 2 ) != 0) {
                 mNewheight = mScaledHeight - 1;
-            }
-            else {
+            } else {
                 mNewheight = mScaledHeight;
             }
-            Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
+
+            final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
             final int [] framingBuffer = new int[mNewWidth];
             ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
             IntBuffer intBuffer;
@@ -240,10 +244,12 @@
                 dos.write(array);
                 tmp += 1;
             }
+
             mScaledWidth = mNewWidth;
             mScaledHeight = mNewheight;
             imageBitmap.recycle();
         }
+
         fl.close();
         System.gc();
     }
@@ -286,7 +292,7 @@
 
     /**
      * @return The file name of image which is decoded and stored
-     * in rgb format
+     * in RGB format
      */
     String getDecodedImageFileName() {
         return mDecodedFilename;
@@ -447,7 +453,7 @@
                  *  Check if the effect overlaps with the end transition
                  */
                 if (effect.getStartTime() + effect.getDuration() >
-                mDurationMs - transitionDurationMs) {
+                    mDurationMs - transitionDurationMs) {
                     mEndTransition.invalidate();
                     break;
                 }
@@ -464,7 +470,7 @@
                      *  Check if the overlay overlaps with the end transition
                      */
                     if (overlay.getStartTime() + overlay.getDuration() >
-                    mDurationMs - transitionDurationMs) {
+                        mDurationMs - transitionDurationMs) {
                         mEndTransition.invalidate();
                         break;
                     }
@@ -648,23 +654,24 @@
             for (int i = 0; i < thumbnailCount; i++) {
                 thumbnailArray[i] = thumbnail;
             }
+
             return thumbnailArray;
-
-
-        }
-        else {
+        } else {
             if (startMs > endMs) {
                 throw new IllegalArgumentException("Start time is greater than end time");
             }
+
             if (endMs > mDurationMs) {
                 throw new IllegalArgumentException("End time is greater than file duration");
             }
+
             if (startMs == endMs) {
                 Bitmap[] bitmap = new Bitmap[1];
                 bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
                     width, height,startMs);
                 return bitmap;
             }
+
             return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
                 height,startMs,endMs,thumbnailCount);
         }
@@ -704,31 +711,51 @@
          */
         if (mBeginTransition != null) {
             final long transitionDurationMs = mBeginTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
+                    transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
+                    transitionDurationMs);
             /**
-             *  If the start time has changed and if the old or the new item
-             *  overlaps with the begin transition, invalidate the transition.
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (((oldStartTimeMs != newStartTimeMs)
-                    || (oldDurationMs != newDurationMs) )&&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
-                    isOverlapping(newStartTimeMs, newDurationMs, 0,
-                    transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mBeginTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs != newStartTimeMs) ||
+                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
+                    mBeginTransition.invalidate();
+                }
             }
         }
 
         if (mEndTransition != null) {
             final long transitionDurationMs = mEndTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mDurationMs - transitionDurationMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mDurationMs - transitionDurationMs, transitionDurationMs);
             /**
-             *  If the start time + duration has changed and if the old or the new
-             *  item overlaps the end transition, invalidate the transition
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs) ||
-                    isOverlapping(newStartTimeMs, newDurationMs,
-                    mDurationMs - transitionDurationMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mEndTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+                        ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
+                        newStartTimeMs > mDurationMs - transitionDurationMs)) {
+                    mEndTransition.invalidate();
+                }
             }
         }
     }
@@ -743,10 +770,12 @@
             setGeneratedImageClip(null);
             setRegenerateClip(true);
         }
+
         if (mScaledFilename != null) {
             new File(mScaledFilename).delete();
             mScaledFilename = null;
         }
+
         if (mDecodedFilename != null) {
             new File(mDecodedFilename).delete();
             mDecodedFilename = null;
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 772b360..2981b41 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -78,12 +78,9 @@
      *
      * @throws IOException if the file cannot be opened for reading
      */
-    public MediaVideoItem(VideoEditor editor, String mediaItemId,
-            String filename,
-            int renderingMode)
-    throws IOException {
-        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE,
-                100, false, null);
+    public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
+            int renderingMode) throws IOException {
+        this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
     }
 
     /**
@@ -105,20 +102,22 @@
      * @throws IOException if the file cannot be opened for reading
      */
     MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
-            int renderingMode,
-            long beginMs, long endMs, int volumePercent, boolean muted,
+            int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
             String audioWaveformFilename)  throws IOException {
         super(editor, mediaItemId, filename, renderingMode);
+
         if (editor instanceof VideoEditorImpl) {
             mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
             mVideoEditor = ((VideoEditorImpl)editor);
         }
-        Properties properties = null;
+
+        final Properties properties;
         try {
              properties = mMANativeHelper.getMediaProperties(filename);
         } catch ( Exception e) {
-            throw new IllegalArgumentException("Unsupported file or file not found");
+            throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
         }
+
         switch (mMANativeHelper.getFileType(properties.fileType)) {
             case MediaProperties.FILE_3GP:
                 break;
@@ -163,8 +162,7 @@
         mMuted = muted;
         mAudioWaveformFilename = audioWaveformFilename;
         if (audioWaveformFilename != null) {
-            mWaveformData =
-                new SoftReference<WaveformData>(
+            mWaveformData = new SoftReference<WaveformData>(
                         new WaveformData(audioWaveformFilename));
         } else {
             mWaveformData = null;
@@ -190,9 +188,11 @@
         if (beginMs > mDurationMs) {
             throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
         }
+
         if (endMs > mDurationMs) {
             throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
         }
+
         if ((endMs != -1) && (beginMs >= endMs) ) {
             throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
         }
@@ -255,18 +255,18 @@
      */
     @Override
     public Bitmap getThumbnail(int width, int height, long timeMs) {
-        if (timeMs > mDurationMs)
-        {
+        if (timeMs > mDurationMs) {
             throw new IllegalArgumentException("Time Exceeds duration");
         }
-        if (timeMs < 0)
-        {
+
+        if (timeMs < 0) {
             throw new IllegalArgumentException("Invalid Time duration");
         }
-        if ((width <=0) || (height <= 0))
-        {
+
+        if ((width <=0) || (height <= 0)) {
             throw new IllegalArgumentException("Invalid Dimensions");
         }
+
         return mMANativeHelper.getPixels(super.getFilename(),
                 width, height,timeMs);
     }
@@ -280,18 +280,21 @@
         if (startMs > endMs) {
             throw new IllegalArgumentException("Start time is greater than end time");
         }
+
         if (endMs > mDurationMs) {
             throw new IllegalArgumentException("End time is greater than file duration");
         }
+
         if ((height <= 0) || (width <= 0)) {
             throw new IllegalArgumentException("Invalid dimension");
         }
+
         if (startMs == endMs) {
-            Bitmap[] bitmap = new Bitmap[1];
-            bitmap[0] = mMANativeHelper.getPixels(super.getFilename(),
-                    width, height,startMs);
+            final Bitmap[] bitmap = new Bitmap[1];
+            bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
             return bitmap;
         }
+
         return mMANativeHelper.getPixelsList(super.getFilename(), width,
                 height,startMs,endMs,thumbnailCount);
     }
@@ -324,40 +327,58 @@
      * {@inheritDoc}
      */
     @Override
-    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
-            long newStartTimeMs,
+    void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
             long newDurationMs) {
         /**
          *  Check if the item overlaps with the beginning and end transitions
          */
         if (mBeginTransition != null) {
             final long transitionDurationMs = mBeginTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mBeginBoundaryTimeMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mBeginBoundaryTimeMs, transitionDurationMs);
             /**
-             *  If the start time has changed and if the old or the new item
-             *  overlaps with the begin transition, invalidate the transition.
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (((oldStartTimeMs != newStartTimeMs)
-                    || (oldDurationMs != newDurationMs) )&&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                            mBeginBoundaryTimeMs, transitionDurationMs) ||
-                            isOverlapping(newStartTimeMs, newDurationMs,
-                                    mBeginBoundaryTimeMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mBeginTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs != newStartTimeMs) ||
+                        !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+                        newStartTimeMs + newDurationMs > transitionDurationMs)) {
+                    mBeginTransition.invalidate();
+                }
             }
         }
 
         if (mEndTransition != null) {
             final long transitionDurationMs = mEndTransition.getDuration();
+            final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
+            final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
             /**
-             *  If the start time + duration has changed and if the old or the new
-             *  item overlaps the end transition, invalidate the transition
+             * Invalidate transition if:
+             *
+             * 1. New item overlaps the transition, the old one did not
+             * 2. New item does not overlap the transition, the old one did
+             * 3. New and old item overlap the transition if begin or end
+             * time changed
              */
-            if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
-                    (isOverlapping(oldStartTimeMs, oldDurationMs,
-                            mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
-                            isOverlapping(newStartTimeMs, newDurationMs,
-                                    mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
+            if (newOverlap != oldOverlap) { // Overlap has changed
                 mEndTransition.invalidate();
+            } else if (newOverlap) { // Both old and new overlap
+                if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+                        ((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
+                        newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
+                    mEndTransition.invalidate();
+                }
             }
         }
     }
@@ -434,7 +455,7 @@
             throw new IllegalArgumentException("requested time not correct");
         }
 
-        Surface surface = surfaceHolder.getSurface();
+        final Surface surface = surfaceHolder.getSurface();
         if (surface == null) {
             throw new RuntimeException("Surface could not be retrieved from Surface holder");
         }
@@ -442,8 +463,7 @@
         if (mFilename != null) {
             return mMANativeHelper.renderMediaItemPreviewFrame(surface,
                     mFilename,timeMs,mWidth,mHeight);
-        }
-        else {
+        } else {
             return 0;
         }
     }
@@ -462,7 +482,7 @@
      *             Audio track
      */
     public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
-    throws IOException {
+        throws IOException {
         int frameDuration = 0;
         int sampleCount = 0;
         final String projectPath = mMANativeHelper.getProjectPath();
@@ -481,19 +501,17 @@
              * Logic to get frame duration = (no. of frames per sample * 1000)/
              * sampling frequency
              */
-            if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AMRNB ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
                 sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
-            }
-            else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AMRWB ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
                 sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
-            }
-            else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+            } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
                 MediaProperties.ACODEC_AAC_LC ) {
                 frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
                 MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
@@ -682,5 +700,4 @@
 
         return clipSettings;
     }
-
 }
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index a7c7fce..abc457e 100644
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -205,6 +205,7 @@
                 values.put(Audio.Playlists.DATA, path);
                 values.put(Audio.Playlists.NAME, name);
                 values.put(Files.FileColumns.FORMAT, format);
+                values.put(Files.FileColumns.DATE_MODIFIED, System.currentTimeMillis() / 1000);
                 values.put(MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, handle);
                 try {
                     Uri uri = mMediaProvider.insert(Audio.Playlists.EXTERNAL_CONTENT_URI, values);
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index 241f18a..8908e67 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -62,6 +62,7 @@
     String8         mStoragePath;
     uint64_t        mReserveSpace;
     jobject         mJavaServer;
+    bool            mDone;
     int             mFd;
 
 public:
@@ -72,6 +73,7 @@
             mStoragePath(storagePath),
             mReserveSpace(reserveSpace),
             mJavaServer(javaServer),
+            mDone(false),
             mFd(-1)
     {
     }
@@ -94,27 +96,33 @@
 
     virtual bool threadLoop() {
         sMutex.lock();
-        mFd = open("/dev/mtp_usb", O_RDWR);
-        printf("open returned %d\n", mFd);
-        if (mFd < 0) {
-            LOGE("could not open MTP driver\n");
+
+        while (!mDone) {
+            mFd = open("/dev/mtp_usb", O_RDWR);
+            printf("open returned %d\n", mFd);
+            if (mFd < 0) {
+                LOGE("could not open MTP driver\n");
+                sMutex.unlock();
+                return false;
+            }
+
+            mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775);
+            mServer->addStorage(mStoragePath, mReserveSpace);
+
             sMutex.unlock();
-            return false;
+
+            LOGD("MtpThread mServer->run");
+            mServer->run();
+            sleep(1);
+
+            sMutex.lock();
+
+            close(mFd);
+            mFd = -1;
+            delete mServer;
+            mServer = NULL;
         }
 
-        mServer = new MtpServer(mFd, mDatabase, AID_MEDIA_RW, 0664, 0775);
-        mServer->addStorage(mStoragePath, mReserveSpace);
-        sMutex.unlock();
-
-        LOGD("MtpThread mServer->run");
-        mServer->run();
-
-        sMutex.lock();
-        close(mFd);
-        mFd = -1;
-        delete mServer;
-        mServer = NULL;
-
         JNIEnv* env = AndroidRuntime::getJNIEnv();
         env->SetIntField(mJavaServer, field_context, 0);
         env->DeleteGlobalRef(mJavaServer);
@@ -124,6 +132,12 @@
         return false;
     }
 
+    void stop() {
+        sMutex.lock();
+        mDone = true;
+        sMutex.unlock();
+    }
+
     void sendObjectAdded(MtpObjectHandle handle) {
         sMutex.lock();
         if (mServer)
@@ -181,6 +195,9 @@
 {
 #ifdef HAVE_ANDROID_OS
     LOGD("stop\n");
+    MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
+    if (thread)
+        thread->stop();
 #endif
 }
 
@@ -212,7 +229,7 @@
     MtpThread *thread = (MtpThread *)env->GetIntField(thiz, field_context);
     if (thread)
         thread->setPtpMode(usePtp);
- #endif
+#endif
 }
 
 // ----------------------------------------------------------------------------
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 27c41be..0a01fb2 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -85,6 +85,6 @@
 # to add this library to the prelink map and set this to true.
 LOCAL_PRELINK_MODULE := false
 
-LOCAL_MODULE_TAGS := eng development
+LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h
index ca8c047..c13f6ff 100755
--- a/media/jni/mediaeditor/VideoEditorLogging.h
+++ b/media/jni/mediaeditor/VideoEditorLogging.h
@@ -21,12 +21,13 @@
 
 #define VIDEOEDIT_LOG_INDENTATION                       (3)
 
+#define VIDEOEDIT_LOG_ERROR                             __android_log_print
+#define VIDEOEDIT_LOG_EXCEPTION                         __android_log_print
+
 #ifdef VIDEOEDIT_LOGGING_ENABLED
 
 #define VIDEOEDIT_LOG_ALLOCATION                        __android_log_print
 #define VIDEOEDIT_LOG_API                               __android_log_print
-#define VIDEOEDIT_LOG_ERROR                             __android_log_print
-#define VIDEOEDIT_LOG_EXCEPTION                         __android_log_print
 #define VIDEOEDIT_LOG_FUNCTION                          __android_log_print
 #define VIDEOEDIT_LOG_RESULT(x,y, ...)                     LOGI(y, __VA_ARGS__ )
 #define VIDEOEDIT_LOG_SETTING                           __android_log_print
@@ -40,8 +41,6 @@
 
 #define VIDEOEDIT_LOG_ALLOCATION                        (void)
 #define VIDEOEDIT_LOG_API                               (void)
-#define VIDEOEDIT_LOG_ERROR                             (void)
-#define VIDEOEDIT_LOG_EXCEPTION                         (void)
 #define VIDEOEDIT_LOG_FUNCTION                          (void)
 #define VIDEOEDIT_LOG_RESULT                            (void)
 #define VIDEOEDIT_LOG_SETTING                           (void)
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index e66e4b9..643f698 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -437,7 +437,7 @@
     VideoEditor_renderPreviewFrameStr frameStr;
     M4OSA_Context tnContext = M4OSA_NULL;
     const char* pMessage = NULL;
-    M4VIFI_ImagePlane *yuvPlane;
+    M4VIFI_ImagePlane *yuvPlane = NULL;
 
     VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
         "VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
@@ -1179,7 +1179,7 @@
     }
 
     /** Remove the alpha channel */
-    for (int i = 0, j = 0; i < frameSize_argb; i++) {
+    for (size_t i = 0, j = 0; i < frameSize_argb; i++) {
         if ((i % 4) == 0) continue;
         pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i];
         j++;
@@ -2729,7 +2729,7 @@
 } M4AM_Buffer;
 
 
-M4OSA_UInt8 logLookUp[256]{
+M4OSA_UInt8 logLookUp[256] = {
 0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193,
 194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210,
 211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220,
@@ -2788,7 +2788,7 @@
     err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
     if (inputFileHandle == M4OSA_NULL) {
         VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Cannot open input file 0x%x", err);
+            "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err);
         return err;
     }
 
@@ -2822,7 +2822,7 @@
         bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
     } else {
         VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
-            "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%x",\
+            "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx",
             M4ERR_ALLOC);
         return M4ERR_ALLOC;
     }
@@ -2862,7 +2862,7 @@
         if (err != M4NO_ERROR) {
             // if out value of bytes-read is 0, break
             if ( numBytesToRead == 0) {
-                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%x",\
+                VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx",
                 numBytesToRead);
                 break; /* stop if file is empty or EOF */
             }
@@ -2914,7 +2914,7 @@
 
     } while (numBytesToRead != 0);
 
-    VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%x", volumeValuesCount);
+    VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount);
 
     /* if some error occured in fwrite */
     if (numBytesToRead != 0) {
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 9ce6738..af67175 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -5,6 +5,7 @@
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
 #include <media/IOMX.h>
+#include <media/stagefright/foundation/ADebug.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/Surface.h>
 
@@ -449,74 +450,8 @@
         }
 
         case GET_PARAMETER:
-        {
-            CHECK_INTERFACE(IOMX, data, reply);
-
-            node_id node = (void*)data.readIntPtr();
-            OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
-            size_t size = data.readInt32();
-
-            // XXX I am not happy with this but Parcel::readInplace didn't work.
-            void *params = malloc(size);
-            data.read(params, size);
-
-            status_t err = getParameter(node, index, params, size);
-
-            reply->writeInt32(err);
-
-            if (err == OK) {
-                reply->write(params, size);
-            }
-
-            free(params);
-            params = NULL;
-
-            return NO_ERROR;
-        }
-
         case SET_PARAMETER:
-        {
-            CHECK_INTERFACE(IOMX, data, reply);
-
-            node_id node = (void*)data.readIntPtr();
-            OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
-            size_t size = data.readInt32();
-            void *params = const_cast<void *>(data.readInplace(size));
-
-            reply->writeInt32(setParameter(node, index, params, size));
-
-            return NO_ERROR;
-        }
-
         case GET_CONFIG:
-        {
-            CHECK_INTERFACE(IOMX, data, reply);
-
-            node_id node = (void*)data.readIntPtr();
-            OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
-
-            size_t size = data.readInt32();
-
-            // XXX I am not happy with this but Parcel::readInplace didn't work.
-            void *params = malloc(size);
-            data.read(params, size);
-
-            status_t err = getConfig(node, index, params, size);
-
-            reply->writeInt32(err);
-
-            if (err == OK) {
-                reply->write(params, size);
-            }
-
-            free(params);
-            params = NULL;
-
-            return NO_ERROR;
-        }
-
         case SET_CONFIG:
         {
             CHECK_INTERFACE(IOMX, data, reply);
@@ -525,9 +460,36 @@
             OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
 
             size_t size = data.readInt32();
-            void *params = const_cast<void *>(data.readInplace(size));
 
-            reply->writeInt32(setConfig(node, index, params, size));
+            void *params = malloc(size);
+            data.read(params, size);
+
+            status_t err;
+            switch (code) {
+                case GET_PARAMETER:
+                    err = getParameter(node, index, params, size);
+                    break;
+                case SET_PARAMETER:
+                    err = setParameter(node, index, params, size);
+                    break;
+                case GET_CONFIG:
+                    err = getConfig(node, index, params, size);
+                    break;
+                case SET_CONFIG:
+                    err = setConfig(node, index, params, size);
+                    break;
+                default:
+                    TRESPASS();
+            }
+
+            reply->writeInt32(err);
+
+            if ((code == GET_PARAMETER || code == GET_CONFIG) && err == OK) {
+                reply->write(params, size);
+            }
+
+            free(params);
+            params = NULL;
 
             return NO_ERROR;
         }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 992abd7..153b2a6 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1229,23 +1229,13 @@
     }
     if (mVideoEncoderLevel != -1) {
         enc_meta->setInt32(kKeyVideoLevel, mVideoEncoderLevel);
-    } else if (mCaptureTimeLapse) {
-        // Check if we are using high resolution and/or high bitrate and
-        // set appropriate level for the software AVCEncoder.
-        if ((width * height >= 921600) // 720p
-                || (videoBitRate >= 20000000)) {
-            enc_meta->setInt32(kKeyVideoLevel, OMX_VIDEO_AVCLevel5);
-        }
     }
 
     OMXClient client;
     CHECK_EQ(client.connect(), OK);
 
-    // Use software codec for time lapse
     uint32_t encoder_flags = 0;
-    if (mCaptureTimeLapse) {
-        encoder_flags |= OMXCodec::kPreferSoftwareCodecs;
-    } else if (mIsMetaDataStoredInVideoBuffers) {
+    if (mIsMetaDataStoredInVideoBuffers) {
         encoder_flags |= OMXCodec::kHardwareCodecsOnly;
         encoder_flags |= OMXCodec::kStoreMetaDataInVideoBuffers;
     }
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 49d05ed..11ac56c 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -58,6 +58,8 @@
 
 static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
 static int64_t kHighWaterMarkUs = 10000000ll;  // 10secs
+static const size_t kLowWaterMarkBytes = 40000;
+static const size_t kHighWaterMarkBytes = 200000;
 
 struct AwesomeEvent : public TimedEventQueue::Event {
     AwesomeEvent(
@@ -165,6 +167,8 @@
       mTimeSource(NULL),
       mVideoRendererIsPreview(false),
       mAudioPlayer(NULL),
+      mDisplayWidth(0),
+      mDisplayHeight(0),
       mFlags(0),
       mExtractorFlags(0),
       mVideoBuffer(NULL),
@@ -329,6 +333,18 @@
         if (!haveVideo && !strncasecmp(mime, "video/", 6)) {
             setVideoSource(extractor->getTrack(i));
             haveVideo = true;
+
+            // Set the presentation/display size
+            int32_t displayWidth, displayHeight;
+            bool success = meta->findInt32(kKeyDisplayWidth, &displayWidth);
+            if (success) {
+                success = meta->findInt32(kKeyDisplayHeight, &displayHeight);
+            }
+            if (success) {
+                mDisplayWidth = displayWidth;
+                mDisplayHeight = displayHeight;
+            }
+
         } else if (!haveAudio && !strncasecmp(mime, "audio/", 6)) {
             setAudioSource(extractor->getTrack(i));
             haveAudio = true;
@@ -370,6 +386,8 @@
 
 void AwesomePlayer::reset_l() {
     LOGI("reset_l");
+    mDisplayWidth = 0;
+    mDisplayHeight = 0;
 
     if (mDecryptHandle != NULL) {
             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -594,9 +612,6 @@
                 // We don't know the bitrate of the stream, use absolute size
                 // limits to maintain the cache.
 
-                const size_t kLowWaterMarkBytes = 40000;
-                const size_t kHighWaterMarkBytes = 200000;
-
                 if ((mFlags & PLAYING) && !eos
                         && (cachedDataRemaining < kLowWaterMarkBytes)) {
                     LOGI("cache is running low (< %d) , pausing.",
@@ -862,6 +877,12 @@
 
     int32_t usableWidth = cropRight - cropLeft + 1;
     int32_t usableHeight = cropBottom - cropTop + 1;
+    if (mDisplayWidth != 0) {
+        usableWidth = mDisplayWidth;
+    }
+    if (mDisplayHeight != 0) {
+        usableHeight = mDisplayHeight;
+    }
 
     int32_t rotationDegrees;
     if (!mVideoTrack->getFormat()->findInt32(
@@ -1513,6 +1534,34 @@
         mConnectingDataSource.clear();
 
         dataSource = mCachedSource;
+
+        // We're going to prefill the cache before trying to instantiate
+        // the extractor below, as the latter is an operation that otherwise
+        // could block on the datasource for a significant amount of time.
+        // During that time we'd be unable to abort the preparation phase
+        // without this prefill.
+
+        mLock.unlock();
+
+        for (;;) {
+            status_t finalStatus;
+            size_t cachedDataRemaining =
+                mCachedSource->approxDataRemaining(&finalStatus);
+
+            if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+                    || (mFlags & PREPARE_CANCELLED)) {
+                break;
+            }
+
+            usleep(200000);
+        }
+
+        mLock.lock();
+
+        if (mFlags & PREPARE_CANCELLED) {
+            LOGI("Prepare cancelled while waiting for initial cache fill.");
+            return UNKNOWN_ERROR;
+        }
     } else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
         String8 uri("http://");
         uri.append(mUri.string() + 11);
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 31b6ec9..b58b9d8 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -66,7 +66,7 @@
         int32_t videoFrameRate,
         const sp<Surface>& surface,
         int64_t timeBetweenTimeLapseFrameCaptureUs)
-    : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface, false),
+    : CameraSource(camera, cameraId, videoSize, videoFrameRate, surface, true),
       mTimeBetweenTimeLapseFrameCaptureUs(timeBetweenTimeLapseFrameCaptureUs),
       mTimeBetweenTimeLapseVideoFramesUs(1E6/videoFrameRate),
       mLastTimeLapseFrameRealTimestampUs(0),
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index e7f00aa..057868c 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -25,13 +25,14 @@
 #include <arpa/inet.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
 
@@ -47,6 +48,82 @@
     disconnect();
 }
 
+static bool MakeSocketBlocking(int s, bool blocking) {
+    // Make socket non-blocking.
+    int flags = fcntl(s, F_GETFL, 0);
+    if (flags == -1) {
+        return false;
+    }
+
+    if (blocking) {
+        flags &= ~O_NONBLOCK;
+    } else {
+        flags |= O_NONBLOCK;
+    }
+
+    return fcntl(s, F_SETFL, flags) != -1;
+}
+
+static status_t MyConnect(
+        int s, const struct sockaddr *addr, socklen_t addrlen) {
+    status_t result = UNKNOWN_ERROR;
+
+    MakeSocketBlocking(s, false);
+
+    if (connect(s, addr, addrlen) == 0) {
+        result = OK;
+    } else if (errno != EINPROGRESS) {
+        result = -errno;
+    } else {
+        for (;;) {
+            fd_set rs, ws;
+            FD_ZERO(&rs);
+            FD_ZERO(&ws);
+            FD_SET(s, &rs);
+            FD_SET(s, &ws);
+
+            struct timeval tv;
+            tv.tv_sec = 0;
+            tv.tv_usec = 100000ll;
+
+            int nfds = ::select(s + 1, &rs, &ws, NULL, &tv);
+
+            if (nfds < 0) {
+                if (errno == EINTR) {
+                    continue;
+                }
+
+                result = -errno;
+                break;
+            }
+
+            if (FD_ISSET(s, &ws) && !FD_ISSET(s, &rs)) {
+                result = OK;
+                break;
+            }
+
+            if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
+                // Get the pending error.
+                int error = 0;
+                socklen_t errorLen = sizeof(error);
+                if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
+                    // Couldn't get the real error, so report why not.
+                    result = -errno;
+                } else {
+                    result = -error;
+                }
+                break;
+            }
+
+            // Timeout expired. Try again.
+        }
+    }
+
+    MakeSocketBlocking(s, true);
+
+    return result;
+}
+
 status_t HTTPStream::connect(const char *server, int port) {
     Mutex::Autolock autoLock(mLock);
 
@@ -82,7 +159,7 @@
     addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
     memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
 
-    int res = ::connect(s, (const struct sockaddr *)&addr, sizeof(addr));
+    status_t res = MyConnect(s, (const struct sockaddr *)&addr, sizeof(addr));
 
     mLock.lock();
 
@@ -90,12 +167,12 @@
         return UNKNOWN_ERROR;
     }
 
-    if (res < 0) {
+    if (res != OK) {
         close(mSocket);
         mSocket = -1;
 
         mState = READY;
-        return UNKNOWN_ERROR;
+        return res;
     }
 
     mState = CONNECTED;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index bafa243..e6e98aa 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1040,8 +1040,23 @@
             // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
             // and thus will grow by 2 bytes per fragment.
             mLastTrack->meta->setInt32(kKeyMaxInputSize, max_size + 10 * 2);
-
             *offset += chunk_size;
+
+            // Calculate average frame rate.
+            const char *mime;
+            CHECK(mLastTrack->meta->findCString(kKeyMIMEType, &mime));
+            if (!strncasecmp("video/", mime, 6)) {
+                size_t nSamples = mLastTrack->sampleTable->countSamples();
+                int64_t durationUs;
+                if (mLastTrack->meta->findInt64(kKeyDuration, &durationUs)) {
+                    if (durationUs > 0) {
+                        int32_t frameRate = (nSamples * 1000000LL +
+                                    (durationUs >> 1)) / durationUs;
+                        mLastTrack->meta->setInt32(kKeyFrameRate, frameRate);
+                    }
+                }
+            }
+
             break;
         }
 
@@ -1321,10 +1336,12 @@
         mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees);
     }
 
-#if 0
+    // Handle presentation display size, which could be different
+    // from the image size indicated by kKeyWidth and kKeyHeight.
     uint32_t width = U32_AT(&buffer[dynSize + 52]);
     uint32_t height = U32_AT(&buffer[dynSize + 56]);
-#endif
+    mLastTrack->meta->setInt32(kKeyDisplayWidth, width >> 16);
+    mLastTrack->meta->setInt32(kKeyDisplayHeight, height >> 16);
 
     return OK;
 }
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 06c4c98..a47ee3a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -590,6 +590,7 @@
 
     status_t err = OK;
     int64_t maxDurationUs = 0;
+    int64_t minDurationUs = 0x7fffffffffffffffLL;
     for (List<Track *>::iterator it = mTracks.begin();
          it != mTracks.end(); ++it) {
         status_t status = (*it)->stop();
@@ -601,6 +602,14 @@
         if (durationUs > maxDurationUs) {
             maxDurationUs = durationUs;
         }
+        if (durationUs < minDurationUs) {
+            minDurationUs = durationUs;
+        }
+    }
+
+    if (mTracks.size() > 1) {
+        LOGD("Duration from tracks range is [%lld, %lld] us",
+            minDurationUs, maxDurationUs);
     }
 
     stopWriterThread();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 20f1655..741aa1c 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
 #define LOG_TAG "NuCachedSource2"
 #include <utils/Log.h>
 
@@ -487,4 +488,5 @@
 String8 NuCachedSource2::getUri() {
     return mSource->getUri();
 }
+
 }  // namespace android
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index e516cb4..d842f65 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2233,7 +2233,11 @@
                 enablePortAsync(portIndex);
 
                 status_t err = allocateBuffersOnPort(portIndex);
-                CHECK_EQ(err, (status_t)OK);
+
+                if (err != OK) {
+                    CODEC_LOGE("allocateBuffersOnPort failed (err = %d)", err);
+                    setState(ERROR);
+                }
             }
             break;
         }
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 5979be6..f20a4cb 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -438,8 +438,7 @@
 
     if (mSeqNumber < firstSeqNumberInPlaylist
             || mSeqNumber > lastSeqNumberInPlaylist) {
-        if (mSeqNumber < firstSeqNumberInPlaylist
-                && mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
+        if (mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
             // Go back to the previous bandwidth.
 
             LOGI("new bandwidth does not have the sequence number "
@@ -493,8 +492,14 @@
 
     CHECK(buffer != NULL);
 
-    CHECK_EQ((status_t)OK,
-             decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer));
+    err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer);
+
+    if (err != OK) {
+        LOGE("decryptBuffer failed w/ error %d", err);
+
+        mDataSource->queueEOS(err);
+        return;
+    }
 
     if (buffer->size() == 0 || buffer->data()[0] != 0x47) {
         // Not a transport stream???
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index fe00856..41ef181 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -150,6 +150,9 @@
     AudioPlayer *mAudioPlayer;
     int64_t mDurationUs;
 
+    int32_t mDisplayWidth;
+    int32_t mDisplayHeight;
+
     uint32_t mFlags;
     uint32_t mExtractorFlags;
     uint32_t mSinceLastDropped;
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 4099c4c..32d1a23 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -272,7 +272,6 @@
     }
 
     /**
-     * @hide
      * Control whether the EGL context is preserved when the GLSurfaceView is paused and
      * resumed.
      * <p>
@@ -295,7 +294,6 @@
     }
 
     /**
-     * @hide
      * @return true if the EGL context will be preserved when paused
      */
     public boolean getPreserveEGLContextOnPause() {
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 2ec2226..21f77e3 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -190,6 +190,7 @@
                 while ((pkg=pm.nextPackageToClean(pkg)) != null) {
                     eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg));
                     eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg));
+                    eraseFiles(Environment.getExternalStorageAppObbDirectory(pkg));
                 }
             } catch (RemoteException e) {
             }
diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf
index 3945183..7b550ee 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock.ttf
Binary files differ
diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
index fa0221e..a95d548 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
new file mode 100644
index 0000000..9812339
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
new file mode 100644
index 0000000..4f61511
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
new file mode 100644
index 0000000..4757125
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
new file mode 100644
index 0000000..8436f5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
new file mode 100644
index 0000000..6005075
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
new file mode 100644
index 0000000..83068a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
new file mode 100644
index 0000000..e6f2f34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
new file mode 100644
index 0000000..2591521
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
new file mode 100644
index 0000000..56a4a1d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
new file mode 100644
index 0000000..7754657
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
new file mode 100644
index 0000000..afc4057
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
index dadb0cd..92ffde9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
index 51d7cc2..0cd05a3 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
index 3359602..993ea55 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
new file mode 100644
index 0000000..22d6c79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
new file mode 100644
index 0000000..24166da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
new file mode 100644
index 0000000..85d9795
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..b389a35
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/panel_notification.png b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
new file mode 100644
index 0000000..3789f3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
deleted file mode 100755
index e9589d9..0000000
--- a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
new file mode 100644
index 0000000..0371322
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+
+<bitmap
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/notify_panel_bg_protect"
+    android:tileMode="repeat"
+    />
+
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index 9da92a7..3a50aa9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -20,7 +20,6 @@
     >
     <item
         android:drawable="@drawable/notification_item_background_color"
-        android:left="16dp"
         />
 </layer-list>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 0533b6f..852b729 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -78,15 +78,14 @@
             </LinearLayout>
 
             <!-- fake space bar zone -->
-            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/fake_space_bar"
+            <com.android.systemui.statusbar.policy.EventHole android:id="@+id/fake_space_bar"
                 android:layout_height="match_parent"
-                android:layout_width="match_parent"
+                android:layout_width="0dp"
                 android:paddingLeft="8dip"
                 android:paddingRight="8dip"
                 android:layout_toRightOf="@+id/navigationArea"
                 android:layout_toLeftOf="@+id/notificationArea"
                 android:visibility="gone"
-                systemui:keyCode="62"
                 />
         </RelativeLayout>
     </FrameLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 7f84b21..26e045c 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -25,8 +25,8 @@
 
     <View
         android:id="@+id/scrim"
-        android:background="@drawable/notify_panel_bg_protect"
-        android:layout_width="match_parent"
+        android:background="@drawable/notify_panel_bg_protect_tiled"
+        android:layout_width="512dp"
         android:layout_height="match_parent"
         android:layout_alignParentTop="true"
         android:layout_alignParentRight="true"
@@ -35,142 +35,27 @@
     <RelativeLayout
         android:id="@+id/content_parent"
         android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_alignParentBottom="true"
         android:layout_alignParentRight="true"
         >
-        <RelativeLayout
-            android:id="@+id/title_area"
-            android:layout_height="160dp"
-            android:layout_width="384dp"
-            android:layout_marginLeft="24dp"
-            android:paddingTop="20dp"
-            android:orientation="vertical"
+
+        <include layout="@layout/status_bar_notification_panel_title"
+            android:layout_width="471dp"
+            android:layout_height="465dp"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
-            android:background="@drawable/panel_notification_tiled"
-            >
-
-            <com.android.systemui.statusbar.tablet.HoloClock
-                android:id="@+id/clock"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:layout_alignParentTop="true"
-                android:layout_marginRight="40dip"
-                android:layout_marginBottom="4dip"
-                >
-                <TextView android:id="@+id/time_bg"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:gravity="right"
-                    android:singleLine="true"
-                    android:textSize="90dip"
-                    android:textColor="#999999" />
-                <TextView android:id="@+id/time_fg"
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:gravity="right"
-                    android:singleLine="true"
-                    android:textSize="90dip"
-                    android:textColor="#666666" />
-            </com.android.systemui.statusbar.tablet.HoloClock>
-
-            <com.android.systemui.statusbar.policy.DateView
-                android:id="@+id/date"
-                style="@style/StatusBarNotificationText"
-                android:layout_height="wrap_content"
-                android:layout_width="match_parent"
-                android:layout_below="@id/clock"
-                android:layout_marginTop="4dp"
-                android:layout_marginRight="48dp"
-                android:gravity="right"
-                />
-
-            <ImageView
-                android:id="@+id/battery"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_alignParentLeft="true"
-                android:layout_below="@id/date"
-                android:layout_marginLeft="48dp"
-                android:layout_marginTop="18dp"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <TextView
-                android:id="@+id/battery_text"
-                style="@style/StatusBarNotificationText"
-                android:layout_width="56dp"
-                android:layout_height="wrap_content"
-                android:layout_toRightOf="@id/battery"
-                android:layout_alignBaseline="@id/battery"
-                android:singleLine="true"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <ImageView
-                android:id="@+id/network_signal"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_toRightOf="@id/battery_text"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <ImageView
-                android:id="@+id/network_type"
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:layout_toRightOf="@id/battery_text"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_marginRight="8dp"
-                android:baseline="15dp"
-                />
-
-            <TextView
-                android:id="@+id/network_text"
-                style="@style/StatusBarNotificationText"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_toRightOf="@id/network_signal"
-                android:layout_alignBaseline="@id/battery"
-                android:singleLine="true"
-                android:text="@string/status_bar_settings_settings_button"
-                />
-
-            <ImageView
-                android:id="@+id/settings_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignBaseline="@id/battery"
-                android:layout_alignParentRight="true"
-                android:paddingRight="16dp"
-                android:src="@drawable/ic_notification_open"
-                android:baseline="21dp"
-                />
-
-            <ImageView
-                android:id="@+id/notification_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_alignBaseline="@id/battery"
-                android:paddingRight="16dp"
-                android:visibility="invisible"
-                android:src="@drawable/status_bar_veto"
-                android:baseline="21dp"
-                />
-        </RelativeLayout>
+            />
 
         <LinearLayout
             android:id="@+id/content_frame"
+            android:background="@drawable/notify_panel_notify_bg"
             android:layout_height="wrap_content"
-            android:layout_width="408dp"
+            android:layout_width="447dp"
             android:orientation="vertical"
-            android:layout_below="@id/title_area"
             android:layout_alignParentRight="true"
+            android:layout_alignParentTop="true"
+            android:layout_marginTop="352dp"
             >
             <ScrollView
                 android:id="@+id/notification_scroller"
@@ -189,17 +74,9 @@
                     android:clickable="true"
                     android:focusable="true"
                     android:descendantFocusability="afterDescendants"
-                    systemui:insetLeft="16dp"
                     >
                 </com.android.systemui.statusbar.tablet.NotificationLinearLayout>
             </ScrollView>
-            <ImageView
-                android:id="@+id/notification_glow"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/status_bar_panel_bottom_offset"
-                android:layout_marginLeft="16dp"
-                android:src="@drawable/notify_item_glow_bottom"
-                />
         </LinearLayout>
     </RelativeLayout>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
new file mode 100644
index 0000000..992995c
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -0,0 +1,153 @@
+<!--
+  Copyright (C) 2006 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"
+    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+    android:id="@+id/title_area"
+    android:layout_width="0dp"
+    android:layout_height="0dp"
+    android:orientation="vertical"
+    android:background="@drawable/notify_panel_clock_bg"
+    >
+
+    <ImageView
+        android:id="@+id/network_signal"
+        android:layout_height="32dp"
+        android:layout_width="32dp"
+        android:scaleType="centerInside"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentBottom="true"
+        android:baseline="22dp"
+        android:layout_marginLeft="32dp"
+        android:layout_marginTop="16dp"
+        android:layout_marginBottom="16dp"
+        />
+
+    <ImageView
+        android:id="@+id/network_type"
+        android:layout_height="wrap_content"
+        android:layout_width="wrap_content"
+        android:layout_alignLeft="@id/network_signal"
+        android:layout_alignBottom="@id/network_signal"
+        android:layout_marginRight="8dp"
+        />
+
+    <TextView
+        android:id="@+id/network_text"
+        style="@style/StatusBarNotificationText"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/network_signal"
+        android:layout_marginRight="8dp"
+        android:layout_alignBaseline="@id/network_signal"
+        android:singleLine="true"
+        android:text="@string/status_bar_settings_settings_button"
+        />
+
+    <ImageView
+        android:id="@+id/battery"
+        android:layout_height="32dp"
+        android:layout_width="32dp"
+        android:scaleType="centerInside"
+        android:layout_toRightOf="@id/network_text"
+        android:layout_alignBaseline="@id/network_signal"
+        android:baseline="22dp"
+        />
+
+    <TextView
+        android:id="@+id/battery_text"
+        style="@style/StatusBarNotificationText"
+        android:layout_width="56dp"
+        android:layout_height="wrap_content"
+        android:layout_toRightOf="@id/battery"
+        android:layout_alignBaseline="@id/battery"
+        android:layout_marginRight="8dp"
+        android:singleLine="true"
+        android:text="@string/status_bar_settings_settings_button"
+        />
+
+    <ImageView
+        android:id="@+id/settings_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@id/battery"
+        android:layout_alignParentRight="true"
+        android:paddingRight="16dp"
+        android:src="@drawable/ic_notification_open"
+        android:baseline="21dp"
+        />
+
+    <ImageView
+        android:id="@+id/notification_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignBaseline="@id/battery"
+        android:paddingRight="16dp"
+        android:visibility="invisible"
+        android:src="@drawable/status_bar_veto"
+        android:baseline="21dp"
+        />
+
+    <View
+        android:id="@+id/title_divider"
+        android:layout_width="match_parent"
+        android:layout_height="1dp"
+        android:layout_marginLeft="32dp"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="64dip"
+        android:background="@android:drawable/divider_horizontal_dark"
+        />
+
+    <com.android.systemui.statusbar.tablet.HoloClock
+        android:id="@+id/clock"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_alignParentRight="true"
+        android:layout_above="@id/title_divider"
+        android:layout_marginRight="32dip"
+        android:layout_marginBottom="8dip"
+        >
+        <TextView android:id="@+id/time_bg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:singleLine="true"
+            android:textSize="80sp"
+            android:textColor="#999999" />
+        <TextView android:id="@+id/time_fg"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="right"
+            android:singleLine="true"
+            android:textSize="80sp"
+            android:textColor="#666666" />
+    </com.android.systemui.statusbar.tablet.HoloClock>
+
+    <com.android.systemui.statusbar.policy.DateView
+        android:id="@+id/date"
+        style="@style/StatusBarNotificationText"
+        android:layout_height="wrap_content"
+        android:layout_width="142dp"
+        android:layout_alignBottom="@id/clock"
+        android:layout_alignParentLeft="true"
+        android:gravity="left"
+        android:layout_marginLeft="32dp"
+        />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
index e97345b..233cb46 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
@@ -32,7 +32,6 @@
         android:layout_alignParentTop="true"
         android:layout_toRightOf="@id/large_icon"
         android:layout_toLeftOf="@id/veto"
-        android:layout_marginLeft="16dp"
         android:focusable="true"
         android:clickable="true"
         />
@@ -40,7 +39,6 @@
     <View
         android:layout_width="match_parent"
         android:layout_height="1dp"
-        android:layout_marginLeft="16dp"
         android:layout_alignParentBottom="true"
         android:background="@android:drawable/divider_horizontal_dark"
         />
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 8a477e4..1dbd759 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -22,8 +22,7 @@
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:background="@drawable/status_bar_item_background"
-        android:paddingLeft="16dp"
-        android:paddingRight="46dp"
+        android:paddingRight="48dp"
         >
 
     <!-- Airplane mode -->
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5f01f4d..b0eac55 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index aa98f7d..53c44c6 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 583044d..168d8af 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index ea5694d..1ff4a80 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index b95c6cb..969a7d8 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4043c2e..cc741ee 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 39a462c..83f29ff 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 72373bb..068451e 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
index f29259a..5c9c6fc 100644
--- a/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS-xlarge/strings.xml
@@ -9,6 +9,8 @@
     <string name="status_bar_settings_rotation_lock" msgid="9125161825884157545">"Bloquear orient. de pant."</string>
     <!-- XL -->
     <string name="recent_tasks_app_label" msgid="5550538721034982973">"Google Apps"</string>
+    <!-- XL -->
+    <string name="bluetooth_tethered" msgid="8017158699581472359">"Bluetooth anclado"</string>
     <!-- XL xlarge -->
     <string name="status_bar_settings_signal_meter_disconnected" msgid="4866302415753953027">"Sin conexión a Internet"</string>
     <!-- XL xlarge -->
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 8013a19..da742e6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 3acfb45..58046ab 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0528d68..3c65051 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 1ce102a..cbb2eec 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 12308fb..d199d9a 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 411336a..3e60b8d 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index b82aa77..dbcd29d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index db170ab..db87cd3 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ca99d86..9d751795 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f2d5621..34eb41f 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 25d8873..3b59844 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 6c5970a..35d7503 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 90a5e44..a5848a9 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index fb33329..cf81e85 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 82405a8..4d6140f 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4efdcbb..339d146 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 07ef5ef..b50c422 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index aa14cce..01544b5 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 17be76a..35ffabb 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index e3fec88..7b94e9b 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -57,4 +57,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2bb3c14..4e32019 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 89b9cc8..7a6a71e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 9716327..6b497b9 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index b05b93c..54145f2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -32,8 +32,7 @@
     <string name="invalid_charger" msgid="4549105996740522523">"Polnjenje po povezavi USB ni podprto."\n"Uporabite priloženi polnilnik."</string>
     <string name="battery_low_why" msgid="7279169609518386372">"Uporaba baterije"</string>
     <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavitve"</string>
-    <!-- no translation found for status_bar_settings_wifi_button (1733928151698311923) -->
-    <skip />
+    <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
     <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Način za letalo"</string>
     <string name="status_bar_settings_rotation_lock" msgid="8361452930058000609">"Zakleni usmerjenost zaslona"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"TIHO"</string>
@@ -45,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index ff1d3fb..6ee4009 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 06b6880..99623c3 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 2d337a90..7d154a6 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e94d3cc..bb56bc2 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4c3f818..361d7ee 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 85ead1c..ae40e56 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 71df0c3..2ec07f1 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0cdc38d..cb15613 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index c85020f..960130f 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -44,4 +44,6 @@
     <skip />
     <!-- no translation found for bluetooth_tethered (7094101612161133267) -->
     <skip />
+    <!-- no translation found for status_bar_input_method_settings_configure_input_methods (737483394044014246) -->
+    <skip />
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
new file mode 100644
index 0000000..47e758c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
@@ -0,0 +1,99 @@
+/*
+ * 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.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Region;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.ServiceManager;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.HapticFeedbackConstants;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
+import android.widget.RemoteViews.RemoteView;
+
+import com.android.systemui.R;
+
+public class EventHole extends View implements ViewTreeObserver.OnComputeInternalInsetsListener {
+    private static final String TAG = "StatusBar.EventHole";
+
+    private boolean mWindowVis;
+    private int[] mLoc = new int[2];
+
+    public EventHole(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public EventHole(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onWindowVisibilityChanged(int visibility) {
+        super.onWindowVisibilityChanged(visibility);
+        mWindowVis = visibility == View.VISIBLE;
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+    }
+
+    public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+        final boolean visible = isShown() && mWindowVis && getWidth() > 0 && getHeight() > 0;
+        final int[] loc = mLoc;
+        getLocationInWindow(loc);
+        final int l = loc[0];
+        final int r = l + getWidth();
+        final int t = loc[1];
+        final int b = t + getHeight();
+        
+        View top = this;
+        while (top.getParent() instanceof View) {
+            top = (View)top.getParent();
+        }
+
+        if (visible) {
+            info.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+            info.touchableRegion.set(0, 0, top.getWidth(), top.getHeight());
+            info.touchableRegion.op(l, t, r, b, Region.Op.DIFFERENCE);
+        } else {
+            info.setTouchableInsets(
+                    ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+        }
+    }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 45a22b6..692d41c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -50,9 +50,8 @@
     View mSettingsButton;
     View mNotificationButton;
     View mNotificationScroller;
-    View mNotificationGlow;
     ViewGroup mContentFrame;
-    Rect mContentArea;
+    Rect mContentArea = new Rect();
     View mSettingsView;
     View mScrim, mGlow;
     ViewGroup mContentParent;
@@ -85,7 +84,6 @@
         mNotificationButton = (ImageView)findViewById(R.id.notification_button);
 
         mNotificationScroller = findViewById(R.id.notification_scroller);
-        mNotificationGlow = findViewById(R.id.notification_glow);
         mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
     }
 
@@ -130,13 +128,13 @@
     @Override
     protected void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
+
         mChoreo.setPanelHeight(mContentParent.getHeight());
     }
 
     @Override
     public void onSizeChanged(int w, int h, int oldw, int oldh) {
         super.onSizeChanged(w, h, oldw, oldh);
-        mContentArea = null;
     }
 
     public void onClick(View v) {
@@ -165,13 +163,11 @@
     }
 
     public boolean isInContentArea(int x, int y) {
-        if (mContentArea == null) {
-            mContentArea = new Rect(mContentFrame.getLeft(),
-                    mTitleArea.getTop(),
-                    mContentFrame.getRight(),
-                    mContentFrame.getBottom());
-            offsetDescendantRectToMyCoords(mContentParent, mContentArea);
-        }
+        mContentArea.left = mContentFrame.getLeft();
+        mContentArea.top = mTitleArea.getTop();
+        mContentArea.right = mContentFrame.getRight();
+        mContentArea.bottom = mContentFrame.getBottom();
+        offsetDescendantRectToMyCoords(mContentParent, mContentArea);
         return mContentArea.contains(x, y);
     }
 
@@ -185,7 +181,7 @@
     void addSettingsView() {
         LayoutInflater infl = LayoutInflater.from(getContext());
         mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
-        mContentFrame.addView(mSettingsView, mContentFrame.indexOfChild(mNotificationGlow));
+        mContentFrame.addView(mSettingsView);
     }
 
     private class Choreographer implements Animator.AnimatorListener {
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
index 63b87b1..a618423 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/packages/VpnServices/src/com/android/server/vpn/VpnService.java
@@ -328,6 +328,7 @@
             public void run() {
                 Log.i(TAG, "VPN connectivity monitor running");
                 try {
+                    mNotification.update(mStartTime); // to pop up notification
                     for (int i = 10; ; i--) {
                         long now = System.currentTimeMillis();
 
@@ -417,13 +418,27 @@
 
     // Helper class for showing, updating notification.
     private class NotificationHelper {
+        private NotificationManager mNotificationManager = (NotificationManager)
+                mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        private Notification mNotification =
+                new Notification(R.drawable.vpn_connected, null, 0L);
+        private PendingIntent mPendingIntent = PendingIntent.getActivity(
+                mContext, 0,
+                new VpnManager(mContext).createSettingsActivityIntent(), 0);
+        private String mConnectedTitle;
+
         void update(long now) {
-            String title = getNotificationTitle(true);
-            Notification n = new Notification(R.drawable.vpn_connected, title,
-                    mStartTime);
-            n.setLatestEventInfo(mContext, title,
+            Notification n = mNotification;
+            if (now == mStartTime) {
+                // to pop up the notification for the first time
+                n.when = mStartTime;
+                n.tickerText = mConnectedTitle = getNotificationTitle(true);
+            } else {
+                n.tickerText = null;
+            }
+            n.setLatestEventInfo(mContext, mConnectedTitle,
                     getConnectedNotificationMessage(now),
-                    prepareNotificationIntent());
+                    mPendingIntent);
             n.flags |= Notification.FLAG_NO_CLEAR;
             n.flags |= Notification.FLAG_ONGOING_EVENT;
             enableNotification(n);
@@ -435,25 +450,18 @@
                     title, System.currentTimeMillis());
             n.setLatestEventInfo(mContext, title,
                     getDisconnectedNotificationMessage(),
-                    prepareNotificationIntent());
+                    mPendingIntent);
             n.flags |= Notification.FLAG_AUTO_CANCEL;
             disableNotification();
             enableNotification(n);
         }
 
         void disableNotification() {
-            ((NotificationManager) mContext.getSystemService(
-                    Context.NOTIFICATION_SERVICE)).cancel(NOTIFICATION_ID);
+            mNotificationManager.cancel(NOTIFICATION_ID);
         }
 
         private void enableNotification(Notification n) {
-            ((NotificationManager) mContext.getSystemService(
-                    Context.NOTIFICATION_SERVICE)).notify(NOTIFICATION_ID, n);
-        }
-
-        private PendingIntent prepareNotificationIntent() {
-            return PendingIntent.getActivity(mContext, 0,
-                    new VpnManager(mContext).createSettingsActivityIntent(), 0);
+            mNotificationManager.notify(NOTIFICATION_ID, n);
         }
 
         private String getNotificationTitle(boolean connected) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 68c1453..c313713b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -166,6 +166,8 @@
 
     private int mTitleColor = 0;
 
+    private boolean mAlwaysReadCloseOnTouchAttr = false;
+    
     private ContextMenuBuilder mContextMenu;
     private MenuDialogHelper mContextMenuHelper;
     private ActionButtonSubmenu mActionButtonPopup;
@@ -1983,6 +1985,7 @@
                 }
 
                 if (mActionModeView != null) {
+                    mActionModeView.killMode();
                     mode = new StandaloneActionMode(getContext(), mActionModeView, wrappedCallback);
                     if (callback.onCreateActionMode(mode, mode.getMenu())) {
                         mode.invalidate();
@@ -2326,6 +2329,15 @@
             addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
         }
         
+        if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
+                >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+            if (a.getBoolean(
+                    com.android.internal.R.styleable.Window_windowCloseOnTouchOutside,
+                    false)) {
+                setCloseOnTouchOutsideIfNotSet(true);
+            }
+        }
+        
         WindowManager.LayoutParams params = getAttributes();
 
         if (!hasSoftInputMode()) {
@@ -2479,6 +2491,11 @@
         return contentParent;
     }
 
+    /** @hide */
+    public void alwaysReadCloseOnTouchAttr() {
+        mAlwaysReadCloseOnTouchAttr = true;
+    }
+
     private void installDecor() {
         if (mDecor == null) {
             mDecor = generateDecor();
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 51b5947..16c042d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -131,18 +131,21 @@
     : BnAudioFlinger(),
         mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
 {
+    Mutex::Autolock _l(mLock);
+
     mHardwareStatus = AUDIO_HW_IDLE;
 
     mAudioHardware = AudioHardwareInterface::create();
 
     mHardwareStatus = AUDIO_HW_INIT;
     if (mAudioHardware->initCheck() == NO_ERROR) {
-        // open 16-bit output stream for s/w mixer
+        AutoMutex lock(mHardwareLock);
         mMode = AudioSystem::MODE_NORMAL;
-        setMode(mMode);
-
-        setMasterVolume(1.0f);
-        setMasterMute(false);
+        mHardwareStatus = AUDIO_HW_SET_MODE;
+        mAudioHardware->setMode(mMode);
+        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+        mAudioHardware->setMasterVolume(1.0f);
+        mHardwareStatus = AUDIO_HW_IDLE;
     } else {
         LOGE("Couldn't even initialize the stubbed audio hardware!");
     }
@@ -440,13 +443,16 @@
     }
 
     // when hw supports master volume, don't scale in sw mixer
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
-        value = 1.0f;
+    { // scope for the lock
+        AutoMutex lock(mHardwareLock);
+        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+        if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
+            value = 1.0f;
+        }
+        mHardwareStatus = AUDIO_HW_IDLE;
     }
-    mHardwareStatus = AUDIO_HW_IDLE;
 
+    Mutex::Autolock _l(mLock);
     mMasterVolume = value;
     for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
        mPlaybackThreads.valueAt(i)->setMasterVolume(value);
@@ -517,6 +523,7 @@
         return PERMISSION_DENIED;
     }
 
+    Mutex::Autolock _l(mLock);
     mMasterMute = muted;
     for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
        mPlaybackThreads.valueAt(i)->setMasterMute(muted);
@@ -579,6 +586,7 @@
         return BAD_VALUE;
     }
 
+    AutoMutex lock(mLock);
     mStreamTypes[stream].mute = muted;
     for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
        mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index eeca7ab..e4086c4 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1052,25 +1052,27 @@
 
     updateDeviceForStrategy();
 #ifdef AUDIO_POLICY_TEST
-    AudioParameter outputCmd = AudioParameter();
-    outputCmd.addInt(String8("set_id"), 0);
-    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+    if (mHardwareOutput != 0) {
+        AudioParameter outputCmd = AudioParameter();
+        outputCmd.addInt(String8("set_id"), 0);
+        mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
 
-    mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
-    mTestSamplingRate = 44100;
-    mTestFormat = AudioSystem::PCM_16_BIT;
-    mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
-    mTestLatencyMs = 0;
-    mCurOutput = 0;
-    mDirectOutput = false;
-    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-        mTestOutputs[i] = 0;
+        mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
+        mTestSamplingRate = 44100;
+        mTestFormat = AudioSystem::PCM_16_BIT;
+        mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
+        mTestLatencyMs = 0;
+        mCurOutput = 0;
+        mDirectOutput = false;
+        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
+            mTestOutputs[i] = 0;
+        }
+
+        const size_t SIZE = 256;
+        char buffer[SIZE];
+        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
+        run(buffer, ANDROID_PRIORITY_AUDIO);
     }
-
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "AudioPolicyManagerTest");
-    run(buffer, ANDROID_PRIORITY_AUDIO);
 #endif //AUDIO_POLICY_TEST
 }
 
@@ -1091,6 +1093,11 @@
    mInputs.clear();
 }
 
+status_t AudioPolicyManagerBase::initCheck()
+{
+    return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR;
+}
+
 #ifdef AUDIO_POLICY_TEST
 bool AudioPolicyManagerBase::threadLoop()
 {
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index f24e08e..46a01ad 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -68,6 +68,8 @@
 {
     char value[PROPERTY_VALUE_MAX];
 
+    Mutex::Autolock _l(mLock);
+
     // start tone playback thread
     mTonePlaybackThread = new AudioCommandThread(String8(""));
     // start audio commands thread
@@ -88,9 +90,18 @@
     }
 #endif
 
-    // load properties
-    property_get("ro.camera.sound.forced", value, "0");
-    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+    if ((mpPolicyManager != NULL) && (mpPolicyManager->initCheck() != NO_ERROR)) {
+        delete mpPolicyManager;
+        mpPolicyManager = NULL;
+    }
+
+    if (mpPolicyManager == NULL) {
+        LOGE("Could not create AudioPolicyManager");
+    } else {
+        // load properties
+        property_get("ro.camera.sound.forced", value, "0");
+        mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+    }
 }
 
 AudioPolicyService::~AudioPolicyService()
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 6b66791..2e83256 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -121,7 +121,7 @@
         const sp<InputReaderPolicyInterface>& policy,
         const sp<InputDispatcherInterface>& dispatcher) :
         mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
-        mGlobalMetaState(0) {
+        mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
     configureExcludedDevices();
     updateGlobalMetaState();
     updateInputConfiguration();
@@ -373,6 +373,24 @@
     } // release state lock
 }
 
+void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+    mDisableVirtualKeysTimeout = time;
+}
+
+bool InputReader::shouldDropVirtualKey(nsecs_t now,
+        InputDevice* device, int32_t keyCode, int32_t scanCode) {
+    if (now < mDisableVirtualKeysTimeout) {
+        LOGI("Dropping virtual key from device %s because virtual keys are "
+                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
+                device->getName().string(),
+                (mDisableVirtualKeysTimeout - now) * 0.000001,
+                keyCode, scanCode);
+        return true;
+    } else {
+        return false;
+    }
+}
+
 void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
     { // acquire state lock
         AutoMutex _l(mStateLock);
@@ -726,7 +744,7 @@
 }
 
 uint32_t SwitchInputMapper::getSources() {
-    return 0;
+    return AINPUT_SOURCE_SWITCH;
 }
 
 void SwitchInputMapper::process(const RawEvent* rawEvent) {
@@ -889,6 +907,12 @@
                 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
             } else {
                 // key down
+                if ((policyFlags & POLICY_FLAG_VIRTUAL)
+                        && mContext->shouldDropVirtualKey(when,
+                                getDevice(), keyCode, scanCode)) {
+                    return;
+                }
+
                 mLocked.keyDowns.push();
                 KeyDown& keyDown = mLocked.keyDowns.editTop();
                 keyDown.keyCode = keyCode;
@@ -1428,6 +1452,7 @@
     mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
     mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
     mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+    mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
 
     String8 deviceTypeString;
     mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
@@ -2219,6 +2244,7 @@
 
     TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
     if (touchResult == DISPATCH_TOUCH) {
+        detectGestures(when);
         dispatchTouches(when, policyFlags);
     }
 
@@ -2304,6 +2330,11 @@
                     if (mCurrentTouch.pointerCount == 1) {
                         const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
                         if (virtualKey) {
+                            if (mContext->shouldDropVirtualKey(when, getDevice(),
+                                    virtualKey->keyCode, virtualKey->scanCode)) {
+                                return DROP_STROKE;
+                            }
+
                             mLocked.currentVirtualKey.down = true;
                             mLocked.currentVirtualKey.downTime = when;
                             mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
@@ -2341,6 +2372,26 @@
     return touchResult;
 }
 
+void TouchInputMapper::detectGestures(nsecs_t when) {
+    // Disable all virtual key touches that happen within a short time interval of the
+    // most recent touch.  The idea is to filter out stray virtual key presses when
+    // interacting with the touch screen.
+    //
+    // Problems we're trying to solve:
+    //
+    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
+    //    virtual key area that is implemented by a separate touch panel and accidentally
+    //    triggers a virtual key.
+    //
+    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
+    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
+    //    are layed out below the screen near to where the on screen keyboard's space bar
+    //    is displayed.
+    if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+        mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
+    }
+}
+
 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
     uint32_t currentPointerCount = mCurrentTouch.pointerCount;
     uint32_t lastPointerCount = mLastTouch.pointerCount;
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 8b2d40a..7619682 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -78,6 +78,12 @@
      */
     virtual bool filterJumpyTouchEvents() = 0;
 
+    /* Gets the amount of time to disable virtual keys after the screen is touched
+     * in order to filter out accidental virtual key presses due to swiping gestures
+     * or taps near the edge of the display.  May be 0 to disable the feature.
+     */
+    virtual nsecs_t getVirtualKeyQuietTime() = 0;
+
     /* Gets the excluded device names for the platform. */
     virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
 
@@ -147,6 +153,10 @@
     virtual void updateGlobalMetaState() = 0;
     virtual int32_t getGlobalMetaState() = 0;
 
+    virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
+
     virtual InputReaderPolicyInterface* getPolicy() = 0;
     virtual InputDispatcherInterface* getDispatcher() = 0;
     virtual EventHubInterface* getEventHub() = 0;
@@ -234,6 +244,11 @@
     InputConfiguration mInputConfiguration;
     void updateInputConfiguration();
 
+    nsecs_t mDisableVirtualKeysTimeout;
+    virtual void disableVirtualKeysUntil(nsecs_t time);
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode);
+
     // state queries
     typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
     int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
@@ -603,6 +618,7 @@
         bool useBadTouchFilter;
         bool useJumpyTouchFilter;
         bool useAveragingTouchFilter;
+        nsecs_t virtualKeyQuietTime;
     } mParameters;
 
     // Immutable calibration parameters in parsed form.
@@ -839,6 +855,7 @@
     void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
             BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
             int32_t motionEventAction);
+    void detectGestures(nsecs_t when);
 
     bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
     const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 8ec6f53..98d627d 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -127,6 +127,10 @@
         mFilterJumpyTouchEvents = enabled;
     }
 
+    virtual nsecs_t getVirtualKeyQuietTime() {
+        return 0;
+    }
+
     void addExcludedDeviceName(const String8& deviceName) {
         mExcludedDeviceNames.push(deviceName);
     }
@@ -722,6 +726,14 @@
     virtual InputDispatcherInterface* getDispatcher() {
         return mDispatcher.get();
     }
+
+    virtual void disableVirtualKeysUntil(nsecs_t time) {
+    }
+
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode) {
+        return false;
+    }
 };
 
 
@@ -1472,7 +1484,7 @@
     SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
     addMapperAndConfigure(mapper);
 
-    ASSERT_EQ(uint32_t(0), mapper->getSources());
+    ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
 }
 
 TEST_F(SwitchInputMapperTest, GetSwitchState) {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 22dd804..59a540b 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -16,6 +16,23 @@
 
 package com.android.server;
 
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
@@ -24,46 +41,37 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.Intent.FilterComparison;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.widget.RemoteViews;
 
-import java.io.IOException;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.appwidget.IAppWidgetHost;
+import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.util.FastXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
+import com.android.internal.widget.IRemoteViewsAdapterConnection;
 
 class AppWidgetService extends IAppWidgetService.Stub
 {
@@ -107,6 +115,56 @@
         Host host;
     }
 
+    /**
+     * Acts as a proxy between the ServiceConnection and the RemoteViewsAdapterConnection.
+     * This needs to be a static inner class since a reference to the ServiceConnection is held
+     * globally and may lead us to leak AppWidgetService instances (if there were more than one).
+     */
+    static class ServiceConnectionProxy implements ServiceConnection {
+        private final AppWidgetService mAppWidgetService;
+        private final Pair<Integer, Intent.FilterComparison> mKey;
+        private final IBinder mConnectionCb;
+
+        ServiceConnectionProxy(AppWidgetService appWidgetService,
+                Pair<Integer, Intent.FilterComparison> key, IBinder connectionCb) {
+            mAppWidgetService = appWidgetService;
+            mKey = key;
+            mConnectionCb = connectionCb;
+        }
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            IRemoteViewsAdapterConnection cb =
+                IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
+            try {
+                cb.onServiceConnected(service);
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+        public void onServiceDisconnected(ComponentName name) {
+            IRemoteViewsAdapterConnection cb =
+                IRemoteViewsAdapterConnection.Stub.asInterface(mConnectionCb);
+            try {
+                cb.onServiceDisconnected();
+                mAppWidgetService.mServiceConnectionUpdateHandler.post(new Runnable() {
+                    public void run() {
+                        // We don't want to touch mBoundRemoteViewsServices from any other thread
+                        // so queue this to run on the main thread.
+                        if (mAppWidgetService.mBoundRemoteViewsServices.containsKey(mKey)) {
+                            mAppWidgetService.mBoundRemoteViewsServices.remove(mKey);
+                        }
+                    }
+                });
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    // Manages connections to RemoteViewsServices
+    private final HashMap<Pair<Integer, FilterComparison>, ServiceConnection>
+        mBoundRemoteViewsServices = new HashMap<Pair<Integer,FilterComparison>,ServiceConnection>();
+    private final Handler mServiceConnectionUpdateHandler = new Handler();
+
     Context mContext;
     Locale mLocale;
     PackageManager mPackageManager;
@@ -294,6 +352,9 @@
     }
 
     void deleteAppWidgetLocked(AppWidgetId id) {
+        // We first unbind all services that are bound to this id
+        unbindAppWidgetRemoteViewsServicesLocked(id);
+
         Host host = id.host;
         host.instances.remove(id);
         pruneHostLocked(host);
@@ -376,6 +437,77 @@
         }
     }
 
+    public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection) {
+        synchronized (mAppWidgetIds) {
+            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+            if (id == null) {
+                throw new IllegalArgumentException("bad appWidgetId");
+            }
+            final ComponentName componentName = intent.getComponent();
+            try {
+                final ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName,
+                        PackageManager.GET_PERMISSIONS);
+                if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(si.permission)) {
+                    throw new SecurityException("Selected service does not require "
+                            + android.Manifest.permission.BIND_REMOTEVIEWS
+                            + ": " + componentName);
+                }
+            } catch (PackageManager.NameNotFoundException e) {
+                throw new IllegalArgumentException("Unknown component " + componentName);
+            }
+
+            // Bind to the RemoteViewsService (which will trigger a callback to the
+            // RemoteViewsAdapter)
+            Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
+                    new FilterComparison(intent));
+            final ServiceConnection conn = new ServiceConnectionProxy(this, key, connection);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+                mBoundRemoteViewsServices.put(key, conn);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
+
+    public void unbindRemoteViewsService(int appWidgetId, Intent intent) {
+        synchronized (mAppWidgetIds) {
+            AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
+            if (id == null) {
+                throw new IllegalArgumentException("bad appWidgetId");
+            }
+
+            // Unbind from the RemoteViewsService (which will trigger a callback to the bound
+            // RemoteViewsAdapter)
+            Pair<Integer, FilterComparison> key = Pair.create(appWidgetId,
+                    new FilterComparison(intent));
+            if (mBoundRemoteViewsServices.containsKey(key)) {
+                final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
+                mBoundRemoteViewsServices.remove(key);
+                conn.onServiceDisconnected(null);
+                mContext.unbindService(conn);
+            }
+        }
+    }
+
+    private void unbindAppWidgetRemoteViewsServicesLocked(AppWidgetId id) {
+        Iterator<Pair<Integer, Intent.FilterComparison>> it =
+            mBoundRemoteViewsServices.keySet().iterator();
+        int appWidgetId = id.appWidgetId;
+
+        // Unbind all connections to AppWidgets bound to this id
+        while (it.hasNext()) {
+            final Pair<Integer, Intent.FilterComparison> key = it.next();
+            if (key.first.intValue() == appWidgetId) {
+                final ServiceConnection conn = mBoundRemoteViewsServices.get(key);
+                it.remove();
+                conn.onServiceDisconnected(null);
+                mContext.unbindService(conn);
+            }
+        }
+    }
+
     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
         synchronized (mAppWidgetIds) {
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index 06595ae..8d249ff 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -481,7 +481,13 @@
             return mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_filterJumpyTouchEvents);
         }
-        
+
+        @SuppressWarnings("unused")
+        public int getVirtualKeyQuietTimeMillis() {
+            return mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
+        }
+
         @SuppressWarnings("unused")
         public String[] getExcludedDeviceNames() {
             ArrayList<String> names = new ArrayList<String>();
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 1eebd6a..059c0b8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4407,10 +4407,19 @@
             }
         }
     }
-    
+
+    /**
+     * Check if the external storage media is available. This is true if there
+     * is a mounted external storage medium or if the external storage is
+     * emulated.
+     */
+    private boolean isExternalMediaAvailable() {
+        return mMediaMounted || Environment.isExternalStorageEmulated();
+    }
+
     public String nextPackageToClean(String lastPackage) {
         synchronized (mPackages) {
-            if (!mMediaMounted) {
+            if (!isExternalMediaAvailable()) {
                 // If the external storage is no longer mounted at this point,
                 // the caller may not have been able to delete all of this
                 // packages files and can not delete any more.  Bail.
@@ -4430,7 +4439,7 @@
     
     void startCleaningPackages() {
         synchronized (mPackages) {
-            if (!mMediaMounted) {
+            if (!isExternalMediaAvailable()) {
                 return;
             }
             if (mSettings.mPackagesToBeCleaned.size() <= 0) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3e930ae..2af291d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -583,7 +583,7 @@
         void broadcastDragStartedLw(final float touchX, final float touchY) {
             // Cache a base-class instance of the clip metadata so that parceling
             // works correctly in calling out to the apps.
-            mDataDescription = mData.getDescription();
+            mDataDescription = (mData != null) ? mData.getDescription() : null;
             mNotifiedWindows.clear();
             mDragInProgress = true;
 
@@ -708,16 +708,20 @@
 
             // Move the surface to the given touch
             if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
-            mSurface.openTransaction();
+            Surface.openTransaction();
             try {
                 mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
             } finally {
-                mSurface.closeTransaction();
+                Surface.closeTransaction();
                 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
             }
 
             // Tell the affected window
             WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+            if (touchedWin == null) {
+                if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
+                return;
+            }
             if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
                 final IBinder touchedBinder = touchedWin.mClient.asBinder();
                 if (touchedBinder != mLocalWin) {
@@ -5865,7 +5869,7 @@
             final InputWindow inputWindow = windowList.add();
             inputWindow.inputChannel = mDragState.mServerChannel;
             inputWindow.name = "drag";
-            inputWindow.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+            inputWindow.layoutParamsFlags = 0;
             inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
             inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
             inputWindow.visible = true;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index dbf9a96..9e9a4f2 100755
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3060,7 +3060,7 @@
                 }
                 if (uid == pkgUid || checkComponentPermission(
                         android.Manifest.permission.CLEAR_APP_USER_DATA,
-                        pid, uid, -1)
+                        pid, uid, -1, true)
                         == PackageManager.PERMISSION_GRANTED) {
                     forceStopPackageLocked(packageName, pkgUid);
                 } else {
@@ -4151,7 +4151,7 @@
      * This can be called with or without the global lock held.
      */
     int checkComponentPermission(String permission, int pid, int uid,
-            int reqUid) {
+            int owningUid, boolean exported) {
         // We might be performing an operation on behalf of an indirect binder
         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
         // client identity accordingly before proceeding.
@@ -4168,9 +4168,14 @@
             !Process.supportsProcesses()) {
             return PackageManager.PERMISSION_GRANTED;
         }
-        // If the target requires a specific UID, always fail for others.
-        if (reqUid >= 0 && uid != reqUid) {
-            Slog.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
+        // If there is a uid that owns whatever is being accessed, it has
+        // blanket access to it regardless of the permissions it requires.
+        if (owningUid >= 0 && uid == owningUid) {
+            return PackageManager.PERMISSION_GRANTED;
+        }
+        // If the target is not exported, then nobody else can get to it.
+        if (!exported) {
+            Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
             return PackageManager.PERMISSION_DENIED;
         }
         if (permission == null) {
@@ -4199,7 +4204,7 @@
         if (permission == null) {
             return PackageManager.PERMISSION_DENIED;
         }
-        return checkComponentPermission(permission, pid, uid, -1);
+        return checkComponentPermission(permission, pid, uid, -1, true);
     }
 
     /**
@@ -5322,12 +5327,12 @@
         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
         final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
-                cpi.exported ? -1 : cpi.applicationInfo.uid)
+                cpi.applicationInfo.uid, cpi.exported)
                 == PackageManager.PERMISSION_GRANTED) {
             return null;
         }
         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
-                cpi.exported ? -1 : cpi.applicationInfo.uid)
+                cpi.applicationInfo.uid, cpi.exported)
                 == PackageManager.PERMISSION_GRANTED) {
             return null;
         }
@@ -5339,12 +5344,12 @@
                 i--;
                 PathPermission pp = pps[i];
                 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
-                        cpi.exported ? -1 : cpi.applicationInfo.uid)
+                        cpi.applicationInfo.uid, cpi.exported)
                         == PackageManager.PERMISSION_GRANTED) {
                     return null;
                 }
                 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
-                        cpi.exported ? -1 : cpi.applicationInfo.uid)
+                        cpi.applicationInfo.uid, cpi.exported)
                         == PackageManager.PERMISSION_GRANTED) {
                     return null;
                 }
@@ -5360,10 +5365,18 @@
             }
         }
 
-        String msg = "Permission Denial: opening provider " + cpi.name
-                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
-                + ", uid=" + callingUid + ") requires "
-                + cpi.readPermission + " or " + cpi.writePermission;
+        String msg;
+        if (!cpi.exported) {
+            msg = "Permission Denial: opening provider " + cpi.name
+                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+                    + ", uid=" + callingUid + ") that is not exported from uid "
+                    + cpi.applicationInfo.uid;
+        } else {
+            msg = "Permission Denial: opening provider " + cpi.name
+                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
+                    + ", uid=" + callingUid + ") requires "
+                    + cpi.readPermission + " or " + cpi.writePermission;
+        }
         Slog.w(TAG, msg);
         return msg;
     }
@@ -5953,7 +5966,7 @@
             
         final int perm = checkComponentPermission(
                 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
-                callingUid, -1);
+                callingUid, -1, true);
         if (perm == PackageManager.PERMISSION_GRANTED) {
             return true;
         }
@@ -6804,6 +6817,9 @@
             if (info.durationMillis != -1) {
                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
             }
+            if (info.numInstances != -1) {
+                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
+            }
             if (info.tags != null) {
                 for (String tag : info.tags) {
                     sb.append("Span-Tag: ").append(tag).append("\n");
@@ -8892,8 +8908,16 @@
             int callingPid = Binder.getCallingPid();
             int callingUid = Binder.getCallingUid();
             if (checkComponentPermission(r.permission,
-                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
+                    callingPid, callingUid, r.appInfo.uid, r.exported)
                     != PackageManager.PERMISSION_GRANTED) {
+                if (!r.exported) {
+                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+                            + " from pid=" + callingPid
+                            + ", uid=" + callingUid
+                            + " that is not exported from uid " + r.appInfo.uid);
+                    return new ServiceLookupResult(null, "not exported from uid "
+                            + r.appInfo.uid);
+                }
                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
                         + " from pid=" + callingPid
                         + ", uid=" + callingUid
@@ -8975,11 +8999,19 @@
         }
         if (r != null) {
             if (checkComponentPermission(r.permission,
-                    callingPid, callingUid, r.exported ? -1 : r.appInfo.uid)
+                    callingPid, callingUid, r.appInfo.uid, r.exported)
                     != PackageManager.PERMISSION_GRANTED) {
+                if (!r.exported) {
+                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
+                            + " from pid=" + callingPid
+                            + ", uid=" + callingUid
+                            + " that is not exported from uid " + r.appInfo.uid);
+                    return new ServiceLookupResult(null, "not exported from uid "
+                            + r.appInfo.uid);
+                }
                 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
-                        + " from pid=" + Binder.getCallingPid()
-                        + ", uid=" + Binder.getCallingUid()
+                        + " from pid=" + callingPid
+                        + ", uid=" + callingUid
                         + " requires " + r.permission);
                 return new ServiceLookupResult(null, r.permission);
             }
@@ -10479,7 +10511,7 @@
                 || uidRemoved) {
             if (checkComponentPermission(
                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
-                    callingPid, callingUid, -1)
+                    callingPid, callingUid, -1, true)
                     == PackageManager.PERMISSION_GRANTED) {
                 if (uidRemoved) {
                     final Bundle intentExtras = intent.getExtras();
@@ -11147,7 +11179,7 @@
         boolean skip = false;
         if (filter.requiredPermission != null) {
             int perm = checkComponentPermission(filter.requiredPermission,
-                    r.callingPid, r.callingUid, -1);
+                    r.callingPid, r.callingUid, -1, true);
             if (perm != PackageManager.PERMISSION_GRANTED) {
                 Slog.w(TAG, "Permission Denial: broadcasting "
                         + r.intent.toString()
@@ -11160,7 +11192,7 @@
         }
         if (r.requiredPermission != null) {
             int perm = checkComponentPermission(r.requiredPermission,
-                    filter.receiverList.pid, filter.receiverList.uid, -1);
+                    filter.receiverList.pid, filter.receiverList.uid, -1, true);
             if (perm != PackageManager.PERMISSION_GRANTED) {
                 Slog.w(TAG, "Permission Denial: receiving "
                         + r.intent.toString()
@@ -11426,17 +11458,26 @@
 
             boolean skip = false;
             int perm = checkComponentPermission(info.activityInfo.permission,
-                    r.callingPid, r.callingUid,
-                    info.activityInfo.exported
-                            ? -1 : info.activityInfo.applicationInfo.uid);
+                    r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
+                    info.activityInfo.exported);
             if (perm != PackageManager.PERMISSION_GRANTED) {
-                Slog.w(TAG, "Permission Denial: broadcasting "
-                        + r.intent.toString()
-                        + " from " + r.callerPackage + " (pid=" + r.callingPid
-                        + ", uid=" + r.callingUid + ")"
-                        + " requires " + info.activityInfo.permission
-                        + " due to receiver " + info.activityInfo.packageName
-                        + "/" + info.activityInfo.name);
+                if (!info.activityInfo.exported) {
+                    Slog.w(TAG, "Permission Denial: broadcasting "
+                            + r.intent.toString()
+                            + " from " + r.callerPackage + " (pid=" + r.callingPid
+                            + ", uid=" + r.callingUid + ")"
+                            + " is not exported from uid " + info.activityInfo.applicationInfo.uid
+                            + " due to receiver " + info.activityInfo.packageName
+                            + "/" + info.activityInfo.name);
+                } else {
+                    Slog.w(TAG, "Permission Denial: broadcasting "
+                            + r.intent.toString()
+                            + " from " + r.callerPackage + " (pid=" + r.callingPid
+                            + ", uid=" + r.callingUid + ")"
+                            + " requires " + info.activityInfo.permission
+                            + " due to receiver " + info.activityInfo.packageName
+                            + "/" + info.activityInfo.name);
+                }
                 skip = true;
             }
             if (r.callingUid != Process.SYSTEM_UID &&
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index bc00478..dd6ddd6 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2035,17 +2035,25 @@
         }
 
         final int perm = mService.checkComponentPermission(aInfo.permission, callingPid,
-                callingUid, aInfo.exported ? -1 : aInfo.applicationInfo.uid);
+                callingUid, aInfo.applicationInfo.uid, aInfo.exported);
         if (perm != PackageManager.PERMISSION_GRANTED) {
             if (resultRecord != null) {
                 sendActivityResultLocked(-1,
                     resultRecord, resultWho, requestCode,
                     Activity.RESULT_CANCELED, null);
             }
-            String msg = "Permission Denial: starting " + intent.toString()
-                    + " from " + callerApp + " (pid=" + callingPid
-                    + ", uid=" + callingUid + ")"
-                    + " requires " + aInfo.permission;
+            String msg;
+            if (!aInfo.exported) {
+                msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " not exported from uid " + aInfo.applicationInfo.uid;
+            } else {
+                msg = "Permission Denial: starting " + intent.toString()
+                        + " from " + callerApp + " (pid=" + callingPid
+                        + ", uid=" + callingUid + ")"
+                        + " requires " + aInfo.permission;
+            }
             Slog.w(TAG, msg);
             throw new SecurityException(msg);
         }
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index e04e4c3..5b329bb 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -62,6 +62,7 @@
     jmethodID checkInjectEventsPermission;
     jmethodID filterTouchEvents;
     jmethodID filterJumpyTouchEvents;
+    jmethodID getVirtualKeyQuietTimeMillis;
     jmethodID getExcludedDeviceNames;
     jmethodID getMaxEventsPerSecond;
     jmethodID getPointerLayer;
@@ -159,6 +160,7 @@
             int32_t* width, int32_t* height, int32_t* orientation);
     virtual bool filterTouchEvents();
     virtual bool filterJumpyTouchEvents();
+    virtual nsecs_t getVirtualKeyQuietTime();
     virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
     virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
 
@@ -191,6 +193,7 @@
     // Cached filtering policies.
     int32_t mFilterTouchEvents;
     int32_t mFilterJumpyTouchEvents;
+    nsecs_t mVirtualKeyQuietTime;
 
     // Cached throttling policy.
     int32_t mMaxEventsPerSecond;
@@ -219,7 +222,7 @@
 
 
 NativeInputManager::NativeInputManager(jobject callbacksObj) :
-    mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
+    mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
     mMaxEventsPerSecond(-1) {
     JNIEnv* env = jniEnv();
 
@@ -355,6 +358,24 @@
     return mFilterJumpyTouchEvents;
 }
 
+nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
+    if (mVirtualKeyQuietTime < 0) {
+        JNIEnv* env = jniEnv();
+
+        jint result = env->CallIntMethod(mCallbacksObj,
+                gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
+        if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
+            result = 0;
+        }
+        if (result < 0) {
+            result = 0;
+        }
+
+        mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
+    }
+    return mVirtualKeyQuietTime;
+}
+
 void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
     outExcludedDeviceNames.clear();
 
@@ -1155,6 +1176,9 @@
     GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
             "filterJumpyTouchEvents", "()Z");
 
+    GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
+            "getVirtualKeyQuietTimeMillis", "()I");
+
     GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
             "getExcludedDeviceNames", "()[Ljava/lang/String;");
 
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index 418e7f8..3abfc12 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -34,9 +34,9 @@
 
 RotationVectorSensor::RotationVectorSensor(sensor_t const* list, size_t count)
     : mSensorDevice(SensorDevice::getInstance()),
-      mALowPass(M_SQRT1_2, 5.0f),
+      mALowPass(M_SQRT1_2, 1.5f),
       mAX(mALowPass), mAY(mALowPass), mAZ(mALowPass),
-      mMLowPass(M_SQRT1_2, 2.5f),
+      mMLowPass(M_SQRT1_2, 1.5f),
       mMX(mMLowPass), mMY(mMLowPass), mMZ(mMLowPass)
 {
     for (size_t i=0 ; i<count ; i++) {
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index b7c9512..17699f8 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -38,9 +38,9 @@
     double mAccTime;
     double mMagTime;
     SecondOrderLowPassFilter mALowPass;
-    BiquadFilter mAX, mAY, mAZ;
+    CascadedBiquadFilter mAX, mAY, mAZ;
     SecondOrderLowPassFilter mMLowPass;
-    BiquadFilter mMX, mMY, mMZ;
+    CascadedBiquadFilter mMX, mMY, mMZ;
 
 public:
     RotationVectorSensor(sensor_t const* list, size_t count);
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 0c1fcf9..9ddb05f 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -534,6 +534,12 @@
     result.append(buffer);
 }
 
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBase::dump(result, scratch, size);
+}
+
+
 // ---------------------------------------------------------------------------
 
 int32_t LayerBaseClient::sIdentity = 1;
@@ -585,6 +591,12 @@
     result.append(buffer);
 }
 
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+    LayerBaseClient::dump(result, scratch, size);
+}
+
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::Surface::Surface(
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index f6c49fc..13af223 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -211,6 +211,7 @@
     
     /** always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 
     enum { // flags for doTransaction()
@@ -324,6 +325,7 @@
 
 protected:
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
 private:
     mutable Mutex mLock;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 65ad956..434e473 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1491,8 +1491,13 @@
             result.append(buffer);
         }
 
+        /*
+         * Dump the visible layer list
+         */
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
+        snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+        result.append(buffer);
         for (size_t i=0 ; i<count ; i++) {
             const sp<LayerBase>& layer(currentLayers[i]);
             layer->dump(result, buffer, SIZE);
@@ -1502,6 +1507,24 @@
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
         }
 
+        /*
+         * Dump the layers in the purgatory
+         */
+
+        const size_t purgatorySize =  mLayerPurgatory.size();
+        snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+        result.append(buffer);
+        for (size_t i=0 ; i<purgatorySize ; i++) {
+            const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+            layer->shortDump(result, buffer, SIZE);
+        }
+
+        /*
+         * Dump SurfaceFlinger global state
+         */
+
+        snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+        result.append(buffer);
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
@@ -1527,6 +1550,9 @@
             result.append(buffer);
         }
 
+        /*
+         * Dump HWComposer state
+         */
         HWComposer& hwc(hw.getHwComposer());
         snprintf(buffer, SIZE, "  h/w composer %s and %s\n",
                 hwc.initCheck()==NO_ERROR ? "present" : "not present",
@@ -1534,6 +1560,9 @@
         result.append(buffer);
         hwc.dump(result, buffer, SIZE);
 
+        /*
+         * Dump gralloc state
+         */
         const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
         alloc.dump(result);
         hw.dump(result);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index e5a46b9..5bcf727 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -89,13 +89,12 @@
     }
 
     private void freeMem() {
-        Log.v(LOGTAG, "freeMem: calling gc/finalization...");
+        Log.v(LOGTAG, "freeMem: calling gc...");
         final VMRuntime runtime = VMRuntime.getRuntime();
 
         runtime.gcSoftReferences();
         runtime.gcSoftReferences();
         runtime.gcSoftReferences();
-        Runtime.getRuntime().runFinalization();
         Runtime.getRuntime().gc();
         Runtime.getRuntime().gc();
 
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 691aff28..7a61b3c 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -53,6 +53,15 @@
         </activity>
         
         <activity
+                android:name="ViewLayersActivity3"
+                android:label="_ViewLayers3">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <activity
                 android:name="AlphaLayersActivity"
                 android:label="_αLayers">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/res/layout/view_layers_3.xml b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
new file mode 100644
index 0000000..a820f5f
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout
+        android:background="#30ff0000"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+
+    <LinearLayout
+        android:background="#3000ff00"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:padding="12dip">
+
+        <ListView
+            android:id="@+id/list1"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:background="#300000ff"
+        android:layout_width="0dip"
+        android:layout_height="match_parent"
+        android:layout_weight="1" />
+
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
new file mode 100644
index 0000000..c8ae75b
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ViewLayersActivity3 extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        setContentView(R.layout.view_layers_3);
+
+        setupList(R.id.list1);
+    }
+
+    private void setupList(int listId) {
+        final ListView list = (ListView) findViewById(listId);
+        list.setAdapter(new SimpleListAdapter(this));
+        list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        ((View) list.getParent()).setLayerType(View.LAYER_TYPE_HARDWARE, null);
+    }
+
+    private static class SimpleListAdapter extends ArrayAdapter<String> {
+        public SimpleListAdapter(Context context) {
+            super(context, android.R.layout.simple_list_item_1, DATA_LIST);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            TextView v = (TextView) super.getView(position, convertView, parent);
+            final Resources r = getContext().getResources();
+            final DisplayMetrics metrics = r.getDisplayMetrics();
+            v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f));
+            v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon),
+                    null, null, null);
+            return v;
+        }
+    }
+
+    private static final String[] DATA_LIST = {
+            "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+            "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+            "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+            "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+            "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+            "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
+            "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
+            "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+            "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+            "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+            "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+            "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+            "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+            "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+            "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+            "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+            "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+            "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+            "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+            "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+            "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+            "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+            "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+            "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+            "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+            "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+            "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+            "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+            "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+            "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+            "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+            "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+            "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+            "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+            "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+            "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+            "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+            "Ukraine", "United Arab Emirates", "United Kingdom",
+            "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+            "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+            "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+    };
+}
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index f96a5ae..3cde949 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -31,7 +31,7 @@
  * Tracks the state changes in supplicant and provides functionality
  * that is based on these state changes:
  * - detect a failed WPA handshake that loops indefinitely
- * - password failure handling
+ * - authentication failure handling
  */
 class SupplicantStateTracker extends HierarchicalStateMachine {
 
@@ -39,14 +39,14 @@
     private static final boolean DBG = false;
 
     private WifiStateMachine mWifiStateMachine;
-    private int mPasswordFailuresCount = 0;
+    private int mAuthenticationFailuresCount = 0;
     /* Indicates authentication failure in supplicant broadcast.
      * TODO: enhance auth failure reporting to include notification
      * for all type of failures: EAP, WPS & WPA networks */
     private boolean mAuthFailureInSupplicantBroadcast = false;
 
-    /* Maximum retries on a password failure notification */
-    private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
+    /* Maximum retries on a authentication failure notification */
+    private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
 
     /* Tracks if networks have been disabled during a connection */
     private boolean mNetworksDisabledDuringConnect = false;
@@ -155,8 +155,8 @@
         public boolean processMessage(Message message) {
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             switch (message.what) {
-                case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
-                    mPasswordFailuresCount++;
+                case WifiStateMachine.AUTHENTICATION_FAILURE_EVENT:
+                    mAuthenticationFailuresCount++;
                     mAuthFailureInSupplicantBroadcast = true;
                     break;
                 case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
@@ -206,18 +206,17 @@
         @Override
          public void enter() {
              if (DBG) Log.d(TAG, getName() + "\n");
-             /* If a disconnect event happens after password key failure
+             /* If a disconnect event happens after authentication failure
               * exceeds maximum retries, disable the network
               */
-
              Message message = getCurrentMessage();
              StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
 
-             if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
+             if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
                  Log.d(TAG, "Failed to authenticate, disabling network " +
                          stateChangeResult.networkId);
                  handleNetworkConnectionFailure(stateChangeResult.networkId);
-                 mPasswordFailuresCount = 0;
+                 mAuthenticationFailuresCount = 0;
              }
          }
     }
@@ -282,8 +281,8 @@
         @Override
          public void enter() {
              if (DBG) Log.d(TAG, getName() + "\n");
-             /* Reset password failure count */
-             mPasswordFailuresCount = 0;
+             /* Reset authentication failure count */
+             mAuthenticationFailuresCount = 0;
              if (mNetworksDisabledDuringConnect) {
                  WifiConfigStore.enableAllNetworks();
                  mNetworksDisabledDuringConnect = false;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 090ad3b..ce38261 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -42,7 +42,8 @@
     private static final int LINK_SPEED   = 5;
     private static final int TERMINATING  = 6;
     private static final int DRIVER_STATE = 7;
-    private static final int UNKNOWN      = 8;
+    private static final int EAP_FAILURE  = 8;
+    private static final int UNKNOWN      = 9;
 
     /** All events coming from the supplicant start with this prefix */
     private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@
      * <code>state</code> is either STARTED or STOPPED
      */
     private static final String driverStateEvent = "DRIVER-STATE";
+    /**
+     * <pre>
+     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
+     * </pre>
+     */
+    private static final String eapFailureEvent = "EAP-FAILURE";
+
+    /**
+     * This indicates an authentication failure on EAP FAILURE event
+     */
+    private static final String eapAuthFailure = "EAP authentication failed";
 
     /**
      * Regex pattern for extracting an Ethernet-style MAC address from a string.
@@ -176,7 +188,7 @@
                 if (!eventStr.startsWith(eventPrefix)) {
                     if (eventStr.startsWith(wpaEventPrefix) &&
                             0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
-                        handlePasswordKeyMayBeIncorrect();
+                        mWifiStateMachine.notifyAuthenticationFailure();
                     } else if (eventStr.startsWith(wpsOverlapEvent)) {
                         mWifiStateMachine.notifyWpsOverlap();
                     }
@@ -207,16 +219,17 @@
                     event = LINK_SPEED;
                 else if (eventName.equals(terminatingEvent))
                     event = TERMINATING;
-                else if (eventName.equals(driverStateEvent)) {
+                else if (eventName.equals(driverStateEvent))
                     event = DRIVER_STATE;
-                }
+                else if (eventName.equals(eapFailureEvent))
+                    event = EAP_FAILURE;
                 else
                     event = UNKNOWN;
 
                 String eventData = eventStr;
                 if (event == DRIVER_STATE || event == LINK_SPEED)
                     eventData = eventData.split(" ")[1];
-                else if (event == STATE_CHANGE) {
+                else if (event == STATE_CHANGE || event == EAP_FAILURE) {
                     int ind = eventStr.indexOf(" ");
                     if (ind != -1) {
                         eventData = eventStr.substring(ind + 1);
@@ -261,6 +274,10 @@
                     // notify and exit
                     mWifiStateMachine.notifySupplicantLost();
                     break;
+                } else if (event == EAP_FAILURE) {
+                    if (eventData.startsWith(eapAuthFailure)) {
+                        mWifiStateMachine.notifyAuthenticationFailure();
+                    }
                 } else {
                     handleEvent(event, eventData);
                 }
@@ -284,10 +301,6 @@
             return false;
         }
 
-        private void handlePasswordKeyMayBeIncorrect() {
-            mWifiStateMachine.notifyPasswordKeyMayBeIncorrect();
-        }
-
         private void handleDriverEvent(String state) {
             if (state == null) {
                 return;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 0548b4d..4d0acdd 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -61,7 +61,6 @@
 import android.provider.Settings;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.Slog;
 import android.app.backup.IBackupManager;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
@@ -213,8 +212,8 @@
     static final int SCAN_RESULTS_EVENT                   = 38;
     /* Supplicate state changed */
     static final int SUPPLICANT_STATE_CHANGE_EVENT        = 39;
-    /* Password may be incorrect */
-    static final int PASSWORD_MAY_BE_INCORRECT_EVENT      = 40;
+    /* Password failure and EAP authentication failure */
+    static final int AUTHENTICATION_FAILURE_EVENT         = 40;
     /* WPS overlap detected */
     static final int WPS_OVERLAP_EVENT                    = 41;
 
@@ -1384,11 +1383,12 @@
     }
 
     /**
-     * Send the tracker a notification that a user-entered password key
-     * may be incorrect (i.e., caused authentication to fail).
+     * Send the tracker a notification that a user provided
+     * configuration caused authentication failure - this could
+     * be a password failure or a EAP authentication failure
      */
-    void notifyPasswordKeyMayBeIncorrect() {
-        sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+    void notifyAuthenticationFailure() {
+        sendMessage(AUTHENTICATION_FAILURE_EVENT);
     }
 
     /**
@@ -1516,7 +1516,7 @@
                 case NETWORK_DISCONNECTION_EVENT:
                 case SCAN_RESULTS_EVENT:
                 case SUPPLICANT_STATE_CHANGE_EVENT:
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
+                case AUTHENTICATION_FAILURE_EVENT:
                 case WPS_OVERLAP_EVENT:
                 case CMD_BLACKLIST_NETWORK:
                 case CMD_CLEAR_BLACKLIST:
@@ -1671,10 +1671,18 @@
                         nwService.startAccessPoint((WifiConfiguration) message.obj,
                                     mInterfaceName,
                                     SOFTAP_IFACE);
-                    } catch(Exception e) {
-                        Log.e(TAG, "Exception in startAccessPoint()");
-                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
-                        break;
+                    } catch (Exception e) {
+                        Log.e(TAG, "Exception in softap start " + e);
+                        try {
+                            nwService.stopAccessPoint();
+                            nwService.startAccessPoint((WifiConfiguration) message.obj,
+                                    mInterfaceName,
+                                    SOFTAP_IFACE);
+                        } catch (Exception ee) {
+                            Log.e(TAG, "Exception during softap restart : " + ee);
+                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
+                            break;
+                        }
                     }
                     Log.d(TAG, "Soft AP start successful");
                     setWifiApState(WIFI_AP_STATE_ENABLED);
@@ -2060,7 +2068,7 @@
                 case SUPPLICANT_STATE_CHANGE_EVENT:
                 case NETWORK_CONNECTION_EVENT:
                 case NETWORK_DISCONNECTION_EVENT:
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
+                case AUTHENTICATION_FAILURE_EVENT:
                 case WPS_OVERLAP_EVENT:
                 case CMD_SET_SCAN_TYPE:
                 case CMD_SET_HIGH_PERF_MODE:
@@ -2293,8 +2301,8 @@
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             StateChangeResult stateChangeResult;
             switch(message.what) {
-                case PASSWORD_MAY_BE_INCORRECT_EVENT:
-                    mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+                case AUTHENTICATION_FAILURE_EVENT:
+                    mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
                     break;
                 case WPS_OVERLAP_EVENT:
                     /* We just need to broadcast the error */
@@ -2824,13 +2832,16 @@
                                     mInterfaceName,
                                     SOFTAP_IFACE);
                     } catch(Exception e) {
-                        Log.e(TAG, "Exception in nwService during soft AP set");
+                        Log.e(TAG, "Exception in softap set " + e);
                         try {
                             nwService.stopAccessPoint();
+                            nwService.startAccessPoint((WifiConfiguration) message.obj,
+                                    mInterfaceName,
+                                    SOFTAP_IFACE);
                         } catch (Exception ee) {
-                            Slog.e(TAG, "Could not stop AP, :" + ee);
+                            Log.e(TAG, "Could not restart softap after set failed " + ee);
+                            sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
                         }
-                        sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
                     }
                     break;
                 /* Fail client mode operation when soft AP is enabled */