Merge change 24773 into eclair

* changes:
  Fix NPE in TelephonyManager.
diff --git a/api/current.xml b/api/current.xml
index d6b272f..f2fb7c0 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1659,6 +1659,17 @@
  visibility="public"
 >
 </field>
+<field name="accountPreferences"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843423"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="accountType"
  type="int"
  transient="false"
@@ -7093,6 +7104,17 @@
  visibility="public"
 >
 </field>
+<field name="smallIcon"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843422"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="smallScreens"
  type="int"
  transient="false"
@@ -14543,6 +14565,10 @@
 </parameter>
 <parameter name="iconId" type="int">
 </parameter>
+<parameter name="smallIconId" type="int">
+</parameter>
+<parameter name="prefId" type="int">
+</parameter>
 </constructor>
 <method name="describeContents"
  return="int"
@@ -14593,6 +14619,16 @@
  visibility="public"
 >
 </field>
+<field name="accountPreferencesId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="iconId"
  type="int"
  transient="false"
@@ -14623,6 +14659,16 @@
  visibility="public"
 >
 </field>
+<field name="smallIconId"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="type"
  type="java.lang.String"
  transient="false"
@@ -25526,6 +25572,30 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<method name="cancelDiscovery"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="checkBluetoothAddress"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="address" type="java.lang.String">
+</parameter>
+</method>
 <method name="disable"
  return="boolean"
  abstract="false"
@@ -25559,6 +25629,17 @@
  visibility="public"
 >
 </method>
+<method name="getBondedDevices"
+ return="java.util.Set&lt;android.bluetooth.BluetoothDevice&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getName"
  return="java.lang.String"
  abstract="false"
@@ -25605,6 +25686,17 @@
  visibility="public"
 >
 </method>
+<method name="isDiscovering"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isEnabled"
  return="boolean"
  abstract="false"
@@ -25657,11 +25749,55 @@
 <parameter name="mode" type="int">
 </parameter>
 </method>
+<method name="startDiscovery"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="ACTION_DISCOVERY_FINISHED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.adapter.action.DISCOVERY_FINISHED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_DISCOVERY_STARTED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.adapter.action.DISCOVERY_STARTED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_LOCAL_NAME_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.adapter.action.LOCAL_NAME_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTION_SCAN_MODE_CHANGED"
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.action.SCAN_MODE_CHANGED&quot;"
+ value="&quot;android.bluetooth.adapter.action.SCAN_MODE_CHANGED&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25672,7 +25808,7 @@
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.action.STATE_CHANGED&quot;"
+ value="&quot;android.bluetooth.adapter.action.STATE_CHANGED&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25683,7 +25819,18 @@
  type="int"
  transient="false"
  volatile="false"
- value="-1"
+ value="-2147483648"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_LOCAL_NAME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.adapter.extra.LOCAL_NAME&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25694,7 +25841,7 @@
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.extra.PREVIOUS_SCAN_MODE&quot;"
+ value="&quot;android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25705,7 +25852,7 @@
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.extra.PREVIOUS_STATE&quot;"
+ value="&quot;android.bluetooth.adapter.extra.PREVIOUS_STATE&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25716,7 +25863,7 @@
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.extra.SCAN_MODE&quot;"
+ value="&quot;android.bluetooth.adapter.extra.SCAN_MODE&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25727,7 +25874,7 @@
  type="java.lang.String"
  transient="false"
  volatile="false"
- value="&quot;android.bluetooth.intent.extra.STATE&quot;"
+ value="&quot;android.bluetooth.adapter.extra.STATE&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25738,7 +25885,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="51"
+ value="21"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25749,7 +25896,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="53"
+ value="23"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25760,7 +25907,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="50"
+ value="20"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25771,7 +25918,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="40"
+ value="10"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25782,7 +25929,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="42"
+ value="12"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25793,7 +25940,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="43"
+ value="13"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25804,7 +25951,900 @@
  type="int"
  transient="false"
  volatile="false"
- value="41"
+ value="11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="BluetoothClass"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDeviceClass"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMajorDeviceClass"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="hasService"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="service" type="int">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</class>
+<class name="BluetoothClass.Device"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BluetoothClass.Device"
+ type="android.bluetooth.BluetoothClass.Device"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="AUDIO_VIDEO_CAMCORDER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1076"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_CAR_AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1056"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_HANDSFREE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1032"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_HEADPHONES"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_HIFI_AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_LOUDSPEAKER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1044"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_MICROPHONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1040"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_PORTABLE_AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1052"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_SET_TOP_BOX"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1060"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VCR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1068"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VIDEO_CAMERA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1072"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VIDEO_CONFERENCING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1088"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1084"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VIDEO_GAMING_TOY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1096"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_VIDEO_MONITOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1080"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AUDIO_VIDEO_WEARABLE_HEADSET"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1028"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_DESKTOP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="260"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_HANDHELD_PC_PDA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="272"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_LAPTOP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="268"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_PALM_SIZE_PC_PDA"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="276"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_SERVER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="264"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER_WEARABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="280"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_BLOOD_PRESSURE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2308"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_DATA_DISPLAY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2332"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_GLUCOSE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2320"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_PULSE_OXIMETER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2324"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_PULSE_RATE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2328"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_THERMOMETER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2312"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2304"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH_WEIGHING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2316"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_CELLULAR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="516"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_CORDLESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="520"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_ISDN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="532"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_MODEM_OR_GATEWAY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="528"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_SMART"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="524"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="512"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_CONTROLLER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_DOLL_ACTION_FIGURE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2060"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_GAME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2068"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_ROBOT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2052"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY_VEHICLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2056"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_GLASSES"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1812"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_HELMET"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1808"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_JACKET"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1804"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_PAGER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1800"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1792"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE_WRIST_WATCH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1796"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="BluetoothClass.Device.Major"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BluetoothClass.Device.Major"
+ type="android.bluetooth.BluetoothClass.Device.Major"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="AUDIO_VIDEO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COMPUTER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="256"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="HEALTH"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2304"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="IMAGING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1536"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MISC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NETWORKING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="768"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PERIPHERAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1280"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PHONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="512"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TOY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="UNCATEGORIZED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7936"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WEARABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1792"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="BluetoothClass.Service"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="BluetoothClass.Service"
+ type="android.bluetooth.BluetoothClass.Service"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<field name="AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2097152"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="CAPTURE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="524288"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="INFORMATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8388608"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="LIMITED_DISCOVERABILITY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8192"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NETWORKING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="131072"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="OBJECT_TRANSFER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1048576"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="POSITIONING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65536"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="RENDER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="262144"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TELEPHONY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4194304"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -25822,6 +26862,28 @@
 >
 <implements name="android.os.Parcelable">
 </implements>
+<method name="cancelBondProcess"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="createBond"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="createRfcommSocket"
  return="android.bluetooth.BluetoothSocket"
  abstract="false"
@@ -25859,6 +26921,28 @@
  visibility="public"
 >
 </method>
+<method name="getBluetoothClass"
+ return="android.bluetooth.BluetoothClass"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getBondState"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getName"
  return="java.lang.String"
  abstract="false"
@@ -25870,6 +26954,17 @@
  visibility="public"
 >
 </method>
+<method name="removeBond"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="writeToParcel"
  return="void"
  abstract="false"
@@ -25885,11 +26980,187 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
+<field name="ACTION_ACL_CONNECTED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.ACL_CONNECTED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_ACL_DISCONNECTED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.ACL_DISCONNECTED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_ACL_DISCONNECT_REQUESTED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_BOND_STATE_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.BOND_STATE_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_CLASS_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.CLASS_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_FOUND"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.FOUND&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_NAME_CHANGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.action.NAME_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="BOND_BONDED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="BOND_BONDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="BOND_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ERROR"
  type="int"
  transient="false"
  volatile="false"
- value="-1"
+ value="-2147483648"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_BOND_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.BOND_STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_CLASS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.CLASS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_DEVICE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.DEVICE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_NAME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.NAME&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PREVIOUS_BOND_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.PREVIOUS_BOND_STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_RSSI"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.bluetooth.device.extra.RSSI&quot;"
  static="true"
  final="true"
  deprecated="not deprecated"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index c211b47..c60045c 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -216,11 +216,9 @@
     } else
         vibrate_fd = -1;
 
-#if 0
     /* switch to non-root user and group */
     setgroups(sizeof(groups)/sizeof(groups[0]), groups);
     setuid(AID_SHELL);
-#endif
 
     /* make it safe to use both printf and STDOUT_FILENO */ 
     setvbuf(stdout, 0, _IONBF, 0);
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 51a0649..39ed769 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -1,9 +1,10 @@
+ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
+
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=       \
-        JPEGSource.cpp  \
 	stagefright.cpp
 
 LOCAL_SHARED_LIBRARIES := \
@@ -39,3 +40,5 @@
 LOCAL_MODULE:= record
 
 include $(BUILD_EXECUTABLE)
+
+endif
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index d1926b4..73215d3 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -25,6 +25,7 @@
 #include <media/IMediaPlayerService.h>
 #include <media/stagefright/CachingDataSource.h>
 #include <media/stagefright/HTTPDataSource.h>
+#include <media/stagefright/JPEGSource.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaPlayerImpl.h>
@@ -35,8 +36,6 @@
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
 
-#include "JPEGSource.h"
-
 using namespace android;
 
 static long gNumRepetitions;
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 8c422a2..03346fe 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -185,7 +185,7 @@
 
         private final HandlerCaller mCaller;
 
-        private AccessibilityService mTarget;
+        private final AccessibilityService mTarget;
 
         public IEventListenerWrapper(AccessibilityService context) {
             mTarget = context;
@@ -211,9 +211,9 @@
             switch (message.what) {
                 case DO_ON_ACCESSIBILITY_EVENT :
                     AccessibilityEvent event = (AccessibilityEvent) message.obj;
-                    if (event != null){
-                      mTarget.onAccessibilityEvent(event);
-                      event.recycle();
+                    if (event != null) {
+                        mTarget.onAccessibilityEvent(event);
+                        event.recycle();
                     }
                     return;
                 case DO_ON_INTERRUPT :
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
index 82cadd5..fdc5fbf 100644
--- a/core/java/android/accounts/AccountAuthenticatorCache.java
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -49,10 +49,15 @@
                     com.android.internal.R.styleable.AccountAuthenticator_label, 0);
             final int iconId = sa.getResourceId(
                     com.android.internal.R.styleable.AccountAuthenticator_icon, 0);
+            final int smallIconId = sa.getResourceId(
+                    com.android.internal.R.styleable.AccountAuthenticator_smallIcon, 0);
+            final int prefId = sa.getResourceId(
+                    com.android.internal.R.styleable.AccountAuthenticator_accountPreferences, 0);
             if (TextUtils.isEmpty(accountType)) {
                 return null;
             }
-            return new AuthenticatorDescription(accountType, packageName, labelId, iconId);
+            return new AuthenticatorDescription(accountType, packageName, labelId, iconId, 
+                    smallIconId, prefId);
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
index 672e648..28673b4 100644
--- a/core/java/android/accounts/AuthenticatorDescription.java
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -6,16 +6,21 @@
 public class AuthenticatorDescription implements Parcelable {
     final public String type;
     final public int labelId;
-    final public int iconId;
+    final public int iconId; 
+    final public int smallIconId; 
+    final public int accountPreferencesId;
     final public String packageName;
 
-    public AuthenticatorDescription(String type, String packageName, int labelId, int iconId) {
+    public AuthenticatorDescription(String type, String packageName, int labelId, int iconId, 
+            int smallIconId, int prefId) {
         if (type == null) throw new IllegalArgumentException("type cannot be null");
         if (packageName == null) throw new IllegalArgumentException("packageName cannot be null");
         this.type = type;
         this.packageName = packageName;
         this.labelId = labelId;
         this.iconId = iconId;
+        this.smallIconId = smallIconId;
+        this.accountPreferencesId = prefId;
     }
 
     public static AuthenticatorDescription newKey(String type) {
@@ -28,6 +33,8 @@
         this.packageName = null;
         this.labelId = 0;
         this.iconId = 0;
+        this.smallIconId = 0;
+        this.accountPreferencesId = 0;
     }
 
     private AuthenticatorDescription(Parcel source) {
@@ -35,6 +42,8 @@
         this.packageName = source.readString();
         this.labelId = source.readInt();
         this.iconId = source.readInt();
+        this.smallIconId = source.readInt();
+        this.accountPreferencesId = source.readInt();
     }
 
     public int describeContents() {
@@ -57,6 +66,8 @@
         dest.writeString(packageName);
         dest.writeInt(labelId);
         dest.writeInt(iconId);
+        dest.writeInt(smallIconId);
+        dest.writeInt(accountPreferencesId);
     }
 
     public static final Creator<AuthenticatorDescription> CREATOR =
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 7e6efec..267d86a 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -769,8 +769,11 @@
  *     </tr>
  *     
  *     <tr><th>android:icon</th>
- *         <td>If provided, this icon will be used <i>in place</i> of the label string.  This
- *         is provided in order to present logos or other non-textual banners.</td>
+ *         <td>If provided, this icon will be shown in place of the label above the search box.
+ *           This is a reference to a drawable (icon) resource. Note that the application icon
+ *           is also used as an icon to the left of the search box and you cannot modify this
+ *           behavior, so including the icon attribute is unecessary and this may be
+ *           deprecated in the future.</td>
  *         <td align="center">No</td>
  *     </tr>
  *     
@@ -779,11 +782,6 @@
  *             entered.</td>
  *         <td align="center">No</td>
  *     </tr>
- *
- *     <tr><th>android:searchButtonText</th>
- *         <td>If provided, this text will replace the default text in the "Search" button.</td>
- *         <td align="center">No</td>
- *     </tr>
  *     
  *     <tr><th>android:searchMode</th>
  *         <td>If provided and non-zero, sets additional modes for control of the search 
@@ -792,15 +790,17 @@
  *                 <tbody>
  *                 <tr><th>showSearchLabelAsBadge</th>
  *                     <td>If set, this flag enables the display of the search target (label) 
- *                         within the search bar.  If this flag and showSearchIconAsBadge
+ *                         above the search box.  If this flag and showSearchIconAsBadge
  *                         (see below) are both not set, no badge will be shown.</td>
  *                 </tr>
  *                 <tr><th>showSearchIconAsBadge</th>
- *                     <td>If set, this flag enables the display of the search target (icon) within
- *                         the search bar.  If this flag and showSearchLabelAsBadge
+ *                     <td>If set, this flag enables the display of the search target (icon)
+ *                         above the search box.  If this flag and showSearchLabelAsBadge
  *                         (see above) are both not set, no badge will be shown.  If both flags
  *                         are set, showSearchIconAsBadge has precedence and the icon will be
- *                         shown.</td>
+ *                         shown. Because the application icon is now used to the left of the
+ *                         search box by default, using this search mode is no longer necessary
+ *                         and may be deprecated in the future.</td>
  *                 </tr>
  *                 <tr><th>queryRewriteFromData</th>
  *                     <td>If set, this flag causes the suggestion column SUGGEST_COLUMN_INTENT_DATA
@@ -2060,4 +2060,4 @@
         Thread thread = Thread.currentThread();
         Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
     }
-}
+}
\ No newline at end of file
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 060f20e..2e9612a 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -51,20 +51,21 @@
     private static final String TAG = "BluetoothA2dp";
     private static final boolean DBG = false;
 
-    /** int extra for SINK_STATE_CHANGED_ACTION */
-    public static final String SINK_STATE =
-        "android.bluetooth.a2dp.intent.SINK_STATE";
-    /** int extra for SINK_STATE_CHANGED_ACTION */
-    public static final String SINK_PREVIOUS_STATE =
-        "android.bluetooth.a2dp.intent.SINK_PREVIOUS_STATE";
+    /** int extra for ACTION_SINK_STATE_CHANGED */
+    public static final String EXTRA_SINK_STATE =
+        "android.bluetooth.a2dp.extra.SINK_STATE";
+    /** int extra for ACTION_SINK_STATE_CHANGED */
+    public static final String EXTRA_PREVIOUS_SINK_STATE =
+        "android.bluetooth.a2dp.extra.PREVIOUS_SINK_STATE";
 
     /** Indicates the state of an A2DP audio sink has changed.
-     *  This intent will always contain SINK_STATE, SINK_PREVIOUS_STATE and
-     *  BluetoothIntent.ADDRESS extras.
+     * This intent will always contain EXTRA_SINK_STATE,
+     * EXTRA_PREVIOUS_SINK_STATE and BluetoothDevice.EXTRA_DEVICE
+     * extras.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String SINK_STATE_CHANGED_ACTION =
-        "android.bluetooth.a2dp.intent.action.SINK_STATE_CHANGED";
+    public static final String ACTION_SINK_STATE_CHANGED =
+        "android.bluetooth.a2dp.action.SINK_STATE_CHANGED";
 
     public static final int STATE_DISCONNECTED = 0;
     public static final int STATE_CONNECTING   = 1;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 18f6995..96a927b 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -36,8 +36,6 @@
  *
  * <p>Use the {@link BluetoothDevice} class for operations on remote Bluetooth
  * devices.
- *
- * <p>TODO: unhide more of this class
  */
 public final class BluetoothAdapter {
     private static final String TAG = "BluetoothAdapter";
@@ -49,20 +47,20 @@
      * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
      * BluetoothAdapter.ERROR)</code>
      */
-    public static final int ERROR = -1;
+    public static final int ERROR = Integer.MIN_VALUE;
 
     /**
      * Broadcast Action: The state of the local Bluetooth adapter has been
      * changed.
      * <p>For example, Bluetooth has been turned on or off.
-     * <p>Contains the extra fields {@link #EXTRA_STATE} and {@link
+     * <p>Always contains the extra fields {@link #EXTRA_STATE} and {@link
      * #EXTRA_PREVIOUS_STATE} containing the new and old states
      * respectively.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_STATE_CHANGED =
-            "android.bluetooth.intent.action.STATE_CHANGED";
+            "android.bluetooth.adapter.action.STATE_CHANGED";
 
     /**
      * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
@@ -73,7 +71,7 @@
      * {@link #STATE_TURNING_OFF},
      */
     public static final String EXTRA_STATE =
-            "android.bluetooth.intent.extra.STATE";
+            "android.bluetooth.adapter.extra.STATE";
     /**
      * Used as an int extra field in {@link #ACTION_STATE_CHANGED}
      * intents to request the previous power state. Possible values are:
@@ -83,39 +81,39 @@
      * {@link #STATE_TURNING_OFF},
      */
     public static final String EXTRA_PREVIOUS_STATE =
-            "android.bluetooth.intent.extra.PREVIOUS_STATE";
+            "android.bluetooth.adapter.extra.PREVIOUS_STATE";
 
     /**
      * Indicates the local Bluetooth adapter is off.
      */
-    public static final int STATE_OFF = 40;
+    public static final int STATE_OFF = 10;
     /**
      * Indicates the local Bluetooth adapter is turning on. However local
      * clients should wait for {@link #STATE_ON} before attempting to
      * use the adapter.
      */
-    public static final int STATE_TURNING_ON = 41;
+    public static final int STATE_TURNING_ON = 11;
     /**
      * Indicates the local Bluetooth adapter is on, and ready for use.
      */
-    public static final int STATE_ON = 42;
+    public static final int STATE_ON = 12;
     /**
      * Indicates the local Bluetooth adapter is turning off. Local clients
      * should immediately attempt graceful disconnection of any remote links.
      */
-    public static final int STATE_TURNING_OFF = 43;
+    public static final int STATE_TURNING_OFF = 13;
 
     /**
      * Broadcast Action: Indicates the Bluetooth scan mode of the local Adapter
      * has changed.
-     * <p>Contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link
+     * <p>Always contains the extra fields {@link #EXTRA_SCAN_MODE} and {@link
      * #EXTRA_PREVIOUS_SCAN_MODE} containing the new and old scan modes
      * respectively.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_SCAN_MODE_CHANGED =
-            "android.bluetooth.intent.action.SCAN_MODE_CHANGED";
+            "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
 
     /**
      * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
@@ -124,7 +122,7 @@
      * {@link #SCAN_MODE_CONNECTABLE},
      * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
      */
-    public static final String EXTRA_SCAN_MODE = "android.bluetooth.intent.extra.SCAN_MODE";
+    public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE";
     /**
      * Used as an int extra field in {@link #ACTION_SCAN_MODE_CHANGED}
      * intents to request the previous scan mode. Possible values are:
@@ -133,37 +131,73 @@
      * {@link #SCAN_MODE_CONNECTABLE_DISCOVERABLE},
      */
     public static final String EXTRA_PREVIOUS_SCAN_MODE =
-            "android.bluetooth.intent.extra.PREVIOUS_SCAN_MODE";
+            "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
 
     /**
      * Indicates that both inquiry scan and page scan are disabled on the local
      * Bluetooth adapter. Therefore this device is neither discoverable
      * nor connectable from remote Bluetooth devices.
      */
-    public static final int SCAN_MODE_NONE = 50;
+    public static final int SCAN_MODE_NONE = 20;
     /**
      * Indicates that inquiry scan is disabled, but page scan is enabled on the
      * local Bluetooth adapter. Therefore this device is not discoverable from
      * remote Bluetooth devices, but is connectable from remote devices that
      * have previously discovered this device.
      */
-    public static final int SCAN_MODE_CONNECTABLE = 51;
+    public static final int SCAN_MODE_CONNECTABLE = 21;
     /**
      * Indicates that both inquiry scan and page scan are enabled on the local
      * Bluetooth adapter. Therefore this device is both discoverable and
      * connectable from remote Bluetooth devices.
      */
-    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 53;
+    public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;
 
-    /** The user will be prompted to enter a pin
-     * @hide */
-    public static final int PAIRING_VARIANT_PIN = 0;
-    /** The user will be prompted to enter a passkey
-     * @hide */
-    public static final int PAIRING_VARIANT_PASSKEY = 1;
-    /** The user will be prompted to confirm the passkey displayed on the screen
-     * @hide */
-    public static final int PAIRING_VARIANT_CONFIRMATION = 2;
+
+    /**
+     * Broadcast Action: The local Bluetooth adapter has started the remote
+     * device discovery process.
+     * <p>This usually involves an inquiry scan of about 12 seconds, followed
+     * by a page scan of each new device to retrieve its Bluetooth name.
+     * <p>Register for {@link BluetoothDevice#ACTION_FOUND} to be notified as
+     * remote Bluetooth devices are found.
+     * <p>Device discovery is a heavyweight procedure. New connections to
+     * remote Bluetooth devices should not be attempted while discovery is in
+     * progress, and existing connections will experience limited bandwidth
+     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
+     * discovery.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DISCOVERY_STARTED =
+            "android.bluetooth.adapter.action.DISCOVERY_STARTED";
+    /**
+     * Broadcast Action: The local Bluetooth adapter has finished the device
+     * discovery process.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DISCOVERY_FINISHED =
+            "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
+
+    /**
+     * Broadcast Action: The local Bluetooth adapter has changed its friendly
+     * Bluetooth name.
+     * <p>This name is visible to remote Bluetooth devices.
+     * <p>Always contains the extra field {@link #EXTRA_LOCAL_NAME} containing
+     * the name.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LOCAL_NAME_CHANGED =
+            "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";
+    /**
+     * Used as a String extra field in {@link #ACTION_LOCAL_NAME_CHANGED}
+     * intents to request the local Bluetooth name.
+     */
+    public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
+
+    private static final int ADDRESS_LENGTH = 17;
 
     private final IBluetooth mService;
 
@@ -182,7 +216,8 @@
      * Get a {@link BluetoothDevice} object for the given Bluetooth hardware
      * address.
      * <p>Valid Bluetooth hardware addresses must be upper case, in a format
-     * such as "00:11:22:33:AA:BB".
+     * such as "00:11:22:33:AA:BB". The helper {@link #checkBluetoothAddress} is
+     * available to validate a Bluetooth address.
      * <p>A {@link BluetoothDevice} will always be returned for a valid
      * hardware address, even if this adapter has never seen that device.
      *
@@ -380,7 +415,29 @@
         } catch (RemoteException e) {Log.e(TAG, "", e);}
     }
 
