Merge change 24643 into eclair

* changes:
  fix [2112575] stuck on DequeueCondition for a surface that doesn't exist anymore
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/stagefright/JPEGSource.cpp b/cmds/stagefright/JPEGSource.cpp
index 4e9ca4e..25c772f 100644
--- a/cmds/stagefright/JPEGSource.cpp
+++ b/cmds/stagefright/JPEGSource.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 
@@ -99,7 +100,7 @@
 
 sp<MetaData> JPEGSource::getFormat() {
     sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, "image/jpeg");
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_IMAGE_JPEG);
     meta->setInt32(kKeyWidth, mWidth);
     meta->setInt32(kKeyHeight, mHeight);
     meta->setInt32(kKeyMaxInputSize, mSize);
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
index 3c25a7f..e5a6ccb 100644
--- a/cmds/stagefright/SineSource.cpp
+++ b/cmds/stagefright/SineSource.cpp
@@ -4,6 +4,7 @@
 
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 
 namespace android {
@@ -48,7 +49,7 @@
 
 sp<MetaData> SineSource::getFormat() {
     sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, "audio/raw");
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     meta->setInt32(kKeyChannelCount, mNumChannels);
     meta->setInt32(kKeySampleRate, mSampleRate);
 
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 4751580..323d448 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -21,6 +21,7 @@
 #include <media/stagefright/CameraSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MPEG4Extractor.h>
 #include <media/stagefright/MPEG4Writer.h>
@@ -45,7 +46,7 @@
         sp<MetaData> meta = new MetaData;
         meta->setInt32(kKeyWidth, mWidth);
         meta->setInt32(kKeyHeight, mHeight);
-        meta->setCString(kKeyMIMEType, "video/raw");
+        meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
 
         return meta;
     }
@@ -149,8 +150,8 @@
 #endif
 
     sp<MetaData> enc_meta = new MetaData;
-    // enc_meta->setCString(kKeyMIMEType, "video/3gpp");
-    enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
+    // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
+    enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
     enc_meta->setInt32(kKeyWidth, width);
     enc_meta->setInt32(kKeyHeight, height);
 
@@ -228,7 +229,8 @@
 #endif
 
     sp<MetaData> encMeta = new MetaData;
-    encMeta->setCString(kKeyMIMEType, 1 ? "audio/amr-wb" : "audio/mp4a-latm");
+    encMeta->setCString(kKeyMIMEType,
+            1 ? MEDIA_MIMETYPE_AUDIO_AMR_WB : MEDIA_MIMETYPE_AUDIO_AAC);
     encMeta->setInt32(kKeySampleRate, kSampleRate);
     encMeta->setInt32(kKeyChannelCount, kNumChannels);
     encMeta->setInt32(kKeyMaxInputSize, 8192);
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index a0b83fb..d1926b4 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -26,6 +26,7 @@
 #include <media/stagefright/CachingDataSource.h>
 #include <media/stagefright/HTTPDataSource.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaPlayerImpl.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaSource.h>
@@ -126,6 +127,7 @@
     fprintf(stderr, "       -l(ist) components\n");
     fprintf(stderr, "       -m max-number-of-frames-to-decode in each pass\n");
     fprintf(stderr, "       -b bug to reproduce\n");
+    fprintf(stderr, "       -p(rofiles) dump decoder profiles supported\n");
 }
 
 int main(int argc, char **argv) {
@@ -133,12 +135,13 @@
 
     bool audioOnly = false;
     bool listComponents = false;
+    bool dumpProfiles = false;
     gNumRepetitions = 1;
     gMaxNumFrames = 0;
     gReproduceBug = -1;
 
     int res;
-    while ((res = getopt(argc, argv, "han:lm:b:")) >= 0) {
+    while ((res = getopt(argc, argv, "han:lm:b:p")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -174,6 +177,12 @@
                 break;
             }
 
+            case 'p':
+            {
+                dumpProfiles = true;
+                break;
+            }
+
             case '?':
             case 'h':
             default:
@@ -188,6 +197,53 @@
     argc -= optind;
     argv += optind;
 
+    if (dumpProfiles) {
+        sp<IServiceManager> sm = defaultServiceManager();
+        sp<IBinder> binder = sm->getService(String16("media.player"));
+        sp<IMediaPlayerService> service =
+            interface_cast<IMediaPlayerService>(binder);
+
+        CHECK(service.get() != NULL);
+
+        sp<IOMX> omx = service->createOMX();
+        CHECK(omx.get() != NULL);
+
+        const char *kMimeTypes[] = {
+            MEDIA_MIMETYPE_VIDEO_AVC, MEDIA_MIMETYPE_VIDEO_MPEG4,
+            MEDIA_MIMETYPE_VIDEO_H263
+        };
+
+        for (size_t k = 0; k < sizeof(kMimeTypes) / sizeof(kMimeTypes[0]);
+             ++k) {
+            printf("type '%s':\n", kMimeTypes[k]);
+
+            Vector<CodecCapabilities> results;
+            CHECK_EQ(QueryCodecs(omx, kMimeTypes[k],
+                                 true, // queryDecoders
+                                 &results), OK);
+
+            for (size_t i = 0; i < results.size(); ++i) {
+                printf("  decoder '%s' supports ",
+                       results[i].mComponentName.string());
+
+                if (results[i].mProfileLevels.size() == 0) {
+                    printf("NOTHING.\n");
+                    continue;
+                }
+
+                for (size_t j = 0; j < results[i].mProfileLevels.size(); ++j) {
+                    const CodecProfileLevel &profileLevel =
+                        results[i].mProfileLevels[j];
+
+                    printf("%s%ld/%ld", j > 0 ? ", " : "",
+                           profileLevel.mProfile, profileLevel.mLevel);
+                }
+
+                printf("\n");
+            }
+        }
+    }
+
     if (listComponents) {
         sp<IServiceManager> sm = defaultServiceManager();
         sp<IBinder> binder = sm->getService(String16("media.player"));
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..a9cec50 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,31 +48,203 @@
      * 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 */
@@ -98,7 +270,6 @@
      * @hide */
     public static final int UNBOND_REASON_REMOVED = 6;
 
-    //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;
@@ -109,8 +280,6 @@
      * @hide */
     public static final int PAIRING_VARIANT_CONFIRMATION = 2;
 
-    private static final int ADDRESS_LENGTH = 17;
-
     private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
 
     private final String mAddress;
@@ -135,7 +304,7 @@
             }
         }
 
-        if (!checkBluetoothAddress(address)) {
+        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
             throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
         }
 
@@ -216,15 +385,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 +403,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 +416,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 +432,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 +491,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 +611,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/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..4c24c50 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -20,7 +20,6 @@
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothIntent;
 import android.bluetooth.BluetoothUuid;
 import android.content.Context;
 import android.content.Intent;
@@ -140,11 +139,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 +161,8 @@
     }
 
     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);
     }
 