-    /** @hide */
+    /**
+     * Start the remote device discovery process.
+     * <p>The discovery process usually involves an inquiry scan of about 12
+     * seconds, followed by a page scan of each new device to retrieve its
+     * Bluetooth name.
+     * <p>This is an asynchronous call, it will return immediately. Register
+     * for {@link #ACTION_DISCOVERY_STARTED} and {@link
+     * #ACTION_DISCOVERY_FINISHED} intents to determine exactly when the
+     * discovery starts and completes. Register for {@link
+     * BluetoothDevice#ACTION_FOUND} to be notified as remote Bluetooth devices
+     * are found.
+     * <p>Device discovery is a heavyweight procedure. New connections to
+     * remote Bluetooth devices should not be attempted while discovery is in
+     * progress, and existing connections will experience limited bandwidth
+     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
+     * discovery.
+     * <p>Device discovery will only find remote devices that are currently
+     * <i>discoverable</i> (inquiry scan enabled). Many Bluetooth devices are
+     * not discoverable by default, and need to be entered into a special mode.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     *
+     * @return true on success, false on error
+     */
     public boolean startDiscovery() {
         try {
             return mService.startDiscovery();
@@ -388,14 +445,33 @@
         return false;
     }
 
-    /** @hide */
-    public void cancelDiscovery() {
+    /**
+     * Cancel the current device discovery process.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     *
+     * @return true on success, false on error
+     */
+    public boolean cancelDiscovery() {
         try {
             mService.cancelDiscovery();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return false;
     }
 
-    /** @hide */
+    /**
+     * Return true if the local Bluetooth adapter is currently in the device
+     * discovery process.
+     * <p>Device discovery is a heavyweight procedure. New connections to
+     * remote Bluetooth devices should not be attempted while discovery is in
+     * progress, and existing connections will experience limited bandwidth
+     * and high latency. Use {@link #cancelDiscovery()} to cancel an ongoing
+     * discovery.
+     * <p>Applications can also register for {@link #ACTION_DISCOVERY_STARTED}
+     * or {@link #ACTION_DISCOVERY_FINISHED} to be notified when discovery
+     * starts or completes.
+     *
+     * @return true if discovering
+     */
     public boolean isDiscovering() {
         try {
             return mService.isDiscovering();
@@ -404,27 +480,10 @@
     }
 
     /**
-     * List remote devices that are bonded (paired) to the local adapter.
+     * Return the set of {@link BluetoothDevice} objects that are bonded
+     * (paired) to the local adapter.
      *
-     * Bonding (pairing) is the process by which the user enters a pin code for
-     * the device, which generates a shared link key, allowing for
-     * authentication and encryption of future connections. In Android we
-     * require bonding before RFCOMM or SCO connections can be made to a remote
-     * device.
-     *
-     * This function lists which remote devices we have a link key for. It does
-     * not cause any RF transmission, and does not check if the remote device
-     * still has it's link key with us. If the other side no longer has its
-     * link key then the RFCOMM or SCO connection attempt will result in an
-     * error.
-     *
-     * This function does not check if the remote device is in range.
-     *
-     * Remote devices that have an in-progress bonding attempt are not
-     * returned.
-     *
-     * @return unmodifiable set of bonded devices, or null on error
-     * @hide
+     * @return unmodifiable set of {@link BluetoothDevice}, or null on error
      */
     public Set<BluetoothDevice> getBondedDevices() {
         try {
@@ -511,4 +570,33 @@
         }
         return Collections.unmodifiableSet(devices);
     }
+
+    /**
+     * Validate a Bluetooth address, such as "00:43:A8:23:10:F0"
+     *
+     * @param address Bluetooth address as string
+     * @return true if the address is valid, false otherwise
+     */
+    public static boolean checkBluetoothAddress(String address) {
+        if (address == null || address.length() != ADDRESS_LENGTH) {
+            return false;
+        }
+        for (int i = 0; i < ADDRESS_LENGTH; i++) {
+            char c = address.charAt(i);
+            switch (i % 3) {
+            case 0:
+            case 1:
+                if (Character.digit(c, 16) != -1) {
+                    break;  // hex character, OK
+                }
+                return false;
+            case 2:
+                if (c == ':') {
+                    break;  // OK
+                }
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 0061f10..1fbbf78 100644
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -16,43 +16,89 @@
 
 package android.bluetooth;
 
+import android.os.Parcel;
+import android.os.Parcelable;
+
 /**
- * The Android Bluetooth API is not finalized, and *will* change. Use at your
- * own risk.
+ * Represents a Bluetooth class.
  *
- * Static helper methods and constants to decode the device class bit vector
- * returned by the Bluetooth API.
- *
- * The Android Bluetooth API returns a 32-bit integer to represent the class.
- * The format of these bits is defined at
+ * <p>Bluetooth Class is a 32 bit field. The format of these bits is defined at
  *   http://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
- * (login required). This class provides static helper methods and constants to
- * determine what Service Class(es) and Device Class are encoded in the 32-bit
- * class.
+ * (login required). This class contains that 32 bit field, and provides
+ * constants and methods to determine which Service Class(es) and Device Class
+ * are encoded in that field.
  *
- * Devices typically have zero or more service classes, and exactly one device
- * class. The device class is encoded as a major and minor device class, the
- * minor being a subset of the major.
+ * <p>Every Bluetooth Class is composed of zero or more service classes, and
+ * exactly one device class. The device class is further broken down into major
+ * and minor device class components.
  *
- * Class is useful to describe a device (for example to show an icon),
- * but does not reliably describe what profiles a device supports. To determine
- * profile support you usually need to perform SDP queries.
+ * <p>Class is useful as a hint to roughly describe a device (for example to
+ * show an icon in the UI), but does not reliably describe which Bluetooth
+ * profiles or services are actually supported by a device. Accurate service
+ * discovery is done through SDP requests.
  *
- * Each of these helper methods takes the 32-bit integer class as an argument.
- *
- * @hide
+ * <p>Use {@link BluetoothDevice#getBluetoothClass} to retrieve the class for
+ * a remote device.
  */
-public class BluetoothClass {
-    /** Indicates the Bluetooth API could not retrieve the class */
+public final class BluetoothClass implements Parcelable {
+    /**
+     * Legacy error value. Applications should use null instead.
+     * @hide
+     */
     public static final int ERROR = 0xFF000000;
 
-    public static final int PROFILE_HEADSET = 0;
-    public static final int PROFILE_A2DP = 1;
-    public static final int PROFILE_OPP = 2;
+    private final int mClass;
 
-    /** Every Bluetooth device has zero or more service classes */
-    public static class Service {
-        public static final int BITMASK                 = 0xFFE000;
+    /** @hide */
+    public BluetoothClass(int classInt) {
+        mClass = classInt;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof BluetoothClass) {
+            return mClass == ((BluetoothClass)o).mClass;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mClass;
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toHexString(mClass);
+    }
+
+    /** @hide */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** @hide */
+    public static final Parcelable.Creator<BluetoothClass> CREATOR =
+            new Parcelable.Creator<BluetoothClass>() {
+        public BluetoothClass createFromParcel(Parcel in) {
+            return new BluetoothClass(in.readInt());
+        }
+        public BluetoothClass[] newArray(int size) {
+            return new BluetoothClass[size];
+        }
+    };
+
+    /** @hide */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mClass);
+    }
+
+    /**
+     * Bluetooth service classes.
+     * <p>Each {@link BluetoothClass} encodes zero or more service classes.
+     */
+    public static final class Service {
+        private static final int BITMASK                 = 0xFFE000;
 
         public static final int LIMITED_DISCOVERABILITY = 0x002000;
         public static final int POSITIONING             = 0x010000;
@@ -63,32 +109,35 @@
         public static final int AUDIO                   = 0x200000;
         public static final int TELEPHONY               = 0x400000;
         public static final int INFORMATION             = 0x800000;
-
-        /** Returns true if the given class supports the given Service Class.
-         * A bluetooth device can claim to support zero or more service classes.
-         * @param btClass The bluetooth class.
-         * @param serviceClass The service class constant to test for. For
-         *                     example, Service.AUDIO. Must be one of the
-         *                     Service.FOO constants.
-         * @return True if the service class is supported.
-         */
-        public static boolean hasService(int btClass, int serviceClass) {
-            if (btClass == ERROR) {
-                return false;
-            }
-            return ((btClass & Service.BITMASK & serviceClass) != 0);
-        }
     }
 
-    /** Every Bluetooth device has exactly one device class, comprimised of
-     *  major and minor components. We have not included the minor classes for
-     *  major classes: NETWORKING, PERIPHERAL and IMAGING yet because they work
-     *  a little differently. */
+    /**
+     * Return true if the specified service class is supported by this class.
+     * <p>Valid service classes are the public constants in
+     * {@link BluetoothClass.Service}. For example, {@link
+     * BluetoothClass.Service#AUDIO}.
+     *
+     * @param service valid service class
+     * @return true if the service class is supported
+     */
+    public boolean hasService(int service) {
+        return ((mClass & Service.BITMASK & service) != 0);
+    }
+
+    /**
+     * Bluetooth device classes.
+     * <p>Each {@link BluetoothClass} encodes exactly one device class, with
+     * major and minor components.
+     * <p>The constants in {@link
+     * BluetoothClass.Device} represent a combination of major and minor
+     * components (the complete device class). The constants in {@link
+     * BluetoothClass.Device.Major} represent just the major device classes.
+     */
     public static class Device {
-        public static final int BITMASK               = 0x1FFC;
+        private static final int BITMASK               = 0x1FFC;
 
         public static class Major {
-            public static final int BITMASK           = 0x1F00;
+            private static final int BITMASK           = 0x1F00;
 
             public static final int MISC              = 0x0000;
             public static final int COMPUTER          = 0x0100;
@@ -101,18 +150,6 @@
             public static final int TOY               = 0x0800;
             public static final int HEALTH            = 0x0900;
             public static final int UNCATEGORIZED     = 0x1F00;
-
-            /** Returns the Major Device Class component of a bluetooth class.
-             * Values returned from this function can be compared with the constants
-             * Device.Major.FOO. A bluetooth device can only be associated
-             * with one major class.
-             */
-            public static int getDeviceMajor(int btClass) {
-                if (btClass == ERROR) {
-                    return ERROR;
-                }
-                return (btClass & Device.Major.BITMASK);
-            }
         }
 
         // Devices in the COMPUTER major class
@@ -178,42 +215,62 @@
         public static final int HEALTH_PULSE_OXIMETER               = 0x0914;
         public static final int HEALTH_PULSE_RATE                   = 0x0918;
         public static final int HEALTH_DATA_DISPLAY                 = 0x091C;
-
-        /** Returns the Device Class component of a bluetooth class. This includes
-         * both the major and minor device components. Values returned from this
-         * function can be compared with the constants Device.FOO. A bluetooth
-         * device can only be associated with one device class.
-         */
-        public static int getDevice(int btClass) {
-            if (btClass == ERROR) {
-                return ERROR;
-            }
-            return (btClass & Device.BITMASK);
-        }
     }
 
     /**
+     * Return the major device class component of this Bluetooth class.
+     * <p>Values returned from this function can be compared with the
+     * public constants in {@link BluetoothClass.Device.Major} to determine
+     * which major class is encoded in this Bluetooth class.
+     *
+     * @return major device class component
+     */
+    public int getMajorDeviceClass() {
+        return (mClass & Device.Major.BITMASK);
+    }
+
+    /**
+     * Return the (major and minor) device class component of this
+     * {@link BluetoothClass}.
+     * <p>Values returned from this function can be compared with the
+     * public constants in {@link BluetoothClass.Device} to determine which
+     * device class is encoded in this Bluetooth class.
+     *
+     * @return device class component
+     */
+    public int getDeviceClass() {
+        return (mClass & Device.BITMASK);
+    }
+
+    /** @hide */
+    public static final int PROFILE_HEADSET = 0;
+    /** @hide */
+    public static final int PROFILE_A2DP = 1;
+    /** @hide */
+    public static final int PROFILE_OPP = 2;
+
+    /**
      * Check class bits for possible bluetooth profile support.
      * This is a simple heuristic that tries to guess if a device with the
      * given class bits might support specified profile. It is not accurate for all
      * devices. It tries to err on the side of false positives.
-     * @param btClass The class
      * @param profile The profile to be checked
      * @return True if this device might support specified profile.
+     * @hide
      */
-    public static boolean doesClassMatch(int btClass, int profile) {
+    public boolean doesClassMatch(int profile) {
         if (profile == PROFILE_A2DP) {
-            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
+            if (hasService(Service.RENDER)) {
                 return true;
             }
             // By the A2DP spec, sinks must indicate the RENDER service.
             // However we found some that do not (Chordette). So lets also
             // match on some other class bits.
-            switch (BluetoothClass.Device.getDevice(btClass)) {
-                case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
-                case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
-                case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
-                case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+            switch (getDeviceClass()) {
+                case Device.AUDIO_VIDEO_HIFI_AUDIO:
+                case Device.AUDIO_VIDEO_HEADPHONES:
+                case Device.AUDIO_VIDEO_LOUDSPEAKER:
+                case Device.AUDIO_VIDEO_CAR_AUDIO:
                     return true;
                 default:
                     return false;
@@ -221,37 +278,37 @@
         } else if (profile == PROFILE_HEADSET) {
             // The render service class is required by the spec for HFP, so is a
             // pretty good signal
-            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
+            if (hasService(Service.RENDER)) {
                 return true;
             }
             // Just in case they forgot the render service class
-            switch (BluetoothClass.Device.getDevice(btClass)) {
-                case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
-                case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
-                case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
+            switch (getDeviceClass()) {
+                case Device.AUDIO_VIDEO_HANDSFREE:
+                case Device.AUDIO_VIDEO_WEARABLE_HEADSET:
+                case Device.AUDIO_VIDEO_CAR_AUDIO:
                     return true;
                 default:
                     return false;
             }
         } else if (profile == PROFILE_OPP) {
-            if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.OBJECT_TRANSFER)) {
+            if (hasService(Service.OBJECT_TRANSFER)) {
                 return true;
             }
 
-            switch (BluetoothClass.Device.getDevice(btClass)) {
-                case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
-                case BluetoothClass.Device.COMPUTER_DESKTOP:
-                case BluetoothClass.Device.COMPUTER_SERVER:
-                case BluetoothClass.Device.COMPUTER_LAPTOP:
-                case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
-                case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
-                case BluetoothClass.Device.COMPUTER_WEARABLE:
-                case BluetoothClass.Device.PHONE_UNCATEGORIZED:
-                case BluetoothClass.Device.PHONE_CELLULAR:
-                case BluetoothClass.Device.PHONE_CORDLESS:
-                case BluetoothClass.Device.PHONE_SMART:
-                case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
-                case BluetoothClass.Device.PHONE_ISDN:
+            switch (getDeviceClass()) {
+                case Device.COMPUTER_UNCATEGORIZED:
+                case Device.COMPUTER_DESKTOP:
+                case Device.COMPUTER_SERVER:
+                case Device.COMPUTER_LAPTOP:
+                case Device.COMPUTER_HANDHELD_PC_PDA:
+                case Device.COMPUTER_PALM_SIZE_PC_PDA:
+                case Device.COMPUTER_WEARABLE:
+                case Device.PHONE_UNCATEGORIZED:
+                case Device.PHONE_CELLULAR:
+                case Device.PHONE_CORDLESS:
+                case Device.PHONE_SMART:
+                case Device.PHONE_MODEM_OR_GATEWAY:
+                case Device.PHONE_ISDN:
                     return true;
                 default:
                     return false;
@@ -261,4 +318,3 @@
         }
     }
 }
-
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1ab4389..b1861ac 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -38,8 +40,6 @@
  * are performed on the remote Bluetooth hardware address, using the
  * {@link BluetoothAdapter} that was used to create this {@link
  * BluetoothDevice}.
- *
- * TODO: unhide more of this class
  */
 public final class BluetoothDevice implements Parcelable {
     private static final String TAG = "BluetoothDevice";
@@ -48,37 +48,209 @@
      * Sentinel error value for this class. Guaranteed to not equal any other
      * integer constant in this class. Provided as a convenience for functions
      * that require a sentinel error value, for example:
-     * <p><code>Intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
-     * BluetoothAdapter.ERROR)</code>
+     * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+     * BluetoothDevice.ERROR)</code>
      */
-    public static final int ERROR = -1;
+    public static final int ERROR = Integer.MIN_VALUE;
 
-    /** We do not have a link key for the remote device, and are therefore not
-     * bonded
-     * @hide*/
-    public static final int BOND_NOT_BONDED = 0;
-    /** We have a link key for the remote device, and are probably bonded.
-     *  @hide */
-    public static final int BOND_BONDED = 1;
-    /** We are currently attempting bonding
-     *  @hide */
-    public static final int BOND_BONDING = 2;
+    /**
+     * Broadcast Action: Remote device discovered.
+     * <p>Sent when a remote device is found during discovery.
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
+     * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
+     * {@link #EXTRA_RSSI} if they are available.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+     // TODO: Change API to not broadcast RSSI if not available (incoming connection)
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_FOUND =
+            "android.bluetooth.device.action.FOUND";
 
-    /** Ask device picker to show all kinds of BT devices.
-     *  @hide */
-    public static final int DEVICE_PICKER_FILTER_TYPE_ALL = 0;
-    /** Ask device picker to show BT devices that support AUDIO profiles.
-     *  @hide */
-    public static final int DEVICE_PICKER_FILTER_TYPE_AUDIO = 1;
-    /** Ask device picker to show BT devices that support Object Transfer.
-     *  @hide */
-    public static final int DEVICE_PICKER_FILTER_TYPE_TRANSFER = 2;
+    /**
+     * Broadcast Action: Remote device disappeared.
+     * <p>Sent when a remote device that was found in the last discovery is not
+     * found in the current discovery.
+     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DISAPPEARED =
+            "android.bluetooth.device.action.DISAPPEARED";
+
+    /**
+     * Broadcast Action: Bluetooth class of a remote device has changed.
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
+     * #EXTRA_CLASS}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @see {@link BluetoothClass}
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CLASS_CHANGED =
+            "android.bluetooth.device.action.CLASS_CHANGED";
+
+    /**
+     * Broadcast Action: Indicates a low level (ACL) connection has been
+     * established with a remote device.
+     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+     * <p>ACL connections are managed automatically by the Android Bluetooth
+     * stack.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ACL_CONNECTED =
+            "android.bluetooth.device.action.ACL_CONNECTED";
+
+    /**
+     * Broadcast Action: Indicates that a low level (ACL) disconnection has
+     * been requested for a remote device, and it will soon be disconnected.
+     * <p>This is useful for graceful disconnection. Applications should use
+     * this intent as a hint to immediately terminate higher level connections
+     * (RFCOMM, L2CAP, or profile connections) to the remote device.
+     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ACL_DISCONNECT_REQUESTED =
+            "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
+
+    /**
+     * Broadcast Action: Indicates a low level (ACL) disconnection from a
+     * remote device.
+     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+     * <p>ACL connections are managed automatically by the Android Bluetooth
+     * stack.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ACL_DISCONNECTED =
+            "android.bluetooth.device.action.ACL_DISCONNECTED";
+
+    /**
+     * Broadcast Action: Indicates the friendly name of a remote device has
+     * been retrieved for the first time, or changed since the last retrieval.
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
+     * #EXTRA_NAME}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NAME_CHANGED =
+            "android.bluetooth.device.action.NAME_CHANGED";
+
+    /**
+     * Broadcast Action: Indicates a change in the bond state of a remote
+     * device. For example, if a device is bonded (paired).
+     * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
+     * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     */
+    // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
+    // contain a hidden extra field EXTRA_REASON with the result code.
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_BOND_STATE_CHANGED =
+            "android.bluetooth.device.action.BOND_STATE_CHANGED";
+
+    /**
+     * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
+     * broadcast by this class. It contains the {@link BluetoothDevice} that
+     * the intent applies to.
+     */
+    public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
+
+    /**
+     * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
+     * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
+     */
+    public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
+
+    /**
+     * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
+     * Contains the RSSI value of the remote device as reported by the
+     * Bluetooth hardware.
+     */
+    public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
+
+    /**
+     * Used as an Parcelable {@link BluetoothClass} extra field in {@link
+     * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
+     */
+    public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
+
+    /**
+     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
+     * Contains the bond state of the remote device.
+     * <p>Possible values are:
+     * {@link #BOND_NONE},
+     * {@link #BOND_BONDING},
+     * {@link #BOND_BONDED}.
+      */
+    public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
+    /**
+     * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
+     * Contains the previous bond state of the remote device.
+     * <p>Possible values are:
+     * {@link #BOND_NONE},
+     * {@link #BOND_BONDING},
+     * {@link #BOND_BONDED}.
+      */
+    public static final String EXTRA_PREVIOUS_BOND_STATE =
+            "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
+    /**
+     * Indicates the remote device is not bonded (paired).
+     * <p>There is no shared link key with the remote device, so communication
+     * (if it is allowed at all) will be unauthenticated and unencrypted.
+     */
+    public static final int BOND_NONE = 10;
+    /**
+     * Indicates bonding (pairing) is in progress with the remote device.
+     */
+    public static final int BOND_BONDING = 11;
+    /**
+     * Indicates the remote device is bonded (paired).
+     * <p>A shared link keys exists locally for the remote device, so
+     * communication can be authenticated and encrypted.
+     * <p><i>Being bonded (paired) with a remote device does not necessarily
+     * mean the device is currently connected. It just means that the ponding
+     * procedure was compeleted at some earlier time, and the link key is still
+     * stored locally, ready to use on the next connection.
+     * </i>
+     */
+    public static final int BOND_BONDED = 12;
+
+    /** @hide */
+    public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+    /** @hide */
+    public static final String EXTRA_PAIRING_VARIANT =
+            "android.bluetooth.device.extra.PAIRING_VARIANT";
+    /** @hide */
+    public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
+
+    /**
+     * Broadcast Action: Indicates a failure to retrieve the name of a remote
+     * device.
+     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+     * @hide
+     */
+    //TODO: is this actually useful?
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_NAME_FAILED =
+            "android.bluetooth.device.action.NAME_FAILED";
+
+    /** @hide */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PAIRING_REQUEST =
+            "android.bluetooth.device.action.PAIRING_REQUEST";
+    /** @hide */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PAIRING_CANCEL =
+            "android.bluetooth.device.action.PAIRING_CANCEL";
 
     /** A bond attempt succeeded
      * @hide */
     public static final int BOND_SUCCESS = 0;
     /** A bond attempt failed because pins did not match, or remote device did
-     * not respond to pin request in time 
+     * not respond to pin request in time
      * @hide */
     public static final int UNBOND_REASON_AUTH_FAILED = 1;
     /** A bond attempt failed because the other side explicilty rejected
@@ -94,11 +266,16 @@
     /** A bond attempt failed because a discovery is in progress
      * @hide */
     public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
+    /** A bond attempt failed because of authentication timeout
+     * @hide */
+    public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
+    /** A bond attempt failed because of repeated attempts
+     * @hide */
+    public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
     /** An existing bond was explicitly revoked
      * @hide */
-    public static final int UNBOND_REASON_REMOVED = 6;
+    public static final int UNBOND_REASON_REMOVED = 8;
 
-    //TODO: Remove duplicates between here and BluetoothAdapter
     /** The user will be prompted to enter a pin
      * @hide */
     public static final int PAIRING_VARIANT_PIN = 0;
@@ -107,9 +284,13 @@
     public static final int PAIRING_VARIANT_PASSKEY = 1;
     /** The user will be prompted to confirm the passkey displayed on the screen
      * @hide */
-    public static final int PAIRING_VARIANT_CONFIRMATION = 2;
-
-    private static final int ADDRESS_LENGTH = 17;
+    public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
+    /** The user will be prompted to accept or deny the incoming pairing request
+     * @hide */
+    public static final int PAIRING_VARIANT_CONSENT = 3;
+    /** The user will be prompted to enter the passkey displayed on remote device
+     * @hide */
+    public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
 
     private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
 
@@ -135,7 +316,7 @@
             }
         }
 
-        if (!checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
         }
 
@@ -216,15 +397,15 @@
     }
 
     /**
-     * Create a bonding with a remote bluetooth device.
+     * Start the bonding (pairing) process with the remote device.
+     * <p>This is an asynchronous call, it will return immediately. Register
+     * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
+     * the bonding process completes, and its result.
+     * <p>Android system services will handle the necessary user interactions
+     * to confirm and complete the bonding process.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
-     * This is an asynchronous call. The result of this bonding attempt can be
-     * observed through BluetoothIntent.BOND_STATE_CHANGED_ACTION intents.
-     *
-     * @param address the remote device Bluetooth address.
-     * @return false If there was an immediate problem creating the bonding,
-     *         true otherwise.
-     * @hide
+     * @return false on immediate error, true if bonding will begin
      */
     public boolean createBond() {
         try {
@@ -234,8 +415,10 @@
     }
 
     /**
-     * Cancel an in-progress bonding request started with createBond.
-     * @hide
+     * Cancel an in-progress bonding request started with {@link #createBond}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
+     *
+     * @return true on sucess, false on error
      */
     public boolean cancelBondProcess() {
         try {
@@ -245,12 +428,13 @@
     }
 
     /**
-     * Removes the remote device and the pairing information associated
-     * with it.
+     * Remove bond (pairing) with the remote device.
+     * <p>Delete the link key associated with the remote device, and
+     * immediately terminate connections to that device that require
+     * authentication and encryption.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
      *
-     * @return true if the device was disconnected, false otherwise and on
-     *         error.
-     * @hide
+     * @return true on sucess, false on error
      */
     public boolean removeBond() {
         try {
@@ -260,21 +444,35 @@
     }
 
     /**
-     * Get the bonding state of a remote device.
+     * Get the bond state of the remote device.
+     * <p>Possible values for the bond state are:
+     * {@link #BOND_NONE},
+     * {@link #BOND_BONDING},
+     * {@link #BOND_BONDED}.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
      *
-     * Result is one of:
-     * BOND_*
-     * ERROR
-     *
-     * @param address Bluetooth hardware address of the remote device to check.
-     * @return Result code
-     * @hide
+     * @return the bond state
      */
     public int getBondState() {
         try {
             return sService.getBondState(mAddress);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothDevice.ERROR;
+        return BOND_NONE;
+    }
+
+    /**
+     * Get the Bluetooth class of the remote device.
+     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
+     *
+     * @return Bluetooth class object, or null on error
+     */
+    public BluetoothClass getBluetoothClass() {
+        try {
+            int classInt = sService.getRemoteClass(mAddress);
+            if (classInt == BluetoothClass.ERROR) return null;
+            return new BluetoothClass(classInt);
+        } catch (RemoteException e) {Log.e(TAG, "", e);}
+        return null;
     }
 
     /**
@@ -305,14 +503,6 @@
     }
 
     /** @hide */
-    public int getBluetoothClass() {
-        try {
-            return sService.getRemoteClass(mAddress);
-        } catch (RemoteException e) {Log.e(TAG, "", e);}
-        return BluetoothDevice.ERROR;
-    }
-
-    /** @hide */
      public String[] getUuids() {
         try {
             return sService.getRemoteUuids(mAddress);
@@ -433,28 +623,4 @@
         return pinBytes;
     }
 
-    /** Sanity check a bluetooth address, such as "00:43:A8:23:10:F0"
-     * @hide */
-    public static boolean checkBluetoothAddress(String address) {
-        if (address == null || address.length() != ADDRESS_LENGTH) {
-            return false;
-        }
-        for (int i = 0; i < ADDRESS_LENGTH; i++) {
-            char c = address.charAt(i);
-            switch (i % 3) {
-            case 0:
-            case 1:
-                if (Character.digit(c, 16) != -1) {
-                    break;  // hex character, OK
-                }
-                return false;
-            case 2:
-                if (c == ':') {
-                    break;  // OK
-                }
-                return false;
-            }
-        }
-        return true;
-    }
 }
diff --git a/core/java/android/bluetooth/BluetoothDevicePicker.java b/core/java/android/bluetooth/BluetoothDevicePicker.java
new file mode 100644
index 0000000..05eed0e
--- /dev/null
+++ b/core/java/android/bluetooth/BluetoothDevicePicker.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+
+/**
+ * A helper to show a system "Device Picker" activity to the user.
+ *
+ * @hide
+ */
+public interface BluetoothDevicePicker {
+    public static final String EXTRA_NEED_AUTH =
+            "android.bluetooth.devicepicker.extra.NEED_AUTH";
+    public static final String EXTRA_FILTER_TYPE =
+            "android.bluetooth.devicepicker.extra.FILTER_TYPE";
+    public static final String EXTRA_LAUNCH_PACKAGE =
+            "android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
+    public static final String EXTRA_LAUNCH_CLASS =
+            "android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
+
+    /**
+     * Broadcast when one BT device is selected from BT device picker screen.
+     * Selected BT device address is contained in extra string {@link BluetoothIntent}
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_DEVICE_SELECTED =
+            "android.bluetooth.devicepicker.action.DEVICE_SELECTED";
+
+    /**
+     * Broadcast when someone want to select one BT device from devices list.
+     * This intent contains below extra data:
+     * - {@link #EXTRA_NEED_AUTH} (boolean): if need authentication
+     * - {@link #EXTRA_FILTER_TYPE} (int): what kinds of device should be
+     *                                     listed
+     * - {@link #EXTRA_LAUNCH_PACKAGE} (string): where(which package) this
+     *                                           intent come from
+     * - {@link #EXTRA_LAUNCH_CLASS} (string): where(which class) this intent
+     *                                         come from
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_LAUNCH =
+            "android.bluetooth.devicepicker.action.LAUNCH";
+
+    /** Ask device picker to show all kinds of BT devices */
+    public static final int FILTER_TYPE_ALL = 0;
+    /** Ask device picker to show BT devices that support AUDIO profiles */
+    public static final int FILTER_TYPE_AUDIO = 1;
+    /** Ask device picker to show BT devices that support Object Transfer */
+    public static final int FILTER_TYPE_TRANSFER = 2;
+}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index d31b6ae..90cff6b 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -54,6 +56,27 @@
     private static final String TAG = "BluetoothHeadset";
     private static final boolean DBG = false;
 
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_STATE_CHANGED =
+            "android.bluetooth.headset.action.STATE_CHANGED";
+    /**
+     * TODO(API release): Consider incorporating as new state in
+     * HEADSET_STATE_CHANGED
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_AUDIO_STATE_CHANGED =
+            "android.bluetooth.headset.action.AUDIO_STATE_CHANGED";
+    public static final String EXTRA_STATE =
+            "android.bluetooth.headset.extra.STATE";
+    public static final String EXTRA_PREVIOUS_STATE =
+            "android.bluetooth.headset.extra.PREVIOUS_STATE";
+    public static final String EXTRA_AUDIO_STATE =
+            "android.bluetooth.headset.extra.AUDIO_STATE";
+
+    /**
+     * TODO(API release): Consider incorporating as new state in
+     * HEADSET_STATE_CHANGED
+     */
     private IBluetoothHeadset mService;
     private final Context mContext;
     private final ServiceListener mServiceListener;
diff --git a/core/java/android/bluetooth/BluetoothIntent.java b/core/java/android/bluetooth/BluetoothIntent.java
deleted file mode 100644
index 8de19f5..0000000
--- a/core/java/android/bluetooth/BluetoothIntent.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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 android.bluetooth;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-
-/**
- * Bluetooth API constants.
- *
- * TODO: Deprecate this class
- * @hide
- */
-public interface BluetoothIntent {
-    public static final String DEVICE =
-        "android.bluetooth.intent.DEVICE";
-    public static final String NAME =
-        "android.bluetooth.intent.NAME";
-    public static final String ALIAS =
-        "android.bluetooth.intent.ALIAS";
-    public static final String RSSI =
-        "android.bluetooth.intent.RSSI";
-    public static final String CLASS =
-        "android.bluetooth.intent.CLASS";
-    public static final String HEADSET_STATE =
-        "android.bluetooth.intent.HEADSET_STATE";
-    public static final String HEADSET_PREVIOUS_STATE =
-        "android.bluetooth.intent.HEADSET_PREVIOUS_STATE";
-    public static final String HEADSET_AUDIO_STATE =
-        "android.bluetooth.intent.HEADSET_AUDIO_STATE";
-    public static final String BOND_STATE =
-        "android.bluetooth.intent.BOND_STATE";
-    public static final String BOND_PREVIOUS_STATE =
-        "android.bluetooth.intent.BOND_PREVIOUS_STATE";
-    public static final String REASON =
-        "android.bluetooth.intent.REASON";
-    public static final String PAIRING_VARIANT =
-        "android.bluetooth.intent.PAIRING_VARIANT";
-    public static final String PASSKEY =
-        "android.bluetooth.intent.PASSKEY";
-
-    public static final String DEVICE_PICKER_NEED_AUTH =
-        "android.bluetooth.intent.DEVICE_PICKER_NEED_AUTH";
-    public static final String DEVICE_PICKER_FILTER_TYPE =
-        "android.bluetooth.intent.DEVICE_PICKER_FILTER_TYPE";
-    public static final String DEVICE_PICKER_LAUNCH_PACKAGE =
-        "android.bluetooth.intent.DEVICE_PICKER_LAUNCH_PACKAGE";
-    public static final String DEVICE_PICKER_LAUNCH_CLASS =
-        "android.bluetooth.intent.DEVICE_PICKER_LAUNCH_CLASS";
-
-     /**
-     * Broadcast when one BT device is selected from BT device picker screen.
-     * Selected BT device address is contained in extra string "BluetoothIntent.ADDRESS".
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String DEVICE_PICKER_DEVICE_SELECTED =
-        "android.bluetooth.intent.action.DEVICE_SELECTED";
-
-    /**
-     * Broadcast when someone want to select one BT device from devices list.
-     * This intent contains below extra data:
-     * - BluetoothIntent.DEVICE_PICKER_NEED_AUTH (boolean): if need authentication
-     * - BluetoothIntent.DEVICE_PICKER_FILTER_TYPE (int): what kinds of device should be listed
-     * - BluetoothIntent.DEVICE_PICKER_LAUNCH_PACKAGE (string): where(which package) this intent come from
-     * - BluetoothIntent.DEVICE_PICKER_LAUNCH_CLASS (string): where(which class) this intent come from
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String DEVICE_PICKER_DEVICE_PICKER =
-        "android.bluetooth.intent.action.DEVICE_PICKER";
-
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String NAME_CHANGED_ACTION  =
-        "android.bluetooth.intent.action.NAME_CHANGED";
-
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String DISCOVERY_STARTED_ACTION          =
-        "android.bluetooth.intent.action.DISCOVERY_STARTED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String DISCOVERY_COMPLETED_ACTION        =
-        "android.bluetooth.intent.action.DISCOVERY_COMPLETED";
-
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String PAIRING_REQUEST_ACTION            =
-        "android.bluetooth.intent.action.PAIRING_REQUEST";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String PAIRING_CANCEL_ACTION             =
-        "android.bluetooth.intent.action.PAIRING_CANCEL";
-
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_FOUND_ACTION        =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_FOUND";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_DISAPPEARED_ACTION  =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_DISAPPEARED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_CLASS_UPDATED_ACTION  =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_DISAPPEARED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_CONNECTED_ACTION    =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_CONNECTED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_DISCONNECT_REQUESTED_ACTION =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_DISCONNECT_REQUESTED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_DEVICE_DISCONNECTED_ACTION =
-        "android.bluetooth.intent.action.REMOTE_DEVICE_DISCONNECTED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_NAME_UPDATED_ACTION        =
-        "android.bluetooth.intent.action.REMOTE_NAME_UPDATED";
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String REMOTE_NAME_FAILED_ACTION         =
-        "android.bluetooth.intent.action.REMOTE_NAME_FAILED";
-
-    /**
-     * Broadcast when the bond state of a remote device changes.
-     * Has string extra ADDRESS and int extras BOND_STATE and
-     * BOND_PREVIOUS_STATE.
-     * If BOND_STATE is BluetoothDevice.BOND_NOT_BONDED then will
-     * also have an int extra REASON with a value of:
-     * BluetoothDevice.BOND_RESULT_*
-     * */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String BOND_STATE_CHANGED_ACTION      =
-        "android.bluetooth.intent.action.BOND_STATE_CHANGED_ACTION";
-
-    /**
-     * TODO(API release): Move into BluetoothHeadset
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String HEADSET_STATE_CHANGED_ACTION      =
-        "android.bluetooth.intent.action.HEADSET_STATE_CHANGED";
-
-    /**
-     * TODO(API release): Consider incorporating as new state in
-     * HEADSET_STATE_CHANGED
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String HEADSET_AUDIO_STATE_CHANGED_ACTION =
-        "android.bluetooth.intent.action.HEADSET_ADUIO_STATE_CHANGED";
-}
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 645e241..b48f48e 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -221,9 +221,9 @@
      * devices. It tries to err on the side of false positives.
      * @return True if this device might support PBAP.
      */
-    public static boolean doesClassMatchSink(int btClass) {
+    public static boolean doesClassMatchSink(BluetoothClass btClass) {
         // TODO optimize the rule
-        switch (BluetoothClass.Device.getDevice(btClass)) {
+        switch (btClass.getDeviceClass()) {
         case BluetoothClass.Device.COMPUTER_DESKTOP:
         case BluetoothClass.Device.COMPUTER_LAPTOP:
         case BluetoothClass.Device.COMPUTER_SERVER:
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 0bc8a9d..0d43b2a 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -24,7 +24,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Locale;
 
 /**
  * Provides access to an application's raw asset files; see {@link Resources}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 7d412a7..ba5c9ed 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -66,8 +66,6 @@
             = new SparseArray<ColorStateList>();
     private static boolean mPreloaded;
 
-    private final LongSparseArray<Drawable.ConstantState> mPreloadedDrawables;
-
     /*package*/ final TypedValue mTmpValue = new TypedValue();
 
     // These are protected by the mTmpValue lock.
@@ -158,11 +156,6 @@
         }
         updateConfiguration(config, metrics);
         assets.ensureStringBlocks();
-        if (mCompatibilityInfo.isScalingRequired()) {
-            mPreloadedDrawables = emptySparseArray();
-        } else {
-            mPreloadedDrawables = sPreloadedDrawables;
-        }
     }
 
     /**
@@ -1669,7 +1662,7 @@
             return dr;
         }
 
-        Drawable.ConstantState cs = mPreloadedDrawables.get(key);
+        Drawable.ConstantState cs = sPreloadedDrawables.get(key);
         if (cs != null) {
             dr = cs.newDrawable();
         } else {
@@ -1976,7 +1969,6 @@
         mMetrics.setToDefaults();
         updateConfiguration(null, null);
         mAssets.ensureStringBlocks();
-        mPreloadedDrawables = sPreloadedDrawables;
         mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
     }
 }
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 5bfdcc4..30ecf5a 100755
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -29,6 +29,7 @@
 import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.FrameLayout;
 import android.os.SystemClock;
+import android.annotation.Widget;
 import com.android.internal.R;
 
 import java.util.ArrayList;
@@ -50,6 +51,7 @@
  * @attr ref android.R.styleable#GestureOverlayView_orientation
  * @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor
  */
+@Widget
 public class GestureOverlayView extends FrameLayout {
     public static final int GESTURE_STROKE_TYPE_SINGLE = 0;
     public static final int GESTURE_STROKE_TYPE_MULTIPLE = 1;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 38c9dbc..04daa1c 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -37,6 +37,23 @@
  * frames for encoding for video.
  * <p>There is no default constructor for this class. Use {@link #open()} to
  * get a Camera object.</p>
+ *
+ * <p>In order to use the device camera, you must declare the 
+ * {@link android.Manifest.permission#CAMERA} permission in your Android 
+ * Manifest. Also be sure to include the
+ * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
+ * manifest element in order to declare camera features used by your application. 
+ * For example, if you use the camera and auto-focus feature, your Manifest 
+ * should include the following:</p>
+ * <pre> &lt;uses-permission android:name="android.permission.CAMERA" />
+ * &lt;uses-feature android:name="android.hardware.camera" />
+ * &lt;uses-feature android:name="android.hardware.camera.autofocus" /></pre>
+ *
+ * <p class="caution"><strong>Caution:</strong> Different Android-powered devices
+ * may have different hardware specifications, such as megapixel ratings and
+ * auto-focus capabilities. In order for your application to be compatible with
+ * more devices, you should not make assumptions about the device camera 
+ * specifications.</p>
  */
 public class Camera {
     private static final String TAG = "Camera";
@@ -179,10 +196,10 @@
         /**
          * The callback that delivers the preview frames.
          *
-         * @param data The contents of the preview frame in {@link
-         *             android.hardware.Camera.Parameters#getPreviewFormat()}
-         *             format. If {@link
-         *             android.hardware.Camera.Parameters#setPreviewFormat(int)}
+         * @param data The contents of the preview frame in the format defined
+         *  by {@link android.graphics.PixelFormat}, which can be queried 
+         *  with {@link android.hardware.Camera.Parameters#getPreviewFormat()}.
+         *  If {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}
          *             is never called, the default will be the YCbCr_420_SP
          *             (NV21) format.
          * @param camera The Camera service object.
@@ -323,6 +340,13 @@
 
     /**
      * Handles the callback for the camera auto focus.
+     * <p>Devices that do not support auto-focus will receive a "fake" 
+     * callback to this interface. If your application needs auto-focus and 
+     * should not be installed on devices <em>without</em> auto-focus, you must
+     * declare that your app uses the
+     * {@code android.hardware.camera.autofocus} feature, in the 
+     * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
+     * manifest element.</p>
      */
     public interface AutoFocusCallback
     {
@@ -343,7 +367,12 @@
      * the camera does not support auto-focus, it is a no-op and {@link
      * AutoFocusCallback#onAutoFocus(boolean, Camera)} callback will be called
      * immediately.
-     *
+     * <p>If your application should not be installed
+     * on devices without auto-focus, you must declare that your application 
+     * uses auto-focus with the 
+     * <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature></a>
+     * manifest element.</p>
+     * 
      * @param cb the callback to run
      */
     public final void autoFocus(AutoFocusCallback cb)
@@ -874,11 +903,14 @@
         }
 
         /**
-         * Sets the image format for preview pictures. If this is never called,
-         * the default will be the YCbCr_420_SP (NV21) format.
-         *
-         * @param pixel_format the desired preview picture format
-         *                     (<var>PixelFormat.YCbCr_420_SP (NV21)</var>,
+         * Sets the image format for preview pictures. 
+         * <p>If this is never called, the default format will be
+         * {@link android.graphics.PixelFormat#YCbCr_420_SP}, which
+         * uses the NV21 encoding format.</p>
+         * 
+         * @param pixel_format the desired preview picture format, defined
+         *   by one of the {@link android.graphics.PixelFormat} constants.
+         *   (E.g., <var>PixelFormat.YCbCr_420_SP</var> (default),
          *                      <var>PixelFormat.RGB_565</var>, or
          *                      <var>PixelFormat.JPEG</var>)
          * @see android.graphics.PixelFormat
@@ -896,9 +928,9 @@
         /**
          * Returns the image format for preview pictures got from
          * {@link PreviewCallback}.
-         *
-         * @return the PixelFormat int representing the preview picture format
-         * @see android.graphics.PixelFormat
+         * 
+         * @return the {@link android.graphics.PixelFormat} int representing 
+         *         the preview picture format.
          */
         public int getPreviewFormat() {
             return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT));
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index f88fcdc..d8db4c1 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -145,12 +145,14 @@
                     if (DBG) Log.d(TAG, mApnType + " Received " + intent.getAction() +
                             " broadcast - state = " + state + ", oldstate = " + mMobileDataState +
                             ", unavailable = " + unavailable + ", reason = " +
-                            (reason == null ? "(unspecified)" : reason));
+                            (reason == null ? "(unspecified)" : reason) +
+                            ", apnTypeList = " + apnTypeList);
 
+                    // set this regardless of the apnTypeList.  It's all the same radio/network
+                    // underneath
+                    mNetworkInfo.setIsAvailable(!unavailable);
 
                     if (isApnTypeIncluded(apnTypeList)) {
-                        // set this even if the apn isn't Enabled
-                        mNetworkInfo.setIsAvailable(!unavailable);
                         if (mEnabled == false) {
                             // if we're not enabled but the APN Type is supported by this connection
                             // we should record the interface name if one's provided.  If the user
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 9f53937..649cb8c 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -131,7 +131,7 @@
         mSubtypeName = subtypeName;
         setDetailedState(DetailedState.IDLE, null, null);
         mState = State.UNKNOWN;
-        mIsAvailable = true;
+        mIsAvailable = false; // until we're told otherwise, assume unavailable
         mIsRoaming = false;
     }
 
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index a24e0d21..9c687e2 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -25,7 +25,6 @@
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothUuid;
 import android.bluetooth.IBluetoothA2dp;
 import android.content.BroadcastReceiver;
@@ -79,7 +78,7 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             BluetoothDevice device =
-                    intent.getParcelableExtra(BluetoothIntent.DEVICE);
+                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                                BluetoothAdapter.ERROR);
@@ -91,19 +90,19 @@
                     onBluetoothDisable();
                     break;
                 }
-            } else if (action.equals(BluetoothIntent.BOND_STATE_CHANGED_ACTION)) {
-                int bondState = intent.getIntExtra(BluetoothIntent.BOND_STATE,
+            } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
+                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                                                    BluetoothDevice.ERROR);
                 switch(bondState) {
                 case BluetoothDevice.BOND_BONDED:
                     setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO);
                     break;
                 case BluetoothDevice.BOND_BONDING:
-                case BluetoothDevice.BOND_NOT_BONDED:
+                case BluetoothDevice.BOND_NONE:
                     setSinkPriority(device, BluetoothA2dp.PRIORITY_OFF);
                     break;
                 }
-            } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) {
+            } else if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
                 if (getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
                         isSinkDevice(device)) {
                     // This device is a preferred sink. Make an A2DP connection
@@ -134,8 +133,8 @@
         mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE);
 
         mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
-        mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
+        mIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+        mIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
         mContext.registerReceiver(mReceiver, mIntentFilter);
 
         mAudioDevices = new HashMap<BluetoothDevice, Integer>();
@@ -361,7 +360,7 @@
     public synchronized boolean setSinkPriority(BluetoothDevice device, int priority) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (!BluetoothDevice.checkBluetoothAddress(device.getAddress())) {
+        if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
             return false;
         }
         return Settings.Secure.putInt(mContext.getContentResolver(),
@@ -411,10 +410,10 @@
             }
             mAudioDevices.put(device, state);
 
-            Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
-            intent.putExtra(BluetoothIntent.DEVICE, device);
-            intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState);
-            intent.putExtra(BluetoothA2dp.SINK_STATE, state);
+            Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+            intent.putExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, prevState);
+            intent.putExtra(BluetoothA2dp.EXTRA_SINK_STATE, state);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
 
             if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index b5eb9ac..1ed5c49 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -17,10 +17,9 @@
 package android.server;
 
 import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothUuid;
 import android.content.Context;
 import android.content.Intent;
@@ -54,6 +53,7 @@
 
     private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
     private static final int EVENT_RESTART_BLUETOOTH = 2;
+    private static final int EVENT_PAIRING_CONSENT_DELAYED_ACCEPT = 3;
 
     // The time (in millisecs) to delay the pairing attempt after the first
     // auto pairing attempt fails. We use an exponential delay with
@@ -68,9 +68,10 @@
     private final Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
+            String address = null;
             switch (msg.what) {
             case EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY:
-                String address = (String)msg.obj;
+                address = (String)msg.obj;
                 if (address != null) {
                     mBluetoothService.createBond(address);
                     return;
@@ -79,6 +80,12 @@
             case EVENT_RESTART_BLUETOOTH:
                 mBluetoothService.restart();
                 break;
+            case EVENT_PAIRING_CONSENT_DELAYED_ACCEPT:
+                address = (String)msg.obj;
+                if (address != null) {
+                    mBluetoothService.setPairingConfirmation(address, true);
+                }
+                break;
             }
         }
     };
@@ -140,11 +147,12 @@
             rssiValue = Short.MIN_VALUE;
         }
         if (classValue != null) {
-            Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
-            intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
-            intent.putExtra(BluetoothIntent.CLASS, Integer.valueOf(classValue));
-            intent.putExtra(BluetoothIntent.RSSI, rssiValue);
-            intent.putExtra(BluetoothIntent.NAME, name);
+            Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+            intent.putExtra(BluetoothDevice.EXTRA_CLASS,
+                    new BluetoothClass(Integer.valueOf(classValue)));
+            intent.putExtra(BluetoothDevice.EXTRA_RSSI, rssiValue);
+            intent.putExtra(BluetoothDevice.EXTRA_NAME, name);
 
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
         } else {
@@ -161,8 +169,19 @@
     }
 
     private void onDeviceDisappeared(String address) {
-        Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
-        intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
+        Intent intent = new Intent(BluetoothDevice.ACTION_DISAPPEARED);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+    }
+
+    private void onDeviceDisconnectRequested(String deviceObjectPath) {
+        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+        if (address == null) {
+            Log.e(TAG, "onDeviceDisconnectRequested: Address of the remote device in null");
+            return;
+        }
+        Intent intent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
     }
 
@@ -182,7 +201,7 @@
             pairingAttempt(address, result);
         } else {
             mBluetoothService.getBondState().setBondState(address,
-                                                          BluetoothDevice.BOND_NOT_BONDED, result);
+                                                          BluetoothDevice.BOND_NONE, result);
             if (mBluetoothService.getBondState().isAutoPairingAttemptsInProgress(address)) {
                 mBluetoothService.getBondState().clearPinAttempts(address);
             }
@@ -202,7 +221,7 @@
                     MAX_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY) {
             mBluetoothService.getBondState().clearPinAttempts(address);
             mBluetoothService.getBondState().setBondState(address,
-                    BluetoothDevice.BOND_NOT_BONDED, result);
+                    BluetoothDevice.BOND_NONE, result);
             return;
         }
 
@@ -213,7 +232,7 @@
         if (!postResult) {
             mBluetoothService.getBondState().clearPinAttempts(address);
             mBluetoothService.getBondState().setBondState(address,
-                    BluetoothDevice.BOND_NOT_BONDED, result);
+                    BluetoothDevice.BOND_NONE, result);
             return;
         }
         mBluetoothService.getBondState().attempt(address);
@@ -228,6 +247,7 @@
                 addDevice(address, properties);
             }
         }
+        mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDING);
         return;
     }
 
@@ -235,7 +255,7 @@
         String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
         if (address != null)
             mBluetoothService.getBondState().setBondState(address.toUpperCase(),
-                    BluetoothDevice.BOND_NOT_BONDED, BluetoothDevice.UNBOND_REASON_REMOVED);
+                    BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED);
     }
 
     /*package*/ void onPropertyChanged(String[] propValues) {
@@ -246,8 +266,8 @@
         }
         String name = propValues[0];
         if (name.equals("Name")) {
-            Intent intent = new Intent(BluetoothIntent.NAME_CHANGED_ACTION);
-            intent.putExtra(BluetoothIntent.NAME, propValues[1]);
+            Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
+            intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setProperty(name, propValues[1]);
         } else if (name.equals("Pairable") || name.equals("Discoverable")) {
@@ -274,12 +294,12 @@
             Intent intent;
             if (propValues[1].equals("true")) {
                 mBluetoothService.setIsDiscovering(true);
-                intent = new Intent(BluetoothIntent.DISCOVERY_STARTED_ACTION);
+                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
             } else {
                 // Stop the discovery.
                 mBluetoothService.cancelDiscovery();
                 mBluetoothService.setIsDiscovering(false);
-                intent = new Intent(BluetoothIntent.DISCOVERY_COMPLETED_ACTION);
+                intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
             }
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setProperty(name, propValues[1]);
@@ -312,25 +332,26 @@
         }
         BluetoothDevice device = mAdapter.getRemoteDevice(address);
         if (name.equals("Name")) {
-            Intent intent = new Intent(BluetoothIntent.REMOTE_NAME_UPDATED_ACTION);
-            intent.putExtra(BluetoothIntent.DEVICE, device);
-            intent.putExtra(BluetoothIntent.NAME, propValues[1]);
+            Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+            intent.putExtra(BluetoothDevice.EXTRA_NAME, propValues[1]);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
         } else if (name.equals("Class")) {
-            Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CLASS_UPDATED_ACTION);
-            intent.putExtra(BluetoothIntent.DEVICE, device);
-            intent.putExtra(BluetoothIntent.CLASS, propValues[1]);
+            Intent intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+            intent.putExtra(BluetoothDevice.EXTRA_CLASS,
+                    new BluetoothClass(Integer.valueOf(propValues[1])));
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
         } else if (name.equals("Connected")) {
             Intent intent = null;
             if (propValues[1].equals("true")) {
-                intent = new Intent(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
+                intent = new Intent(BluetoothDevice.ACTION_ACL_CONNECTED);
             } else {
-                intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISCONNECTED_ACTION);
+                intent = new Intent(BluetoothDevice.ACTION_ACL_DISCONNECTED);
             }
-            intent.putExtra(BluetoothIntent.DEVICE, device);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
             mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
         } else if (name.equals("UUIDs")) {
@@ -350,7 +371,7 @@
                 mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
             } else {
                 mBluetoothService.getBondState().setBondState(address,
-                        BluetoothDevice.BOND_NOT_BONDED);
+                        BluetoothDevice.BOND_NONE);
                 mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false");
             }
         } else if (name.equals("Trusted")) {
@@ -378,15 +399,40 @@
         return address;
     }
 
-    private void onRequestConfirmation(String objectPath, int passkey, int nativeData) {
+    private void onRequestPairingConsent(String objectPath, int nativeData) {
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
 
-        Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
-        intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothIntent.PASSKEY, passkey);
-        intent.putExtra(BluetoothIntent.PAIRING_VARIANT,
-                BluetoothDevice.PAIRING_VARIANT_CONFIRMATION);
+        /* The link key will not be stored if the incoming request has MITM
+         * protection switched on. Unfortunately, some devices have MITM
+         * switched on even though their capabilities are NoInputNoOutput,
+         * so we may get this request many times. Also if we respond immediately,
+         * the other end is unable to handle it. Delay sending the message.
+         */
+        if (mBluetoothService.getBondState().getBondState(address) == BluetoothDevice.BOND_BONDED) {
+            Message message = mHandler.obtainMessage(EVENT_PAIRING_CONSENT_DELAYED_ACCEPT);
+            message.obj = address;
+            mHandler.sendMessageDelayed(message, 1500);
+            return;
+        }
+
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                        BluetoothDevice.PAIRING_VARIANT_CONSENT);
+        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+        return;
+    }
+
+    private void onRequestPasskeyConfirmation(String objectPath, int passkey, int nativeData) {
+        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
+        if (address == null) return;
+
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
+        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
         return;
     }