@@ -182,7 +182,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 +202,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 +213,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);
@@ -235,7 +235,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 +246,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 +274,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 +312,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 +351,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")) {
@@ -382,10 +383,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.PASSKEY, passkey);
-        intent.putExtra(BluetoothIntent.PAIRING_VARIANT,
+        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_CONFIRMATION);
         mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
         return;
@@ -395,9 +396,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 +411,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,9 +429,9 @@
                 }
            }
         }
-        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;
     }
@@ -464,7 +466,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..53fb03c 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);
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index 2eef0b6..125d2c5 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -58,14 +58,15 @@
                             android.R.style.TextAppearance_Medium,
                             android.R.styleable.TextAppearance);
                     final int textSize = a.getDimensionPixelSize(
-                            android.R.styleable.TextAppearance_textSize, 20);
+                            android.R.styleable.TextAppearance_textSize,
+                            (int) (20 * getResources().getDisplayMetrics().density));
 
-                    setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
+                    // textSize is already expressed in pixels
+                    setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
                     setMaxLines(2);
                     super.onMeasure(widthMeasureSpec, heightMeasureSpec);      
                 }
             }
         }
     }
-   
-}
\ No newline at end of file
+}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 723fd4b..7748aba 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -50,14 +50,6 @@
 #undef __KERNEL__
 #endif
 
-/*
- * List of cgroup names which map to ANDROID_TGROUP_ values in Thread.h
- * and Process.java
- * These names are used to construct the path to the cgroup control dir
- */
-
-static const char *cgroup_names[] = { NULL, "bg_non_interactive", "fg_boost" };
-
 using namespace android;
 
 static void signalExceptionForPriorityError(JNIEnv* env, jobject obj, int err)
@@ -194,14 +186,13 @@
     return -1;
 }
 
-static int add_pid_to_cgroup(int pid, int grp)
+static int add_pid_to_cgroup(int pid, const char *grp_name)
 {
     int fd;
     char path[255];
     char text[64];
 
-    sprintf(path, "/dev/cpuctl/%s/tasks",
-           (cgroup_names[grp] ? cgroup_names[grp] : ""));
+    sprintf(path, "/dev/cpuctl/%s/tasks", grp_name);
 
     if ((fd = open(path, O_WRONLY)) < 0)
         return -1;
@@ -216,6 +207,37 @@
     return 0;
 }
 
+void setSchedPolicy(JNIEnv* env, jobject clazz, int pid, SchedPolicy policy)
+{
+    static int __sys_supports_schedgroups = -1;
+
+    if (__sys_supports_schedgroups < 0) {
+        if (!access("/dev/cpuctl/tasks", F_OK)) {
+            __sys_supports_schedgroups = 1;
+        } else {
+            __sys_supports_schedgroups = 0;
+        }
+    }
+
+    if (__sys_supports_schedgroups) {
+        const char *grp = NULL;
+
+        if (policy == SP_BACKGROUND) {
+            grp = "bg_non_interactive";
+        }
+
+        if (add_pid_to_cgroup(pid, grp)) {
+            if (errno != ESRCH && errno != ENOENT)
+                signalExceptionForGroupError(env, clazz, errno);
+        }
+    } else {
+        struct sched_param param;
+
+        param.sched_priority = 0;
+        sched_setscheduler(pid, (policy == SP_BACKGROUND) ? 5 : 0, &param);
+    }
+}
+
 void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
 {
     if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
@@ -223,11 +245,9 @@
         return;
     }
 
-    if (add_pid_to_cgroup(pid, grp)) {
-        // If the thread exited on us, don't generate an exception
-        if (errno != ESRCH && errno != ENOENT)
-            signalExceptionForGroupError(env, clazz, errno);
-    }
+    setSchedPolicy(env, clazz, pid,
+                   (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                           SP_BACKGROUND : SP_FOREGROUND);
 }
 
 void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) 
@@ -271,14 +291,9 @@
             continue;
         }
      
-        if (add_pid_to_cgroup(t_pid, grp)) {
-            // If the thread exited on us, ignore it and keep going
-            if (errno != ESRCH && errno != ENOENT) {
-                signalExceptionForGroupError(env, clazz, errno);
-                closedir(d);
-                return;
-            }
-        }
+        setSchedPolicy(env, clazz, t_pid,
+                       (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                               SP_BACKGROUND : SP_FOREGROUND);
     }
     closedir(d);
 }
@@ -287,9 +302,9 @@
                                               jint pid, jint pri)
 {
     if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        add_pid_to_cgroup(pid, ANDROID_TGROUP_BG_NONINTERACT);
+        setSchedPolicy(env, clazz, pid, SP_BACKGROUND);
     } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