@@ -395,9 +441,10 @@
         String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
         if (address == null) return;
 
-        Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
-        intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PASSKEY);
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                BluetoothDevice.PAIRING_VARIANT_PASSKEY);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
         return;
     }
@@ -409,10 +456,10 @@
         if (mBluetoothService.getBondState().getBondState(address) ==
                 BluetoothDevice.BOND_BONDING) {
             // we initiated the bonding
-            int btClass = mBluetoothService.getRemoteClass(address);
+            BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
 
             // try 0000 once if the device looks dumb
-            switch (BluetoothClass.Device.getDevice(btClass)) {
+            switch (btClass.getDeviceClass()) {
             case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
             case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
             case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
@@ -427,13 +474,25 @@
                 }
            }
         }
-        Intent intent = new Intent(BluetoothIntent.PAIRING_REQUEST_ACTION);
-        intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
-        intent.putExtra(BluetoothIntent.PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.PAIRING_VARIANT_PIN);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
         return;
     }
 
+    private void onDisplayPasskey(String objectPath, int passkey, int nativeData) {
+        String address = checkPairingRequestAndGetAddress(objectPath, nativeData);
+        if (address == null) return;
+
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+        intent.putExtra(BluetoothDevice.EXTRA_PASSKEY, passkey);
+        intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
+                        BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY);
+        mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+    }
+
     private boolean onAgentAuthorize(String objectPath, String deviceUuid) {
         String address = mBluetoothService.getAddressFromObjectPath(objectPath);
         if (address == null) {
@@ -464,7 +523,7 @@
     }
 
     private void onAgentCancel() {
-        Intent intent = new Intent(BluetoothIntent.PAIRING_CANCEL_ACTION);
+        Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
         return;
     }
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 6482c4c..6ce0f5f 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -28,7 +28,6 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.IBluetooth;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -183,7 +182,7 @@
 
         // mark in progress bondings as cancelled
         for (String address : mBondState.listInState(BluetoothDevice.BOND_BONDING)) {
-            mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+            mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
                                     BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
         }
 
@@ -441,17 +440,17 @@
             }
             if (DBG) log(address + " bond state " + oldState + " -> " + state + " (" +
                          reason + ")");
-            Intent intent = new Intent(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
-            intent.putExtra(BluetoothIntent.DEVICE, mAdapter.getRemoteDevice(address));
-            intent.putExtra(BluetoothIntent.BOND_STATE, state);
-            intent.putExtra(BluetoothIntent.BOND_PREVIOUS_STATE, oldState);
-            if (state == BluetoothDevice.BOND_NOT_BONDED) {
+            Intent intent = new Intent(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
+            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mAdapter.getRemoteDevice(address));
+            intent.putExtra(BluetoothDevice.EXTRA_BOND_STATE, state);
+            intent.putExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, oldState);
+            if (state == BluetoothDevice.BOND_NONE) {
                 if (reason <= 0) {
                     Log.w(TAG, "setBondState() called to unbond device, but reason code is " +
                           "invalid. Overriding reason code with BOND_RESULT_REMOVED");
                     reason = BluetoothDevice.UNBOND_REASON_REMOVED;
                 }
-                intent.putExtra(BluetoothIntent.REASON, reason);
+                intent.putExtra(BluetoothDevice.EXTRA_REASON, reason);
                 mState.remove(address);
             } else {
                 mState.put(address, state);
@@ -470,7 +469,7 @@
         public synchronized int getBondState(String address) {
             Integer state = mState.get(address);
             if (state == null) {
-                return BluetoothDevice.BOND_NOT_BONDED;
+                return BluetoothDevice.BOND_NONE;
             }
             return state.intValue();
         }
@@ -526,7 +525,7 @@
 
     private static String toBondStateString(int bondState) {
         switch (bondState) {
-        case BluetoothDevice.BOND_NOT_BONDED:
+        case BluetoothDevice.BOND_NONE:
             return "not bonded";
         case BluetoothDevice.BOND_BONDING:
             return "bonding";
@@ -642,9 +641,11 @@
         case BluetoothAdapter.SCAN_MODE_CONNECTABLE:
             pairable = true;
             discoverable = false;
+            break;
         case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE:
             pairable = true;
             discoverable = true;
+            break;
         default:
             Log.w(TAG, "Requested invalid scan mode " + mode);
             return false;
@@ -685,7 +686,7 @@
      */
     public synchronized String getRemoteName(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return null;
         }
         Map <String, String> properties = mDeviceProperties.get(address);
@@ -747,7 +748,7 @@
     public synchronized boolean createBond(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
         address = address.toUpperCase();
@@ -762,7 +763,7 @@
         // Check for bond state only if we are not performing auto
         // pairing exponential back-off attempts.
         if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
-                mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
+                mBondState.getBondState(address) != BluetoothDevice.BOND_NONE) {
             log("Ignoring createBond(): this device is already bonding or bonded");
             return false;
         }
@@ -778,7 +779,7 @@
     public synchronized boolean cancelBondProcess(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
         address = address.toUpperCase();
@@ -786,7 +787,7 @@
             return false;
         }
 
-        mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+        mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
                                 BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
         cancelDeviceCreationNative(address);
         return true;
@@ -795,7 +796,7 @@
     public synchronized boolean removeBond(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
         return removeDeviceNative(getObjectPathFromAddress(address));
@@ -808,7 +809,7 @@
 
     public synchronized int getBondState(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return BluetoothDevice.ERROR;
         }
         return mBondState.getBondState(address.toUpperCase());
@@ -898,7 +899,7 @@
      * @return boolean to indicate operation success or fail
      */
     public synchronized boolean setTrust(String address, boolean value) {
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
             return false;
         }
@@ -915,7 +916,7 @@
      * @return boolean to indicate trust or untrust state
      */
     public synchronized boolean getTrustState(String address) {
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
             return false;
         }
@@ -939,7 +940,7 @@
      *         classes.
      */
     public synchronized int getRemoteClass(String address) {
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
             return BluetoothClass.ERROR;
         }
@@ -961,7 +962,7 @@
      */
     public synchronized String[] getRemoteUuids(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return null;
         }
         String value = getRemoteDeviceProperty(address, "UUIDs");
@@ -982,7 +983,7 @@
      */
     public int getRemoteServiceChannel(String address, String uuid) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return BluetoothDevice.ERROR;
         }
         return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid, 0x0004);
@@ -992,7 +993,7 @@
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
         if (pin == null || pin.length <= 0 || pin.length > 16 ||
-            !BluetoothDevice.checkBluetoothAddress(address)) {
+            !BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
         address = address.toUpperCase();
@@ -1017,7 +1018,7 @@
     public synchronized boolean setPasskey(String address, int passkey) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (passkey < 0 || passkey > 999999 || !BluetoothDevice.checkBluetoothAddress(address)) {
+        if (passkey < 0 || passkey > 999999 || !BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
         address = address.toUpperCase();
@@ -1048,10 +1049,10 @@
     public synchronized boolean cancelPairingUserInput(String address) {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
                                                 "Need BLUETOOTH_ADMIN permission");
-        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             return false;
         }
-        mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
+        mBondState.setBondState(address, BluetoothDevice.BOND_NONE,
                 BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
         address = address.toUpperCase();
         Integer data = mEventLoop.getPasskeyAgentRequestData().remove(address);
@@ -1265,5 +1266,4 @@
     private native boolean setPairingConfirmationNative(String address, boolean confirm,
             int nativeData);
     private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
-
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2f17bbc..f63c2f1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6038,16 +6038,23 @@
      * some form of this public, but should think about the API.
      */
     Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor) {
-        final int width = mRight - mLeft;
-        final int height = mBottom - mTop;
+        int width = mRight - mLeft;
+        int height = mBottom - mTop;
 
-        Bitmap bitmap = Bitmap.createBitmap(width, height, quality);
+        final AttachInfo attachInfo = mAttachInfo;
+        final float scale = attachInfo.mApplicationScale;
+        width = (int) ((width * scale) + 0.5f);
+        height = (int) ((height * scale) + 0.5f);
+        
+        Bitmap bitmap = Bitmap.createBitmap(width > 0 ? width : 1,
+                height > 0 ? height : 1, quality);
         if (bitmap == null) {
             throw new OutOfMemoryError();
         }
 
+        bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
+        
         Canvas canvas;
-        final AttachInfo attachInfo = mAttachInfo;
         if (attachInfo != null) {
             canvas = attachInfo.mCanvas;
             if (canvas == null) {
@@ -6070,6 +6077,7 @@
 
         computeScroll();
         final int restoreCount = canvas.save();
+        canvas.scale(scale, scale);
         canvas.translate(-mScrollX, -mScrollY);
 
         // Temporarily remove the dirty mask
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a611d5a..e98fd13 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -732,7 +732,11 @@
             }
         } else if (digits != null) {
             mInput = DigitsKeyListener.getInstance(digits.toString());
-            mInputType = inputType;
+            // If no input type was specified, we will default to generic
+            // text, since we can't tell the IME about the set of digits
+            // that was selected.
+            mInputType = inputType != EditorInfo.TYPE_NULL
+                    ? inputType : EditorInfo.TYPE_CLASS_TEXT;
         } else if (inputType != EditorInfo.TYPE_NULL) {
             setInputType(inputType, true);
             singleLine = (inputType&(EditorInfo.TYPE_MASK_CLASS
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index fd5271e..50df0f7 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -1,4 +1,25 @@
+/*
+**
+** Copyright 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.
+*/
+
+#define LOG_TAG "9patch"
+#define LOG_NDEBUG 1
+
 #include <utils/ResourceTypes.h>
+#include <utils/Log.h>
 
 #include "SkCanvas.h"
 #include "SkRegion.h"
@@ -62,6 +83,9 @@
             
             if (destDensity == srcDensity || destDensity == 0
                     || srcDensity == 0) {
+                LOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)",
+                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
+                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom));
                 NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
             } else {
                 canvas->save();
@@ -74,6 +98,11 @@
                 bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
                 bounds.fLeft = bounds.fTop = 0;
     
+                LOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
+                        SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
+                        SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom),
+                        srcDensity, destDensity);
+                
                 NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
     
                 canvas->restore();
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index f82053c..ff24a87 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -16,8 +16,10 @@
 */
 
 #define LOG_TAG "NinePatch"
+#define LOG_NDEBUG 1
 
 #include <utils/ResourceTypes.h>
+#include <utils/Log.h>
 
 #include "SkBitmap.h"
 #include "SkCanvas.h"
@@ -25,7 +27,7 @@
 #include "SkPaint.h"
 #include "SkUnPreMultiply.h"
 
-#define USE_TRACEx
+#define USE_TRACE
 
 #ifdef USE_TRACE
     static bool gTrace;
@@ -106,6 +108,13 @@
     if (canvas && canvas->quickReject(bounds, SkCanvas::kBW_EdgeType)) {
         return;
     }
+
+    SkPaint defaultPaint;
+    if (NULL == paint) {
+        // matches default dither in NinePatchDrawable.java.
+        defaultPaint.setDither(true);
+        paint = &defaultPaint;
+    }
     
     // if our canvas is GL, draw this as a mesh, which will be faster than
     // in parts (which is faster for raster)
@@ -123,10 +132,10 @@
 
     SkASSERT(canvas || outRegion);
 
-#if 0
+#ifdef USE_TRACE
     if (canvas) {
         const SkMatrix& m = canvas->getTotalMatrix();
-        SkDebugf("ninepatch [%g %g %g] [%g %g %g]\n",
+        LOGV("ninepatch [%g %g %g] [%g %g %g]\n",
                  SkScalarToFloat(m[0]), SkScalarToFloat(m[1]), SkScalarToFloat(m[2]),
                  SkScalarToFloat(m[3]), SkScalarToFloat(m[4]), SkScalarToFloat(m[5]));
     }
@@ -134,10 +143,10 @@
 
 #ifdef USE_TRACE
     if (gTrace) {
-        SkDEBUGF(("======== ninepatch bounds [%g %g]\n", SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height())));
-        SkDEBUGF(("======== ninepatch paint bm [%d,%d]\n", bitmap.width(), bitmap.height()));
-        SkDEBUGF(("======== ninepatch xDivs [%d,%d]\n", chunk.xDivs[0], chunk.xDivs[1]));
-        SkDEBUGF(("======== ninepatch yDivs [%d,%d]\n", chunk.yDivs[0], chunk.yDivs[1]));
+        LOGV("======== ninepatch bounds [%g %g]\n", SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height()));
+        LOGV("======== ninepatch paint bm [%d,%d]\n", bitmap.width(), bitmap.height());
+        LOGV("======== ninepatch xDivs [%d,%d]\n", chunk.xDivs[0], chunk.xDivs[1]);
+        LOGV("======== ninepatch yDivs [%d,%d]\n", chunk.yDivs[0], chunk.yDivs[1]);
     }
 #endif
 
@@ -146,7 +155,7 @@
         (paint && paint->getXfermode() == NULL && paint->getAlpha() == 0))
     {
 #ifdef USE_TRACE
-        if (gTrace) SkDEBUGF(("======== abort ninepatch draw\n"));
+        if (gTrace) LOGV("======== abort ninepatch draw\n");
 #endif
         return;
     }
@@ -158,11 +167,6 @@
     if (bitmap.getPixels() == NULL)
         return;
 
-    SkPaint defaultPaint;
-    if (NULL == paint) {
-        paint = &defaultPaint;
-    }
-
     const bool hasXfer = paint->getXfermode() != NULL;
     SkRect      dst;
     SkIRect     src;
@@ -196,8 +200,8 @@
     }
     int numFixedYPixelsRemaining = bitmapHeight - numStretchyYPixelsRemaining;
 
-#if 0
-    SkDebugf("NinePatch [%d %d] bounds [%g %g %g %g] divs [%d %d]\n",
+#ifdef USE_TRACE
+    LOGV("NinePatch [%d %d] bounds [%g %g %g %g] divs [%d %d]\n",
              bitmap.width(), bitmap.height(),
              SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop),
              SkScalarToFloat(bounds.width()), SkScalarToFloat(bounds.height()),
@@ -300,13 +304,13 @@
                 goto nextDiv;
             }
             if (canvas) {
-#if 0
-                SkDebugf("-- src [%d %d %d %d] dst [%g %g %g %g]\n",
+#ifdef USE_TRACE
+                LOGV("-- src [%d %d %d %d] dst [%g %g %g %g]\n",
                          src.fLeft, src.fTop, src.width(), src.height(),
                          SkScalarToFloat(dst.fLeft), SkScalarToFloat(dst.fTop),
                          SkScalarToFloat(dst.width()), SkScalarToFloat(dst.height()));
                 if (2 == src.width() && SkIntToScalar(5) == dst.width()) {
-                    SkDebugf("--- skip patch\n");
+                    LOGV("--- skip patch\n");
                 }
 #endif
                 drawStretchyPatch(canvas, src, dst, bitmap, *paint, initColor,
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 8fe7487..e703ed8 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -45,13 +45,16 @@
 static jmethodID method_onDeviceDisappeared;
 static jmethodID method_onDeviceCreated;
 static jmethodID method_onDeviceRemoved;
+static jmethodID method_onDeviceDisconnectRequested;
 
 static jmethodID method_onCreatePairedDeviceResult;
 static jmethodID method_onGetDeviceServiceChannelResult;
 
 static jmethodID method_onRequestPinCode;
 static jmethodID method_onRequestPasskey;
-static jmethodID method_onRequestConfirmation;
+static jmethodID method_onRequestPasskeyConfirmation;
+static jmethodID method_onRequestPairingConsent;
+static jmethodID method_onDisplayPasskey;
 static jmethodID method_onAgentAuthorize;
 static jmethodID method_onAgentCancel;
 
@@ -84,6 +87,8 @@
                                                   "(Ljava/lang/String;)V");
     method_onDeviceCreated = env->GetMethodID(clazz, "onDeviceCreated", "(Ljava/lang/String;)V");
     method_onDeviceRemoved = env->GetMethodID(clazz, "onDeviceRemoved", "(Ljava/lang/String;)V");
+    method_onDeviceDisconnectRequested = env->GetMethodID(clazz, "onDeviceDisconnectRequested",
+                                                        "(Ljava/lang/String;)V");
 
     method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
                                                          "(Ljava/lang/String;I)V");
@@ -95,7 +100,11 @@
                                                "(Ljava/lang/String;I)V");
     method_onRequestPasskey = env->GetMethodID(clazz, "onRequestPasskey",
                                                "(Ljava/lang/String;I)V");
-    method_onRequestConfirmation = env->GetMethodID(clazz, "onRequestConfirmation",
+    method_onRequestPasskeyConfirmation = env->GetMethodID(clazz, "onRequestPasskeyConfirmation",
+                                               "(Ljava/lang/String;II)V");
+    method_onRequestPairingConsent = env->GetMethodID(clazz, "onRequestPairingConsent",
+                                               "(Ljava/lang/String;I)V");
+    method_onDisplayPasskey = env->GetMethodID(clazz, "onDisplayPasskey",
                                                "(Ljava/lang/String;II)V");
 
     field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
@@ -227,7 +236,7 @@
 
 
 const char * get_adapter_path(DBusConnection *conn) {
-    DBusMessage *msg, *reply = NULL;
+    DBusMessage *msg = NULL, *reply = NULL;
     DBusError err;
     const char *device_path = NULL;
     int attempt = 0;
@@ -815,6 +824,14 @@
                             str_array);
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         goto success;
+    } else if (dbus_message_is_signal(msg,
+                                      "org.bluez.Device",
+                                      "DisconnectRequested")) {
+        const char *remote_device_path = dbus_message_get_path(msg);
+        env->CallVoidMethod(nat->me,
+                            method_onDeviceDisconnectRequested,
+                            env->NewStringUTF(remote_device_path));
+        goto success;
     }
 
     ret = a2dp_event_filter(msg, env);
@@ -845,9 +862,7 @@
 
     if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "Cancel")) {
-
         env->CallVoidMethod(nat->me, method_onAgentCancel);
-
         // reply
         DBusMessage *reply = dbus_message_new_method_return(msg);
         if (!reply) {
@@ -928,6 +943,24 @@
                                        int(msg));
         goto success;
     } else if (dbus_message_is_method_call(msg,
+            "org.bluez.Agent", "DisplayPasskey")) {
+        char *object_path;
+        uint32_t passkey;
+        if (!dbus_message_get_args(msg, NULL,
+                                   DBUS_TYPE_OBJECT_PATH, &object_path,
+                                   DBUS_TYPE_UINT32, &passkey,
+                                   DBUS_TYPE_INVALID)) {
+            LOGE("%s: Invalid arguments for RequestPasskey() method", __FUNCTION__);
+            goto failure;
+        }
+
+        dbus_message_ref(msg);  // increment refcount because we pass to java
+        env->CallVoidMethod(nat->me, method_onDisplayPasskey,
+                                       env->NewStringUTF(object_path),
+                                       passkey,
+                                       int(msg));
+        goto success;
+    } else if (dbus_message_is_method_call(msg,
             "org.bluez.Agent", "RequestConfirmation")) {
         char *object_path;
         uint32_t passkey;
@@ -940,12 +973,27 @@
         }
 
         dbus_message_ref(msg);  // increment refcount because we pass to java
-        env->CallVoidMethod(nat->me, method_onRequestConfirmation,
+        env->CallVoidMethod(nat->me, method_onRequestPasskeyConfirmation,
                                        env->NewStringUTF(object_path),
                                        passkey,
                                        int(msg));
         goto success;
     } else if (dbus_message_is_method_call(msg,
+            "org.bluez.Agent", "RequestPairingConsent")) {
+        char *object_path;
+        if (!dbus_message_get_args(msg, NULL,
+                                   DBUS_TYPE_OBJECT_PATH, &object_path,
+                                   DBUS_TYPE_INVALID)) {
+            LOGE("%s: Invalid arguments for RequestPairingConsent() method", __FUNCTION__);
+            goto failure;
+        }
+
+        dbus_message_ref(msg);  // increment refcount because we pass to java
+        env->CallVoidMethod(nat->me, method_onRequestPairingConsent,
+                                       env->NewStringUTF(object_path),
+                                       int(msg));
+        goto success;
+    } else if (dbus_message_is_method_call(msg,
                   "org.bluez.Agent", "Release")) {
         // reply
         DBusMessage *reply = dbus_message_new_method_return(msg);
@@ -981,6 +1029,8 @@
 #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__);
@@ -1026,6 +1076,12 @@
                    !strcmp(err.message, "Discover in progress")) {
             LOGV("... error = %s (%s)\n", err.name, err.message);
             result = BOND_RESULT_DISCOVERY_IN_PROGRESS;
+        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.RepeatedAttempts")) {
+            LOGV("... error = %s (%s)\n", err.name, err.message);
+            result = BOND_RESULT_REPEATED_ATTEMPTS;
+        } else if (!strcmp(err.name, BLUEZ_DBUS_BASE_IFC ".Error.AuthenticationTimeout")) {
+            LOGV("... error = %s (%s)\n", err.name, err.message);
+            result = BOND_RESULT_AUTH_TIMEOUT;
         } else {
             LOGE("%s: D-Bus error: %s (%s)\n", __FUNCTION__, err.name, err.message);
             result = BOND_RESULT_ERROR;
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index de921f1..0b71acb 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -455,8 +455,8 @@
         }
 
         if (!reply) {
-            LOGE("%s: Cannot create message reply to RequestConfirmation to "
-                 "D-Bus\n", __FUNCTION__);
+            LOGE("%s: Cannot create message reply to RequestPasskeyConfirmation or"
+                  "RequestPairingConsent to D-Bus\n", __FUNCTION__);
             dbus_message_unref(msg);
             return JNI_FALSE;
         }
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1fcfe63d..568ed92 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2838,9 +2838,11 @@
         For a more in-depth discussion of search configuration, please refer to
         {@link android.app.SearchManager}. -->
     <declare-styleable name="Searchable">
-        <!-- If provided, this icon will be shown in place of the label.  It is typically used
-             in order to identify a searchable application via a logo or branding, instead of
-             plain text.  This is a reference to a drawable (icon) resource.
+        <!-- If provided, this icon will be shown in place of the label above the search box.
+             This is a reference to a drawable (icon) resource. Note that the application icon
+             is also used as an icon to the left of the search box and you cannot modify this
+             behavior, so including the icon attribute is unecessary and this may be
+             deprecated in the future.
              <i>Optional attribute.</i> -->
         <attr name="icon" />
         <!-- This is the user-displayed name of the searchable activity.  <i>Required
@@ -3438,6 +3440,10 @@
         <attr name="label"/>
         <!-- the icon of the authenticator. -->
         <attr name="icon"/>
+        <!-- smaller icon of the authenticator -->
+        <attr name="smallIcon" format="reference"/>
+        <!-- a preferences.xml file for authenticator-specific settings -->
+        <attr name="accountPreferences" format="reference"/>
     </declare-styleable>
 
     <!-- =============================== -->
@@ -3469,4 +3475,3 @@
     </declare-styleable>
 
 </resources>
-
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 6ef6f52..cac26b9 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -65,4 +65,6 @@
   <item type="id" name="startSelectingText" />
   <item type="id" name="stopSelectingText" />
   <item type="id" name="addToDictionary" />
+  <item type="id" name="accountPreferences" />
+  <item type="id" name="smallIcon" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 8541c73..c4636f3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1162,6 +1162,8 @@
   <public type="attr" name="supportsUploading" />
   <public type="attr" name="killAfterRestore" />
   <public type="attr" name="restoreNeedsApplication" />
+  <public type="attr" name="smallIcon" />
+  <public type="attr" name="accountPreferences" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index a4dcc5e..acf6899 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -100,8 +100,7 @@
 <li>It lets applications describe the framework API revision that they
 require</li>
 <li>It lets the system negotiate the installation of applications on the user's
-device, such that version-incompatible applications are not installed on a
-user's device</li>
+device, such that version-incompatible applications are not installed.</li>
 </ul>
 
 <p>Each Android platform version stores its API Level identifier internally, in
@@ -137,7 +136,7 @@
 the system assumes that the application requires API Level 1. </li>
 <li>If a <code>android:maxSdkVersion</code> attribute is declared, its value
 must be equal to or greater than the system's API Level integer. 
-in the system itself. If not declared, the system assumes that the application
+If not declared, the system assumes that the application
 has no maximum API Level. </li>
 </ul>
 
@@ -154,7 +153,7 @@
 <code>android:minSdkVersion</code> is to tell the Android system that it is
 using APIs that were <em>introduced</em> in the API Level specified. If the
 application were to be somehow installed on a platform with a lower API Level,
-then it would crash at run-time when it tries to access APIs that don't exist.
+then it would crash at run-time when it tried to access APIs that don't exist.
 The system prevents such an outcome by not allowing the application to be
 installed if the lowest API Level it requires is higher than that of the
 platform version on the target device.</p>
@@ -194,7 +193,7 @@
 application and use it successfully, then later receive an OTA update to a new
 version of the Android platform. Once the update is installed, your application
 will run in a new run-time version of the environment, but one that has the API
-and system capabilities that it depends on. </p>
+and system capabilities that your application depends on. </p>
 
 <p>In some cases, changes <em>below</em> the API, such those in the underlying
 system itself, may affect your application when it is run in the new
@@ -222,8 +221,8 @@
 <p>Although it's unlikely that an Android-powered device would be downgraded to
 a previous version of the platform, it's important to realize that there are
 likely to be many devices in the field that run earlier versions of the
-platform. Even among devices that receive OTA updates, some might lag and not
-receive an update for a significant amount of time. </p>
+platform. Even among devices that receive OTA updates, some might lag and
+might not receive an update for a significant amount of time. </p>
 
 <h3 id="platform">Selecting a platform version and API Level</h3>
 
@@ -285,39 +284,32 @@
 of the Android platform it runs. See the table at the top of this document for
 a list of platform versions and their API Levels. </p>
 
-<!--
-The Framework API makeup: the API available in a specific platform version is
-made up of API parts introduced in previous versions, plus some parts that are
-new.
--->
 
 <h2 id="filtering">Filtering the Reference Documentation by API Level</h2>
 
 <p>Reference documentation pages on the Android Developers site offer a "Filter
-by API Level" control in the top-right area of each page. </p>
+by API Level" control in the top-right area of each page. You can use the 
+control to show documentation only for parts of the API that are actually 
+accessible to your application, based on the API Level that it specifies in 
+the <code>android:minSdkVersion</code> attribute of its manifest file. </p>
 
-<p>The "Filter by API Level" lets you show documentation only for parts of the
-API that are actually accessible to your application, based on the API Level
-that it specifies in the <code>minSdkVersion</code> attribute in its manifest 
-file </p>
+<p>To use filtering, set the control to the same API Level as that specified
+by your application. Notice that APIs introduced in a later API Level are 
+then grayed out and their content is masked, since they would not be
+accessible to your application. </p>
 
-<p>When you filter the reference documentation by an API level, only the APIs
-available at that API level are shown. APIs introduced in a later API level are
-grayed out and their content is masked, since they would not be accessible to
-your application. </p>
-
-<p>Note that filtering by API Level in the documentation does not provide a view
-of what is new or introduced in each API Level. Filtering simply provides a way
+<p>Filtering by API Level in the documentation does not provide a view
+of what is new or introduced in each API Level &mdash; it simply provides a way
 to view the entire API associated with a given API Level, while excluding API
 elements introduced in later API Levels.</p>
 
 <p>By default, API Level filtering is enabled and set to show the latest API
-Level. If you do not want to use filtering reference documentation, select the
-highest available API Level.</p>
+Level. If you do not want to use filtering reference documentation, 
+simply select the highest available API Level. </p>
 
-<p>Note that the reference documentation for API elements also specifies the API
-Level at which the element was introduced. The API Level for packages and
-classes is specified as "Since &lt;api level&gt;" at the top-right corner of the
-content area on each documentation page. The API Level for each class member is
-specified in the member's detailed description section header, at the right
-margin. </p>
+<p>Also note that the reference documentation for individual API elements
+specifies the API Level at which the elements were introduced. The API Level 
+for packages and classes is specified as "Since &lt;api level&gt;" at the 
+top-right corner of the content area on each documentation page. The API Level 
+for class members is specified in their detailed description headers, 
+at the right margin. </p>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index ee8d03d..aa1e8ae 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -36,30 +36,27 @@
 <dd>
 <dl class="attr">
   <dt><a name="min"></a>{@code android:minSdkVersion}</dt>
-  <dd>An integer designating the minimum level of the Android API that's required 
-  for the application to run.
+  <dd>An integer designating the minimum API Level required
+  for the application to run. The Android system will prevent the user from installing
+  the application if the system's API Level is lower than the value specified in
+  this attribute. You should always declare this attribute.
   
-  <p>Prior to installing an application, the Android system checks the value of this
-  attribute and allows the installation only if it
-  is less than or equal to the API Level used by the system itself.</p>
-  
-  <p>If you do not declare this attribute, then a value of "1" is assumed, which
+  <p class="caution"><strong>Caution:</strong>
+  If you do not declare this attribute, then a value of "1" is assumed, which
   indicates that your application is compatible with all versions of Android. If your
-  application is <em>not</em> universally compatible (for instance if it uses APIs
-  introduced in Android 1.5) and you have not declared the proper <code>minSdkVersion</code>, 
-  then when installed on a system with a lower API Level, the application 
-  will crash during runtime. For this reason, be certain to declare the appropriate API Level
+  application is <em>not</em> compatible with all versions (for instance, it uses APIs
+  introduced in API Level 3) and you have not declared the proper <code>minSdkVersion</code>,
+  then when installed on a system with an API Level less than 3, the application will crash
+  during runtime when attempting to access the unavailable APIs. For this reason, 
+  be certain to declare the appropriate API Level
   in the <code>minSdkVersion</code> attribute.</p>
   </dd>
   
   <dt><a name="max"></a>{@code android:maxSdkVersion}</dt>
-  <dd>An integer designating the maximum level of the Android API that the application is 
-  compatible with. You can use this to ensure your application is filtered out
-  of later versions of the platform when you know you have incompatibility with them.</p>
-  
-  <p>Prior to installing an application, the Android system checks the value of this
-  attribute and allows the installation only it
-  is greater than or equal to the API Level used by the system itself.</p>
+  <dd>An integer designating the maximum API Level on which the application is 
+  designed to run. The Android system will prevent the user from installing the 
+  application if the system's API Level is higher than the value specified
+  in this attribute. 
   
   <p>Introduced in: API Level 4</p>
   </dd>
diff --git a/docs/html/guide/topics/resources/available-resources.jd b/docs/html/guide/topics/resources/available-resources.jd
index 2a6a6ac..0dfc625 100644
--- a/docs/html/guide/topics/resources/available-resources.jd
+++ b/docs/html/guide/topics/resources/available-resources.jd
@@ -36,6 +36,7 @@
       </ol>
     </li>
     <li><a href="#stylesandthemes">Styles and Themes</a></li>
+    <li><a href="#Searchable">Searchable</a></li>
   </ol>
 
 </div>
@@ -86,7 +87,7 @@
     <code>&lt;color&gt;</code> tags.
 </p>
 <p>
-    <strong>Resource source file location</strong>: res/values/<em>colors</em>.xml (file name is arbitrary)
+    <strong>Resource source file location</strong>: {@code res/values/<em>colors</em>.xml} (File name is arbitrary.)
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a Java int.
@@ -183,7 +184,7 @@
     <strong>Source file format:</strong> XML file requiring a <code>&lt;?xml version="1.0" encoding="utf-8"?&gt;</code> declaration, and a root <code>&lt;resources&gt;</code> element containing one or more <code>&lt;string&gt;</code> tags.
 </p>
 <p>
-    <strong>Resource source file location</strong>: res/values/<em>strings</em>.xml (file name is arbitrary)
+    <strong>Resource source file location</strong>: {@code res/values/<em>strings</em>.xml} (File name is arbitrary.)
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a Java CharSequence.
@@ -338,8 +339,8 @@
 <code>&lt;resources&gt;</code> element containing one or more
 <code>&lt;dimen&gt;</code> tags.</p>
 