-        add_pid_to_cgroup(pid, ANDROID_TGROUP_DEFAULT);
+        setSchedPolicy(env, clazz, pid, SP_FOREGROUND);
     }
 
     if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1fcfe63..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/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 250612f..0902c21 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1848,7 +1848,7 @@
     <!-- Title of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_title">USB debugging connected</string>
     <!-- Message of notification shown when ADB is actively connected to the phone. -->
-    <string name="adb_active_notification_message">A computer is connected to your phone.</string>
+    <string name="adb_active_notification_message">Select to disable USB debugging.</string>
 
     <!-- Used to replace %s in urls retreived from the signin server with locales.  For Some        -->
     <!-- devices we don't support all the locales we ship to and need to replace the '%s' with a    -->
@@ -1858,7 +1858,7 @@
     <string name="locale_replacement">""</string>
 
     <!-- Title of the pop-up dialog in which the user switches input method components. -->
-    <string name="select_input_method">Select Input Method</string>
+    <string name="select_input_method">Select input method</string>
 
     <string name="fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
     <string name="fast_scroll_numeric_alphabet">\u00200123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
@@ -1974,5 +1974,8 @@
     <string name="wallpaper_binding_label">Wallpaper</string>
     <!-- Dialog title for user to select a different wallpaper from service list -->
     <string name="chooser_wallpaper">Change wallpaper</string>
-    
+
+    <!-- Do Not Translate: Alternate eri.xml -->
+    <string name="alternate_eri_file">/data/eri.xml</string>
+
 </resources>
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..71811de 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>
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/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
new file mode 100644
index 0000000..feb66e3
--- /dev/null
+++ b/include/media/stagefright/MediaDefs.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef MEDIA_DEFS_H_
+
+#define MEDIA_DEFS_H_
+
+namespace android {
+
+extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
+
+extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
+extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
+extern const char *MEDIA_MIMETYPE_VIDEO_H263;
+extern const char *MEDIA_MIMETYPE_VIDEO_RAW;
+
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_NB;
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB;
+extern const char *MEDIA_MIMETYPE_AUDIO_MPEG;
+extern const char *MEDIA_MIMETYPE_AUDIO_AAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_RAW;
+
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG4;
+
+}  // namespace android
+
+#endif  // MEDIA_DEFS_H_
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 7f99553..ff7e34a 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -33,7 +33,12 @@
     static sp<OMXCodec> Create(
             const sp<IOMX> &omx,
             const sp<MetaData> &meta, bool createEncoder,
-            const sp<MediaSource> &source);
+            const sp<MediaSource> &source,
+            const char *matchComponentName = NULL);
+
+    static void setComponentRole(
+            const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
+            const char *mime);
 
     virtual status_t start(MetaData *params = NULL);
     virtual status_t stop();
@@ -206,6 +211,32 @@
     OMXCodec &operator=(const OMXCodec &);
 };
 
+struct CodecProfileLevel {
+    OMX_U32 mProfile;
+    OMX_U32 mLevel;
+};
+
+struct CodecCapabilities {
+    String8 mComponentName;
+    Vector<CodecProfileLevel> mProfileLevels;
+};
+
+// Return a vector of componentNames with supported profile/level pairs
+// supporting the given mime type, if queryDecoders==true, returns components
+// that decode content of the given type, otherwise returns components
+// that encode content of the given type.
+// profile and level indications only make sense for h.263, mpeg4 and avc
+// video.
+// The profile/level values correspond to
+// OMX_VIDEO_H263PROFILETYPE, OMX_VIDEO_MPEG4PROFILETYPE,
+// OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263LEVELTYPE, OMX_VIDEO_MPEG4LEVELTYPE
+// and OMX_VIDEO_AVCLEVELTYPE respectively.
+
+status_t QueryCodecs(
+        const sp<IOMX> &omx,
+        const char *mimeType, bool queryDecoders,
+        Vector<CodecCapabilities> *results);
+
 }  // namespace android
 
 #endif  // OMX_CODEC_H_
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..f5304f7 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -90,6 +90,11 @@
     ANDROID_TGROUP_MAX              = ANDROID_TGROUP_FG_BOOST,
 };
 
+typedef enum {
+    SP_BACKGROUND = 0,
+    SP_FOREGROUND = 1,
+} SchedPolicy;
+
 // Create and run a new thread.
 extern int androidCreateThread(android_thread_func_t, void *);
 
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/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 4772aca..8d85ce2 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -22,6 +22,7 @@
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
@@ -66,7 +67,7 @@
     float confidence;
     if (SniffAMR(mDataSource, &mimeType, &confidence)) {
         mInitCheck = OK;
-        mIsWide = (mimeType == "audio/amr-wb");
+        mIsWide = (mimeType == MEDIA_MIMETYPE_AUDIO_AMR_WB);
     }
 }
 
@@ -96,7 +97,10 @@
 // static
 sp<MetaData> AMRExtractor::makeAMRFormat(bool isWide) {
     sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, isWide ? "audio/amr-wb" : "audio/3gpp");
+    meta->setCString(
+            kKeyMIMEType, isWide ? MEDIA_MIMETYPE_AUDIO_AMR_WB
+                                 : MEDIA_MIMETYPE_AUDIO_AMR_NB);
+
     meta->setInt32(kKeyChannelCount, 1);
     meta->setInt32(kKeySampleRate, isWide ? 16000 : 8000);
 