-<p><strong>Resource source file location</strong>: res/values/dimens.xml (File
-name is arbitrary; standard practice is to put all dimensions in one file
+<p><strong>Resource source file location</strong>: {@code res/values/dimens.xml} (File
+name is arbitrary, but standard practice is to put all dimensions in one file
 devoted to dimensions.)</p>
 <p><strong>Compiled resource datatype:</strong> Resource pointer to a
 dimension.</p>
@@ -424,7 +425,7 @@
     <strong>Source file formats:</strong> png (preferred), jpg (acceptable), gif (discouraged). One resource per file.
 </p>
 <p>
-    <strong>Resource file location</strong>: res/drawable/<em>some_file</em>.png or <em>some_file</em>.jpg or <em>some_file</em>.gif.
+    <strong>Resource file location</strong>: {@code res/drawable/<em>some_file</em>.png}
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a {@link android.graphics.drawable.BitmapDrawable BitmapDrawable}.
@@ -453,7 +454,8 @@
 <code>&lt;resources&gt;</code> element containing one or more
 <code>&lt;drawable&gt;</code> tags.</p>
 <p>
-    <strong>Resource source file location</strong>: res/values/colors.xml (File name is arbitrary; standard practice is to put the PaintDrawable items in the file along with the <a href="resources-i18n.html#numericcolorresources">numeric color values</a>.)
+    <strong>Resource source file location</strong>: {@code res/values/colors.xml} (File name is arbitrary, but standard practice is to put the PaintDrawable 
+    items in the file along with the <a href="resources-i18n.html#numericcolorresources">numeric color values</a>.)
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a {@link android.graphics.drawable.PaintDrawable}.
@@ -540,7 +542,7 @@
     <strong>Source file format:</strong> PNG &mdash; one resource per file
 </p>
 <p>
-    <strong>Resource source file location</strong>: res/drawable/<em>some_name</em>.9.png (must end in .9.png)
+    <strong>Resource source file location</strong>: {@code res/drawable/<em>some_name</em>.9.png} (Filename must end in {@code .9.png})
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a {@link android.graphics.drawable.NinePatchDrawable NinePatchDrawable}.
@@ -573,7 +575,7 @@
     <strong>Source file format:</strong> XML file, one resource per file, one root tag with no <code>&lt;?xml&gt;</code> declaration
 </p>
 <p>
-    <strong>Resource file location</strong>: res/anim/<em>some_file</em>.xml
+    <strong>Resource file location</strong>: {@code res/anim/<em>some_file</em>.xml}
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to an {@link android.view.animation.Animation}.
@@ -1055,7 +1057,7 @@
     <strong>Source file format:</strong> XML file without an <code>&lt;?xml&gt;</code> declaration, and a <code>&lt;resources&gt;</code> root element containing one or more custom element tags.
 </p>
 <p>
-    <strong>Resource file location</strong>: res/values/<em>attrs</em>.xml (file name is arbitrary).
+    <strong>Resource file location</strong>: {@code res/values/<em>attrs</em>.xml} (File name is arbitrary.)
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a {@link android.view.View} (or subclass) resource.
@@ -1084,7 +1086,7 @@
     <strong>Source file format:</strong> XML file requiring a <code>&lt;?xml version="1.0" encoding="utf-8"?&gt;</code> declaration, and a root <code>&lt;resources&gt;</code> element containing one or more <code>&lt;style&gt;</code> tags.
 </p>
 <p>
-    <strong>Resource source file location</strong>: res/values/styles.xml (file name is arbitrary). The file name is arbitrary, but standard practice is to put all styles into a file named styles.xml.
+    <strong>Resource source file location</strong>: {@code res/values/styles.xml} (File name is arbitrary, but standard practice is to put all styles into a file named styles.xml.)
 </p>
 <p>
     <strong>Compiled resource datatype:</strong> Resource pointer to a Java CharSequence.
@@ -1133,3 +1135,317 @@
 
 <p>For examples of how to declare and apply styles and themes, read 
 <a href="{@docRoot}guide/topics/ui/themes.html">Applying Styles and Themes</a>.</p>
+
+
+
+<h2 id="Searchable">Searchable</h2>
+
+<p>To make search appear to the user as a seamless system-wide feature, the Android framework 
+offers APIs that let applications control how they are searched.
+Applications can customize how search is invoked, how the search dialog looks, and what type of 
+search results are available, including suggestions that are shown as the user types.</p>
+
+<p>In order to utilize the Android search framework, an application must provide a search configuration
+in the form of an XML resource.
+This section describes the search configuration XML in terms of its syntax and usage. For a more
+complete discussion about how to implement search features for your application, see
+<!-- <a href="{@docRoot}guide/topics/search/index.html">Search</a> -->
+{@link android.app.SearchManager}.</p>
+
+<p>
+  <strong>Source file format:</strong> 
+  XML file requiring a <code>&lt;?xml version="1.0" encoding="utf-8"?&gt;</code> 
+  declaration, and a root <code>&lt;searchable&gt;</code> element.
+</p>
+
+<p>
+  <strong>Resource source file location</strong>: {@code res/xml/searchable.xml} 
+  (The file name is arbitrary, but standard practice is to use searchable.xml.)
+</p>
+
+<p>
+  <strong>Compiled resource datatype:</strong> 
+  Resource pointer to an xml object.
+</p>
+
+<p>
+  <strong>Resource reference name:</strong>
+</p>
+
+<ul>
+  <li>
+    <strong>Java:</strong> 
+    <code>R.xml.<em>filename</em></code>.
+  </li>
+  <li>
+    <strong>XML:</strong> 
+    <code>@[<em>package</em>:]xml/<em>filename</em></code> (e.g., <code>@xml/searchable</code>).
+  </li>
+</ul>
+
+<p>
+  <strong>Syntax</strong>
+</p>
+
+<pre>
+&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android
+     android:label="@string/search_label" 
+     ... &gt;
+     <em>&lt;actionkey
+          android:keycode="KEYCODE_CALL"
+          ... &gt;</em>     
+&lt;/searchable&gt;
+</pre>
+
+<dl>
+  <dt>
+    &lt;searchable&gt;
+  </dt>
+  <dd>
+    Defines all application search configurations, including settings for text and voice searches
+    performed within the application. It accepts the following attributes:
+    <ul>
+      <li>
+        <em>label</em> - <strong>Required</strong>. This is the name for your application, as it 
+        will appear to the user. This will be visible only if <em>searchMode</em> is set to 
+        "showSearchLabelAsBadge" (see below).
+      </li>
+      <li>
+        <em>hint</em> -	This is the text to display in the search text field when no text has 
+        been entered. This is recommended in order to provide context to the search about to be 
+        performed (e.g., "Search the Dictionary").
+      </li>
+      <li>
+        <em>searchMode</em> - If provided and non-zero, this sets additional modes for control
+        of the search presentation. The following mode values are accepted: 
+        <ul>
+          <li>
+            <em>showSearchLabelAsBadge</em> - If set, this enables the display of the 
+            search target (label) within the search bar.
+          </li>
+          <li>
+            <em>queryRewriteFromData</em> - If set, this causes the suggestion column 
+            SUGGEST_COLUMN_INTENT_DATA to be considered as the text for suggestion query 
+            rewriting. This should only be used when the values in 
+            SUGGEST_COLUMN_INTENT_DATA are suitable for user inspection and editing -
+            typically, HTTP/HTTPS Uri's.
+          </li>
+          <li>
+            <em>queryRewriteFromText</em> - If set, this causes the suggestion 
+            column SUGGEST_COLUMN_TEXT_1 to be considered as the text for suggestion query
+            rewriting. This should be used for suggestions in which no query 
+            text is provided and the SUGGEST_COLUMN_INTENT_DATA values are not suitable 
+            for user inspection and editing.
+          </li>
+        </ul>
+        <p>More than one of the above values for <em>searchMode</em> can be used at once. For 
+        example, you can declare two modes at once, like this:
+        <code>searchMode="queryRewriteFromData|queryRewriteFromText"</code>
+      </li>
+      <li>
+        <em>inputType</em> - If provided, supplies a hint about the type of search text 
+        the user will be entering. For most searches, in which free form text is expected, 
+        this attribute is not needed. See
+        {@link android.R.attr#inputType} for a list of suitable values for this attribute.
+      </li>
+      <li>
+        <em>imeOptions</em> - If provided, supplies additional options for the input method. 
+        For most searches, in  which free form text is expected, this attribute is not needed, 
+        and will default to "actionSearch". See 
+        {@link android.R.attr#imeOptions} for a list of suitable values for this attribute.
+      </li>
+    </ul>
+    
+    <p>If you have defined a content provider to generate search suggestions, you need to
+    provide some more searchable metadata in order to configure communications with the content
+    provider. The following are additional {@code &lt;searchable>} attributes for use when 
+    providing search suggestions:</p>
+    
+    <ul>
+      <li>
+        <em>searchSuggestAuthority</em> - <strong>Required to provide search suggestions</strong>. 
+        This value must match the authority string provided in the provider section of your manifest.
+      </li>
+      <li>
+        <em>searchSuggestPath</em> - If provided, this path will be inserted in the suggestions 
+        query Uri, after the authority you have provide but before the standard suggestions path.
+        This is only required if you have a single content provider issuing different types 
+        of suggestions (e.g. for different data types) and you need 
+        a way to disambiguate the suggestions queries when they are received.
+      </li>
+      <li>
+        <em>searchSuggestSelection</em> - If provided, this value will be passed into your 
+        query function as the selection parameter. Typically this will be a WHERE clause for 
+        your database, and will contain a single question mark, which represents the actual query
+        string that has been typed by the user. However, you can also use any non-null value to simply
+        trigger the delivery of the query text (via selection arguments), and then use the query 
+        text in any way appropriate for your provider (ignoring the actual text of the selection parameter.)
+      </li>
+      <li>
+        <em>searchSuggestIntentAction</em> - The default Intent action to be used when a user 
+        clicks on a search suggestion.
+        If provided, and not overridden by the selected suggestion, this value will 
+        be placed in the action field of the {@link android.content.Intent} when the 
+        user clicks a suggestion.
+      </li>
+      <li>
+        <em>searchSuggestIntentData</em> - The default Intent data to be used when a user 
+        clicks on a search suggestion.
+        If provided, and not overridden by the selected suggestion, this value will be 
+        placed in the data field of the {@link android.content.Intent} when the user clicks 
+        a suggestion.
+      </li>
+    </ul>
+    
+    <p>Beyond providing search suggestions while using your application's local search, you 
+    can also configure your search suggestions to be made available to Quick Search Box, 
+    which will allow users so receive search suggestions from your application content from outside
+    your application. The following are additional {@code &lt;searchable>} attributes for use when 
+    providing search suggestions to Quick Search Box:</p>
+    
+    <ul>
+      <li>
+        <em>includeInGlobalSearch</em> - <strong>Required to provide search suggestions in
+        Quick Search Box</strong>. If true, this indicates the search suggestions provided by your 
+        application should be included in the globally accessible Quick Search Box. The user must
+        still enable your application as a searchable item in the system search settings in order
+        for your suggestions to appear in Quick Search Box.
+      </li>
+      <li>
+        <em>searchSettingsDescription</em> - If provided, this provides a brief description
+        of the search suggestions that you provide to Quick Search Box, 
+        and will be displayed in the search settings entry for your application.
+      </li>
+      <li>
+        <em>queryAfterZeroResults</em> - Indicates whether a source should be invoked for 
+        supersets of queries it has returned zero results for in the past. For example, if a
+        source returned zero results for "bo", it would be ignored for "bob". If set to false,
+        this source will only be ignored for a single session; the next time the search dialog
+        is invoked, all sources will be queried. The default value is false.
+      </li>
+      <li>
+        <em>searchSuggestThreshold</em> - Indicates the minimum number of characters needed to
+        trigger a source lookup from Quick Search Box. Only guarantees that a source will not be
+        queried for anything shorter than the threshold. The default value is 0.
+      </li>
+    </ul>
+    
+    <p>To enable voice search for your Activity, you can add fields to the searchable metadata 
+    that enable and configure voice search. The following are additional {@code &lt;searchable>} 
+    attributes for use when implementing voice search:</p>
+    
+    <ul>
+        <li>
+          <em>voiceSearchMode</em> -  <strong>Required to provide voice search 
+          capabilities</strong>. 
+          If provided and non-zero, enables voice search. 
+          (Voice search may not be provided by the device, in which case these flags will
+          have no effect.) The following mode values are accepted:
+          <ul>
+            <li>
+              <em>showVoiceSearchButton</em> - If set, display a voice search button. This only 
+              takes effect if voice search is available on the device. If set, then "launchWebSearch" 
+              or "launchRecognizer" must also be set.
+            </li>
+            <li>
+              <em>launchWebSearch</em> - If set, the voice search button will take the user directly 
+              to a built-in voice web search activity. Most applications will not use this flag, as 
+              it will take the user away from the activity in which search was invoked.
+            </li>
+            <li>
+              <em>launchRecognizer</em> - If set, the voice search button will take 
+              the user directly to a built-in voice recording activity. This activity 
+              will prompt the user to speak, transcribe the spoken text, and forward the resulting 
+              query text to the searchable activity, just as if the user had typed it into the 
+              search UI and clicked the search button.
+            </li>
+          </ul>
+        </li>
+        <li>
+          <em>voiceLanguageModel</em> - A string constant from 
+          {@link android.speech.RecognizerIntent}.
+          If provided, this specifies the language model that 
+          should be used by the voice recognition system. See 
+          {@link android.speech.RecognizerIntent#EXTRA_LANGUAGE_MODEL } for more 
+          information. If not provided, the default value 
+          {@link android.speech.RecognizerIntent#LANGUAGE_MODEL_FREE_FORM } will be used.
+        </li>
+        <li>
+          <em>voicePromptText</em> - A string. If provided, this specifies a prompt 
+          that will be displayed during voice input. If not provided, a default prompt 
+          will be displayed.
+        </li>
+        <li>
+          <em>voiceLanguage</em> - A string constant from {@link java.util.Locale}. 
+          If provided, this specifies the spoken language to be expected. 
+          This is only needed if it is different from the current value of 
+          {@link java.util.Locale#getDefault()}. 
+        </li>
+        <li>
+          <em>voiceMaxResults</em> - If provided, enforces the maximum number of results to return, 
+          including the "best" result which will always be provided as the SEARCH intent's primary 
+          query. Must be one or greater. Use EXTRA_RESULTS to get the results from the intent. 
+          If not provided, the recognizer will choose how many results to return.
+        </li>
+    </ul>
+  </dd>
+  
+  <dt>
+      &lt;actionkey&gt;
+  </dt>
+  <dd>
+    Defines a shortcut key for a search action.
+    <ul>
+      <li>
+        <em>keycode</em> - <strong>Required</strong>. This attribute denotes the action key
+        you wish to respond to. Note that not all action keys are actually supported using 
+        this mechanism, as many of them are used for typing, 
+        navigation, or system functions. This will be added to the 
+        {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is passed to your 
+        searchable Activity. To examine the key code, use 
+        {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}.
+        Note that, in addition to the keycode, you must also provide one or more of 
+        the action specifier attributes below.
+      </li>
+      <li>
+        <em>queryActionMsg</em> - If you wish to handle an action key during normal 
+        search query entry, you must define an action string here. This will be added to the
+        {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent that is 
+        passed to your searchable Activity. To examine the string, use 
+        {@link android.content.Intent#getStringExtra
+        getStringExtra(SearchManager.ACTION_MSG)}.
+      </li>
+      <li>
+        <em>suggestActionMsg</em> - If you wish to handle an action key while a 
+        suggestion is being displayed and selected, there are two ways to handle this. 
+        If all of your suggestions can handle the action key, you can simply define 
+        the action message using this attribute. This will be added to the 
+        {@link android.content.Intent#ACTION_SEARCH} Intent that is passed to your 
+        searchable Activity. To examine the string, 
+        use {@link android.content.Intent#getStringExtra 
+        getStringExtra(SearchManager.ACTION_MSG)}.
+      </li>
+      <li>
+        <em>suggestActionMsgColumn</em> - If you wish to handle an action key while
+        a suggestion is being displayed and selected, but you do not wish to enable
+        this action key for every suggestion, then you can use this attribute to control 
+        it on a suggestion-by-suggestion basis. First, you must define a column 
+        (and name it here) where your suggestions will include the action string. Then,
+        in your content provider, you must provide this column, and when desired, 
+        provide data in this column. The search manager will look at your suggestion cursor, 
+        using the string provided here in order to select a column, and will use 
+        that to select a string from the cursor. That string will be added to the 
+        {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} 
+        Intent that is passed to your searchable Activity. To examine 
+        the string, use {@link android.content.Intent#getStringExtra 
+        getStringExtra(SearchManager.ACTION_MSG)}. If the data does not exist for the 
+        selection suggestion, the action key will be ignored.
+      </li>
+    </ul>
+  </dd>
+</dl>
+
+
+
+
+
diff --git a/docs/html/intl/ja/index.jd b/docs/html/intl/ja/index.jd
index a5378c9..3ed2357 100644
--- a/docs/html/intl/ja/index.jd
+++ b/docs/html/intl/ja/index.jd
@@ -56,7 +56,7 @@
                                       <td>
                                               <h2 class="green">公開</h2>
                                               <p>Android マーケットは、アプリケーションを携帯端末に配信するためのオープン サービスです。</p>
-                                              <p><a href="http://www.android.com/market.html">詳細 &raquo;</a></p>
+                                              <p><a href="http://market.android.com/publish/Home">詳細 &raquo;</a></p>
                                       </td>
                               </tr>
                               <tr>
@@ -118,10 +118,10 @@
     'sdk': {
       'layout':"imgLeft",
       'icon':"sdk-small.png",
-      'name':"SDK 1.5 r3",
-      'img':"sdk-large.png",
-      'title':"Android 1.5 SDK",
-      'desc': "<p>Android 1.5 SDK の最新バージョンが公開されました。このリリースには Android 1.5 用の API、最新版デベロッパーツール、複数プラットフォーム(バージョン)サポート、そして Google API のアドオンが含まれています。</p><p><a href='{@docRoot}sdk/1.5_r3/index.html'>Android 1.5 SDK をダウンロード &raquo;</a></p>"
+      'name':"SDK 1.6 r1",
+      'img':"donut-android.png",
+      'title':"Android 1.6 SDK",
+      'desc': "<p>Android 1.6 SDK の最新バージョンが公開されました。このリリースには Android 1.6 用の API、最新版デベロッパーツール、複数プラットフォーム(バージョン)サポート、そして Google API のアドオンが含まれています。</p><p><a href='{@docRoot}sdk/1.6_r1/index.html'>Android 1.6 SDK をダウンロード &raquo;</a></p>"
     },
     
     'io': {
diff --git a/docs/html/sdk/1.6_r1/requirements.jd b/docs/html/sdk/1.6_r1/requirements.jd
index 781ee32..8e698fa 100644
--- a/docs/html/sdk/1.6_r1/requirements.jd
+++ b/docs/html/sdk/1.6_r1/requirements.jd
@@ -11,7 +11,7 @@
 <ul>
   <li>Windows XP (32-bit) or Vista (32- or 64-bit)</li>
   <li>Mac OS X 10.4.8 or later (x86 only)</li>
-  <li>Linux (tested on Linux Ubuntu Dapper Drake)</li>
+  <li>Linux (tested on Linux Ubuntu Hardy Heron)</li>
 </ul>
 
 <h3>Supported Development Environments</h3>
diff --git a/docs/html/sdk/1.6_r1/upgrading.jd b/docs/html/sdk/1.6_r1/upgrading.jd
index 2f9cc73..ebe6a95 100644
--- a/docs/html/sdk/1.6_r1/upgrading.jd
+++ b/docs/html/sdk/1.6_r1/upgrading.jd
@@ -219,7 +219,7 @@
 building in alternate support or graceful degradation, or you can specify them 
 as hardware requirements in a 
 <a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html"><code>&lt;uses-configuration&gt;</code>.</a>
-element in the application's manifest file. Also see the <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code>
+element in the application's manifest file. Also see the <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>
 manifest element, which lets your application declare a requirement for 
 specific features, such as an OpenGL ES version or a camera that has 
 autofocus capability.
@@ -258,7 +258,7 @@
 starting with Android 1.6, the platform provides a Compatibility Mode that
 automatically scales the UI of applications if they do not explicitly indicate
 support for the current screen in the 
-<a href="{@docRoot}guide/topics/manifest/supports-screen-element.html"><code>&lt;supports-screen&gt;</code>
+<a href="{@docRoot}guide/topics/manifest/supports-screen-element.html"><code>&lt;supports-screen&gt;</code></a>
 element in their manifest files. As part of testing, you should evaluate how
 your application is displayed in Compatibility Mode on different screens. </p>
   </li>
diff --git a/docs/html/sdk/android-1.6-highlights.jd b/docs/html/sdk/android-1.6-highlights.jd
index 882f117..74dcd9f 100644
--- a/docs/html/sdk/android-1.6-highlights.jd
+++ b/docs/html/sdk/android-1.6-highlights.jd
@@ -5,7 +5,8 @@
 
 
 <style type="text/css">
-#jd-content div.screenshot {
+#jd-content div.screenshot,
+#jd-content div.video {
   float:right;
   clear:right;
   padding:15px 70px;
@@ -13,11 +14,25 @@
   font-weight:bold;
   line-height:1.7em;
 }
+#jd-content div.video {
+  padding-top:0;
+  margin-top:-15px;
+}
 #jd-content div.screenshot img {
   margin:0;
 }
 </style>
 
+<div class="video">
+<object width="293" height="180">
+<param name="movie" value="http://www.youtube.com/v/MBRFkLKRwFw&hl=en&fs=1&"></param>
+<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
+<embed src="http://www.youtube.com/v/MBRFkLKRwFw&hl=en&fs=1&" type="application/x-shockwave-flash" 
+allowscriptaccess="always" allowfullscreen="true" width="293" height="180"></embed>
+</object>
+</div>
+
+
 <p>The Android 1.6 platform introduces new features for users and developers. 
 This page provides an overview of some new features and technologies.</p>
 
@@ -29,7 +44,7 @@
 
 
     
-<h2 id="UserFeatures">New User Features</h2>
+<h2 id="UserFeatures" style="clear:right">New User Features</h2>
 
 <!-- screenshots float right -->
 
diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd
index 29dceec..5dd2d95 100644
--- a/docs/html/sdk/android-1.6.jd
+++ b/docs/html/sdk/android-1.6.jd
@@ -11,7 +11,7 @@
 
 <ul>
 <li><a href="#overview">Overview</a>
-<li><a href="#features">New Features</a>
+<li><a href="#features">Release Highlights</a>
 <li><a href="#apps">Built-in Applications</a>
 <li><a href="#locs">Locales</a>
 <li><a href="#api-changes">API Changes</a>
@@ -20,9 +20,9 @@
 <h2 id="overview">Overview</h2>
 
 <p>The Android 1.6 system delivered in the SDK (as library and system image) is
-the development counterpart to the Android 1.6 production system image,
-deployable to Android-powered handsets starting September 2009. The system is fully
-compliant and includes no external libraries.</p>
+the development counterpart to the Android 1.6 production system image, which is
+deployable to Android-powered handsets starting October 2009. The system is
+fully compliant and includes no external libraries. </p>
 
 <p>The Android 1.6 system delivers an updated version of the framework
 API. As with previous versions, the Android 1.6 API 
@@ -32,11 +32,11 @@
 the system, prior to installing the application. </p>
 
 <p>For more information about how to use API Level, see the <a
-href="{@docRoot}guide/developing/">API Levels</a> document. </p>
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
 
-<h2 id="features">New Features</h2>
+<h2 id="features">Highlights</h2>
 
-<p>For a list of new system features, see the <a
+<p>For a list of new user features and platform highlights, see the <a
 href="http://developer.android.com/sdk/android-1.6-highlights.html">Android 1.6 Platform
 Highlights</a> document.</p>
 
@@ -139,22 +139,45 @@
 </tr>
 </table>
 
-<p>Localized UI strings match the locales that are displayable in 
-the emulator, accessible through the device Settings application.</p>
+<p>Localized UI strings match the locales that are accessible 
+through Settings.</p>
 
 <h2 id="api-changes">API Changes</h2>
 
-<h3 style="padding-top:0">Overview</h3>
+<h4 id="UIFramework">UI framework</h4>
+    <ul>
+      <li>New classes in {@link android.view.animation}
+      to control the behavior of animations:
+        <ul>
+          <li><code>AnticipateInterpolator</code></li>
+          <li><code>AnticipateOvershootInterpolator</code></li>
+          <li><code>BounceInterpolator</code></li>
+          <li><code>OvershootInterpolator</code></li>
+        </ul>
+      </li>
+      <li>New XML attribute <code>android:onClick</code> to specify a View's 
+<a href="/reference/android/view/View.OnClickListener.html">View.OnClickListener</a> 
+from a layout file.
+      </li>
+      <li>New support for dealing with varying screen densities. Density
+information is associated with Bitmap and Canvas for performing the
+correct scaling. The framework will automatically scale bitmaps and
+nine-patches based on the density the resource was found under and the
+density of the screen, etc.
+      </li>
+    </ul>
 
-<ul>
-
-<li>Search framework</li>
+<h4>Search framework</h4>
   <ul>
-    <li>Applications can now expose relevant content to users as search suggestions in the Quick Search Box, a new device-wide search capability that is accessible from the home screen. To support this, the search framework adds new attributes to the searchable metadata file. For complete information, see the {@link android.app.SearchManager SearchManager} documentation.</li>
+    <li>Applications can now expose relevant content to users as search
+suggestions in the Quick Search Box, a new device-wide search capability that is
+accessible from the home screen. To support this, the search framework adds new
+attributes to the searchable metadata file. For complete information, see the
+{@link android.app.SearchManager SearchManager} documentation.
+    </li>
   </ul>
-</li>
 
-<li>Accessibility framework</li>
+<h4>Accessibility framework</h4>
   <ul>
     <li>New {@link android.view.accessibility android.accessibility} package
 that includes classes for capturing accessibility events and forwarding them to
@@ -163,73 +186,139 @@
 that lets your application track user events and provide visual, audible, or
 haptic feedback to the user. </li>
   </ul>
-</li>
 
-<li>Gestures</li>
+<h4>Gesture Input</h4>
   <ul>
     <li>New {@link android.gesture gesture} API for creating, recognizing,
 loading, and saving gestures.</li>
   </ul>
-</li>
 
-<li>Text-to-speech</li>
+<h4>Text-to-speech</h4>
   <ul>
-    <li>New package {@link android.speech.tts android.speech.tts} provides
+    <li>New {@link android.speech.tts android.speech.tts} package provides
 classes for synthesizing speech from text, for immediate playback or to create a
 sound file.</li>
   </ul>
-</li>
 
-<li>Permissions</li>
-  <ul>
-
-    <li>New permissions for 
-{@link android.Manifest.permission#CHANGE_WIFI_MULTICAST_STATE CHANGE_WIFI_MULTICAST_STATE}, 
-{@link android.Manifest.permission#INSTALL_LOCATION_PROVIDER INSTALL_LOCATION_PROVIDER}, 
-{@link android.Manifest.permission#READ_HISTORY_BOOKMARKS READ_HISTORY_BOOKMARKS},
-{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE}, and  
-{@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS WRITE_HISTORY_BOOKMARKS}.</li>
-  </ul>
-</li>
-
-<li>Graphics</li>
+<h4>Graphics</h4>
   <ul>
     <li>Classes in {@link android.graphics android.graphics} now support scaling
 for different screen densities.</li>
   </ul>
-</li>
 
-<li>Telephony</li>
+<h4>Telephony</h4>
   <ul>
     <li>New {@link android.telephony.SmsManager SmsManager} and other classes
 for sending and receiving SMS messages.</li>
   </ul>
-</li>
 
-<li>Utilities</li>
+<h4>Utilities</h4>
   <ul>
     <li>New {@link android.util.DisplayMetrics DisplayMetrics} fields for
 determining the density of the current device screen.</li>
   </ul>
-</li>
 
-<li>Application-defined support for various screen densities</li>
-   <p>Applications can now use a new element in their manifest files, <a
-href="{@docRoot}guide/topics/manifest/supports-screen-element.html">&lt;supports-
-screen&gt;</a> to indicate to the specific screen resolutions/densities that
-they are designed to support. When the application is installed on a device
-whose screen is not explicitly supported by the application, the system
-runs the application in Compatibility Mode, where possible. </p>
-</li>
-</ul>
+<h4 id="AndroidManifest">Android Manifest elements</h4>
+
+    <ul>
+      <li>New <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code 
+      &lt;supports-screens>}</a> element lets you specify the device screen sizes that your 
+      application is designed and tested to support, where "size" is a combination
+      of resolution and density. If your application is run on a device whose screen 
+      size is not specified in the <code>&lt;supports-screen&gt;</code> element, the system 
+      displays the application in <em>compatibility mode</em>, which performs best-effort scaling
+      of the application UI to match the resolution and density of the screen. 
+
+    <p>The attributes available for defining an application's screen support are:
+
+        <ul>
+
+          <li><code>smallScreen</code>: Boolean value that indicates whether the
+            application is designed to run on devices with small screens. 
+            Examples: QVGA low density; VGA high density.
+          </li>
+          <li><code>normalScreens</code>: Boolean value that indicates whether 
+            the application is designed to run on devices with normal screens. 
+            Examples: WQVGA low density; HVGA medium density; WVGA high density.
+          </li>
+          <li><code>largeScreens</code>: Boolean value that indicates whether 
+            the application is designed to run on devices with significantly 
+            larger screens, such that special care may be required on
+            the application's part to make proper use of the screen area. 
+            Examples: VGA medium density; WVGA medium density.
+          </li>
+          <li><code>anyDensity</code>: Boolean value that indicates whether 
+            the application can accommodate any screen density.
+          </li>
+          <li><code>resizable</code>: Boolean value that indicates whether
+            the application can expand its layout to fit slightly larger screens.
+          </li>
+        </ul>
+    </p>
+    </li>
+
+      <li>New <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code &lt;uses-feature>}</a>
+        element lets an application specify hardware (or other)
+        features that it requires to function normally. When an application
+        specifies such features, the system allows the application to be installed only
+        on devices that offer the required features. The element supports these
+        attributes:
+        <ul>
+          <li><code>name</code>: The name of the feature required by the application. Currently accepts 
+          "android.hardware.camera" and "android.hardware.camera.autofocus" values, which specify that a 
+          camera and camera autofocus are required, respectively.</li>
+          <li><code>glEsVersion</code>: Indicates the minimum version of OpenGL ES required.</li>
+        </ul>
+      </li>
+      <li>New attributes for the 
+      <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk>}</a> element:
+        <ul>
+          <li><code>maxSdkVersion</code>: This indicates the maximum API Level on which an application is 
+          designed to run. If an application declares this attribute, the Android system prevents the user 
+          from installing the application if the system's API Level is higher than the value specified in 
+          this attribute. </li>
+          <li><code>targetSdkVersion</code>: This indicates the API Level that the application is targeting. 
+          It is able to run on older versions (down to minSdkVersion), but was explicitly tested to 
+          work with the version specified here. Specifying this version allows the platform to 
+          disable compatibility code that is not required or enable newer features that are not 
+          available to older applications. </li>
+        </ul>
+      </li>
+
+      </li>
+    </ul>
+
+<h4>New Permissions</h4>
+
+    <ul>
+      <li>{@link android.Manifest.permission#CHANGE_WIFI_MULTICAST_STATE
+          CHANGE_WIFI_MULTICAST_STATE}: Allows applications to enter Wi-Fi 
+          Multicast mode.
+      </li>
+      <li>{@link android.Manifest.permission#GLOBAL_SEARCH}: Allows the 
+          global search system to access the data of a specified content provider.
+      </li> 
+      <li>{@link android.Manifest.permission#INSTALL_LOCATION_PROVIDER INSTALL_LOCATION_PROVIDER}: 
+          Allows an application to install a location provider into the Location Manager.
+      </li>
+      <li>{@link android.Manifest.permission#READ_HISTORY_BOOKMARKS READ_HISTORY_BOOKMARKS}: 
+          Allows an application to read (but not write) the user's browsing history 
+          and bookmarks.
+      </li>
+      <li>{@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS WRITE_HISTORY_BOOKMARKS}: 
+          Allows an application to write (but not read) the user's browsing history 
+          and bookmarks.
+      </li>
+      <li>{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE}: 
+          Allows an application to write to external storage. Applications using API Level 3
+          and lower will be implicitly granted this permission (and this will be visible to 
+          the user); Applications using API Level 4 or higher must explicitly request this 
+          permission.
+      </li>
+    </ul>
+
 
 <h3 id="api-diff">API Change Details</h3>
 
-<p>For a detailed view of API changes in this platform (API Level 4), see the <a
+<p>For a detailed view of API changes in Android 1.6 (API Level 4), see the <a
 href="{@docRoot}sdk/api_diff/4/changes.html">API Differences Report</a>.</p>
-
-
-
-
-
-
diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd
index c9c88cf..ddb9f86 100644
--- a/docs/html/videos/index.jd
+++ b/docs/html/videos/index.jd
@@ -37,10 +37,12 @@
  * Each playlist ID is paired with a custom video description.
  */
 var featured = {
+// Android 1.6 Release
+  'MBRFkLKRwFw' : "The Android 1.6 release includes new features and improvements to the Android platform. Here's an introduction to what's new in Android 1.6.",
 // How to Make your Android UI Fast..
   'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.", 
 // Coding for Life: Battery Life
-  'OUemfrKe65c' : "Learn what kinds of operations consume the most battery and how you can reduce your usage, with tips for parsing and zipping data, using wakelocks, and running a Service.",
+//  'OUemfrKe65c' : "Learn what kinds of operations consume the most battery and how you can reduce your usage, with tips for parsing and zipping data, using wakelocks, and running a Service.",
 // How Do I Code Thee?
   'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video."
 };
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index 159accc..221c2f8 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -52,6 +52,12 @@
      * by the hardware.
      */
     public static final int YCbCr_422_SP= 0x10;
+
+    /** YCbCr format used for images, which uses the NV21 encoding format.   
+     *  This is the default format for camera preview images, when not
+     *  otherwise set with 
+     *  {@link android.hardware.Camera.Parameters#setPreviewFormat(int)}.
+     */
     public static final int YCbCr_420_SP= 0x11;
 
     /**
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 1755d4f..30cef67 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -56,7 +56,8 @@
  */
 public class BitmapDrawable extends Drawable {
 
-    private static final int DEFAULT_PAINT_FLAGS = Paint.FILTER_BITMAP_FLAG;
+    private static final int DEFAULT_PAINT_FLAGS =
+            Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
     private BitmapState mBitmapState;
     private Bitmap mBitmap;
     private final Rect mDstRect = new Rect();   // Gravity.apply() sets this
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 6b50406..af1a289 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -19,12 +19,23 @@
 import android.graphics.*;
 
 public class DrawableContainer extends Drawable implements Drawable.Callback {
-    
+
+    /**
+     * To be proper, we should have a getter for dither (and alpha, etc.)
+     * so that proxy classes like this can save/restore their delegates'
+     * values, but we don't have getters. Since we do have setters
+     * (e.g. setDither), which this proxy forwards on, we have to have some
+     * default/initial setting.
+     *
+     * The initial setting for dither is now true, since it almost always seems
+     * to improve the quality at negligible cost.
+     */
+    private static final boolean DEFAULT_DITHER = true;
     private DrawableContainerState mDrawableContainerState;
     private Drawable mCurrDrawable;
     private int mAlpha = 0xFF;
     private ColorFilter mColorFilter;
-    private boolean mDither;
+    private boolean mDither = DEFAULT_DITHER;
 
     private int mCurIndex = -1;
     private boolean mMutated;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 1b1ea94..997efb8 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -21,6 +21,7 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.TypedValue;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -36,6 +37,8 @@
  *
  */
 public class NinePatchDrawable extends Drawable {
+    // dithering helps a lot, and is pretty cheap, so default is true
+    private static final boolean DEFAULT_DITHER = true;
     private NinePatchState mNinePatchState;
     private NinePatch mNinePatch;
     private Rect mPadding;
@@ -101,7 +104,11 @@
         mNinePatch = state.mNinePatch;
         mPadding = state.mPadding;
         mTargetDensity = state.mTargetDensity;
-        if (state.mDither) setDither(state.mDither);
+        if (DEFAULT_DITHER != state.mDither) {
+            // avoid calling the setter unless we need to, since it does a
+            // lazy allocation of a paint
+            setDither(state.mDither);
+        }
         if (mNinePatch != null) {
             computeBitmapSize();
         }
@@ -164,6 +171,11 @@
 
     @Override
     public void draw(Canvas canvas) {
+        if (false) {
+            float[] pts = new float[2];
+            canvas.getMatrix().mapPoints(pts);
+            Log.v("9patch", "Drawing 9-patch @ " + pts[0] + "," + pts[1] + ": " + getBounds());
+        }
         mNinePatch.draw(canvas, getBounds(), mPaint);
     }
 
@@ -215,7 +227,8 @@
         }
 
         final boolean dither = a.getBoolean(
-                com.android.internal.R.styleable.NinePatchDrawable_dither, false);
+                com.android.internal.R.styleable.NinePatchDrawable_dither,
+                DEFAULT_DITHER);
         final BitmapFactory.Options options = new BitmapFactory.Options();
         if (dither) {
             options.inDither = false;
@@ -251,12 +264,10 @@
         a.recycle();
     }
 
-
     public Paint getPaint() {
         if (mPaint == null) {
             mPaint = new Paint();
-            // dithering helps a lot, and is pretty cheap, so default on
-            mPaint.setDither(true);
+            mPaint.setDither(DEFAULT_DITHER);
         }
         return mPaint;
     }
@@ -327,7 +338,7 @@
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
 
         NinePatchState(NinePatch ninePatch, Rect padding) {
-            this(ninePatch, padding, false);
+            this(ninePatch, padding, DEFAULT_DITHER);
         }
 
         NinePatchState(NinePatch ninePatch, Rect rect, boolean dither) {
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index a8274b1..59cb226 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -50,6 +50,17 @@
  * @attr ref android.R.styleable#DrawableStates_state_pressed
  */
 public class StateListDrawable extends DrawableContainer {
+    /**
+     * To be proper, we should have a getter for dither (and alpha, etc.)
+     * so that proxy classes like this can save/restore their delegates'
+     * values, but we don't have getters. Since we do have setters
+     * (e.g. setDither), which this proxy forwards on, we have to have some
+     * default/initial setting.
+     *
+     * The initial setting for dither is now true, since it almost always seems
+     * to improve the quality at negligible cost.
+     */
+    private static final boolean DEFAULT_DITHER = true;
     private final StateListState mStateListState;
     private boolean mMutated;
 
@@ -105,7 +116,8 @@
         mStateListState.setConstantSize(a.getBoolean(
                 com.android.internal.R.styleable.StateListDrawable_constantSize, false));
 
-        setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither, false));
+        setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither,
+                               DEFAULT_DITHER));
 
         a.recycle();
 
diff --git a/cmds/stagefright/JPEGSource.h b/include/media/stagefright/JPEGSource.h
similarity index 97%
rename from cmds/stagefright/JPEGSource.h
rename to include/media/stagefright/JPEGSource.h
index 051c034..9d0a700 100644
--- a/cmds/stagefright/JPEGSource.h
+++ b/include/media/stagefright/JPEGSource.h
@@ -26,7 +26,6 @@
 class MediaBufferGroup;
 
 struct JPEGSource : public MediaSource {
-    // Assumes ownership of "source".
     JPEGSource(const sp<DataSource> &source);
 
     virtual status_t start(MetaData *params = NULL);
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
index 2bd5344..6181f55 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -85,6 +85,7 @@
 
 public:
     SharedBufferStack();
+    void init(int32_t identity);
     status_t setDirtyRegion(int buffer, const Region& reg);
     Region getDirtyRegion(int buffer) const;
 
@@ -93,12 +94,12 @@
     volatile int32_t available; // number of dequeue-able buffers
     volatile int32_t queued;    // number of buffers waiting for post
     volatile int32_t inUse;     // buffer currently in use by SF
+    volatile status_t status;   // surface's status code
 
     // not part of the conditions
     volatile int32_t reallocMask;
 
     int32_t     identity;       // surface's identity (const)
-    status_t    status;         // surface's status code
     int32_t     reserved32[13];
     FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
 };
@@ -114,7 +115,6 @@
 
     status_t validate(size_t token) const;
     uint32_t getIdentity(size_t token) const;
-    status_t setIdentity(size_t token, uint32_t identity);
 
 private:
     friend class SharedBufferBase;
@@ -168,10 +168,11 @@
 template <typename T>
 status_t SharedBufferBase::waitForCondition(T condition) 
 {
+    const SharedBufferStack& stack( *mSharedStack );
     SharedClient& client( *mSharedClient );
     const nsecs_t TIMEOUT = s2ns(1); 
     Mutex::Autolock _l(client.lock);
-    while (!condition()) {
+    while ((condition()==false) && (stack.status == NO_ERROR)) {
         status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
         
         // handle errors and timeouts
@@ -195,7 +196,7 @@
             }
         }
     }
-    return NO_ERROR;
+    return stack.status;
 }
 
 
@@ -261,13 +262,15 @@
 class SharedBufferServer : public SharedBufferBase
 {
 public:
-    SharedBufferServer(SharedClient* sharedClient, int surface, int num);
+    SharedBufferServer(SharedClient* sharedClient, int surface, int num,
+            int32_t identity);
 
     ssize_t retireAndLock();
     status_t unlock(int buffer);
+    void setStatus(status_t status);
     status_t reallocate();
     status_t assertReallocate(int buffer);
-
+    
     Region getDirtyRegion(int buffer) const;
 
 private:
@@ -283,6 +286,12 @@
         inline ssize_t operator()();
     };
 
+    struct StatusUpdate : public UpdateBase {
+        const status_t status;
+        inline StatusUpdate(SharedBufferBase* sbb, status_t status);
+        inline ssize_t operator()();
+    };
+
     struct ReallocateCondition : public ConditionBase {
         int buf;
         inline ReallocateCondition(SharedBufferBase* sbb, int buf);
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index ecb6b32..6275910 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -49,13 +49,12 @@
 
 Layer::Layer(SurfaceFlinger* flinger, DisplayID display, 
         const sp<Client>& c, int32_t i)
-    :   LayerBaseClient(flinger, display, c, i), lcblk(NULL),
+    :   LayerBaseClient(flinger, display, c, i),
         mSecure(false),
         mNeedsBlending(true)
 {
     // no OpenGL operation is possible here, since we might not be
     // in the OpenGL thread.
-    lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS);
     mFrontBufferIndex = lcblk->getFrontBuffer();
 }
 
@@ -63,8 +62,14 @@
 {
     destroy();
     // the actual buffers will be destroyed here
-    delete lcblk;
+}
 
+// called with SurfaceFlinger::mStateLock as soon as the layer is entered
+// in the purgatory list
+void Layer::onRemoved()
+{
+    // wake up the condition
+    lcblk->setStatus(NO_INIT);
 }
 
 void Layer::destroy()
@@ -79,7 +84,9 @@
             eglDestroyImageKHR(dpy, mTextures[i].image);
             mTextures[i].image = EGL_NO_IMAGE_KHR;
         }
+        Mutex::Autolock _l(mLock);
         mBuffers[i].clear();
+        mWidth = mHeight = 0;
     }
     mSurface.clear();
 }
@@ -213,6 +220,16 @@
 
 sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
 {
+    sp<Buffer> buffer;
+
+    // this ensures our client doesn't go away while we're accessing
+    // the shared area.
+    sp<Client> ourClient(client.promote());
+    if (ourClient == 0) {
+        // oops, the client is already gone
+        return buffer;
+    }
+
     /*
      * This is called from the client's Surface::dequeue(). This can happen
      * at any time, especially while we're in the middle of using the
@@ -225,12 +242,21 @@
      */
     status_t err = lcblk->assertReallocate(index);
     LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
+    if (err != NO_ERROR) {
+        // the surface may have died
+        return buffer;
+    }
 
-    Mutex::Autolock _l(mLock);
-    uint32_t w = mWidth;
-    uint32_t h = mHeight;
-    
-    sp<Buffer>& buffer(mBuffers[index]);
+    uint32_t w, h;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        w = mWidth;
+        h = mHeight;
+        buffer = mBuffers[index];
+        mBuffers[index].clear();
+    }
+
+
     if (buffer->getStrongCount() == 1) {
         err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
     } else {
@@ -253,8 +279,16 @@
     }
 
     if (err == NO_ERROR && buffer->handle != 0) {
-        // texture is now dirty...
-        mTextures[index].dirty = true;
+        Mutex::Autolock _l(mLock);
+        if (mWidth && mHeight) {
+            // and we have new buffer
+            mBuffers[index] = buffer;
+            // texture is now dirty...
+            mTextures[index].dirty = true;
+        } else {
+            // oops we got killed while we were allocating the buffer
+            buffer.clear();
+        }
     }
     return buffer;
 }
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 3b4489e..2e8173d 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -51,10 +51,6 @@
     static const char* const typeID;
     virtual char const* getTypeID() const { return typeID; }
     virtual uint32_t getTypeInfo() const { return typeInfo; }
-
-    
-    SharedBufferServer*     lcblk;
-
     
                  Layer(SurfaceFlinger* flinger, DisplayID display,
                          const sp<Client>& client, int32_t i);
@@ -88,6 +84,8 @@
         return mBuffers[mFrontBufferIndex];
     }
  
+    virtual void onRemoved();
+
     void reloadTexture(const Region& dirty);
 
     sp<SurfaceBuffer> requestBuffer(int index, int usage);
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 62e41b0..1f22488 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -642,9 +642,12 @@
 
 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
-    : LayerBase(flinger, display), client(client),
+    : LayerBase(flinger, display), lcblk(NULL), client(client),
       mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
 {
+    lcblk = new SharedBufferServer(
+            client->ctrlblk, i, NUM_BUFFERS,
+            mIdentity);
 }
 
 void LayerBaseClient::onFirstRef()
@@ -652,8 +655,6 @@
     sp<Client> client(this->client.promote());
     if (client != 0) {
         client->bindLayer(this, mIndex);
-        // Initialize this layer's identity
-        client->ctrlblk->setIdentity(mIndex, mIdentity);
     }
 }
 
@@ -663,6 +664,7 @@
     if (client != 0) {
         client->free(mIndex);
     }
+    delete lcblk;
 }
 
 int32_t LayerBaseClient::serverIndex() const 
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 78bb4bf..3a52240 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -292,13 +292,16 @@
     virtual char const* getTypeID() const { return typeID; }
     virtual uint32_t getTypeInfo() const { return typeInfo; }
 
+    // lcblk is (almost) only accessed from the main SF thread, in the places
+    // where it's not, a reference to Client must be held
+    SharedBufferServer*     lcblk;
+
     LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
             const sp<Client>& client, int32_t i);
     virtual ~LayerBaseClient();
     virtual void onFirstRef();
 