@@ -221,12 +225,12 @@
     }
 
     if (!memcmp(header, "#!AMR\n", 6)) {
-        *mimeType = "audio/3gpp";
+        *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_NB;
         *confidence = 0.5;
 
         return true;
     } else if (!memcmp(header, "#!AMR-WB\n", 9)) {
-        *mimeType = "audio/amr-wb";
+        *mimeType = MEDIA_MIMETYPE_AUDIO_AMR_WB;
         *confidence = 0.5;
 
         return true;
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index c3a4722..a4f2c79 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -13,6 +13,7 @@
         MPEG4Writer.cpp           \
         MediaBuffer.cpp           \
         MediaBufferGroup.cpp      \
+        MediaDefs.cpp             \
         MediaExtractor.cpp        \
         MediaPlayerImpl.cpp       \
         MediaSource.cpp           \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 140bc68..319488e 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -20,6 +20,7 @@
 #include <media/AudioTrack.h>
 #include <media/stagefright/AudioPlayer.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
 
@@ -61,7 +62,7 @@
     const char *mime;
     bool success = format->findCString(kKeyMIMEType, &mime);
     CHECK(success);
-    CHECK(!strcasecmp(mime, "audio/raw"));
+    CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW));
 
     success = format->findInt32(kKeySampleRate, &mSampleRate);
     CHECK(success);
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index f75b173..596ab67 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -155,7 +155,7 @@
 
 sp<MetaData> CameraSource::getFormat() {
     sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, "video/raw");
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
     meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420SemiPlanar);
     meta->setInt32(kKeyWidth, 480);
     meta->setInt32(kKeyHeight, 320);
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 14f3e0c..7fd699f 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
@@ -330,7 +331,7 @@
 
         mMeta = new MetaData;
 
-        mMeta->setCString(kKeyMIMEType, "audio/mpeg");
+        mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
         mMeta->setInt32(kKeySampleRate, sample_rate);
         mMeta->setInt32(kKeyBitRate, bitrate);
         mMeta->setInt32(kKeyChannelCount, num_channels);
@@ -510,7 +511,7 @@
         return false;
     }
 
-    *mimeType = "audio/mpeg";
+    *mimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
     *confidence = 0.3f;
 
     return true;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 433fb18..9174d19 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -29,6 +29,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/SampleTable.h>
@@ -116,25 +117,25 @@
     }
 }
 