-    wp<Client>              client;
-//    SharedBufferServer*     lcblk;
+    const wp<Client>    client;
 
     inline  uint32_t    getIdentity() const { return mIdentity; }
     inline  int32_t     clientIndex() const { return mIndex; }
@@ -308,6 +311,7 @@
             sp<Surface> getSurface();
     virtual sp<Surface> createSurface() const;
     
+    virtual void onRemoved() { }
 
     class Surface : public BnSurface 
     {
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index b368db6..8685f99 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -654,6 +654,7 @@
         // some layers might have been removed, so
         // we need to update the regions they're exposing.
         if (mLayersRemoved) {
+            mLayersRemoved = false;
             mVisibleRegionsDirty = true;
             const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
             const size_t count = previousLayers.size();
@@ -1093,9 +1094,6 @@
 
 void SurfaceFlinger::free_resources_l()
 {
-    // Destroy layers that were removed
-    mLayersRemoved = false;
-    
     // free resources associated with disconnected clients
     Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
     const size_t count = disconnectedClients.size();
@@ -1321,11 +1319,15 @@
      * to wait for all client's references to go away first).
      */
 
+    status_t err = NAME_NOT_FOUND;
     Mutex::Autolock _l(mStateLock);
     sp<LayerBaseClient> layer = getLayerUser_l(index);
-    status_t err = purgatorizeLayer_l(layer);
-    if (err == NO_ERROR) {
-        setTransactionFlags(eTransactionNeeded);
+    if (layer != 0) {
+        err = purgatorizeLayer_l(layer);
+        if (err == NO_ERROR) {
+            layer->onRemoved();
+            setTransactionFlags(eTransactionNeeded);
+        }
     }
     return err;
 }
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
index 5995af5..3fbd8c7 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -53,21 +53,20 @@
     return uint32_t(surfaces[token].identity);
 }
 
-status_t SharedClient::setIdentity(size_t token, uint32_t identity) {
-    if (token >= NUM_LAYERS_MAX)
-        return BAD_INDEX;
-    surfaces[token].identity = identity;
-    return NO_ERROR;
-}
-
 // ----------------------------------------------------------------------------
 
 
 SharedBufferStack::SharedBufferStack()
-    : inUse(-1), identity(-1), status(NO_ERROR)
 {
 }
 
+void SharedBufferStack::init(int32_t i)
+{
+    inUse = -1;
+    status = NO_ERROR;
+    identity = i;
+}
+
 status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
 {
     if (uint32_t(buffer) >= NUM_BUFFER_MAX)
@@ -231,6 +230,16 @@
     return head;
 }
 
+SharedBufferServer::StatusUpdate::StatusUpdate(
+        SharedBufferBase* sbb, status_t status)
+    : UpdateBase(sbb), status(status) {
+}
+
+ssize_t SharedBufferServer::StatusUpdate::operator()() {
+    android_atomic_write(status, &stack.status);
+    return NO_ERROR;
+}
+
 // ============================================================================
 
 SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
@@ -302,9 +311,10 @@
 // ----------------------------------------------------------------------------
 
 SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
-        int surface, int num)
+        int surface, int num, int32_t identity)
     : SharedBufferBase(sharedClient, surface, num)
 {
+    mSharedStack->init(identity);
     mSharedStack->head = num-1;
     mSharedStack->available = num;
     mSharedStack->queued = 0;
@@ -327,6 +337,12 @@
     return err;
 }
 
+void SharedBufferServer::setStatus(status_t status)
+{
+    StatusUpdate update(this, status);
+    updateCondition( update );
+}
+
 status_t SharedBufferServer::reallocate()
 {
     SharedBufferStack& stack( *mSharedStack );
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 665d353..307cf22 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -25,7 +25,6 @@
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothHeadset;
 
 import android.content.pm.PackageManager;
@@ -265,8 +264,8 @@
         // Register for device connection intent broadcasts.
         IntentFilter intentFilter =
                 new IntentFilter(Intent.ACTION_HEADSET_PLUG);
-        intentFilter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
-        intentFilter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
+        intentFilter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
+        intentFilter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
         context.registerReceiver(mReceiver, intentFilter);
 
     }
@@ -1372,10 +1371,10 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
-                int state = intent.getIntExtra(BluetoothA2dp.SINK_STATE,
+            if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
                                                BluetoothA2dp.STATE_DISCONNECTED);
-                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothIntent.DEVICE);
+                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 String address = btDevice.getAddress();
                 boolean isConnected = (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) &&
                                        ((String)mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)).equals(address));
@@ -1395,19 +1394,17 @@
                     mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP),
                             address);
                 }
-            } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
-                int state = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
+            } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
+                int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                                                BluetoothHeadset.STATE_ERROR);
                 int device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
-                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothIntent.DEVICE);
+                BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                 String address = null;
-                int btClass = BluetoothClass.ERROR;
                 if (btDevice != null) {
                     address = btDevice.getAddress();
-                    btClass = btDevice.getBluetoothClass();
-                    if (BluetoothClass.Device.Major.getDeviceMajor(btClass) ==
-                                BluetoothClass.Device.Major.AUDIO_VIDEO) {
-                        switch (BluetoothClass.Device.getDevice(btClass)) {
+                    BluetoothClass btClass = btDevice.getBluetoothClass();
+                    if (btClass != null) {
+                        switch (btClass.getDeviceClass()) {
                         case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
                         case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
                             device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
@@ -1415,8 +1412,6 @@
                         case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
                             device = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
                             break;
-                        default:
-                            break;
                         }
                     }
                 }
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 59ecde6..93b7a3a 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -10,13 +10,21 @@
     MediaRecorderClient.cpp     \
     MediaPlayerService.cpp      \
     MetadataRetrieverClient.cpp \
-    StagefrightPlayer.cpp       \
     TestPlayerStub.cpp          \
     VorbisPlayer.cpp            \
     VorbisMetadataRetriever.cpp \
     MidiMetadataRetriever.cpp \
     MidiFile.cpp
 
+ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
+
+LOCAL_SRC_FILES +=              \
+    StagefrightPlayer.cpp
+
+LOCAL_CFLAGS += -DBUILD_WITH_FULL_STAGEFRIGHT=1
+
+endif
+
 ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
 LOCAL_LDLIBS += -ldl -lpthread
 endif
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8998f10..8b1c9dc 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -602,11 +602,13 @@
 }
 
 static player_type getDefaultPlayerType() {
+#if BUILD_WITH_FULL_STAGEFRIGHT
     char value[PROPERTY_VALUE_MAX];
     if (property_get("media.stagefright.enable-player", value, NULL)
         && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
         return STAGEFRIGHT_PLAYER;
     }
+#endif
 
     return PV_PLAYER;
 }
@@ -684,10 +686,12 @@
             LOGV(" create VorbisPlayer");
             p = new VorbisPlayer();
             break;
+#if BUILD_WITH_FULL_STAGEFRIGHT
         case STAGEFRIGHT_PLAYER:
             LOGV(" create StagefrightPlayer");
             p = new StagefrightPlayer;
             break;
+#endif
         case TEST_PLAYER:
             LOGV("Create Test Player stub");
             p = new TestPlayerStub();
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index a4f2c79..79a32b5 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -2,34 +2,41 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:=                 \
+        ESDS.cpp                  \
+        MediaBuffer.cpp           \
+        MediaBufferGroup.cpp      \
+        MediaDefs.cpp             \
+        MediaSource.cpp           \
+        MetaData.cpp              \
+        OMXCodec.cpp              \
+        Utils.cpp                 \
+        OMXClient.cpp
+
+ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
+
+LOCAL_SRC_FILES +=                \
         AMRExtractor.cpp          \
         CachingDataSource.cpp     \
         DataSource.cpp            \
         FileSource.cpp            \
         HTTPDataSource.cpp        \
         HTTPStream.cpp            \
+        JPEGSource.cpp            \
+        MediaExtractor.cpp        \
         MP3Extractor.cpp          \
         MPEG4Extractor.cpp        \
         MPEG4Writer.cpp           \
-        MediaBuffer.cpp           \
-        MediaBufferGroup.cpp      \
-        MediaDefs.cpp             \
-        MediaExtractor.cpp        \
         MediaPlayerImpl.cpp       \
-        MediaSource.cpp           \
-        MetaData.cpp              \
         MmapSource.cpp            \
-        OMXCodec.cpp              \
         SampleTable.cpp           \
         ShoutcastSource.cpp       \
         TimeSource.cpp            \
         TimedEventQueue.cpp       \
-        Utils.cpp                 \
         AudioPlayer.cpp           \
-        ESDS.cpp                  \
-        OMXClient.cpp             \
         string.cpp
 
+endif
+
 LOCAL_C_INCLUDES:= \
         $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
         $(TOP)/external/opencore/android
diff --git a/cmds/stagefright/JPEGSource.cpp b/media/libstagefright/JPEGSource.cpp
similarity index 98%
rename from cmds/stagefright/JPEGSource.cpp
rename to media/libstagefright/JPEGSource.cpp
index 25c772f..d1dfd83 100644
--- a/cmds/stagefright/JPEGSource.cpp
+++ b/media/libstagefright/JPEGSource.cpp
@@ -18,9 +18,8 @@
 #define LOG_TAG "JPEGSource"
 #include <utils/Log.h>
 
-#include "JPEGSource.h"
-
 #include <media/stagefright/DataSource.h>
+#include <media/stagefright/JPEGSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MediaDefs.h>
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 4d3c2f4..90e6d29 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -118,10 +118,10 @@
 
 /*
  * If the active textures are EGLImage, they need to be locked before
- * they can be used. 
- * 
+ * they can be used.
+ *
  * FIXME: code below is far from being optimal
- * 
+ *
  */
 
 void ogles_lock_textures(ogles_context_t* c)
@@ -409,6 +409,49 @@
     return 0;
 }
 
+static size_t dataSizePalette4(int numLevels, int width, int height, int format)
+{
+    int indexBits = 8;
+    int entrySize = 0;
+    switch (format) {
+    case GL_PALETTE4_RGB8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGB8_OES:
+        entrySize = 3;
+        break;
+
+    case GL_PALETTE4_RGBA8_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_RGBA8_OES:
+        entrySize = 4;
+        break;
+
+    case GL_PALETTE4_R5_G6_B5_OES:
+    case GL_PALETTE4_RGBA4_OES:
+    case GL_PALETTE4_RGB5_A1_OES:
+        indexBits = 4;
+        /* FALLTHROUGH */
+    case GL_PALETTE8_R5_G6_B5_OES:
+    case GL_PALETTE8_RGBA4_OES:
+    case GL_PALETTE8_RGB5_A1_OES:
+        entrySize = 2;
+        break;
+    }
+
+    size_t size = (1 << indexBits) * entrySize; // palette size
+
+    for (int i=0 ; i< numLevels ; i++) {
+        int w = (width  >> i) ? : 1;
+        int h = (height >> i) ? : 1;
+        int levelSize = h * ((w * indexBits) / 8) ? : 1;
+        size += levelSize;
+    }
+
+    return size;
+}
+
 static void decodePalette4(const GLvoid *data, int level, int width, int height,
                            void *surface, int stride, int format)
 
@@ -443,6 +486,7 @@
     }
 
     const int paletteSize = (1 << indexBits) * entrySize;
+
     uint8_t const* pixels = (uint8_t *)data + paletteSize;
     for (int i=0 ; i<level ; i++) {
         int w = (width  >> i) ? : 1;
@@ -652,7 +696,7 @@
         ogles_context_t* c)
 {
     ogles_lock_textures(c);
-    
+
     const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
     y = gglIntToFixed(cbSurface.height) - (y + h);
     w >>= FIXED_BITS;
@@ -799,7 +843,7 @@
             c->rasterizer.procs.disable(c, GGL_AA);
             c->rasterizer.procs.shadeModel(c, GL_FLAT);
             c->rasterizer.procs.recti(c, x, y, x+w, y+h);
-            
+
             ogles_unlock_textures(c);
 
             return;
@@ -1091,6 +1135,12 @@
     GGLSurface* surface;
     // all mipmap levels are specified at once.
     const int numLevels = level<0 ? -level : 1;
+
+    if (dataSizePalette4(numLevels, width, height, format) > imageSize) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
     for (int i=0 ; i<numLevels ; i++) {
         int lod_w = (width  >> i) ? : 1;
         int lod_h = (height >> i) ? : 1;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 56a279a..13db005 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,33 +16,31 @@
 
 package com.android.providers.settings;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
-import java.io.EOFException;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.zip.CRC32;
 
 import android.backup.BackupDataInput;
 import android.backup.BackupDataOutput;
 import android.backup.BackupHelperAgent;
-import android.bluetooth.BluetoothAdapter;
-import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
-import android.media.AudioManager;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
@@ -72,7 +70,6 @@
 
     private static final String TAG = "SettingsBackupAgent";
 
-    private static final int COLUMN_ID = 0;
     private static final int COLUMN_NAME = 1;
     private static final int COLUMN_VALUE = 2;
 
@@ -83,12 +80,12 @@
     };
 
     private static final String FILE_WIFI_SUPPLICANT = "/data/misc/wifi/wpa_supplicant.conf";
+    private static final String FILE_WIFI_SUPPLICANT_TEMPLATE =
+            "/system/etc/wifi/wpa_supplicant.conf";
 
     // the key to store the WIFI data under, should be sorted as last, so restore happens last.
     // use very late unicode character to quasi-guarantee last sort position.
-    private static final String KEY_WIFI_SUPPLICANT = "\uffeeWIFI";
-
-    private static final String FILE_BT_ROOT = "/data/misc/hcid/";
+    private static final String KEY_WIFI_SUPPLICANT = "\uffedWIFI";
 
     private SettingsHelper mSettingsHelper;
 
@@ -105,7 +102,7 @@
         byte[] secureSettingsData = getSecureSettings();
         byte[] syncProviders = mSettingsHelper.getSyncProviders();
         byte[] locale = mSettingsHelper.getLocaleData();
-        byte[] wifiData = getFileData(FILE_WIFI_SUPPLICANT);
+        byte[] wifiData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
 
         long[] stateChecksums = readOldChecksums(oldState);
 
@@ -127,9 +124,6 @@
     public void onRestore(BackupDataInput data, int appVersionCode,
             ParcelFileDescriptor newState) throws IOException {
 
-
-        enableBluetooth(false);
-
         while (data.readNextHeader()) {
             final String key = data.getKey();
             final int size = data.getDataSize();
@@ -140,7 +134,7 @@
                 restoreSettings(data, Settings.Secure.CONTENT_URI);
             } else if (KEY_WIFI_SUPPLICANT.equals(key)) {
                 int retainedWifiState = enableWifi(false);
-                restoreFile(FILE_WIFI_SUPPLICANT, data);
+                restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, data);
                 FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
                         FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                         FileUtils.S_IRGRP | FileUtils.S_IWGRP,
@@ -319,19 +313,27 @@
         return result;
     }
 
-    private byte[] getFileData(String filename) {
+    private byte[] getWifiSupplicant(String filename) {
         try {
             File file = new File(filename);
             if (file.exists()) {
-                byte[] bytes = new byte[(int) file.length()];
-                FileInputStream fis = new FileInputStream(file);
-                int offset = 0;
-                int got = 0;
-                do {
-                    got = fis.read(bytes, offset, bytes.length - offset);
-                    if (got > 0) offset += got;
-                } while (offset < bytes.length && got > 0);
-                return bytes;
+                BufferedReader br = new BufferedReader(new FileReader(file));
+                StringBuffer relevantLines = new StringBuffer();
+                boolean started = false;
+                String line;
+                while ((line = br.readLine()) != null) {
+                    if (!started && line.startsWith("network")) {
+                        started = true;
+                    }
+                    if (started) {
+                        relevantLines.append(line).append("\n");
+                    }
+                }
+                if (relevantLines.length() > 0) {
+                    return relevantLines.toString().getBytes();
+                } else {
+                    return EMPTY_DATA;
+                }
             } else {
                 return EMPTY_DATA;
             }
@@ -341,18 +343,39 @@
         }
     }
 
-    private void restoreFile(String filename, BackupDataInput data) {
+    private void restoreWifiSupplicant(String filename, BackupDataInput data) {
         byte[] bytes = new byte[data.getDataSize()];
         if (bytes.length <= 0) return;
         try {
             data.readEntityData(bytes, 0, bytes.length);
-            FileOutputStream fos = new FileOutputStream(filename);
+            File supplicantFile = new File(FILE_WIFI_SUPPLICANT);
+            if (supplicantFile.exists()) supplicantFile.delete();
+            copyWifiSupplicantTemplate();
+
+            FileOutputStream fos = new FileOutputStream(filename, true);
+            fos.write("\n".getBytes());
             fos.write(bytes);
         } catch (IOException ioe) {
             Log.w(TAG, "Couldn't restore " + filename);
         }
     }
 
+    private void copyWifiSupplicantTemplate() {
+        try {
+            BufferedReader br = new BufferedReader(new FileReader(FILE_WIFI_SUPPLICANT_TEMPLATE));
+            BufferedWriter bw = new BufferedWriter(new FileWriter(FILE_WIFI_SUPPLICANT));
+            char[] temp = new char[1024];
+            int size;
+            while ((size = br.read(temp)) > 0) {
+                bw.write(temp, 0, size);
+            }
+            bw.close();
+            br.close();
+        } catch (IOException ioe) {
+            Log.w(TAG, "Couldn't copy wpa_supplicant file");
+        }
+    }
+
     /**
      * Write an int in BigEndian into the byte array.
      * @param out byte array
@@ -391,15 +414,4 @@
         }
         return WifiManager.WIFI_STATE_UNKNOWN;
     }
-
-    private void enableBluetooth(boolean enable) {
-        BluetoothAdapter bt = (BluetoothAdapter) getSystemService(Context.BLUETOOTH_SERVICE);
-        if (bt != null) {
-            if (!enable) {
-                bt.disable();
-            } else {
-                bt.enable();
-            }
-        }
-    }
 }
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index e26dd13..408a4d2 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -640,20 +640,14 @@
             return false;
         }
         NetworkStateTracker tracker = mNetTrackers[networkType];
-        /*
-         * If there's only one connected network, and it's the one requested,
-         * then we don't have to do anything - the requested route already
-         * exists. If it's not the requested network, then it's not possible
-         * to establish the requested route. Finally, if there is more than
-         * one connected network, then we must insert an entry in the routing
-         * table.
-         */
-        if (getNumConnectedNetworks() > 1) {
-            return tracker.requestRouteToHost(hostAddress);
-        } else {
-            return (mNetAttributes[networkType].isDefault() &&
-                    tracker.getNetworkInfo().isConnected());
+
+        if (!tracker.getNetworkInfo().isConnected() || tracker.isTeardownRequested()) {
+            if (DBG) {
+                Log.d(TAG, "requestRouteToHost on down network (" + networkType + " - dropped");
+            }
+            return false;
         }
+        return tracker.requestRouteToHost(hostAddress);
     }
 
     /**
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 2dc747e..6e6f66f 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -1434,10 +1434,10 @@
                     return;
                 }
                 mPluggedType = pluggedType;
-            } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
+            } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
                 boolean isBluetoothPlaying =
                         intent.getIntExtra(
-                                BluetoothA2dp.SINK_STATE,
+                                BluetoothA2dp.EXTRA_SINK_STATE,
                                 BluetoothA2dp.STATE_DISCONNECTED) == BluetoothA2dp.STATE_PLAYING;
                 mWifiStateTracker.setBluetoothScanMode(isBluetoothPlaying);
             } else {
@@ -1556,7 +1556,7 @@
         intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
         intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
         intentFilter.addAction(ACTION_DEVICE_IDLE);
-        intentFilter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
+        intentFilter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
         mContext.registerReceiver(mReceiver, intentFilter);
     }
     
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index f3127f3..da64e54 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -20,7 +20,6 @@
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothPbap;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -362,8 +361,8 @@
                 onBatteryOkay(intent);
             }
             else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) ||
-                    action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION) ||
-                    action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION) ||
+                    action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) ||
+                    action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) ||
                     action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
                 updateBluetooth(intent);
             }
@@ -507,8 +506,8 @@
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
         filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
-        filter.addAction(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION);
-        filter.addAction(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
+        filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
+        filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
         filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
         filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
@@ -1074,11 +1073,11 @@
         if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
             mBluetoothEnabled = state == BluetoothAdapter.STATE_ON;
-        } else if (action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION)) {
-            mBluetoothHeadsetState = intent.getIntExtra(BluetoothIntent.HEADSET_STATE,
+        } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
+            mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
                     BluetoothHeadset.STATE_ERROR);
-        } else if (action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
-            mBluetoothA2dpState = intent.getIntExtra(BluetoothA2dp.SINK_STATE,
+        } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
+            mBluetoothA2dpState = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE,
                     BluetoothA2dp.STATE_DISCONNECTED);
         } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) {
             mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE,
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index bf42257..623d985 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -21,6 +21,7 @@
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
 import android.content.ContentValues;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.database.SQLException;
@@ -73,6 +74,23 @@
         Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!");
     }
 
+    private void handleCdmaStatusReport(SmsMessage sms) {
+        for (int i = 0, count = deliveryPendingList.size(); i < count; i++) {
+            SmsTracker tracker = deliveryPendingList.get(i);
+            if (tracker.mMessageRef == sms.messageRef) {
+                // Found it.  Remove from list and broadcast.
+                deliveryPendingList.remove(i);
+                PendingIntent intent = tracker.mDeliveryIntent;
+                Intent fillIn = new Intent();
+                fillIn.putExtra("pdu", sms.getPdu());
+                try {
+                    intent.send(mContext, Activity.RESULT_OK, fillIn);
+                } catch (CanceledException ex) {}
+                break;  // Only expect to see one tracker matching this message.
+            }
+        }
+    }
+
     /** {@inheritDoc} */
     protected int dispatchMessage(SmsMessageBase smsb) {
 
@@ -105,6 +123,11 @@
             editor.commit();
             ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
             handled = true;
+        } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
+                (SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
+                sms.isStatusReportMessage()) {
+            handleCdmaStatusReport(sms);
+            handled = true;
         } else if ((sms.getUserData() == null)) {
             if (Config.LOGD) {
                 Log.d(TAG, "Received SMS without user data");
@@ -354,8 +377,12 @@
             uData.payloadStr = parts.get(i);
             uData.userDataHeader = smsHeader;
 
+            /* By setting the statusReportRequested bit only for the
+             * last message fragment, this will result in only one
+             * callback to the sender when that last fragment delivery
+             * has been acknowledged. */
             SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr,
-                    uData, deliveryIntent != null);
+                    uData, (deliveryIntent != null) && (i == (msgCount - 1)));
 
             sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
         }
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index d17468c..165d583 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -424,12 +424,9 @@
         return (status << 16);
     }
 
-    /**
-     *  Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
+    /** Return true iff the bearer data message type is DELIVERY_ACK. */
     public boolean isStatusReportMessage() {
-        Log.w(LOG_TAG, "isStatusReportMessage: is not supported in CDMA mode.");
-        return false;
+        return (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK);
     }
 
     /**
@@ -548,17 +545,6 @@
             messageBody = mBearerData.userData.payloadStr;
         }
 
-        // TP-Message-Type-Indicator (See 3GPP2 C.S0015-B, v2, 4.5.1)
-        switch (mBearerData.messageType) {
-        case BearerData.MESSAGE_TYPE_USER_ACK:
-        case BearerData.MESSAGE_TYPE_READ_ACK:
-        case BearerData.MESSAGE_TYPE_DELIVER:
-        case BearerData.MESSAGE_TYPE_DELIVERY_ACK:
-            break;
-        default:
-            throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
-        }
-
         if (originatingAddress != null) {
             originatingAddress.address = new String(originatingAddress.origBytes);
             if (Config.LOGV) Log.v(LOG_TAG, "SMS originating address: "
@@ -571,11 +557,26 @@
 
         if (Config.LOGD) Log.d(LOG_TAG, "SMS SC timestamp: " + scTimeMillis);
 
-        // TODO(Teleca): do we really want this test to occur only for DELIVERY_ACKs?
-        if ((mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) &&
-                (mBearerData.errorClass != BearerData.ERROR_UNDEFINED)) {
-            status = mBearerData.errorClass << 8;
-            status |= mBearerData.messageStatus;
+        // Message Type (See 3GPP2 C.S0015-B, v2, 4.5.1)
+        if (mBearerData.messageType == BearerData.MESSAGE_TYPE_DELIVERY_ACK) {
+            // The BearerData MsgStatus subparameter should only be
+            // included for DELIVERY_ACK messages.  If it occurred for
+            // other messages, it would be unclear what the status
+            // being reported refers to.  The MsgStatus subparameter
+            // is primarily useful to indicate error conditions -- a
+            // message without this subparameter is assumed to
+            // indicate successful delivery (status == 0).
+            if (! mBearerData.messageStatusSet) {
+                Log.d(LOG_TAG, "DELIVERY_ACK message without msgStatus (" +
+                        (userData == null ? "also missing" : "does have") +
+                        " userData).");
+                status = 0;
+            } else {
+                status = mBearerData.errorClass << 8;
+                status |= mBearerData.messageStatus;
+            }
+        } else if (mBearerData.messageType != BearerData.MESSAGE_TYPE_DELIVER) {
+            throw new RuntimeException("Unsupported message type: " + mBearerData.messageType);
         }
 
         if (messageBody != null) {