-static const char *const FourCC2MIME(uint32_t fourcc) {
+static const char *FourCC2MIME(uint32_t fourcc) {
     switch (fourcc) {
         case FOURCC('m', 'p', '4', 'a'):
-            return "audio/mp4a-latm";
+            return MEDIA_MIMETYPE_AUDIO_AAC;
 
         case FOURCC('s', 'a', 'm', 'r'):
-            return "audio/3gpp";
+            return MEDIA_MIMETYPE_AUDIO_AMR_NB;
 
         case FOURCC('s', 'a', 'w', 'b'):
-            return "audio/amr-wb";
+            return MEDIA_MIMETYPE_AUDIO_AMR_WB;
 
         case FOURCC('m', 'p', '4', 'v'):
-            return "video/mp4v-es";
+            return MEDIA_MIMETYPE_VIDEO_MPEG4;
 
         case FOURCC('s', '2', '6', '3'):
-            return "video/3gpp";
+            return MEDIA_MIMETYPE_VIDEO_H263;
 
         case FOURCC('a', 'v', 'c', '1'):
-            return "video/avc";
+            return MEDIA_MIMETYPE_VIDEO_AVC;
 
         default:
             CHECK(!"should not be here.");
@@ -499,8 +500,10 @@
             uint16_t data_ref_index = U16_AT(&buffer[6]);
             uint16_t num_channels = U16_AT(&buffer[16]);
 
-            if (!strcasecmp("audio/3gpp", FourCC2MIME(chunk_type))
-                || !strcasecmp("audio/amr-wb", FourCC2MIME(chunk_type))) {
+            if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB,
+                            FourCC2MIME(chunk_type))
+                || !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB,
+                               FourCC2MIME(chunk_type))) {
                 // AMR audio is always mono.
                 num_channels = 1;
             }
@@ -746,7 +749,7 @@
     success = mFormat->findInt32(kKeyTimeScale, &mTimescale);
     CHECK(success);
 
-    mIsAVC = !strcasecmp(mime, "video/avc");
+    mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
 }
 
 MPEG4Source::~MPEG4Source() {
@@ -978,7 +981,7 @@
 
     if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
         || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)) {
-        *mimeType = "video/mp4";
+        *mimeType = MEDIA_MIMETYPE_CONTAINER_MPEG4;
         *confidence = 0.1;
 
         return true;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index d3da889..fa35768 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaSource.h>
 #include <media/stagefright/Utils.h>
 
@@ -351,7 +352,7 @@
     sp<MetaData> meta = mSource->getFormat();
     const char *mime;
     meta->findCString(kKeyMIMEType, &mime);
-    is_mpeg4 = !strcasecmp(mime, "video/mp4v-es");
+    is_mpeg4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4);
 
     MediaBuffer *buffer;
     while (!mDone && mSource->read(&buffer) == OK) {
@@ -528,9 +529,9 @@
             mOwner->writeInt32(1);               // entry count
             if (is_audio) {
                 const char *fourcc = NULL;
-                if (!strcasecmp("audio/3gpp", mime)) {
+                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
                     fourcc = "samr";
-                } else if (!strcasecmp("audio/amr-wb", mime)) {
+                } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
                     fourcc = "sawb";
                 } else {
                     LOGE("Unknown mime type '%s'.", mime);
@@ -555,9 +556,9 @@
                   mOwner->writeInt32(samplerate << 16);
                 mOwner->endBox();
             } else {
-                if (!strcasecmp("video/mp4v-es", mime)) {
+                if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
                     mOwner->beginBox("mp4v");
-                } else if (!strcasecmp("video/3gpp", mime)) {
+                } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
                     mOwner->beginBox("s263");
                 } else {
                     LOGE("Unknown mime type '%s'.", mime);
@@ -590,7 +591,7 @@
 
                   CHECK(23 + mCodecSpecificDataSize < 128);
 
-                  if (!strcasecmp("video/mp4v-es", mime)) {
+                  if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
                       mOwner->beginBox("esds");
 
                         mOwner->writeInt32(0);           // version=0, flags=0
@@ -625,7 +626,7 @@
                         mOwner->write(kData2, sizeof(kData2));
 
                       mOwner->endBox();  // esds
-                  } else if (!strcasecmp("video/3gpp", mime)) {
+                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
                       mOwner->beginBox("d263");
 
                           mOwner->writeInt32(0);  // vendor
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
new file mode 100644
index 0000000..87b5b24
--- /dev/null
+++ b/media/libstagefright/MediaDefs.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include <media/stagefright/MediaDefs.h>
+
+namespace android {
+
+const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg";
+
+const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
+const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
+const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp";
+const char *MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
+
+const char *MEDIA_MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
+const char *MEDIA_MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
+const char *MEDIA_MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+const char *MEDIA_MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+const char *MEDIA_MIMETYPE_AUDIO_RAW = "audio/raw";
+
+const char *MEDIA_MIMETYPE_CONTAINER_MPEG4 = "video/mpeg4";
+
+}  // namespace android
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 8afa8e1..8535f52 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -20,6 +20,7 @@
 
 #include <media/stagefright/AMRExtractor.h>
 #include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MP3Extractor.h>
 #include <media/stagefright/MPEG4Extractor.h>
 #include <media/stagefright/MediaExtractor.h>
@@ -44,12 +45,13 @@
              mime, confidence);
     }
 
-    if (!strcasecmp(mime, "video/mp4") || !strcasecmp(mime, "audio/mp4")) {
+    if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG4)
+            || !strcasecmp(mime, "audio/mp4")) {
         return new MPEG4Extractor(source);
-    } else if (!strcasecmp(mime, "audio/mpeg")) {
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEG)) {
         return new MP3Extractor(source);
-    } else if (!strcasecmp(mime, "audio/3gpp")
-            || !strcasecmp(mime, "audio/amr-wb")) {
+    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)
+            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
         return new AMRExtractor(source);
     }
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 034457f..a964d17 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -26,6 +26,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/MmapSource.h>
@@ -44,40 +45,40 @@
 };
 
 static const CodecInfo kDecoderInfo[] = {
-    { "image/jpeg", "OMX.TI.JPEG.decode" },
-    { "audio/mpeg", "OMX.TI.MP3.decode" },
-    { "audio/mpeg", "OMX.PV.mp3dec" },
-    { "audio/3gpp", "OMX.TI.AMR.decode" },
-    { "audio/3gpp", "OMX.PV.amrdec" },
-    { "audio/amr-wb", "OMX.TI.WBAMR.decode" },
-    { "audio/amr-wb", "OMX.PV.amrdec" },
-    { "audio/mp4a-latm", "OMX.TI.AAC.decode" },
-    { "audio/mp4a-latm", "OMX.PV.aacdec" },
-    { "video/mp4v-es", "OMX.qcom.video.decoder.mpeg4" },
-    { "video/mp4v-es", "OMX.TI.Video.Decoder" },
-    { "video/mp4v-es", "OMX.PV.mpeg4dec" },
-    { "video/3gpp", "OMX.qcom.video.decoder.h263" },
-    { "video/3gpp", "OMX.TI.Video.Decoder" },
-    { "video/3gpp", "OMX.PV.h263dec" },
-    { "video/avc", "OMX.qcom.video.decoder.avc" },
-    { "video/avc", "OMX.TI.Video.Decoder" },
-    { "video/avc", "OMX.PV.avcdec" },
+    { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
+    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
+    { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" },
+    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" },
+    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.decoder.mpeg4" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" },
 };
 
 static const CodecInfo kEncoderInfo[] = {
-    { "audio/3gpp", "OMX.TI.AMR.encode" },
-    { "audio/3gpp", "OMX.PV.amrencnb" },
-    { "audio/amr-wb", "OMX.TI.WBAMR.encode" },
-    { "audio/mp4a-latm", "OMX.TI.AAC.encode" },
-    { "audio/mp4a-latm", "OMX.PV.aacenc" },
-    { "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
-    { "video/mp4v-es", "OMX.TI.Video.encoder" },
-    { "video/mp4v-es", "OMX.PV.mpeg4enc" },
-    { "video/3gpp", "OMX.qcom.video.encoder.h263" },
-    { "video/3gpp", "OMX.TI.Video.encoder" },
-    { "video/3gpp", "OMX.PV.h263enc" },
-    { "video/avc", "OMX.TI.Video.encoder" },
-    { "video/avc", "OMX.PV.avcenc" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.encode" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrencnb" },
+    { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.encode" },
+    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" },
+    { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" },
+    { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" },
+    { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" },
+    { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" },
 };
 
 #define CODEC_LOGI(x, ...) LOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
@@ -169,7 +170,8 @@
 sp<OMXCodec> OMXCodec::Create(
         const sp<IOMX> &omx,
         const sp<MetaData> &meta, bool createEncoder,
-        const sp<MediaSource> &source) {
+        const sp<MediaSource> &source,
+        const char *matchComponentName) {
     const char *mime;
     bool success = meta->findCString(kKeyMIMEType, &mime);
     CHECK(success);
@@ -191,6 +193,11 @@
             return NULL;
         }
 
+        // If a specific codec is requested, skip the non-matching ones.
+        if (matchComponentName && strcmp(componentName, matchComponentName)) {
+            continue;
+        }
+
         LOGV("Attempting to allocate OMX node '%s'", componentName);
 
         status_t err = omx->allocate_node(componentName, &node);
@@ -318,13 +325,13 @@
         }
     }
 
-    if (!strcasecmp("audio/3gpp", mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
         codec->setAMRFormat();
     }
-    if (!strcasecmp("audio/amr-wb", mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
         codec->setAMRWBFormat();
     }
-    if (!strcasecmp("audio/mp4a-latm", mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
         int32_t numChannels, sampleRate;
         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
@@ -343,7 +350,7 @@
             codec->setVideoOutputFormat(mime, width, height);
         }
     }
-    if (!strcasecmp(mime, "image/jpeg")
+    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
         && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
         OMX_COLOR_FORMATTYPE format =
             OMX_COLOR_Format32bitARGB8888;
@@ -471,11 +478,11 @@
     CODEC_LOGI("setVideoInputFormat width=%ld, height=%ld", width, height);
 
     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
-    if (!strcasecmp("video/avc", mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
         compressionFormat = OMX_VIDEO_CodingAVC;
-    } else if (!strcasecmp("video/mp4v-es", mime)) {
+    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
         compressionFormat = OMX_VIDEO_CodingMPEG4;
-    } else if (!strcasecmp("video/3gpp", mime)) {
+    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
         compressionFormat = OMX_VIDEO_CodingH263;
     } else {
         LOGE("Not a supported video mime type: %s", mime);
@@ -547,11 +554,11 @@
     CODEC_LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
 
     OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
-    if (!strcasecmp("video/avc", mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
         compressionFormat = OMX_VIDEO_CodingAVC;
-    } else if (!strcasecmp("video/mp4v-es", mime)) {
+    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
         compressionFormat = OMX_VIDEO_CodingMPEG4;
-    } else if (!strcasecmp("video/3gpp", mime)) {
+    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
         compressionFormat = OMX_VIDEO_CodingH263;
     } else {
         LOGE("Not a supported video mime type: %s", mime);
@@ -670,7 +677,10 @@
     setComponentRole();
 }
 
-void OMXCodec::setComponentRole() {
+// static
+void OMXCodec::setComponentRole(
+        const sp<IOMX> &omx, IOMX::node_id node, bool isEncoder,
+        const char *mime) {
     struct MimeToRole {
         const char *mime;
         const char *decoderRole;
@@ -678,13 +688,20 @@
     };
 
     static const MimeToRole kMimeToRole[] = {
-        { "audio/mpeg", "audio_decoder.mp3", "audio_encoder.mp3" },
-        { "audio/3gpp", "audio_decoder.amrnb", "audio_encoder.amrnb" },
-        { "audio/amr-wb", "audio_decoder.amrwb", "audio_encoder.amrwb" },
-        { "audio/mp4a-latm", "audio_decoder.aac", "audio_encoder.aac" },
-        { "video/avc",  "video_decoder.avc", "video_encoder.avc" },
-        { "video/mp4v-es", "video_decoder.mpeg4", "video_encoder.mpeg4" },
-        { "video/3gpp", "video_decoder.h263", "video_encoder.h263" },
+        { MEDIA_MIMETYPE_AUDIO_MPEG,
+            "audio_decoder.mp3", "audio_encoder.mp3" },
+        { MEDIA_MIMETYPE_AUDIO_AMR_NB,
+            "audio_decoder.amrnb", "audio_encoder.amrnb" },
+        { MEDIA_MIMETYPE_AUDIO_AMR_WB,
+            "audio_decoder.amrwb", "audio_encoder.amrwb" },
+        { MEDIA_MIMETYPE_AUDIO_AAC,
+            "audio_decoder.aac", "audio_encoder.aac" },
+        { MEDIA_MIMETYPE_VIDEO_AVC,
+            "video_decoder.avc", "video_encoder.avc" },
+        { MEDIA_MIMETYPE_VIDEO_MPEG4,
+            "video_decoder.mpeg4", "video_encoder.mpeg4" },
+        { MEDIA_MIMETYPE_VIDEO_H263,
+            "video_decoder.h263", "video_encoder.h263" },
     };
 
     static const size_t kNumMimeToRole =
@@ -692,7 +709,7 @@
 
     size_t i;
     for (i = 0; i < kNumMimeToRole; ++i) {
-        if (!strcasecmp(mMIME, kMimeToRole[i].mime)) {
+        if (!strcasecmp(mime, kMimeToRole[i].mime)) {
             break;
         }
     }
@@ -702,12 +719,10 @@
     }
 
     const char *role =
-        mIsEncoder ? kMimeToRole[i].encoderRole
-                   : kMimeToRole[i].decoderRole;
+        isEncoder ? kMimeToRole[i].encoderRole
+                  : kMimeToRole[i].decoderRole;
 
     if (role != NULL) {
-        CODEC_LOGV("Setting component role '%s'.", role);
-
         OMX_PARAM_COMPONENTROLETYPE roleParams;
         InitOMXParams(&roleParams);
 
@@ -716,8 +731,8 @@
 
         roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
 
-        status_t err = mOMX->set_parameter(
-                mNode, OMX_IndexParamStandardComponentRole,
+        status_t err = omx->set_parameter(
+                node, OMX_IndexParamStandardComponentRole,
                 &roleParams, sizeof(roleParams));
 
         if (err != OK) {
@@ -726,6 +741,10 @@
     }
 }
 
+void OMXCodec::setComponentRole() {
+    setComponentRole(mOMX, mNode, mIsEncoder, mMIME);
+}
+
 OMXCodec::~OMXCodec() {
     CHECK(mState == LOADED || mState == ERROR);
 
@@ -1359,7 +1378,7 @@
 
         size_t size = specific->mSize;
 
-        if (!strcasecmp("video/avc", mMIME)
+        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME)
                 && !(mQuirks & kWantsNALFragments)) {
             static const uint8_t kNALStartCode[4] =
                     { 0x00, 0x00, 0x00, 0x01 };
@@ -2250,7 +2269,7 @@
             OMX_IMAGE_PORTDEFINITIONTYPE *imageDef = &def.format.image;
             CHECK_EQ(imageDef->eCompressionFormat, OMX_IMAGE_CodingUnused);
 
-            mOutputFormat->setCString(kKeyMIMEType, "image/raw");
+            mOutputFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
             mOutputFormat->setInt32(kKeyColorFormat, imageDef->eColorFormat);
             mOutputFormat->setInt32(kKeyWidth, imageDef->nFrameWidth);
             mOutputFormat->setInt32(kKeyHeight, imageDef->nFrameHeight);
@@ -2283,7 +2302,8 @@
                          "the input stream contains.");
                 }
 
-                mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
 
                 // Use the codec-advertised number of channels, as some
                 // codecs appear to output stereo even if the input data is
@@ -2306,17 +2326,20 @@
 
                 if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeNB0
                     && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeNB7) {
-                    mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
+                    mOutputFormat->setCString(
+                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
                     mOutputFormat->setInt32(kKeySampleRate, 8000);
                 } else if (amr.eAMRBandMode >= OMX_AUDIO_AMRBandModeWB0
                             && amr.eAMRBandMode <= OMX_AUDIO_AMRBandModeWB8) {
-                    mOutputFormat->setCString(kKeyMIMEType, "audio/amr-wb");
+                    mOutputFormat->setCString(
+                            kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
                     mOutputFormat->setInt32(kKeySampleRate, 16000);
                 } else {
                     CHECK(!"Unknown AMR band mode.");
                 }
             } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
-                mOutputFormat->setCString(kKeyMIMEType, "audio/mp4a-latm");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
             } else {
                 CHECK(!"Should not be here. Unknown audio encoding.");
             }
@@ -2328,13 +2351,17 @@
             OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
 
             if (video_def->eCompressionFormat == OMX_VIDEO_CodingUnused) {
-                mOutputFormat->setCString(kKeyMIMEType, "video/raw");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingMPEG4) {
-                mOutputFormat->setCString(kKeyMIMEType, "video/mp4v-es");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingH263) {
-                mOutputFormat->setCString(kKeyMIMEType, "video/3gpp");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
             } else if (video_def->eCompressionFormat == OMX_VIDEO_CodingAVC) {
-                mOutputFormat->setCString(kKeyMIMEType, "video/avc");
+                mOutputFormat->setCString(
+                        kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
             } else {
                 CHECK(!"Unknown compression format.");
             }
@@ -2362,4 +2389,67 @@
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+
+status_t QueryCodecs(
+        const sp<IOMX> &omx,
+        const char *mime, bool queryDecoders,
+        Vector<CodecCapabilities> *results) {
+    results->clear();
+
+    for (int index = 0;; ++index) {
+        const char *componentName;
+
+        if (!queryDecoders) {
+            componentName = GetCodec(
+                    kEncoderInfo, sizeof(kEncoderInfo) / sizeof(kEncoderInfo[0]),
+                    mime, index);
+        } else {
+            componentName = GetCodec(
+                    kDecoderInfo, sizeof(kDecoderInfo) / sizeof(kDecoderInfo[0]),
+                    mime, index);
+        }
+
+        if (!componentName) {
+            return OK;
+        }
+
+        IOMX::node_id node;
+        status_t err = omx->allocate_node(componentName, &node);
+
+        if (err != OK) {
+            continue;
+        }
+
+        OMXCodec::setComponentRole(omx, node, queryDecoders, mime);
+
+        results->push();
+        CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
+        caps->mComponentName = componentName;
+
+        OMX_VIDEO_PARAM_PROFILELEVELTYPE param;
+        InitOMXParams(&param);
+
+        param.nPortIndex = queryDecoders ? 0 : 1;
+
+        for (param.nProfileIndex = 0;; ++param.nProfileIndex) {
+            err = omx->get_parameter(
+                    node, OMX_IndexParamVideoProfileLevelQuerySupported,
+                    &param, sizeof(param));
+
+            if (err != OK) {
+                break;
+            }
+
+            CodecProfileLevel profileLevel;
+            profileLevel.mProfile = param.eProfile;
+            profileLevel.mLevel = param.eLevel;
+
+            caps->mProfileLevels.push(profileLevel);
+        }
+
+        CHECK_EQ(omx->free_node(node), OK);
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/ShoutcastSource.cpp b/media/libstagefright/ShoutcastSource.cpp
index 4375f38..8e8f4fa 100644
--- a/media/libstagefright/ShoutcastSource.cpp
+++ b/media/libstagefright/ShoutcastSource.cpp
@@ -20,6 +20,7 @@
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaBufferGroup.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/ShoutcastSource.h>
 #include <media/stagefright/string.h>
@@ -77,7 +78,7 @@
 
 sp<MetaData> ShoutcastSource::getFormat() {
     sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, "audio/mpeg");
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
     meta->setInt32(kKeySampleRate, 44100);
     meta->setInt32(kKeyChannelCount, 2);  // XXX
 
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/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/PackageManagerBackupAgent.java b/services/java/com/android/server/PackageManagerBackupAgent.java
index 786f423..772ddeb 100644
--- a/services/java/com/android/server/PackageManagerBackupAgent.java
+++ b/services/java/com/android/server/PackageManagerBackupAgent.java
@@ -327,6 +327,13 @@
         try {
             int num = in.readInt();
             Log.v(TAG, " ... unflatten read " + num);
+
+            // Sensical?
+            if (num > 20) {
+                Log.e(TAG, "Suspiciously large sig count in restore data; aborting");
+                throw new IllegalStateException("Bad restore state");
+            }
+
             sigs = new Signature[num];
             for (int i = 0; i < num; i++) {
                 int len = in.readInt();
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/EriManager.java b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
index 6c1384c..44c6173 100644
--- a/telephony/java/com/android/internal/telephony/cdma/EriManager.java
+++ b/telephony/java/com/android/internal/telephony/cdma/EriManager.java
@@ -19,12 +19,19 @@
 import android.content.res.XmlResourceParser;
 import android.os.Message;
 import android.util.Log;
+import android.util.Xml;
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
 
 import com.android.internal.util.XmlUtils;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.HashMap;
 
 /**
@@ -76,7 +83,8 @@
         }
     }
 
-    static final String LOG_TAG = "CDMA";
+    private static final String LOG_TAG = "CDMA";
+    private static final boolean DBG = true;
 
     public static final int ERI_FROM_XML          = 0;
     public static final int ERI_FROM_FILE_SYSTEM  = 1;
@@ -143,8 +151,30 @@
      *
      */
     private void loadEriFileFromXml() {
+        XmlPullParser parser = null;
+        FileInputStream stream = null;
         Resources r = mContext.getResources();
-        XmlResourceParser parser = r.getXml(com.android.internal.R.xml.eri);
+
+        try {
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: check for alternate file");
+            stream = new FileInputStream(
+                            r.getString(com.android.internal.R.string.alternate_eri_file));
+            parser = Xml.newPullParser();
+            parser.setInput(stream, null);
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: opened alternate file");
+        } catch (FileNotFoundException e) {
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no alternate file");
+            parser = null;
+        } catch (XmlPullParserException e) {
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: no parser for alternate file");
+            parser = null;
+        }
+
+        if (parser == null) {
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: open normal file");
+            parser = r.getXml(com.android.internal.R.xml.eri);
+        }
+
         try {
             XmlUtils.beginDocument(parser, "EriFile");
             mEriFile.mVersionNumber = Integer.parseInt(
@@ -187,12 +217,22 @@
                 }
             }
 
+            if (DBG) Log.d(LOG_TAG, "loadEriFileFromXml: eri parsing successful, file loaded");
             isEriFileLoaded = true;
 
         } catch (Exception e) {
             Log.e(LOG_TAG, "Got exception while loading ERI file.", e);
         } finally {
-            parser.close();
+            if (parser instanceof XmlResourceParser) {
+                ((XmlResourceParser)parser).close();
+            }
+            try {
+                if (stream != null) {
+                    stream.close();
+                }
+            } catch (IOException e) {
+                // Ignore
+            }
         }
     }
 
@@ -345,16 +385,16 @@
         default:
             if (!isEriFileLoaded) {
                 // ERI file NOT loaded
-                Log.d(LOG_TAG, "ERI File not loaded");
+                if (DBG) Log.d(LOG_TAG, "ERI File not loaded");
                 if(defRoamInd > 2) {
-                    Log.d(LOG_TAG, "ERI defRoamInd > 2 ...flashing");
+                    if (DBG) Log.d(LOG_TAG, "ERI defRoamInd > 2 ...flashing");
                     ret = new EriDisplayInformation(
                             EriInfo.ROAMING_INDICATOR_FLASH,
                             EriInfo.ROAMING_ICON_MODE_FLASH,
                             mContext.getText(com.android.internal
                                                             .R.string.roamingText2).toString());
                 } else {
-                    Log.d(LOG_TAG, "ERI defRoamInd <= 2");
+                    if (DBG) Log.d(LOG_TAG, "ERI defRoamInd <= 2");
                     switch (defRoamInd) {
                     case EriInfo.ROAMING_INDICATOR_ON:
                         ret = new EriDisplayInformation(
@@ -386,12 +426,14 @@
                 }
             } else {
                 // ERI file loaded
-                Log.d(LOG_TAG, "ERI File loaded");
+                if (DBG) Log.d(LOG_TAG, "ERI File loaded");
                 EriInfo eriInfo = getEriInfo(roamInd);
                 EriInfo defEriInfo = getEriInfo(defRoamInd);
                 if (eriInfo == null) {
-                    Log.d(LOG_TAG, "ERI roamInd " + roamInd
+                    if (DBG) {
+                        Log.d(LOG_TAG, "ERI roamInd " + roamInd
                             + " not found in ERI file ...using defRoamInd " + defRoamInd);
+                    }
                     if(defEriInfo == null) {
                         Log.e(LOG_TAG, "ERI defRoamInd " + defRoamInd
                                 + " not found in ERI file ...on");
@@ -402,14 +444,16 @@
                                                              .R.string.roamingText0).toString());
 
                     } else {
-                        Log.d(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file");
+                        if (DBG) {
+                            Log.d(LOG_TAG, "ERI defRoamInd " + defRoamInd + " found in ERI file");
+                        }
                         ret = new EriDisplayInformation(
                                 defEriInfo.mIconIndex,
                                 defEriInfo.mIconMode,
                                 defEriInfo.mEriText);
                     }
                 } else {
-                    Log.d(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
+                    if (DBG) Log.d(LOG_TAG, "ERI roamInd " + roamInd + " found in ERI file");
                     ret = new EriDisplayInformation(
                             eriInfo.mIconIndex,
                             eriInfo.mIconMode,
@@ -418,7 +462,7 @@
             }
             break;
         }
-        Log.d(LOG_TAG, "Displaying ERI " + ret.toString());
+        if (DBG) Log.d(LOG_TAG, "Displaying ERI " + ret.toString());
         return ret;
     }