Merge change 23646 into eclair

* changes:
  Immediately destroy BluetoothSocket's on close().
diff --git a/api/4.xml b/api/4.xml
index 49f5271..bca9816 100644
--- a/api/4.xml
+++ b/api/4.xml
@@ -4123,6 +4123,17 @@
  visibility="public"
 >
 </field>
+<field name="includeInGlobalSearch"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843374"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="indeterminate"
  type="int"
  transient="false"
@@ -6191,6 +6202,17 @@
  visibility="public"
 >
 </field>
+<field name="queryAfterZeroResults"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843394"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="radioButtonStyle"
  type="int"
  transient="false"
@@ -6686,6 +6708,17 @@
  visibility="public"
 >
 </field>
+<field name="searchSettingsDescription"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843402"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="searchSuggestAuthority"
  type="int"
  transient="false"
@@ -6741,6 +6774,17 @@
  visibility="public"
 >
 </field>
+<field name="searchSuggestThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843373"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="secondaryProgress"
  type="int"
  transient="false"
@@ -21158,6 +21202,17 @@
  visibility="public"
 >
 </field>
+<field name="INTENT_ACTION_WEB_SEARCH_SETTINGS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.search.action.WEB_SEARCH_SETTINGS&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="MENU_KEY"
  type="char"
  transient="false"
@@ -21191,6 +21246,17 @@
  visibility="public"
 >
 </field>
+<field name="SHORTCUT_MIME_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;vnd.android.cursor.item/vnd.android.search.suggest&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_COLUMN_FORMAT"
  type="java.lang.String"
  transient="false"
@@ -21279,6 +21345,28 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_COLUMN_SHORTCUT_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;suggest_shortcut_id&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;suggest_spinner_while_refreshing&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_COLUMN_TEXT_1"
  type="java.lang.String"
  transient="false"
@@ -21312,6 +21400,17 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_NEVER_MAKE_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;_-1&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SUGGEST_URI_PATH_QUERY"
  type="java.lang.String"
  transient="false"
@@ -21323,6 +21422,17 @@
  visibility="public"
 >
 </field>
+<field name="SUGGEST_URI_PATH_SHORTCUT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;search_suggest_shortcut&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="USER_QUERY"
  type="java.lang.String"
  transient="false"
diff --git a/api/current.xml b/api/current.xml
index 7e6c2df..d8609ec 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -4695,6 +4695,17 @@
  visibility="public"
 >
 </field>
+<field name="killAfterRestore"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843416"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="label"
  type="int"
  transient="false"
@@ -6477,6 +6488,17 @@
  visibility="public"
 >
 </field>
+<field name="restoreNeedsApplication"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843417"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="right"
  type="int"
  transient="false"
@@ -18039,6 +18061,50 @@
  visibility="public"
 >
 </field>
+<field name="FLAG_FOREGROUND"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_PERSISTENT_PROCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_STARTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLAG_SYSTEM_PROCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="activeSince"
  type="long"
  transient="false"
@@ -18069,6 +18135,16 @@
  visibility="public"
 >
 </field>
+<field name="flags"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="foreground"
  type="boolean"
  transient="false"
@@ -18139,6 +18215,16 @@
  visibility="public"
 >
 </field>
+<field name="uid"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="ActivityManager.RunningTaskInfo"
  extends="java.lang.Object"
@@ -64966,6 +65052,39 @@
 <parameter name="key" type="java.lang.String">
 </parameter>
 </method>
+<method name="getAntibanding"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getColorEffect"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFlashMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getInt"
  return="int"
  abstract="false"
@@ -64979,6 +65098,39 @@
 <parameter name="key" type="java.lang.String">
 </parameter>
 </method>
+<method name="getJpegQuality"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getJpegThumbnailQuality"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getJpegThumbnailSize"
+ return="android.hardware.Camera.Size"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getPictureFormat"
  return="int"
  abstract="false"
@@ -65034,6 +65186,138 @@
  visibility="public"
 >
 </method>
+<method name="getSceneMode"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedAntibanding"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedColorEffects"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedFlashModes"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPictureFormats"
+ return="java.util.List&lt;java.lang.Integer&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPictureSizes"
+ return="java.util.List&lt;android.hardware.Camera.Size&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewFormats"
+ return="java.util.List&lt;java.lang.Integer&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewFrameRates"
+ return="java.util.List&lt;java.lang.Integer&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedPreviewSizes"
+ return="java.util.List&lt;android.hardware.Camera.Size&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedSceneModes"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSupportedWhiteBalance"
+ return="java.util.List&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getWhiteBalance"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="remove"
  return="void"
  abstract="false"
@@ -65047,6 +65331,17 @@
 <parameter name="key" type="java.lang.String">
 </parameter>
 </method>
+<method name="removeGpsData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="set"
  return="void"
  abstract="false"
@@ -65077,6 +65372,138 @@
 <parameter name="value" type="int">
 </parameter>
 </method>
+<method name="setAntibanding"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="antibanding" type="java.lang.String">
+</parameter>
+</method>
+<method name="setColorEffect"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setFlashMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setGpsAltitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="altitude" type="double">
+</parameter>
+</method>
+<method name="setGpsLatitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="latitude" type="double">
+</parameter>
+</method>
+<method name="setGpsLongitude"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="longitude" type="double">
+</parameter>
+</method>
+<method name="setGpsTimestamp"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timestamp" type="long">
+</parameter>
+</method>
+<method name="setJpegQuality"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="quality" type="int">
+</parameter>
+</method>
+<method name="setJpegThumbnailQuality"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="quality" type="int">
+</parameter>
+</method>
+<method name="setJpegThumbnailSize"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+</method>
 <method name="setPictureFormat"
  return="void"
  abstract="false"
@@ -65146,6 +65573,45 @@
 <parameter name="height" type="int">
 </parameter>
 </method>
+<method name="setRotation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="rotation" type="int">
+</parameter>
+</method>
+<method name="setSceneMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
+<method name="setWhiteBalance"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+</method>
 <method name="unflatten"
  return="void"
  abstract="false"
@@ -65159,6 +65625,446 @@
 <parameter name="flattened" type="java.lang.String">
 </parameter>
 </method>
+<field name="ANTIBANDING_50HZ"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;50hz&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_60HZ"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;60hz&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;auto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ANTIBANDING_OFF"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;off&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_AQUA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;aqua&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_BLACKBOARD"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;blackboard&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_MONO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;mono&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_NEGATIVE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;negative&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_NONE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;none&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_POSTERIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;posterize&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_SEPIA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;sepia&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_SOLARIZE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;solarize&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EFFECT_WHITEBOARD"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;whiteboard&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;auto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_OFF"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;off&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_ON"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;on&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="FLASH_MODE_RED_EYE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;red-eye&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_ACTION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;action&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;auto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_BEACH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;beach&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_CANDLELIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;candlelight&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_FIREWORKS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;fireworks&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_LANDSCAPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;landscape&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_NIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;night&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_NIGHT_PORTRAIT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;night-portrait&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_PARTY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;party&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_PORTRAIT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;portrait&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SNOW"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;snow&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SPORTS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;sports&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_STEADYPHOTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;steadyphoto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_SUNSET"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;sunset&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCENE_MODE_THEATRE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;theatre&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_AUTO"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;auto&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_CLOUDY_DAYLIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;cloudy-daylight&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_DAYLIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;daylight&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_FLUORESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;fluorescent&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_INCANDESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;incandescent&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_SHADE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;shade&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_TWILIGHT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;twilight&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="WHITE_BALANCE_WARM_FLUORESCENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;warm-fluorescent&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <interface name="Camera.PictureCallback"
  abstract="true"
@@ -97544,6 +98450,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<implements name="android.os.Parcelable">
+</implements>
 <constructor name="Debug.MemoryInfo"
  type="android.os.Debug.MemoryInfo"
  static="false"
@@ -97552,6 +98460,55 @@
  visibility="public"
 >
 </constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="readFromParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="source" type="android.os.Parcel">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="dalvikPrivateDirty"
  type="int"
  transient="false"
@@ -117279,6 +118236,17 @@
  visibility="public"
 >
 </method>
+<method name="hasIccCard"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isNetworkRoaming"
  return="boolean"
  abstract="false"
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 18713e9..3ddc922 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -20,6 +20,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <limits.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -34,6 +35,8 @@
 
 static struct tm now;
 
+static void dump_kernel_log(const char *path, const char *title) ;
+
 /* dumps the current system state to stdout */
 static void dumpstate(int full) {
     if (full) {
@@ -101,8 +104,12 @@
         DUMP("/data/system/packages.xml");
         PRINT("------ PACKAGE UID ERRORS ------");
         DUMP("/data/system/uiderrors.txt");
-        PRINT("------ LAST KERNEL LOG ------");
-        DUMP("/data/last_kmsg");
+
+        dump_kernel_log("/data/dontpanic/last_kmsg", "RAMCONSOLE");
+        dump_kernel_log("/data/dontpanic/apanic_console",
+                        "PANIC CONSOLE");
+        dump_kernel_log("/data/dontpanic/apanic_threads",
+                        "PANIC THREADS");
     }
     PRINT("========================================================");
     PRINT("== build.prop");
@@ -295,3 +302,13 @@
     return 0;
 }
 
+static void dump_kernel_log(const char *path, const char *title) 
+
+{
+	printf("------ KERNEL %s LOG ------\n", title);
+        if (access(path, R_OK) < 0)
+		printf("%s: %s\n", path, strerror(errno));
+	else
+        	DUMP(path);
+}
+
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 5ed8941..8cfb758 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1397,7 +1397,7 @@
                 Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi);
             }
 
-            if (!imsi.equals(storedImsi) && !"initial".equals(storedImsi)) {
+            if (!imsi.equals(storedImsi) && !TextUtils.isEmpty(storedImsi)) {
                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.v(TAG, "wiping all passwords and authtokens");
                 }
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 07520c9d..ad06fa9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -289,6 +289,11 @@
         public int pid;
         
         /**
+         * The UID that owns this service.
+         */
+        public int uid;
+        
+        /**
          * The name of the process this service runs in.
          */
         public String process;
@@ -299,7 +304,7 @@
         public boolean foreground;
         
         /**
-         * The time when the service was first made activity, either by someone
+         * The time when the service was first made active, either by someone
          * starting or binding to it.
          */
         public long activeSince;
@@ -332,6 +337,35 @@
          */
         public long restarting;
         
+        /**
+         * Bit for {@link #flags}: set if this service has been
+         * explicitly started.
+         */
+        public static final int FLAG_STARTED = 1<<0;
+        
+        /**
+         * Bit for {@link #flags}: set if the service has asked to
+         * run as a foreground process.
+         */
+        public static final int FLAG_FOREGROUND = 1<<1;
+        
+        /**
+         * Bit for {@link #flags): set if the service is running in a
+         * core system process.
+         */
+        public static final int FLAG_SYSTEM_PROCESS = 1<<2;
+        
+        /**
+         * Bit for {@link #flags): set if the service is running in a
+         * persistent process.
+         */
+        public static final int FLAG_PERSISTENT_PROCESS = 1<<3;
+        
+        /**
+         * Running flags.
+         */
+        public int flags;
+        
         public RunningServiceInfo() {
         }
 
@@ -342,6 +376,7 @@
         public void writeToParcel(Parcel dest, int flags) {
             ComponentName.writeToParcel(service, dest);
             dest.writeInt(pid);
+            dest.writeInt(uid);
             dest.writeString(process);
             dest.writeInt(foreground ? 1 : 0);
             dest.writeLong(activeSince);
@@ -350,11 +385,13 @@
             dest.writeInt(crashCount);
             dest.writeLong(lastActivityTime);
             dest.writeLong(restarting);
+            dest.writeInt(this.flags);
         }
 
         public void readFromParcel(Parcel source) {
             service = ComponentName.readFromParcel(source);
             pid = source.readInt();
+            uid = source.readInt();
             process = source.readString();
             foreground = source.readInt() != 0;
             activeSince = source.readLong();
@@ -363,6 +400,7 @@
             crashCount = source.readInt();
             lastActivityTime = source.readLong();
             restarting = source.readLong();
+            flags = source.readInt();
         }
         
         public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d14ec15..52d6891 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -29,6 +29,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Parcelable;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -1107,6 +1108,25 @@
             reply.writeNoException();
             return true;
         }
+        
+        case GET_PROCESS_MEMORY_INFO_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int pid = data.readInt();
+            Debug.MemoryInfo mi = new Debug.MemoryInfo();
+            getProcessMemoryInfo(pid, mi);
+            reply.writeNoException();
+            mi.writeToParcel(reply, 0);
+            return true;
+        }
+
+        case KILL_APPLICATION_PROCESS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            String processName = data.readString();
+            int uid = data.readInt();
+            killApplicationProcess(processName, uid);
+            reply.writeNoException();
+            return true;
+        }
         }
         
         return super.onTransact(code, data, reply, flags);
@@ -2424,6 +2444,31 @@
         data.recycle();
         reply.recycle();
     }
+    
+    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(pid);
+        mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0);
+        reply.readException();
+        outInfo.readFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void killApplicationProcess(String processName, int uid) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(processName);
+        data.writeInt(uid);
+        mRemote.transact(KILL_APPLICATION_PROCESS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
         
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e915b4..8a26aba 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1463,6 +1463,10 @@
             queueOrSendMessage(H.EXIT_APPLICATION, null);
         }
 
+        public final void scheduleSuicide() {
+            queueOrSendMessage(H.SUICIDE, null);
+        }
+
         public void requestThumbnail(IBinder token) {
             queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
         }
@@ -1546,6 +1550,10 @@
             }
         }
         
+        public void getMemoryInfo(Debug.MemoryInfo outInfo) {
+            Debug.getMemoryInfo(outInfo);
+        }
+        
         @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             long nativeMax = Debug.getNativeHeapSize() / 1024;
@@ -1748,7 +1756,8 @@
         public static final int RELAUNCH_ACTIVITY       = 126;
         public static final int PROFILER_CONTROL        = 127;
         public static final int CREATE_BACKUP_AGENT     = 128;
-        public static final int DESTROY_BACKUP_AGENT     = 129;
+        public static final int DESTROY_BACKUP_AGENT    = 129;
+        public static final int SUICIDE                 = 130;
         String codeToString(int code) {
             if (localLOGV) {
                 switch (code) {
@@ -1782,6 +1791,7 @@
                     case PROFILER_CONTROL: return "PROFILER_CONTROL";
                     case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
                     case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
+                    case SUICIDE: return "SUICIDE";
                 }
             }
             return "(unknown)";
@@ -1890,6 +1900,11 @@
                 case DESTROY_BACKUP_AGENT:
                     handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
                     break;
+                case SUICIDE:
+                    {
+                        Process.killProcess(Process.myPid());
+                    }
+                    break;
             }
         }
     }
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index ad64465..928981d 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -26,6 +26,7 @@
 import android.content.res.Configuration;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.IBinder;
@@ -257,6 +258,13 @@
             return true;
         }
 
+        case SCHEDULE_SUICIDE_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            scheduleSuicide();
+            return true;
+        }
+
         case REQUEST_THUMBNAIL_TRANSACTION:
         {
             data.enforceInterface(IApplicationThread.descriptor);
@@ -370,6 +378,16 @@
             scheduleDestroyBackupAgent(appInfo);
             return true;
         }
+
+        case GET_MEMORY_INFO_TRANSACTION:
+        {
+            data.enforceInterface(IApplicationThread.descriptor);
+            Debug.MemoryInfo mi = new Debug.MemoryInfo();
+            getMemoryInfo(mi);
+            reply.writeNoException();
+            mi.writeToParcel(reply, 0);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -641,7 +659,15 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
-    
+
+    public final void scheduleSuicide() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
+                IBinder.FLAG_ONEWAY);
+        data.recycle();
+    }
+
     public final void requestThumbnail(IBinder token)
             throws RemoteException {
         Parcel data = Parcel.obtain();
@@ -756,5 +782,16 @@
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
+    
+    public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IApplicationThread.descriptor);
+        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
+        reply.readException();
+        outInfo.readFromParcel(reply);
+        data.recycle();
+        reply.recycle();
+    }
 }
 
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c3e7224..98a8481 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -30,6 +30,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.Debug;
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.IInterface;
@@ -157,6 +158,7 @@
             throws RemoteException;
     public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;
     public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;
+    public void killApplicationProcess(String processName, int uid) throws RemoteException;
     
     public boolean startInstrumentation(ComponentName className, String profileFile,
             int flags, Bundle arguments, IInstrumentationWatcher watcher)
@@ -272,6 +274,9 @@
     
     public void closeSystemDialogs(String reason) throws RemoteException;
     
+    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+            throws RemoteException;
+    
     /*
      * Private non-Binder interfaces
      */
@@ -428,4 +433,6 @@
     int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
     int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
     int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
+    int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
+    int KILL_APPLICATION_PROCESS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+98;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 6faaa34..8dda898 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -25,6 +25,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.IBinder;
@@ -82,6 +83,7 @@
             IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
             Configuration config, Map<String, IBinder> services) throws RemoteException;
     void scheduleExit() throws RemoteException;
+    void scheduleSuicide() throws RemoteException;
     void requestThumbnail(IBinder token) throws RemoteException;
     void scheduleConfigurationChanged(Configuration config) throws RemoteException;
     void updateTimeZone() throws RemoteException;
@@ -97,6 +99,7 @@
     void profilerControl(boolean start, String path, ParcelFileDescriptor fd)
             throws RemoteException;
     void setSchedulingGroup(int group) throws RemoteException;
+    void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException;
     
     String descriptor = "android.app.IApplicationThread";
 
@@ -130,4 +133,6 @@
     int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
     int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
     int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
+    int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
+    int SCHEDULE_SUICIDE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
 }
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 0a71961..0ec3243 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -266,6 +266,33 @@
         return BluetoothError.ERROR_IPC;
     }
 
+    /**
+     * Get trust state of a remote device.
+     * @hide
+     */
+    public boolean getTrustState() {
+        try {
+            return sService.getTrustState(mAddress);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
+    }
+
+    /**
+     * Set trust state for a remote device.
+     * @param value the trust state value (true or false)
+     * @hide
+     */
+    public boolean setTrust(boolean value) {
+        try {
+            return sService.setTrust(mAddress, value);
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        }
+        return false;
+    }
+
     /** @hide */
     public int getBluetoothClass() {
         try {
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 9e05a87..a11ceac 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -58,4 +58,6 @@
     boolean setPairingConfirmation(in String address, boolean confirm);
     boolean cancelPairingUserInput(in String address);
 
+    boolean setTrust(in String address, in boolean value);
+    boolean getTrustState(in String address);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 59529be..2a17672 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1267,6 +1267,8 @@
      * enabled or disabled.  The data contains the name of the package.
      * <ul>
      * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
+     * <li> {@link #EXTRA_CHANGED_COMPONENT_NAME} containing the class name of the changed component.
+     * <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the default action of restarting the application.
      * </ul>
      * 
      * <p class="note">This is a protected intent that can only be sent
@@ -2034,6 +2036,14 @@
     public static final String EXTRA_REMOTE_INTENT_TOKEN =
             "android.intent.extra.remote_intent_token";
 
+    /**
+     * Used as an int extra field in {@link android.content.Intent#ACTION_PACKAGE_CHANGED}
+     * intent to supply the name of the component that changed.
+     * @hide
+     */
+    public static final String EXTRA_CHANGED_COMPONENT_NAME =
+            "android.intent.extra.changed_component_name";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 15144a2..4e9e49c 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -148,6 +148,9 @@
     private volatile boolean mSyncPollInitialized;
     private final PendingIntent mSyncAlarmIntent;
     private final PendingIntent mSyncPollAlarmIntent;
+    // Synchronized on "this". Instead of using this directly one should instead call
+    // its accessor, getConnManager().
+    private ConnectivityManager mConnManagerDoNotUseDirectly;
 
     private final SyncAdaptersCache mSyncAdapters;
 
@@ -280,6 +283,16 @@
 
     private final boolean mFactoryTest;
 
+    private ConnectivityManager getConnectivityManager() {
+        synchronized (this) {
+            if (mConnManagerDoNotUseDirectly == null) {
+                mConnManagerDoNotUseDirectly = (ConnectivityManager)mContext.getSystemService(
+                        Context.CONNECTIVITY_SERVICE);
+            }
+            return mConnManagerDoNotUseDirectly;
+        }
+    }
+
     public SyncManager(Context context, boolean factoryTest) {
         mFactoryTest = factoryTest;
 
@@ -536,6 +549,14 @@
             return;
         }
 
+        if (!getConnectivityManager().getBackgroundDataSetting()) {
+            if (isLoggable) {
+                Log.v(TAG, "not syncing because background data usage isn't allowed");
+            }
+            setStatusText("Sync is disabled.");
+            return;
+        }
+
         if (mAccounts == null) setStatusText("The accounts aren't known yet.");
         if (!mDataConnectionIsConnected) setStatusText("No data connection");
         if (mStorageIsLow) setStatusText("Memory low");
@@ -602,6 +623,8 @@
             if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority);
         }
 
+        final boolean masterSyncAutomatically = mSyncStorageEngine.getMasterSyncAutomatically();
+
         for (String authority : syncableAuthorities) {
             for (Account account : accounts) {
                 int isSyncable = mSyncStorageEngine.getIsSyncable(account, authority);
@@ -618,22 +641,36 @@
                     if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) {
                         continue;
                     }
+
                     // make this an initialization sync if the isSyncable state is unknown
                     Bundle extrasCopy = extras;
+                    long delayCopy = delay;
                     if (isSyncable < 0) {
                         extrasCopy = new Bundle(extras);
                         extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
+                        delayCopy = -1; // expedite this
+                    } else {
+                        final boolean syncAutomatically = masterSyncAutomatically
+                                && mSyncStorageEngine.getSyncAutomatically(account, authority);
+                        boolean syncAllowed = manualSync || syncAutomatically;
+                        if (!syncAllowed) {
+                            if (isLoggable) {
+                                Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority
+                                        + " is not allowed, dropping request");
+                                continue;
+                            }
+                        }
                     }
                     if (isLoggable) {
                         Log.v(TAG, "scheduleSync:"
-                                + " delay " + delay
+                                + " delay " + delayCopy
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
                                 + ", extras " + extrasCopy);
                     }
                     scheduleSyncOperation(
-                            new SyncOperation(account, source, authority, extrasCopy, delay));
+                            new SyncOperation(account, source, authority, extrasCopy, delayCopy));
                 }
             }
         }
@@ -1591,9 +1628,8 @@
             // found that is runnable (not disabled, etc). If that one is ready to run then
             // start it, otherwise just get out.
             SyncOperation op;
-            final ConnectivityManager connManager = (ConnectivityManager)
-                    mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-            final boolean backgroundDataUsageAllowed = connManager.getBackgroundDataSetting();
+            final boolean backgroundDataUsageAllowed =
+                    getConnectivityManager().getBackgroundDataSetting();
             synchronized (mSyncQueue) {
                 while (true) {
                     op = mSyncQueue.head();
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 0a42a6f..8839f95 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -184,7 +184,29 @@
      * {@hide}
      */
     public static final int FLAG_ALLOW_BACKUP = 1<<14;
-    
+
+    /**
+     * Value for {@link #flags}: this is false if the application has set
+     * its android:killAfterRestore to false, true otherwise.
+     *
+     * <p>If android:allowBackup is set to false or no android:backupAgent
+     * is specified, this flag will be ignored.
+     *
+     * {@hide}
+     */
+    public static final int FLAG_KILL_AFTER_RESTORE = 1<<15;
+
+    /**
+     * Value for {@link #flags}: this is true if the application has set
+     * its android:restoreNeedsApplication to true, false otherwise.
+     *
+     * <p>If android:allowBackup is set to false or no android:backupAgent
+     * is specified, this flag will be ignored.
+     *
+     * {@hide}
+     */
+    public static final int FLAG_RESTORE_NEEDS_APPLICATION = 1<<16;
+
     /**
      * Flags associated with the application.  Any combination of
      * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
@@ -193,7 +215,8 @@
      * {@link #FLAG_ALLOW_CLEAR_USER_DATA}, {@link #FLAG_UPDATED_SYSTEM_APP},
      * {@link #FLAG_TEST_ONLY}, {@link #FLAG_SUPPORTS_SMALL_SCREENS},
      * {@link #FLAG_SUPPORTS_NORMAL_SCREENS},
-     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS}.
+     * {@link #FLAG_SUPPORTS_LARGE_SCREENS}, {@link #FLAG_RESIZEABLE_FOR_SCREENS},
+     * {@link #FLAG_SUPPORTS_SCREEN_DENSITIES}.
      */
     public int flags = 0;
     
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4399df4..b4a6fee 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -1296,12 +1296,26 @@
                 com.android.internal.R.styleable.AndroidManifestApplication_allowBackup, true);
         if (allowBackup) {
             ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
+
+            // backupAgent, killAfterRestore, and restoreNeedsApplication are only relevant
+            // if backup is possible for the given application.
             String backupAgent = sa.getNonResourceString(
                     com.android.internal.R.styleable.AndroidManifestApplication_backupAgent);
             if (backupAgent != null) {
                 ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
                 Log.v(TAG, "android:backupAgent = " + ai.backupAgentName
                         + " from " + pkgName + "+" + backupAgent);
+
+                if (sa.getBoolean(
+                        com.android.internal.R.styleable.AndroidManifestApplication_killAfterRestore,
+                        true)) {
+                    ai.flags |= ApplicationInfo.FLAG_KILL_AFTER_RESTORE;
+                }
+                if (sa.getBoolean(
+                        com.android.internal.R.styleable.AndroidManifestApplication_restoreNeedsApplication,
+                        false)) {
+                    ai.flags |= ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION;
+                }
             }
         }
         
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 5d7af69d..57bf3f7 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -62,53 +62,53 @@
      */
     public enum ConflictAlgorithm {
         /**
-         *  When a constraint violation occurs, an immediate ROLLBACK occurs, 
-         * thus ending the current transaction, and the command aborts with a 
-         * return code of SQLITE_CONSTRAINT. If no transaction is active 
+         *  When a constraint violation occurs, an immediate ROLLBACK occurs,
+         * thus ending the current transaction, and the command aborts with a
+         * return code of SQLITE_CONSTRAINT. If no transaction is active
          * (other than the implied transaction that is created on every command)
          *  then this algorithm works the same as ABORT.
          */
         ROLLBACK("ROLLBACK"),
-        
+
         /**
-         * When a constraint violation occurs,no ROLLBACK is executed 
-         * so changes from prior commands within the same transaction 
+         * When a constraint violation occurs,no ROLLBACK is executed
+         * so changes from prior commands within the same transaction
          * are preserved. This is the default behavior.
          */
         ABORT("ABORT"),
-        
+
         /**
-         * When a constraint violation occurs, the command aborts with a return 
-         * code SQLITE_CONSTRAINT. But any changes to the database that 
-         * the command made prior to encountering the constraint violation 
+         * When a constraint violation occurs, the command aborts with a return
+         * code SQLITE_CONSTRAINT. But any changes to the database that
+         * the command made prior to encountering the constraint violation
          * are preserved and are not backed out.
          */
         FAIL("FAIL"),
-        
+
         /**
-         * When a constraint violation occurs, the one row that contains 
-         * the constraint violation is not inserted or changed. 
-         * But the command continues executing normally. Other rows before and 
-         * after the row that contained the constraint violation continue to be 
+         * When a constraint violation occurs, the one row that contains
+         * the constraint violation is not inserted or changed.
+         * But the command continues executing normally. Other rows before and
+         * after the row that contained the constraint violation continue to be
          * inserted or updated normally. No error is returned.
          */
         IGNORE("IGNORE"),
-        
+
         /**
          * When a UNIQUE constraint violation occurs, the pre-existing rows that
-         * are causing the constraint violation are removed prior to inserting 
+         * are causing the constraint violation are removed prior to inserting
          * or updating the current row. Thus the insert or update always occurs.
-         * The command continues executing normally. No error is returned. 
+         * The command continues executing normally. No error is returned.
          * If a NOT NULL constraint violation occurs, the NULL value is replaced
-         * by the default value for that column. If the column has no default 
-         * value, then the ABORT algorithm is used. If a CHECK constraint 
-         * violation occurs then the IGNORE algorithm is used. When this conflict 
-         * resolution strategy deletes rows in order to satisfy a constraint, 
+         * by the default value for that column. If the column has no default
+         * value, then the ABORT algorithm is used. If a CHECK constraint
+         * violation occurs then the IGNORE algorithm is used. When this conflict
+         * resolution strategy deletes rows in order to satisfy a constraint,
          * it does not invoke delete triggers on those rows.
          *  This behavior might change in a future release.
          */
         REPLACE("REPLACE");
-        
+
         private final String mValue;
         ConflictAlgorithm(String value) {
             mValue = value;
@@ -117,7 +117,7 @@
             return mValue;
         }
     }
-    
+
     /**
      * Maximum Length Of A LIKE Or GLOB Pattern
      * The pattern matching algorithm used in the default LIKE and GLOB implementation
@@ -180,17 +180,19 @@
 
     private long mLockAcquiredWallTime = 0L;
     private long mLockAcquiredThreadTime = 0L;
-    
+
     // limit the frequency of complaints about each database to one within 20 sec
-    // unless run command adb shell setprop log.tag.Database VERBOSE  
+    // unless run command adb shell setprop log.tag.Database VERBOSE
     private static final int LOCK_WARNING_WINDOW_IN_MS = 20000;
     /** If the lock is held this long then a warning will be printed when it is released. */
     private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300;
     private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100;
     private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000;
 
+    private static final int SLEEP_AFTER_YIELD_QUANTUM = 500;
+
     private long mLastLockMessageTime = 0L;
-    
+
     /** Used by native code, do not rename */
     /* package */ int mNativeHandle = 0;
 
@@ -205,15 +207,15 @@
 
     /** The optional factory to use when creating new Cursors */
     private CursorFactory mFactory;
-    
+
     private WeakHashMap<SQLiteClosable, Object> mPrograms;
- 
+
     private final RuntimeException mLeakedException;
 
     // package visible, since callers will access directly to minimize overhead in the case
     // that logging is not enabled.
     /* package */ final boolean mLogStats;
-    
+
     /**
      * @param closable
      */
@@ -225,7 +227,7 @@
             unlock();
         }
     }
-    
+
     void removeSQLiteClosable(SQLiteClosable closable) {
         lock();
         try {
@@ -233,8 +235,8 @@
         } finally {
             unlock();
         }
-    }    
-   
+    }
+
     @Override
     protected void onAllReferencesReleased() {
         if (isOpen()) {
@@ -245,10 +247,10 @@
     /**
      * Attempts to release memory that SQLite holds but does not require to
      * operate properly. Typically this memory will come from the page cache.
-     * 
+     *
      * @return the number of bytes actually released
      */
-    static public native int releaseMemory(); 
+    static public native int releaseMemory();
 
     /**
      * Control whether or not the SQLiteDatabase is made thread-safe by using locks
@@ -284,7 +286,7 @@
      * touch the native sqlite3* object since it is single threaded and uses
      * a polling lock contention algorithm. The lock is recursive, and may be acquired
      * multiple times by the same thread. This is a no-op if mLockingEnabled is false.
-     * 
+     *
      * @see #unlock()
      */
     /* package */ void lock() {
@@ -320,7 +322,7 @@
 
     /**
      * Releases the database lock. This is a no-op if mLockingEnabled is false.
-     * 
+     *
      * @see #unlock()
      */
     /* package */ void unlock() {
@@ -350,7 +352,7 @@
     private void checkLockHoldTime() {
         // Use elapsed real-time since the CPU may sleep when waiting for IO
         long elapsedTime = SystemClock.elapsedRealtime();
-        long lockedTime = elapsedTime - mLockAcquiredWallTime;                
+        long lockedTime = elapsedTime - mLockAcquiredWallTime;
         if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT &&
                 !Log.isLoggable(TAG, Log.VERBOSE) &&
                 (elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) {
@@ -567,10 +569,21 @@
             }
         }
         if (sleepAfterYieldDelay > 0) {
-            try {
-                Thread.sleep(sleepAfterYieldDelay);
-            } catch (InterruptedException e) {
-                Thread.interrupted();
+            // Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to
+            // check if anyone is using the database.  If the database is not contended,
+            // retake the lock and return.
+            long remainingDelay = sleepAfterYieldDelay;
+            while (remainingDelay > 0) {
+                try {
+                    Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ?
+                            remainingDelay : SLEEP_AFTER_YIELD_QUANTUM);
+                } catch (InterruptedException e) {
+                    Thread.interrupted();
+                }
+                remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM;
+                if (mLock.getQueueLength() == 0) {
+                    break;
+                }
             }
         }
         beginTransaction();
@@ -720,9 +733,9 @@
             if (program != null) {
                 program.onAllReferencesReleasedFromContainer();
             }
-        }        
+        }
     }
-    
+
     /**
      * Native call to close the database.
      */
@@ -1157,8 +1170,8 @@
 
     /**
      * Runs the provided SQL and returns a cursor over the result set.
-     * The cursor will read an initial set of rows and the return to the caller. 
-     * It will continue to read in batches and send data changed notifications 
+     * The cursor will read an initial set of rows and the return to the caller.
+     * It will continue to read in batches and send data changed notifications
      * when the later batches are ready.
      * @param sql the SQL query. The SQL string must not be ; terminated
      * @param selectionArgs You may include ?s in where clause in the query,
@@ -1167,19 +1180,19 @@
      * @param initialRead set the initial count of items to read from the cursor
      * @param maxRead set the count of items to read on each iteration after the first
      * @return A {@link Cursor} object, which is positioned before the first entry
-     * 
+     *
      * This work is incomplete and not fully tested or reviewed, so currently
      * hidden.
      * @hide
      */
-    public Cursor rawQuery(String sql, String[] selectionArgs, 
+    public Cursor rawQuery(String sql, String[] selectionArgs,
             int initialRead, int maxRead) {
         SQLiteCursor c = (SQLiteCursor)rawQueryWithFactory(
                 null, sql, selectionArgs, null);
         c.setLoadStyle(initialRead, maxRead);
         return c;
     }
-    
+
     /**
      * Convenience method for inserting a row into the database.
      *
@@ -1232,7 +1245,7 @@
      */
     public long replace(String table, String nullColumnHack, ContentValues initialValues) {
         try {
-            return insertWithOnConflict(table, nullColumnHack, initialValues, 
+            return insertWithOnConflict(table, nullColumnHack, initialValues,
                     ConflictAlgorithm.REPLACE);
         } catch (SQLException e) {
             Log.e(TAG, "Error inserting " + initialValues, e);
@@ -1254,7 +1267,7 @@
      */
     public long replaceOrThrow(String table, String nullColumnHack,
             ContentValues initialValues) throws SQLException {
-        return insertWithOnConflict(table, nullColumnHack, initialValues, 
+        return insertWithOnConflict(table, nullColumnHack, initialValues,
                 ConflictAlgorithm.REPLACE);
     }
 
@@ -1410,7 +1423,7 @@
     public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
         return updateWithOnConflict(table, values, whereClause, whereArgs, null);
     }
-    
+
     /**
      * Convenience method for updating rows in the database.
      *
@@ -1423,7 +1436,7 @@
      * @return the number of rows affected
      * @hide
      */
-    public int updateWithOnConflict(String table, ContentValues values, 
+    public int updateWithOnConflict(String table, ContentValues values,
             String whereClause, String[] whereArgs, ConflictAlgorithm algorithm) {
         if (!isOpen()) {
             throw new IllegalStateException("database not open");
@@ -1440,7 +1453,7 @@
             sql.append(algorithm.value());
             sql.append(" ");
         }
-        
+
         sql.append(table);
         sql.append(" SET ");
 
@@ -1601,7 +1614,7 @@
         mFlags = flags;
         mPath = path;
         mLogStats = "1".equals(android.os.SystemProperties.get("db.logstats"));
-        
+
         mLeakedException = new IllegalStateException(path +
             " SQLiteDatabase created and never closed");
         mFactory = factory;
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index aa3b852..38c9dbc 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -17,7 +17,9 @@
 package android.hardware;
 
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.io.IOException;
 
@@ -38,7 +40,7 @@
  */
 public class Camera {
     private static final String TAG = "Camera";
-    
+
     // These match the enums in frameworks/base/include/ui/Camera.h
     private static final int CAMERA_MSG_ERROR            = 0x001;
     private static final int CAMERA_MSG_SHUTTER          = 0x002;
@@ -62,12 +64,12 @@
     private ZoomCallback mZoomCallback;
     private ErrorCallback mErrorCallback;
     private boolean mOneShot;
-    
+
     /**
      * Returns a new Camera object.
      */
-    public static Camera open() { 
-        return new Camera(); 
+    public static Camera open() {
+        return new Camera();
     }
 
     Camera() {
@@ -89,32 +91,32 @@
 
         native_setup(new WeakReference<Camera>(this));
     }
-    
-    protected void finalize() { 
-        native_release(); 
+
+    protected void finalize() {
+        native_release();
     }
-    
+
     private native final void native_setup(Object camera_this);
     private native final void native_release();
-    
+
 
     /**
      * Disconnects and releases the Camera object resources.
-     * <p>It is recommended that you call this as soon as you're done with the 
+     * <p>It is recommended that you call this as soon as you're done with the
      * Camera object.</p>
      */
-    public final void release() { 
+    public final void release() {
         native_release();
     }
 
     /**
      * Reconnect to the camera after passing it to MediaRecorder. To save
      * setup/teardown time, a client of Camera can pass an initialized Camera
-     * object to a MediaRecorder to use for video recording. Once the 
+     * object to a MediaRecorder to use for video recording. Once the
      * MediaRecorder is done with the Camera, this method can be used to
      * re-establish a connection with the camera hardware. NOTE: The Camera
      * object must first be unlocked by the process that owns it before it
-     * can be connected to another proces.
+     * can be connected to another process.
      *
      * @throws IOException if the method fails.
      *
@@ -122,7 +124,7 @@
      * @hide
      */
     public native final void reconnect() throws IOException;
-    
+
     /**
      * Lock the camera to prevent other processes from accessing it. To save
      * setup/teardown time, a client of Camera can pass an initialized Camera
@@ -137,9 +139,9 @@
      * @hide
      */
     public native final int lock();
-    
+
     /**
-     * Unlock the camera to allow aother process to access it. To save
+     * Unlock the camera to allow another process to access it. To save
      * setup/teardown time, a client of Camera can pass an initialized Camera
      * object to another process. This method is used to unlock the Camera
      * object before handing off the Camera object to the other process.
@@ -150,12 +152,12 @@
      * @hide
      */
     public native final int unlock();
-    
+
     /**
      * Sets the SurfaceHolder to be used for a picture preview. If the surface
      * changed since the last call, the screen will blank. Nothing happens
      * if the same surface is re-set.
-     * 
+     *
      * @param holder the SurfaceHolder upon which to place the picture preview
      * @throws IOException if the method fails.
      */
@@ -177,23 +179,27 @@
         /**
          * The callback that delivers the preview frames.
          *
-         * @param data The contents of the preview frame in getPreviewFormat()
-         *             format.
+         * @param data The contents of the preview frame in {@link
+         *             android.hardware.Camera.Parameters#getPreviewFormat()}
+         *             format. 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.
          */
         void onPreviewFrame(byte[] data, Camera camera);
     };
-    
+
     /**
      * Start drawing preview frames to the surface.
      */
     public native final void startPreview();
-    
+
     /**
      * Stop drawing preview frames to the surface.
      */
     public native final void stopPreview();
-    
+
     /**
      * Return current preview state.
      *
@@ -201,7 +207,7 @@
      * @hide
      */
     public native final boolean previewEnabled();
-    
+
     /**
      * Can be called at any time to instruct the camera to use a callback for
      * each preview frame in addition to displaying it.
@@ -260,7 +266,7 @@
                     mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
                 }
                 return;
-            
+
             case CAMERA_MSG_PREVIEW_FRAME:
                 if (mPreviewCallback != null) {
                     mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera);
@@ -321,8 +327,10 @@
     public interface AutoFocusCallback
     {
         /**
-         * Callback for the camera auto focus.
-         * 
+         * Callback for the camera auto focus. If the camera does not support
+         * auto-focus and autoFocus is called, onAutoFocus will be called
+         * immediately with success.
+         *
          * @param success true if focus was successful, false if otherwise
          * @param camera  the Camera service object
          */
@@ -330,10 +338,12 @@
     };
 
     /**
-     * Starts auto-focus function and registers a callback function to
-     * run when camera is focused. Only valid after startPreview() has
-     * been called.
-     * 
+     * Starts auto-focus function and registers a callback function to run when
+     * camera is focused. Only valid after startPreview() has been called. If
+     * the camera does not support auto-focus, it is a no-op and {@link
+     * AutoFocusCallback#onAutoFocus(boolean, Camera)} callback will be called
+     * immediately.
+     *
      * @param cb the callback to run
      */
     public final void autoFocus(AutoFocusCallback cb)
@@ -361,7 +371,7 @@
     public interface PictureCallback {
         /**
          * Callback for when a picture is taken.
-         * 
+         *
          * @param data   a byte array of the picture data
          * @param camera the Camera service object
          */
@@ -369,16 +379,16 @@
     };
 
     /**
-     * Triggers an asynchronous image capture. The camera service
-     * will initiate a series of callbacks to the application as the
-     * image capture progresses. The shutter callback occurs after
-     * the image is captured. This can be used to trigger a sound
-     * to let the user know that image has been captured. The raw
-     * callback occurs when the raw image data is available. The jpeg
-     * callback occurs when the compressed image is available. If the
-     * application does not need a particular callback, a null can be
-     * passed instead of a callback method.
-     * 
+     * Triggers an asynchronous image capture. The camera service will initiate
+     * a series of callbacks to the application as the image capture progresses.
+     * The shutter callback occurs after the image is captured. This can be used
+     * to trigger a sound to let the user know that image has been captured. The
+     * raw callback occurs when the raw image data is available (NOTE: the data
+     * may be null if the hardware does not have enough memory to make a copy).
+     * The jpeg callback occurs when the compressed image is available. If the
+     * application does not need a particular callback, a null can be passed
+     * instead of a callback method.
+     *
      * @param shutter   callback after the image is captured, may be null
      * @param raw       callback with raw image data, may be null
      * @param jpeg      callback with jpeg image data, may be null
@@ -390,17 +400,17 @@
     private native final void native_takePicture();
 
     /**
-     * Triggers an asynchronous image capture. The camera service
-     * will initiate a series of callbacks to the application as the
-     * image capture progresses. The shutter callback occurs after
-     * the image is captured. This can be used to trigger a sound
-     * to let the user know that image has been captured. The raw
-     * callback occurs when the raw image data is available. The
-     * postview callback occurs when a scaled, fully processed
-     * postview image is available (NOTE: not all hardware supports
-     * this). The jpeg callback occurs when the compressed image is
-     * available. If the application does not need a particular
-     * callback, a null can be passed instead of a callback method.
+     * Triggers an asynchronous image capture. The camera service will initiate
+     * a series of callbacks to the application as the image capture progresses.
+     * The shutter callback occurs after the image is captured. This can be used
+     * to trigger a sound to let the user know that image has been captured. The
+     * raw callback occurs when the raw image data is available (NOTE: the data
+     * may be null if the hardware does not have enough memory to make a copy).
+     * The postview callback occurs when a scaled, fully processed postview
+     * image is available (NOTE: not all hardware supports this). The jpeg
+     * callback occurs when the compressed image is available. If the
+     * application does not need a particular callback, a null can be passed
+     * instead of a callback method.
      *
      * @param shutter   callback after the image is captured, may be null
      * @param raw       callback with raw image data, may be null
@@ -441,14 +451,14 @@
     {
         mZoomCallback = cb;
     }
-    
+
     // These match the enum in include/ui/Camera.h
     /** Unspecified camerar error.  @see #ErrorCallback */
     public static final int CAMERA_ERROR_UNKNOWN = 1;
     /** Media server died. In this case, the application must release the
      * Camera object and instantiate a new one. @see #ErrorCallback */
     public static final int CAMERA_ERROR_SERVER_DIED = 100;
-    
+
     /**
      * Handles the camera error callback.
      */
@@ -474,13 +484,13 @@
     {
         mErrorCallback = cb;
     }
-    
+
     private native final void native_setParameters(String params);
     private native final String native_getParameters();
 
     /**
      * Sets the Parameters for pictures from this Camera service.
-     * 
+     *
      * @param params the Parameters to use for this Camera service
      */
     public void setParameters(Parameters params) {
@@ -503,7 +513,7 @@
     public class Size {
         /**
          * Sets the dimensions for pictures.
-         * 
+         *
          * @param w the photo width (pixels)
          * @param h the photo height (pixels)
          */
@@ -519,8 +529,111 @@
 
     /**
      * Handles the parameters for pictures created by a Camera service.
+     *
+     * <p>To make camera parameters take effect, applications have to call
+     * Camera.setParameters. For example, after setWhiteBalance is called, white
+     * balance is not changed until Camera.setParameters() is called.
+     *
+     * <p>Different devices may have different camera capabilities, such as
+     * picture size or flash modes. The application should query the camera
+     * capabilities before setting parameters. For example, the application
+     * should call getSupportedColorEffects before calling setEffect. If the
+     * camera does not support color effects, getSupportedColorEffects will
+     * return null.
      */
     public class Parameters {
+        // Parameter keys to communicate with the camera driver.
+        private static final String KEY_PREVIEW_SIZE = "preview-size";
+        private static final String KEY_PREVIEW_FORMAT = "preview-format";
+        private static final String KEY_PREVIEW_FRAME_RATE = "preview-frame-rate";
+        private static final String KEY_PICTURE_SIZE = "picture-size";
+        private static final String KEY_PICTURE_FORMAT = "picture-format";
+        private static final String KEY_JPEG_THUMBNAIL_WIDTH = "jpeg-thumbnail-width";
+        private static final String KEY_JPEG_THUMBNAIL_HEIGHT = "jpeg-thumbnail-height";
+        private static final String KEY_JPEG_THUMBNAIL_QUALITY = "jpeg-thumbnail-quality";
+        private static final String KEY_JPEG_QUALITY = "jpeg-quality";
+        private static final String KEY_ROTATION = "rotation";
+        private static final String KEY_GPS_LATITUDE = "gps-latitude";
+        private static final String KEY_GPS_LONGITUDE = "gps-longitude";
+        private static final String KEY_GPS_ALTITUDE = "gps-altitude";
+        private static final String KEY_GPS_TIMESTAMP = "gps-timestamp";
+        private static final String KEY_WHITE_BALANCE = "whitebalance";
+        private static final String KEY_EFFECT = "effect";
+        private static final String KEY_ANTIBANDING = "antibanding";
+        private static final String KEY_SCENE_MODE = "scene-mode";
+        private static final String KEY_FLASH_MODE = "flash-mode";
+        // Parameter key suffix for supported values.
+        private static final String SUPPORTED_VALUES_SUFFIX = "-values";
+
+        // Values for white balance settings.
+        public static final String WHITE_BALANCE_AUTO = "auto";
+        public static final String WHITE_BALANCE_INCANDESCENT = "incandescent";
+        public static final String WHITE_BALANCE_FLUORESCENT = "fluorescent";
+        public static final String WHITE_BALANCE_WARM_FLUORESCENT = "warm-fluorescent";
+        public static final String WHITE_BALANCE_DAYLIGHT = "daylight";
+        public static final String WHITE_BALANCE_CLOUDY_DAYLIGHT = "cloudy-daylight";
+        public static final String WHITE_BALANCE_TWILIGHT = "twilight";
+        public static final String WHITE_BALANCE_SHADE = "shade";
+
+        // Values for color effect settings.
+        public static final String EFFECT_NONE = "none";
+        public static final String EFFECT_MONO = "mono";
+        public static final String EFFECT_NEGATIVE = "negative";
+        public static final String EFFECT_SOLARIZE = "solarize";
+        public static final String EFFECT_SEPIA = "sepia";
+        public static final String EFFECT_POSTERIZE = "posterize";
+        public static final String EFFECT_WHITEBOARD = "whiteboard";
+        public static final String EFFECT_BLACKBOARD = "blackboard";
+        public static final String EFFECT_AQUA = "aqua";
+
+        // Values for antibanding settings.
+        public static final String ANTIBANDING_AUTO = "auto";
+        public static final String ANTIBANDING_50HZ = "50hz";
+        public static final String ANTIBANDING_60HZ = "60hz";
+        public static final String ANTIBANDING_OFF = "off";
+
+        // Values for flash mode settings.
+        /**
+         * Flash will not be fired.
+         */
+        public static final String FLASH_MODE_OFF = "off";
+        /**
+         * Flash will be fired automatically when required. The timing is
+         * decided by camera driver.
+         */
+        public static final String FLASH_MODE_AUTO = "auto";
+        /**
+         * Flash will always be fired. The timing is decided by camera driver.
+         */
+        public static final String FLASH_MODE_ON = "on";
+        /**
+         * Flash will be fired in red-eye reduction mode.
+         */
+        public static final String FLASH_MODE_RED_EYE = "red-eye";
+
+        // Values for scene mode settings.
+        public static final String SCENE_MODE_AUTO = "auto";
+        public static final String SCENE_MODE_ACTION = "action";
+        public static final String SCENE_MODE_PORTRAIT = "portrait";
+        public static final String SCENE_MODE_LANDSCAPE = "landscape";
+        public static final String SCENE_MODE_NIGHT = "night";
+        public static final String SCENE_MODE_NIGHT_PORTRAIT = "night-portrait";
+        public static final String SCENE_MODE_THEATRE = "theatre";
+        public static final String SCENE_MODE_BEACH = "beach";
+        public static final String SCENE_MODE_SNOW = "snow";
+        public static final String SCENE_MODE_SUNSET = "sunset";
+        public static final String SCENE_MODE_STEADYPHOTO = "steadyphoto";
+        public static final String SCENE_MODE_FIREWORKS = "fireworks";
+        public static final String SCENE_MODE_SPORTS = "sports";
+        public static final String SCENE_MODE_PARTY = "party";
+        public static final String SCENE_MODE_CANDLELIGHT = "candlelight";
+
+        // Formats for setPreviewFormat and setPictureFormat.
+        private static final String PIXEL_FORMAT_YUV422SP = "yuv422sp";
+        private static final String PIXEL_FORMAT_YUV420SP = "yuv420sp";
+        private static final String PIXEL_FORMAT_RGB565 = "rgb565";
+        private static final String PIXEL_FORMAT_JPEG = "jpeg";
+
         private HashMap<String, String> mMap;
 
         private Parameters() {
@@ -543,7 +656,7 @@
          * Creates a single string with all the parameters set in
          * this Parameters object.
          * <p>The {@link #unflatten(String)} method does the reverse.</p>
-         * 
+         *
          * @return a String with all values from this Parameters object, in
          *         semi-colon delimited key-value pairs
          */
@@ -561,16 +674,16 @@
         }
 
         /**
-         * Takes a flattened string of parameters and adds each one to 
+         * Takes a flattened string of parameters and adds each one to
          * this Parameters object.
          * <p>The {@link #flatten()} method does the reverse.</p>
-         * 
-         * @param flattened a String of parameters (key-value paired) that 
+         *
+         * @param flattened a String of parameters (key-value paired) that
          *                  are semi-colon delimited
          */
         public void unflatten(String flattened) {
             mMap.clear();
-            
+
             StringTokenizer tokenizer = new StringTokenizer(flattened, ";");
             while (tokenizer.hasMoreElements()) {
                 String kv = tokenizer.nextToken();
@@ -583,14 +696,14 @@
                 mMap.put(k, v);
             }
         }
-        
+
         public void remove(String key) {
             mMap.remove(key);
         }
 
         /**
          * Sets a String parameter.
-         * 
+         *
          * @param key   the key name for the parameter
          * @param value the String value of the parameter
          */
@@ -609,7 +722,7 @@
 
         /**
          * Sets an integer parameter.
-         * 
+         *
          * @param key   the key name for the parameter
          * @param value the int value of the parameter
          */
@@ -619,7 +732,7 @@
 
         /**
          * Returns the value of a String parameter.
-         * 
+         *
          * @param key the key name for the parameter
          * @return the String value of the parameter
          */
@@ -629,7 +742,7 @@
 
         /**
          * Returns the value of an integer parameter.
-         * 
+         *
          * @param key the key name for the parameter
          * @return the int value of the parameter
          */
@@ -639,110 +752,133 @@
 
         /**
          * Sets the dimensions for preview pictures.
-         * 
+         *
          * @param width  the width of the pictures, in pixels
          * @param height the height of the pictures, in pixels
          */
         public void setPreviewSize(int width, int height) {
             String v = Integer.toString(width) + "x" + Integer.toString(height);
-            set("preview-size", v);
+            set(KEY_PREVIEW_SIZE, v);
         }
 
         /**
          * Returns the dimensions setting for preview pictures.
-         * 
-         * @return a Size object with the height and width setting 
+         *
+         * @return a Size object with the height and width setting
          *          for the preview picture
          */
         public Size getPreviewSize() {
-            String pair = get("preview-size");
-            if (pair == null)
-                return null;
-            String[] dims = pair.split("x");
-            if (dims.length != 2)
-                return null;
-
-            return new Size(Integer.parseInt(dims[0]),
-                            Integer.parseInt(dims[1]));
-
+            String pair = get(KEY_PREVIEW_SIZE);
+            return strToSize(pair);
         }
 
         /**
-         * Sets the dimensions for EXIF thumbnails.
-         * 
+         * Gets the supported preview sizes.
+         *
+         * @return a List of Size object. null if preview size setting is not
+         *         supported.
+         */
+        public List<Size> getSupportedPreviewSizes() {
+            String str = get(KEY_PREVIEW_SIZE + SUPPORTED_VALUES_SUFFIX);
+            return splitSize(str);
+        }
+
+        /**
+         * Sets the dimensions for EXIF thumbnail in Jpeg picture.
+         *
          * @param width  the width of the thumbnail, in pixels
          * @param height the height of the thumbnail, in pixels
-         *
-         * FIXME: unhide before release
-         * @hide
          */
-        public void setThumbnailSize(int width, int height) {
-            set("jpeg-thumbnail-width", width);
-            set("jpeg-thumbnail-height", height);
+        public void setJpegThumbnailSize(int width, int height) {
+            set(KEY_JPEG_THUMBNAIL_WIDTH, width);
+            set(KEY_JPEG_THUMBNAIL_HEIGHT, height);
         }
 
         /**
-         * Returns the dimensions for EXIF thumbnail
-         * 
-         * @return a Size object with the height and width setting 
-         *          for the EXIF thumbnails
+         * Returns the dimensions for EXIF thumbnail in Jpeg picture.
          *
-         * FIXME: unhide before release
-         * @hide
+         * @return a Size object with the height and width setting for the EXIF
+         *         thumbnails
          */
-        public Size getThumbnailSize() {
-            return new Size(getInt("jpeg-thumbnail-width"),
-                            getInt("jpeg-thumbnail-height"));
+        public Size getJpegThumbnailSize() {
+            return new Size(getInt(KEY_JPEG_THUMBNAIL_WIDTH),
+                            getInt(KEY_JPEG_THUMBNAIL_HEIGHT));
         }
 
         /**
-         * Sets the quality of the EXIF thumbnail
-         * 
-         * @param quality the JPEG quality of the EXIT thumbnail
+         * Sets the quality of the EXIF thumbnail in Jpeg picture.
          *
-         * FIXME: unhide before release
-         * @hide
+         * @param quality the JPEG quality of the EXIF thumbnail. The range is 1
+         *                to 100, with 100 being the best.
          */
-        public void setThumbnailQuality(int quality) {
-            set("jpeg-thumbnail-quality", quality);
+        public void setJpegThumbnailQuality(int quality) {
+            set(KEY_JPEG_THUMBNAIL_QUALITY, quality);
         }
 
         /**
-         * Returns the quality setting for the EXIF thumbnail
-         * 
-         * @return the JPEG quality setting of the EXIF thumbnail
+         * Returns the quality setting for the EXIF thumbnail in Jpeg picture.
          *
-         * FIXME: unhide before release
-         * @hide
+         * @return the JPEG quality setting of the EXIF thumbnail.
          */
-        public int getThumbnailQuality() {
-            return getInt("jpeg-thumbnail-quality");
+        public int getJpegThumbnailQuality() {
+            return getInt(KEY_JPEG_THUMBNAIL_QUALITY);
+        }
+
+        /**
+         * Sets Jpeg quality of captured picture.
+         *
+         * @param quality the JPEG quality of captured picture. The range is 1
+         *                to 100, with 100 being the best.
+         */
+        public void setJpegQuality(int quality) {
+            set(KEY_JPEG_QUALITY, quality);
+        }
+
+        /**
+         * Returns the quality setting for the JPEG picture.
+         *
+         * @return the JPEG picture quality setting.
+         */
+        public int getJpegQuality() {
+            return getInt(KEY_JPEG_QUALITY);
         }
 
         /**
          * Sets the rate at which preview frames are received.
-         * 
+         *
          * @param fps the frame rate (frames per second)
          */
         public void setPreviewFrameRate(int fps) {
-            set("preview-frame-rate", fps);
+            set(KEY_PREVIEW_FRAME_RATE, fps);
         }
 
         /**
          * Returns the setting for the rate at which preview frames
          * are received.
-         * 
+         *
          * @return the frame rate setting (frames per second)
          */
         public int getPreviewFrameRate() {
-            return getInt("preview-frame-rate");
+            return getInt(KEY_PREVIEW_FRAME_RATE);
         }
 
         /**
-         * Sets the image format for preview pictures.
-         * 
-         * @param pixel_format the desired preview picture format 
-         *                     (<var>PixelFormat.YCbCr_420_SP</var>,
+         * Gets the supported preview frame rates.
+         *
+         * @return a List of Integer objects (preview frame rates). null if
+         *         preview frame rate setting is not supported.
+         */
+        public List<Integer> getSupportedPreviewFrameRates() {
+            String str = get(KEY_PREVIEW_FRAME_RATE + SUPPORTED_VALUES_SUFFIX);
+            return splitInt(str);
+        }
+
+        /**
+         * 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>,
          *                      <var>PixelFormat.RGB_565</var>, or
          *                      <var>PixelFormat.JPEG</var>)
          * @see android.graphics.PixelFormat
@@ -750,56 +886,73 @@
         public void setPreviewFormat(int pixel_format) {
             String s = cameraFormatForPixelFormat(pixel_format);
             if (s == null) {
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException(
+                        "Invalid pixel_format=" + pixel_format);
             }
 
-            set("preview-format", s);
+            set(KEY_PREVIEW_FORMAT, s);
         }
 
         /**
-         * Returns the image format for preview pictures.
-         * 
+         * Returns the image format for preview pictures got from
+         * {@link PreviewCallback}.
+         *
          * @return the PixelFormat int representing the preview picture format
+         * @see android.graphics.PixelFormat
          */
         public int getPreviewFormat() {
-            return pixelFormatForCameraFormat(get("preview-format"));
+            return pixelFormatForCameraFormat(get(KEY_PREVIEW_FORMAT));
+        }
+
+        /**
+         * Gets the supported preview formats.
+         *
+         * @return a List of Integer objects. null if preview format setting is
+         *         not supported.
+         */
+        public List<Integer> getSupportedPreviewFormats() {
+            String str = get(KEY_PREVIEW_FORMAT + SUPPORTED_VALUES_SUFFIX);
+            return splitInt(str);
         }
 
         /**
          * Sets the dimensions for pictures.
-         * 
+         *
          * @param width  the width for pictures, in pixels
          * @param height the height for pictures, in pixels
          */
         public void setPictureSize(int width, int height) {
             String v = Integer.toString(width) + "x" + Integer.toString(height);
-            set("picture-size", v);
+            set(KEY_PICTURE_SIZE, v);
         }
 
         /**
          * Returns the dimension setting for pictures.
-         * 
-         * @return a Size object with the height and width setting 
+         *
+         * @return a Size object with the height and width setting
          *          for pictures
          */
         public Size getPictureSize() {
-            String pair = get("picture-size");
-            if (pair == null)
-                return null;
-            String[] dims = pair.split("x");
-            if (dims.length != 2)
-                return null;
+            String pair = get(KEY_PICTURE_SIZE);
+            return strToSize(pair);
+        }
 
-            return new Size(Integer.parseInt(dims[0]),
-                            Integer.parseInt(dims[1]));
-
+        /**
+         * Gets the supported picture sizes.
+         *
+         * @return a List of Size objects. null if picture size setting is not
+         *         supported.
+         */
+        public List<Size> getSupportedPictureSizes() {
+            String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
+            return splitSize(str);
         }
 
         /**
          * Sets the image format for pictures.
-         * 
-         * @param pixel_format the desired picture format 
-         *                     (<var>PixelFormat.YCbCr_420_SP</var>,
+         *
+         * @param pixel_format the desired picture format
+         *                     (<var>PixelFormat.YCbCr_420_SP (NV21)</var>,
          *                      <var>PixelFormat.RGB_565</var>, or
          *                      <var>PixelFormat.JPEG</var>)
          * @see android.graphics.PixelFormat
@@ -807,27 +960,39 @@
         public void setPictureFormat(int pixel_format) {
             String s = cameraFormatForPixelFormat(pixel_format);
             if (s == null) {
-                throw new IllegalArgumentException();
+                throw new IllegalArgumentException(
+                        "Invalid pixel_format=" + pixel_format);
             }
 
-            set("picture-format", s);
+            set(KEY_PICTURE_FORMAT, s);
         }
 
         /**
          * Returns the image format for pictures.
-         * 
+         *
          * @return the PixelFormat int representing the picture format
          */
         public int getPictureFormat() {
-            return pixelFormatForCameraFormat(get("picture-format"));
+            return pixelFormatForCameraFormat(get(KEY_PICTURE_FORMAT));
+        }
+
+        /**
+         * Gets the supported picture formats.
+         *
+         * @return a List of Integer objects (values are PixelFormat.XXX). null
+         *         if picture setting is not supported.
+         */
+        public List<Integer> getSupportedPictureFormats() {
+            String str = get(KEY_PICTURE_SIZE + SUPPORTED_VALUES_SUFFIX);
+            return splitInt(str);
         }
 
         private String cameraFormatForPixelFormat(int pixel_format) {
             switch(pixel_format) {
-            case PixelFormat.YCbCr_422_SP: return "yuv422sp";
-            case PixelFormat.YCbCr_420_SP: return "yuv420sp";
-            case PixelFormat.RGB_565:      return "rgb565";
-            case PixelFormat.JPEG:         return "jpeg";
+            case PixelFormat.YCbCr_422_SP: return PIXEL_FORMAT_YUV422SP;
+            case PixelFormat.YCbCr_420_SP: return PIXEL_FORMAT_YUV420SP;
+            case PixelFormat.RGB_565:      return PIXEL_FORMAT_RGB565;
+            case PixelFormat.JPEG:         return PIXEL_FORMAT_JPEG;
             default:                       return null;
             }
         }
@@ -836,21 +1001,309 @@
             if (format == null)
                 return PixelFormat.UNKNOWN;
 
-            if (format.equals("yuv422sp"))
+            if (format.equals(PIXEL_FORMAT_YUV422SP))
                 return PixelFormat.YCbCr_422_SP;
 
-            if (format.equals("yuv420sp"))
+            if (format.equals(PIXEL_FORMAT_YUV420SP))
                 return PixelFormat.YCbCr_420_SP;
 
-            if (format.equals("rgb565"))
+            if (format.equals(PIXEL_FORMAT_RGB565))
                 return PixelFormat.RGB_565;
 
-            if (format.equals("jpeg"))
+            if (format.equals(PIXEL_FORMAT_JPEG))
                 return PixelFormat.JPEG;
 
             return PixelFormat.UNKNOWN;
         }
 
+        /**
+         * Sets the orientation of the device in degrees, which instructs the
+         * camera driver to rotate the picture and thumbnail, in order to match
+         * what the user sees from the viewfinder. For example, suppose the
+         * natural position of the device is landscape. If the user takes a
+         * picture in landscape mode in 2048x1536 resolution, the rotation
+         * should be set to 0. If the user rotates the phone 90 degrees
+         * clockwise, the rotation should be set to 90. Applications can use
+         * {@link android.view.OrientationEventListener} to set this parameter.
+         *
+         * Since the picture is rotated, the orientation in the EXIF header is
+         * missing or always 1 (row #0 is top and column #0 is left side).
+         *
+         * @param rotation The orientation of the device in degrees. Rotation
+         *                 can only be 0, 90, 180 or 270.
+         * @throws IllegalArgumentException if rotation value is invalid.
+         * @see android.view.OrientationEventListener
+         */
+        public void setRotation(int rotation) {
+            if (rotation == 0 || rotation == 90 || rotation == 180
+                    || rotation == 270) {
+                set(KEY_ROTATION, Integer.toString(rotation));
+            } else {
+                throw new IllegalArgumentException(
+                        "Invalid rotation=" + rotation);
+            }
+        }
+
+        /**
+         * Sets GPS latitude coordinate. This will be stored in JPEG EXIF
+         * header.
+         *
+         * @param latitude GPS latitude coordinate.
+         */
+        public void setGpsLatitude(double latitude) {
+            set(KEY_GPS_LATITUDE, Double.toString(latitude));
+        }
+
+        /**
+         * Sets GPS longitude coordinate. This will be stored in JPEG EXIF
+         * header.
+         *
+         * @param longitude GPS longitude coordinate.
+         */
+        public void setGpsLongitude(double longitude) {
+            set(KEY_GPS_LONGITUDE, Double.toString(longitude));
+        }
+
+        /**
+         * Sets GPS altitude. This will be stored in JPEG EXIF header.
+         *
+         * @param altitude GPS altitude in meters.
+         */
+        public void setGpsAltitude(double altitude) {
+            set(KEY_GPS_ALTITUDE, Double.toString(altitude));
+        }
+
+        /**
+         * Sets GPS timestamp. This will be stored in JPEG EXIF header.
+         *
+         * @param timestamp GPS timestamp (UTC in seconds since January 1,
+         *                  1970).
+         */
+        public void setGpsTimestamp(long timestamp) {
+            set(KEY_GPS_TIMESTAMP, Long.toString(timestamp));
+        }
+
+        /**
+         * Removes GPS latitude, longitude, altitude, and timestamp from the
+         * parameters.
+         */
+        public void removeGpsData() {
+            remove(KEY_GPS_LATITUDE);
+            remove(KEY_GPS_LONGITUDE);
+            remove(KEY_GPS_ALTITUDE);
+            remove(KEY_GPS_TIMESTAMP);
+        }
+
+        /**
+         * Gets the current white balance setting.
+         *
+         * @return one of WHITE_BALANCE_XXX string constant. null if white
+         *         balance setting is not supported.
+         */
+        public String getWhiteBalance() {
+            return get(KEY_WHITE_BALANCE);
+        }
+
+        /**
+         * Sets the white balance.
+         *
+         * @param value WHITE_BALANCE_XXX string constant.
+         */
+        public void setWhiteBalance(String value) {
+            set(KEY_WHITE_BALANCE, value);
+        }
+
+        /**
+         * Gets the supported white balance.
+         *
+         * @return a List of WHITE_BALANCE_XXX string constants. null if white
+         *         balance setting is not supported.
+         */
+        public List<String> getSupportedWhiteBalance() {
+            String str = get(KEY_WHITE_BALANCE + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+        /**
+         * Gets the current color effect setting.
+         *
+         * @return one of EFFECT_XXX string constant. null if color effect
+         *         setting is not supported.
+         */
+        public String getColorEffect() {
+            return get(KEY_EFFECT);
+        }
+
+        /**
+         * Sets the current color effect setting.
+         *
+         * @param value EFFECT_XXX string constants.
+         */
+        public void setColorEffect(String value) {
+            set(KEY_EFFECT, value);
+        }
+
+        /**
+         * Gets the supported color effects.
+         *
+         * @return a List of EFFECT_XXX string constants. null if color effect
+         *         setting is not supported.
+         */
+        public List<String> getSupportedColorEffects() {
+            String str = get(KEY_EFFECT + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+
+        /**
+         * Gets the current antibanding setting.
+         *
+         * @return one of ANTIBANDING_XXX string constant. null if antibanding
+         *         setting is not supported.
+         */
+        public String getAntibanding() {
+            return get(KEY_ANTIBANDING);
+        }
+
+        /**
+         * Sets the antibanding.
+         *
+         * @param antibanding ANTIBANDING_XXX string constant.
+         */
+        public void setAntibanding(String antibanding) {
+            set(KEY_ANTIBANDING, antibanding);
+        }
+
+        /**
+         * Gets the supported antibanding values.
+         *
+         * @return a List of ANTIBANDING_XXX string constants. null if
+         *         antibanding setting is not supported.
+         */
+        public List<String> getSupportedAntibanding() {
+            String str = get(KEY_ANTIBANDING + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+        /**
+         * Gets the current scene mode setting.
+         *
+         * @return one of SCENE_MODE_XXX string constant. null if scene mode
+         *         setting is not supported.
+         */
+        public String getSceneMode() {
+            return get(KEY_SCENE_MODE);
+        }
+
+        /**
+         * Sets the scene mode.
+         *
+         * @param value SCENE_MODE_XXX string constants.
+         */
+        public void setSceneMode(String value) {
+            set(KEY_SCENE_MODE, value);
+        }
+
+        /**
+         * Gets the supported scene modes.
+         *
+         * @return a List of SCENE_MODE_XXX string constant. null if scene mode
+         *         setting is not supported.
+         */
+        public List<String> getSupportedSceneModes() {
+            String str = get(KEY_SCENE_MODE + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+        /**
+         * Gets the current flash mode setting.
+         *
+         * @return one of FLASH_MODE_XXX string constant. null if flash mode
+         *         setting is not supported.
+         */
+        public String getFlashMode() {
+            return get(KEY_FLASH_MODE);
+        }
+
+        /**
+         * Sets the flash mode.
+         *
+         * @param value FLASH_MODE_XXX string constants.
+         */
+        public void setFlashMode(String value) {
+            set(KEY_FLASH_MODE, value);
+        }
+
+        /**
+         * Gets the supported flash modes.
+         *
+         * @return a List of FLASH_MODE_XXX string constants. null if flash mode
+         *         setting is not supported.
+         */
+        public List<String> getSupportedFlashModes() {
+            String str = get(KEY_FLASH_MODE + SUPPORTED_VALUES_SUFFIX);
+            return split(str);
+        }
+
+        // Splits a comma delimited string to an ArrayList of String.
+        // Return null if the passing string is null or the size is 0.
+        private ArrayList<String> split(String str) {
+            if (str == null) return null;
+
+            // Use StringTokenizer because it is faster than split.
+            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            ArrayList<String> substrings = new ArrayList<String>();
+            while (tokenizer.hasMoreElements()) {
+                substrings.add(tokenizer.nextToken());
+            }
+            return substrings;
+        }
+
+        // Splits a comma delimited string to an ArrayList of Integer.
+        // Return null if the passing string is null or the size is 0.
+        private ArrayList<Integer> splitInt(String str) {
+            if (str == null) return null;
+
+            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            ArrayList<Integer> substrings = new ArrayList<Integer>();
+            while (tokenizer.hasMoreElements()) {
+                String token = tokenizer.nextToken();
+                substrings.add(Integer.parseInt(token));
+            }
+            if (substrings.size() == 0) return null;
+            return substrings;
+        }
+
+        // Splits a comma delimited string to an ArrayList of Size.
+        // Return null if the passing string is null or the size is 0.
+        private ArrayList<Size> splitSize(String str) {
+            if (str == null) return null;
+
+            StringTokenizer tokenizer = new StringTokenizer(str, ",");
+            ArrayList<Size> sizeList = new ArrayList<Size>();
+            while (tokenizer.hasMoreElements()) {
+                Size size = strToSize(tokenizer.nextToken());
+                if (size != null) sizeList.add(size);
+            }
+            if (sizeList.size() == 0) return null;
+            return sizeList;
+        }
+
+        // Parses a string (ex: "480x320") to Size object.
+        // Return null if the passing string is null.
+        private Size strToSize(String str) {
+            if (str == null) return null;
+
+            int pos = str.indexOf('x');
+            if (pos != -1) {
+                String width = str.substring(0, pos);
+                String height = str.substring(pos + 1);
+                return new Size(Integer.parseInt(width),
+                                Integer.parseInt(height));
+            }
+            Log.e(TAG, "Invalid size parameter string=" + str);
+            return null;
+        }
     };
 }
 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index b0fc78e..5352cf6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -104,7 +104,7 @@
      * This class is used to retrieved various statistics about the memory mappings for this
      * process. The returns info broken down by dalvik, native, and other. All results are in kB.
      */
-    public static class MemoryInfo {
+    public static class MemoryInfo implements Parcelable {
         /** The proportional set size for dalvik. */
         public int dalvikPss;
         /** The private dirty pages used by dalvik. */
@@ -125,6 +125,50 @@
         public int otherPrivateDirty;
         /** The shared dirty pages used by everything else. */
         public int otherSharedDirty;
+        
+        public MemoryInfo() {
+        }
+
+        public int describeContents() {
+            return 0;
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(dalvikPss);
+            dest.writeInt(dalvikPrivateDirty);
+            dest.writeInt(dalvikSharedDirty);
+            dest.writeInt(nativePss);
+            dest.writeInt(nativePrivateDirty);
+            dest.writeInt(nativeSharedDirty);
+            dest.writeInt(otherPss);
+            dest.writeInt(otherPrivateDirty);
+            dest.writeInt(otherSharedDirty);
+        }
+
+        public void readFromParcel(Parcel source) {
+            dalvikPss = source.readInt();
+            dalvikPrivateDirty = source.readInt();
+            dalvikSharedDirty = source.readInt();
+            nativePss = source.readInt();
+            nativePrivateDirty = source.readInt();
+            nativeSharedDirty = source.readInt();
+            otherPss = source.readInt();
+            otherPrivateDirty = source.readInt();
+            otherSharedDirty = source.readInt();
+        }
+        
+        public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() {
+            public MemoryInfo createFromParcel(Parcel source) {
+                return new MemoryInfo(source);
+            }
+            public MemoryInfo[] newArray(int size) {
+                return new MemoryInfo[size];
+            }
+        };
+
+        private MemoryInfo(Parcel source) {
+            readFromParcel(source);
+        }
     }
 
 
@@ -556,6 +600,13 @@
     public static native void getMemoryInfo(MemoryInfo memoryInfo);
 
     /**
+     * Note: currently only works when the requested pid has the same UID
+     * as the caller.
+     * @hide
+     */
+    public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo);
+
+    /**
      * Establish an object allocation limit in the current thread.  Useful
      * for catching regressions in code that is expected to operate
      * without causing any allocations.
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 6b491ab..84753ee 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -59,6 +59,8 @@
 
         /** Valid tag values.  Extend as necessary for your needs. */
         public enum Tag {
+            APANIC_CONSOLE,
+            APANIC_THREADS,
             AUTOTEST_FAILURE,
             AUTOTEST_SEQUENCE_BEGIN,
             AUTOTEST_SUITE_BEGIN,
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e48f539..2b67946 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -289,6 +289,32 @@
         }
 
         /**
+         * Computes a content URI (see {@link #CONTENT_URI}) given a lookup URI.
+         * <p>
+         * Returns null if the contact cannot be found.
+         */
+        public static Uri lookupContact(ContentResolver resolver, Uri lookupUri) {
+            if (lookupUri == null) {
+                return null;
+            }
+
+            Cursor c = resolver.query(lookupUri, new String[]{Contacts._ID}, null, null, null);
+            if (c == null) {
+                return null;
+            }
+
+            try {
+                if (c.moveToFirst()) {
+                    long contactId = c.getLong(0);
+                    return ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+                }
+            } finally {
+                c.close();
+            }
+            return null;
+        }
+
+        /**
          * The content:// style URI for this table joined with useful data from
          * {@link Data}.
          *
@@ -991,13 +1017,13 @@
             private Phone() {}
 
             /** MIME type used when storing this in data table. */
-            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone";
+            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2";
 
             /**
              * The MIME type of {@link #CONTENT_URI} providing a directory of
              * phones.
              */
-            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone";
+            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2";
 
             /**
              * The content:// style URI for all data records of the
@@ -1076,7 +1102,7 @@
             private Email() {}
 
             /** MIME type used when storing this in data table. */
-            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email";
+            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2";
 
             /**
              * The content:// style URI for all data records of the
@@ -1114,13 +1140,14 @@
             }
 
             /** MIME type used when storing this in data table. */
-            public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/postal-address";
+            public static final String CONTENT_ITEM_TYPE =
+                    "vnd.android.cursor.item/postal-address_v2";
 
             /**
              * The MIME type of {@link #CONTENT_URI} providing a directory of
              * postal addresses.
              */
-            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address";
+            public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address_v2";
 
             /**
              * The content:// style URI for all data records of the
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 4425e51..073ae6c 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -1548,11 +1548,12 @@
                     getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_UNREAD_CONVERSATIONS);
             // There seems to be a race condition here that can get the label maps into a bad
             // state and lose state on a particular label.
-            if (unreadConversations == null) {
-                return 0;
-            } else {
-                return unreadConversations;
+            int result = 0;
+            if (unreadConversations != null) {
+                result = unreadConversations < 0 ? 0 : unreadConversations;
             }
+
+            return result;
         }
 
         /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 77d1740..125ed0b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2231,6 +2231,32 @@
         public static final String BACKGROUND_DATA = "background_data";
 
         /**
+         * The time in msec, when the LAST_KMSG file was send to the checkin server.
+         * We will only send the LAST_KMSG file if it was modified after this time.
+         *
+         * @hide
+         */
+        public static final String CHECKIN_SEND_LAST_KMSG_TIME = "checkin_kmsg_time";
+
+        /**
+         * The time in msec, when the apanic_console file was send to the checkin server.
+         * We will only send the apanic_console file if it was modified after this time.
+         *
+         * @hide
+         */
+        public static final String CHECKIN_SEND_APANIC_CONSOLE_TIME =
+            "checkin_apanic_console_time";
+
+        /**
+         * The time in msec, when the apanic_thread file was send to the checkin server.
+         * We will only send the apanic_thread file if it was modified after this time.
+         *
+         * @hide
+         */
+        public static final String CHECKIN_SEND_APANIC_THREAD_TIME =
+            "checkin_apanic_thread_time";
+
+        /**
          * The CDMA roaming mode 0 = Home Networks, CDMA default
          *                       1 = Roaming on Affiliated networks
          *                       2 = Roaming on any networks
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 0207330..4584382 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -558,6 +558,23 @@
                 "android.provider.Telephony.SIM_FULL";
 
             /**
+             * Broadcast Action: An incoming SMS has been rejected by the
+             * telephony framework.  This intent is sent in lieu of any
+             * of the RECEIVED_ACTION intents.  The intent will have the
+             * following extra value:</p>
+             *
+             * <ul>
+             *   <li><em>result</em> - An int result code, eg,
+             *   <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>,
+             *   indicating the error returned to the network.</li>
+             * </ul>
+
+             */
+            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+            public static final String SMS_REJECTED_ACTION =
+                "android.provider.Telephony.SMS_REJECTED";
+
+            /**
              * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
              * {@link #DATA_SMS_RECEIVED_ACTION} intent.
              *
@@ -1522,6 +1539,9 @@
         public static final Uri CONTENT_DRAFT_URI = Uri.parse(
                 "content://mms-sms/draft");
 
+        public static final Uri CONTENT_LOCKED_URI = Uri.parse(
+                "content://mms-sms/locked");
+
         /***
          * Pass in a query parameter called "pattern" which is the text
          * to search for.
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 79a7cf8..8cef3a2 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -347,7 +347,12 @@
             } else {
                 mBluetoothService.getBondState().setBondState(address,
                         BluetoothDevice.BOND_NOT_BONDED);
+                mBluetoothService.setRemoteDeviceProperty(address, "Trusted", "false");
             }
+        } else if (name.equals("Trusted")) {
+            if (DBG)
+                log("set trust state succeded, value is  " + propValues[1]);
+            mBluetoothService.setRemoteDeviceProperty(address, name, propValues[1]);
         }
     }
 
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 21104c8..b168850 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -885,6 +885,42 @@
     }
 
     /**
+     * Sets the remote device trust state.
+     *
+     * @return boolean to indicate operation success or fail
+     */
+    public synchronized boolean setTrust(String address, boolean value) {
+        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+            mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+            return false;
+        }
+
+        return setDevicePropertyBooleanNative(getObjectPathFromAddress(address), "Trusted",
+                value ? 1 : 0);
+    }
+
+    /**
+     * Gets the remote device trust state as boolean.
+     * Note: this value may be
+     * retrieved from cache if we retrieved the data before *
+     *
+     * @return boolean to indicate trust or untrust state
+     */
+    public synchronized boolean getTrustState(String address) {
+        if (!BluetoothDevice.checkBluetoothAddress(address)) {
+            mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+            return false;
+        }
+
+        String val = getRemoteDeviceProperty(address, "Trusted");
+        if (val == null) {
+            return false;
+        } else {
+            return val.equals("true") ? true : false;
+        }
+    }
+
+    /**
      * Gets the remote major, minor classes encoded as a 32-bit
      * integer.
      *
@@ -1220,5 +1256,6 @@
     private native boolean setPasskeyNative(String address, int passkey, int nativeData);
     private native boolean setPairingConfirmationNative(String address, boolean confirm,
             int nativeData);
+    private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
 
 }
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 29dc2ea52..a92800d 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1527,7 +1527,7 @@
                     if (bm != null) {
                         workPaint.set(paint);
                         Styled.measureText(paint, workPaint, text,
-                                           offset, offset + 1, null);
+                                           j, j + 2, null);
 
                         float wid = (float) bm.getWidth() *
                                     -workPaint.ascent() / bm.getHeight();
diff --git a/core/java/android/webkit/ContentLoader.java b/core/java/android/webkit/ContentLoader.java
index 27cd6b5..19aa087 100644
--- a/core/java/android/webkit/ContentLoader.java
+++ b/core/java/android/webkit/ContentLoader.java
@@ -57,6 +57,16 @@
 
     }
 
+    private String errString(Exception ex) {
+        String exMessage = ex.getMessage();
+        String errString = mContext.getString(
+                com.android.internal.R.string.httpErrorFileNotFound);
+        if (exMessage != null) {
+            errString += " " + exMessage;
+        }
+        return errString;
+    }
+
     @Override
     protected boolean setupStreamAndSendStatus() {
         Uri uri = Uri.parse(mUrl);
@@ -73,28 +83,16 @@
             mDataStream = mContext.getContentResolver().openInputStream(uri);
             mHandler.status(1, 1, 0, "OK");
         } catch (java.io.FileNotFoundException ex) {
-            mHandler.error(
-                    EventHandler.FILE_NOT_FOUND_ERROR,
-                    mContext.getString(
-                            com.android.internal.R.string.httpErrorFileNotFound) +
-                    " " + ex.getMessage());
+            mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
             return false;
 
         } catch (java.io.IOException ex) {
-            mHandler.error(
-                    EventHandler.FILE_ERROR,
-                    mContext.getString(
-                            com.android.internal.R.string.httpErrorFileNotFound) +
-                    " " + ex.getMessage());
+            mHandler.error(EventHandler.FILE_ERROR, errString(ex));
             return false;
         } catch (RuntimeException ex) {
             // readExceptionWithFileNotFoundExceptionFromParcel in DatabaseUtils
             // can throw a serial of RuntimeException. Catch them all here.
-            mHandler.error(
-                    EventHandler.FILE_ERROR,
-                    mContext.getString(
-                            com.android.internal.R.string.httpErrorFileNotFound) +
-                    " " + ex.getMessage());
+            mHandler.error(EventHandler.FILE_ERROR, errString(ex));
             return false;
         }
         return true;
diff --git a/core/java/android/webkit/FileLoader.java b/core/java/android/webkit/FileLoader.java
index 54a4c1d..085f1f4 100644
--- a/core/java/android/webkit/FileLoader.java
+++ b/core/java/android/webkit/FileLoader.java
@@ -72,6 +72,15 @@
         }
     }
 
+    private String errString(Exception ex) {
+        String exMessage = ex.getMessage();
+        String errString = mContext.getString(R.string.httpErrorFileNotFound);
+        if (exMessage != null) {
+            errString += " " + exMessage;
+        }
+        return errString;
+    }
+
     @Override
     protected boolean setupStreamAndSendStatus() {
         try {
@@ -95,16 +104,11 @@
             mHandler.status(1, 1, 0, "OK");
 
         } catch (java.io.FileNotFoundException ex) {
-            mHandler.error(
-                    EventHandler.FILE_NOT_FOUND_ERROR,
-                    mContext.getString(R.string.httpErrorFileNotFound) +
-                    " " + ex.getMessage());
+            mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
             return false;
 
         } catch (java.io.IOException ex) {
-            mHandler.error(EventHandler.FILE_ERROR,
-                           mContext.getString(R.string.httpErrorFileNotFound) +
-                           " " + ex.getMessage());
+            mHandler.error(EventHandler.FILE_ERROR, errString(ex));
             return false;
         }
         return true;
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 43c76a8..1a5b2eb 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -606,6 +606,7 @@
                 // before calling it.
                 if (mCacheLoader != null) {
                     mCacheLoader.load();
+                    mFromCache = true;
                     if (DebugFlags.LOAD_LISTENER) {
                         Log.v(LOGTAG, "LoadListener cache load url=" + url());
                     }
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index f474f15..081250b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1244,6 +1244,18 @@
             }
         }
 
+        private synchronized boolean hasMessages(int what) {
+            if (mBlockMessages) {
+                return false;
+            }
+            if (mMessages != null) {
+                Log.w(LOGTAG, "hasMessages() is not supported in this case.");
+                return false;
+            } else {
+                return mHandler.hasMessages(what);
+            }
+        }
+
         private synchronized void sendMessageDelayed(Message msg, long delay) {
             if (mBlockMessages) {
                 return;
@@ -1355,9 +1367,22 @@
         // We don't want anyone to post a message between removing pending
         // messages and sending the destroy message.
         synchronized (mEventHub) {
+            // RESUME_TIMERS and PAUSE_TIMERS are per process base. They need to
+            // be preserved even the WebView is destroyed.
+            // Note: we should not have more than one RESUME_TIMERS/PAUSE_TIMERS
+            boolean hasResume = mEventHub.hasMessages(EventHub.RESUME_TIMERS);
+            boolean hasPause = mEventHub.hasMessages(EventHub.PAUSE_TIMERS);
             mEventHub.removeMessages();
             mEventHub.sendMessageAtFrontOfQueue(
                     Message.obtain(null, EventHub.DESTROY));
+            if (hasPause) {
+                mEventHub.sendMessageAtFrontOfQueue(
+                        Message.obtain(null, EventHub.PAUSE_TIMERS));
+            }
+            if (hasResume) {
+                mEventHub.sendMessageAtFrontOfQueue(
+                        Message.obtain(null, EventHub.RESUME_TIMERS));
+            }
             mEventHub.blockMessages();
             mWebView = null;
         }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index b179a13..2f28d9f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -651,6 +651,7 @@
 
             if (mProgress > max) {
                 mProgress = max;
+                refreshProgress(R.id.progress, mProgress, false);
             }
         }
     }
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 8bae3e4..ce0c9cb 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -425,6 +425,11 @@
     }
 
     public void onClick(View view) {
+        // Make sure there is a contact
+        if (mContactUri == null) {
+            return;
+        }
+
         switch (view.getId()) {
             case R.id.star: {
                 // Toggle "starred" state
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index b4c60f1..3ee404a 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -200,12 +200,13 @@
     fclose(fp);
 }
 
-static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
+static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
+        jint pid, jobject object)
 {
     stats_t stats;
     memset(&stats, 0, sizeof(stats_t));
     
-    load_maps(getpid(), &stats);
+    load_maps(pid, &stats);
 
     env->SetIntField(object, dalvikPss_field, stats.dalvikPss);
     env->SetIntField(object, dalvikPrivateDirty_field, stats.dalvikPrivateDirty);
@@ -220,6 +221,11 @@
     env->SetIntField(object, otherSharedDirty_field, stats.otherSharedDirty);
 }
 
+static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object)
+{
+    android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object);
+}
+
 static jint read_binder_stat(const char* stat)
 {
     FILE* fp = fopen(BINDER_STATS, "r");
@@ -281,6 +287,8 @@
             (void*) android_os_Debug_getNativeHeapFreeSize },
     { "getMemoryInfo",          "(Landroid/os/Debug$MemoryInfo;)V",
             (void*) android_os_Debug_getDirtyPages },
+    { "getMemoryInfo",          "(ILandroid/os/Debug$MemoryInfo;)V",
+            (void*) android_os_Debug_getDirtyPagesPid },
     { "getBinderSentTransactions", "()I",
             (void*) android_os_Debug_getBinderSentTransactions },
     { "getBinderReceivedTransactions", "()I",
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 1bfabd7..8fe7487 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -227,37 +227,58 @@
 
 
 const char * get_adapter_path(DBusConnection *conn) {
-    DBusMessage *msg, *reply;
+    DBusMessage *msg, *reply = NULL;
     DBusError err;
     const char *device_path = NULL;
-    msg = dbus_message_new_method_call("org.bluez", "/",
-          "org.bluez.Manager", "DefaultAdapter");
-    if (!msg) {
-        LOGE("%s: Can't allocate new method call for GetProperties!",
-              __FUNCTION__);
-        return NULL;
-    }
-    dbus_message_append_args(msg, DBUS_TYPE_INVALID);
+    int attempt = 0;
 
-    dbus_error_init(&err);
-    reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
-    dbus_message_unref(msg);
-
-    if (!reply) {
-        if (dbus_error_is_set(&err)) {
-            LOG_AND_FREE_DBUS_ERROR(&err);
+    for (attempt = 0; attempt < 1000 && reply == NULL; attempt ++) {
+        msg = dbus_message_new_method_call("org.bluez", "/",
+              "org.bluez.Manager", "DefaultAdapter");
+        if (!msg) {
+            LOGE("%s: Can't allocate new method call for get_adapter_path!",
+                  __FUNCTION__);
+            return NULL;
         }
-        return NULL;
+        dbus_message_append_args(msg, DBUS_TYPE_INVALID);
+        dbus_error_init(&err);
+        reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err);
+
+        if (!reply) {
+            if (dbus_error_is_set(&err)) {
+                if (dbus_error_has_name(&err,
+                    "org.freedesktop.DBus.Error.ServiceUnknown")) {
+                    // bluetoothd is still down, retry
+                    LOG_AND_FREE_DBUS_ERROR(&err);
+                    usleep(10000);  // 10 ms
+                    continue;
+                } else {
+                    // Some other error we weren't expecting
+                    LOG_AND_FREE_DBUS_ERROR(&err);
+                }
+            }
+            goto failed;
+        }
     }
+    if (attempt == 1000) {
+        LOGE("Time out while trying to get Adapter path, is bluetoothd up ?");
+        goto failed;
+    }
+
     if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH,
                                &device_path, DBUS_TYPE_INVALID)
                                || !device_path){
         if (dbus_error_is_set(&err)) {
             LOG_AND_FREE_DBUS_ERROR(&err);
         }
-        return NULL;
+        goto failed;
     }
+    dbus_message_unref(msg);
     return device_path;
+
+failed:
+    dbus_message_unref(msg);
+    return NULL;
 }
 
 static int register_agent(native_data_t *nat,
@@ -274,6 +295,9 @@
     }
 
     nat->adapter = get_adapter_path(nat->conn);
+    if (nat->adapter == NULL) {
+        return -1;
+    }
     msg = dbus_message_new_method_call("org.bluez", nat->adapter,
           "org.bluez.Adapter", "RegisterAgent");
     if (!msg) {
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index d1901b4..de921f1 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -646,6 +646,7 @@
         if (!msg) {
             LOGE("%s: Can't allocate new method call for GetProperties!",
                   __FUNCTION__);
+            env->ReleaseStringUTFChars(key, c_key);
             return JNI_FALSE;
         }
 
@@ -701,6 +702,60 @@
 #endif
 }
 
+static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
+                                               jstring key, void *value, jint type) {
+#ifdef HAVE_BLUETOOTH
+    LOGV(__FUNCTION__);
+    native_data_t *nat = get_native_data(env, object);
+    if (nat) {
+        DBusMessage *reply, *msg;
+        DBusMessageIter iter;
+        DBusError err;
+
+        const char *c_key = env->GetStringUTFChars(key, NULL);
+        const char *c_path = env->GetStringUTFChars(path, NULL);
+
+        dbus_error_init(&err);
+        msg = dbus_message_new_method_call(BLUEZ_DBUS_BASE_IFC,
+                                          c_path, DBUS_DEVICE_IFACE, "SetProperty");
+        if (!msg) {
+            LOGE("%s: Can't allocate new method call for device SetProperty!", __FUNCTION__);
+            env->ReleaseStringUTFChars(key, c_key);
+            env->ReleaseStringUTFChars(path, c_path);
+            return JNI_FALSE;
+        }
+
+        dbus_message_append_args(msg, DBUS_TYPE_STRING, &c_key, DBUS_TYPE_INVALID);
+        dbus_message_iter_init_append(msg, &iter);
+        append_variant(&iter, type, value);
+
+        reply = dbus_connection_send_with_reply_and_block(nat->conn, msg, -1, &err);
+        dbus_message_unref(msg);
+
+        env->ReleaseStringUTFChars(key, c_key);
+        env->ReleaseStringUTFChars(path, c_path);
+        if (!reply) {
+            if (dbus_error_is_set(&err)) {
+                LOG_AND_FREE_DBUS_ERROR(&err);
+            } else
+            LOGE("DBus reply is NULL in function %s", __FUNCTION__);
+            return JNI_FALSE;
+        }
+        return JNI_TRUE;
+    }
+#endif
+    return JNI_FALSE;
+}
+
+static jboolean setDevicePropertyBooleanNative(JNIEnv *env, jobject object,
+                                                     jstring path, jstring key, jint value) {
+#ifdef HAVE_BLUETOOTH
+    return setDevicePropertyNative(env, object, path, key,
+                                        (void *)&value, DBUS_TYPE_BOOLEAN);
+#else
+    return JNI_FALSE;
+#endif
+}
 
 static JNINativeMethod sMethods[] = {
      /* name, signature, funcPtr */
@@ -740,6 +795,8 @@
     {"setPinNative", "(Ljava/lang/String;Ljava/lang/String;I)Z", (void *)setPinNative},
     {"cancelPairingUserInputNative", "(Ljava/lang/String;I)Z",
             (void *)cancelPairingUserInputNative},
+    {"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
+            (void *)setDevicePropertyBooleanNative},
 };
 
 int register_android_server_BluetoothService(JNIEnv *env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1ea5fa3..53e0125 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1113,6 +1113,7 @@
                  android:label="@string/android_system_label"
                  android:allowClearUserData="false"
                  android:backupAgent="com.android.server.SystemBackupAgent"
+                 android:killAfterRestore="false"
                  android:icon="@drawable/ic_launcher_android">
         <activity android:name="com.android.internal.app.ChooserActivity"
                 android:theme="@style/Theme.Dialog.Alert"
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
new file mode 100644
index 0000000..58d2dbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
new file mode 100644
index 0000000..cd1afe9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
new file mode 100644
index 0000000..c398d6f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
new file mode 100644
index 0000000..e1eb5b0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_connected_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_connected_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_in_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_in_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_inandout_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_inandout_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_data_out_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_out_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
index 42c8ab4..82ba310 100644
--- a/core/res/res/values-en-rUS/donottranslate-names.xml
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -147,7 +147,7 @@
         MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
     </string>
     <string name="common_last_name_prefixes">
-        D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
+        D\', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
     </string>
     <string name="common_name_conjunctions">
         &amp;, AND, OR
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index ce421db..7aaf218 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -580,6 +580,15 @@
     <!-- This is not the attribute you are looking for. -->
     <attr name="allowBackup" format="boolean" />
 
+    <!-- Whether the application in question should be terminated after its
+         settings have been restored.  The default is to do so. -->
+    <attr name="killAfterRestore" format="boolean" />
+
+    <!-- Whether the application needs to have its own Application subclass
+         active during restore.  The default is to run restore with a minimal
+         Application class to avoid interference with application logic. -->
+    <attr name="restoreNeedsApplication" format="boolean" />
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -656,6 +665,8 @@
         <attr name="testOnly" />
         <attr name="backupAgent" />
         <attr name="allowBackup" />
+        <attr name="killAfterRestore" />
+        <attr name="restoreNeedsApplication" />
     </declare-styleable>
     
     <!-- The <code>permission</code> tag declares a security permission that can be
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0fba0f6..1a362f7 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1155,10 +1155,11 @@
   <public type="attr" name="wallpaperActivityOpenExitAnimation" />
   <public type="attr" name="wallpaperActivityCloseEnterAnimation" />
   <public type="attr" name="wallpaperActivityCloseExitAnimation" />
+  <public type="attr" name="supportsUploading" />
+  <public type="attr" name="killAfterRestore" />
+  <public type="attr" name="restoreNeedsApplication" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar.Fullscreen" />
-
-  <public type="attr" name="supportsUploading" />
 </resources>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 0248985..e508392 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -15,20 +15,60 @@
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
 
 <dt>description:</dt>
-<dd>This element specifies a specific feature used by the application.
+<dd>This element declares a specific feature used by the application.
 Android provides some features that may not be equally supported by all
 Android devices. In a manner similar to the <code><a href="uses-sdk-element.html">&lt;uses-sdk></a></code> 
-element, this element allows an application to specify which potentially variable
-features it requires. In this way, the application
-will not be installed on devices that do not offer the required feature.</p>
+element, this element allows an application to specify which device-variable
+features it uses. In this way, the application
+will not be installed on devices that do not offer the feature.</p>
 
-<p>For example, an application might specify that it requires a certain version of Open GL.
-If a device does not support that version of Open GL, then it will not allow installation of the application.</p>
+<p>For example, an application might specify that it requires a camera with auto-focus capabilities.
+If a device does not provide a camera with auto-focus, then it will not allow
+installation of the application.</p>
+
+<p>In order to maintain strict device compatibility, it's very important that you use
+this element to declare all features that your application uses. Failure to declare
+a feature may result your application being installed on a device
+that does not support the feature and your application failing.</p>
+
+<p>For some features, there may exist a specfic attribute that allows you to define
+a version of the feature, such as the version of Open GL used (declared with
+<a href="#glEsVersion">{@code glEsVersion}</a>). Other features that either do or do not
+exist for a device, such as camera auto-focus, are declared using the
+<a href="#name">{@code name}</a> attribute.</p>
+
+<p>Any software or hardware features that may vary among Android-powered
+devices will be listed on this page among the attributes below. If you see any features
+here that you use in your application, you should include a {@code
+&lt;uses-feature>} element for each one. For example, if your application uses the device
+camera, then you should include the following in your {@code AndroidManifest.xml}:</p>
+
+<pre>
+&lt;uses-feature android:name="android.hardware.camera" />
+</pre>
+
+<p>If you declare "android.hardware.camera", then your application is considered
+compatible with all devices that include a camera, regardless of whether auto-focus is
+available or not. If you also use the auto-focus features (available through the {@link
+android.hardware.Camera Camera API}), then you need to include an additional
+{@code &lt;uses-feature>} element that declares the "android.hardware.camera.autofocus"
+feature. Also note that you must still request the {@link android.Manifest.permission#CAMERA
+CAMERA permission}. Requesting permission grants your application access to the
+appropriate hardware and software, while declaring the features used by
+your application ensures proper device compatibility.</p>
+
+<p>Although the {@code &lt;uses-feature>} element is only activated for devices running 
+API Level 4 or higher, it is safe to include this for applications that declare 
+a <a href="uses-sdk-element.html#min">{@code minSdkVersion}</a> 
+of "3" or lower. Devices running older versions of the platform 
+will simply ignore this element, but newer devices will recognize it and enforce 
+installation restrictions based on whether the device supports the feature.</p>
 
 <p class="note"><strong>Note:</strong>
 For each feature required by your application, you must include a new {@code
 &lt;uses-feature>} element. Multiple features cannot be declared in one 
 instance of this element.</p>
+
 </dd> 
 
 
@@ -51,16 +91,30 @@
   
   <table> 
     <tr> 
+       <th>Feature</th>
        <th>Value</th> 
        <th>Description</th> 
     </tr><tr> 
+       <td rowspan="3">Camera</td>
        <td>"{@code android.hardware.camera}"</td> 
        <td>The application requires a camera.</td> 
     </tr><tr> 
        <td>"{@code android.hardware.camera.autofocus}"</td> 
        <td>The application requires a camera with auto-focus capability.
        As a prerequisite, "{@code android.hardware.camera}" must also be declared
-       with a separate {@code &lt;uses-feature>} element.</td> 
+       with a separate {@code &lt;uses-feature>} element.
+       </td>
+     <tr>
+       <td colspan="2">
+         <strong>Note:</strong> Any application that requests the 
+         {@link android.Manifest.permission#CAMERA CAMERA permission} but does <em>not</em>
+         declare any camera features with the {@code &lt;uses-feature>} element will be assumed
+         to use all camera features (such as auto-focus). Thus, the application will not
+         be compatible with devices that do not support all features. Please use 
+         {@code &lt;uses-feature>} to declare only the camera features that your 
+         application needs.
+       </td>
+     </tr>
     </tr>
   </table>
   
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index adcdc28..ee8d03d 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -3,7 +3,10 @@
 
 <dl class="xml">
 <dt>syntax:</dt>
-<dd><pre class="stx">&lt;uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" /&gt;</pre></dd>
+<dd><pre>
+&lt;uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" 
+          android:<a href="#max">maxSdkVersion</a>="<i>integer</i>"
+          android:<a href="#target">targetSdkVersion</a>="<i>integer</i>" /&gt;</pre></dd>
 
 <dt>contained in:</dt>
 <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code></dd>
@@ -64,12 +67,16 @@
   <dt><a name="target"></a>{@code android:targetSdkVersion}</dt>
   <dd>An integer designating the API Level that the application is targetting.
   
-  <p>With this attribute set, the application says that is is be able to run on 
+  <p>With this attribute set, the application says that it is able to run on 
   older versions (down to {@code minSdkVersion}), but was explicitly tested to work 
   with the version specified here.
-  Specifying this version allows the platform to disable compatibility
-  code that is not required or enable newer features that are not
-  available to older applications.</p>
+  Specifying this target version allows the platform to disable compatibility
+  settings that are not required for the target version (which may otherwise be turned on
+  in order to maintain forward-compatibility) or enable newer features that are not
+  available to older applications. This does not mean that you can program different 
+  features for different versions of the platform&mdash;it simply informs the platform that you
+  have tested against the target version and the platform should not perform any extra
+  work to maintain forward-compatibility with the target version.</p>
   
   <p>Introduced in: API Level 4</p>
   </dd>
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 29cdf21..5b0e0b4 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -136,7 +136,7 @@
     void clearCodecSpecificData();
 
     void setAMRFormat();
-    void setAACFormat();
+    void setAACFormat(int32_t numChannels, int32_t sampleRate);
 
     status_t setVideoPortFormatType(
             OMX_U32 portIndex,
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
index d1174ad..6caeb3e 100644
--- a/keystore/java/android/security/CertTool.java
+++ b/keystore/java/android/security/CertTool.java
@@ -163,15 +163,9 @@
                 return ret;
             }
         }
-        while ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
-            if (i++ > 0) {
-                if ((ret = sKeystore.put(CA_CERTIFICATE, keyname + i, pemData)) != 0) {
-                    return ret;
-                }
-            } else {
-                if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
-                    return ret;
-                }
+        if ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
+            if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
+                return ret;
             }
         }
         return 0;
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
index 006a0a3..91114d6 100644
--- a/keystore/jni/cert.c
+++ b/keystore/jni/cert.c
@@ -212,13 +212,14 @@
     }
 err:
     if (bio) BIO_free(bio);
-    return (len == 0) ? -1 : 0;
+    return len;
 }
 
 int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
 {
     if ((p12store != NULL) && (p12store->cert != NULL)) {
-        return convert_to_pem((void*)p12store->cert, 1, buf, size);
+        int len = convert_to_pem((void*)p12store->cert, 1, buf, size);
+        return (len == 0) ? -1 : 0;
     }
     return -1;
 }
@@ -226,7 +227,8 @@
 int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
 {
     if ((p12store != NULL) && (p12store->pkey != NULL)) {
-        return convert_to_pem((void*)p12store->pkey, 0, buf, size);
+        int len = convert_to_pem((void*)p12store->pkey, 0, buf, size);
+        return (len == 0) ? -1 : 0;
     }
     return -1;
 }
@@ -234,12 +236,19 @@
 int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
 {
     X509 *cert = NULL;
+    int len = 0;
 
-    if ((p12store != NULL) && (p12store->certs != NULL) &&
-        ((cert = sk_X509_pop(p12store->certs)) != NULL)) {
-        int ret = convert_to_pem((void*)cert, 1, buf, size);
-        X509_free(cert);
-        return ret;
+    if ((p12store != NULL) && (p12store->certs != NULL)) {
+        while (((cert = sk_X509_pop(p12store->certs)) != NULL) && (len < size)) {
+            int s = convert_to_pem((void*)cert, 1, buf + len, size - len);
+            if (s == 0) {
+                LOGE("buffer size is too small. len=%d size=%d\n", len, size);
+                return -1;
+            }
+            len += s;
+            X509_free(cert);
+        }
+        return (len == 0) ? -1 : 0;
     }
     return -1;
 }
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 3a419b5..ef71641 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1449,6 +1449,8 @@
         int j = activeTracks.indexOf(t);
         if (j >= 0) {
             mActiveTracks.add(t);
+            // force buffer refilling and no ramp volume when the track is mixed for the first time
+            t->mFillingUpStatus = Track::FS_FILLING;
         }
     }
 }
@@ -3512,10 +3514,11 @@
             if (tracks.size()) {
                 dstThread->putTracks(tracks, activeTracks);
             }
-            dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
         }
     }
 
+    dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
+
     return NO_ERROR;
 }
 
diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c
index 8c1cad4..99f4048 100644
--- a/libs/rs/java/Fountain/res/raw/fountain.c
+++ b/libs/rs/java/Fountain/res/raw/fountain.c
@@ -4,45 +4,44 @@
 #pragma stateFragment(default)
 #pragma stateFragmentStore(default)
 
+struct PartStruct {float dx; float dy; float x; float y; int c;};
+int newPart = 0;
+
 int main(int launchID) {
     int ct;
     int count = Control_count - 1;
     int rate = Control_rate;
-    float *dataF = loadArrayF(1, 0);
     float height = getHeight();
+    struct PartStruct * p = (struct PartStruct *)loadArrayF(1, 0);
 
     if (rate) {
-        int *dataI = loadArrayI32(1, 0);
         float rMax = ((float)rate) * 0.005f;
         int x = Control_x;
         int y = Control_y;
-        int newPart = loadI32(1, count * 5);
         int c = colorFloatRGBAtoUNorm8(Control_r, Control_g, Control_b, 0.99f);
 
         while (rate--) {
-            int idx = newPart * 5;
-            vec2Rand(dataF + idx, rMax);
-            dataF[idx + 2] = x;
-            dataF[idx + 3] = y;
-            dataI[idx + 4] = c;
+            vec2Rand((float *)(p + newPart), rMax);
+            p[newPart].x = x;
+            p[newPart].y = y;
+            p[newPart].c = c;
             newPart++;
             if (newPart >= count) {
                 newPart = 0;
             }
         }
-        storeI32(1, count * 5, newPart);
     }
 
     for (ct=0; ct < count; ct++) {
-        float dy = dataF[1] + 0.15f;
-        float posy = dataF[3] + dy;
+        float dy = p->dy + 0.15f;
+        float posy = p->y + dy;
         if ((posy > height) && (dy > 0)) {
             dy *= -0.3f;
         }
-        dataF[1] = dy;
-        dataF[2] += dataF[0];
-        dataF[3] = posy;
-        dataF += 5;
+        p->dy = dy;
+        p->x += p->dx;
+        p->y = posy;
+        p++;
     }
 
     uploadToBufferObject(NAMED_PartBuffer);
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 0831f4a..f80843d 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3284,7 +3284,16 @@
                     break;
                 }
                 if (c == '\'' && (quoted == 0 || quoted == '\'')) {
-                    break;
+                    /*
+                     * In practice, when people write ' instead of \'
+                     * in a string, they are doing it by accident
+                     * instead of really meaning to use ' as a quoting
+                     * character.  Warn them so they don't lose it.
+                     */
+                    if (outErrorMsg) {
+                        *outErrorMsg = "Apostrophe not preceded by \\";
+                    }
+                    return false;
                 }
             }
             p++;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 098ddbd..6af7df9 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -174,7 +174,7 @@
     *http_status = -1;
     mHeaders.clear();
 
-    char line[256];
+    char line[1024];
     status_t err = receive_line(line, sizeof(line));
     if (err != OK) {
         return err;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3a065ae..7c8defc 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -302,7 +302,11 @@
         codec->setAMRFormat();
     }
     if (!createEncoder && !strcasecmp("audio/mp4a-latm", mime)) {
-        codec->setAACFormat();
+        int32_t numChannels, sampleRate;
+        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
+        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
+
+        codec->setAACFormat(numChannels, sampleRate);
     }
     if (!strncasecmp(mime, "video/", 6)) {
         int32_t width, height;
@@ -1321,10 +1325,6 @@
         return;
     }
 
-    // We're going to temporarily give up the lock while reading data
-    // from the source. A certain client unfortunately chose to have the
-    // thread supplying input data and reading output data be the same...
-
     MediaBuffer *srcBuffer;
     status_t err;
     if (mSeekTimeUs >= 0) {
@@ -1332,13 +1332,10 @@
         options.setSeekTo(mSeekTimeUs);
         mSeekTimeUs = -1;
 
-        mLock.unlock();
         err = mSource->read(&srcBuffer, &options);
     } else {
-        mLock.unlock();
         err = mSource->read(&srcBuffer);
     }
-    mLock.lock();
 
     OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
     OMX_TICKS timestamp = 0;
@@ -1496,20 +1493,22 @@
     }
 }
 
-void OMXCodec::setAACFormat() {
-    OMX_AUDIO_PARAM_AACPROFILETYPE def;
-    def.nSize = sizeof(def);
-    def.nVersion.s.nVersionMajor = 1;
-    def.nVersion.s.nVersionMinor = 1;
-    def.nPortIndex = kPortIndexInput;
+void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
+    OMX_AUDIO_PARAM_AACPROFILETYPE profile;
+    profile.nSize = sizeof(profile);
+    profile.nVersion.s.nVersionMajor = 1;
+    profile.nVersion.s.nVersionMinor = 1;
+    profile.nPortIndex = kPortIndexInput;
 
     status_t err =
-        mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+        mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
     CHECK_EQ(err, OK);
 
-    def.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+    profile.nChannels = numChannels;
+    profile.nSampleRate = sampleRate;
+    profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
 
-    err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &def, sizeof(def));
+    err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
     CHECK_EQ(err, OK);
 }
 
@@ -2123,8 +2122,19 @@
             inputFormat->findInt32(kKeyChannelCount, &numChannels);
             inputFormat->findInt32(kKeySampleRate, &sampleRate);
 
+            if ((OMX_U32)numChannels != params.nChannels) {
+                LOGW("Codec outputs a different number of channels than "
+                     "the input stream contains.");
+            }
+
             mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
-            mOutputFormat->setInt32(kKeyChannelCount, numChannels);
+
+            // Use the codec-advertised number of channels, as some
+            // codecs appear to output stereo even if the input data is
+            // mono.
+            mOutputFormat->setInt32(kKeyChannelCount, params.nChannels);
+
+            // The codec-reported sampleRate is not reliable...
             mOutputFormat->setInt32(kKeySampleRate, sampleRate);
             break;
         }
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index af0a1bd..1e1d729 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -8,6 +8,7 @@
                  android:label="@string/app_label"
                  android:process="system"
                  android:backupAgent="SettingsBackupAgent"
+                 android:killAfterRestore="false"
                  android:icon="@drawable/ic_launcher_settings">
 
         <provider android:name="SettingsProvider" android:authorities="settings"
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 071a90d..0ec8dab 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -41,7 +41,7 @@
 #define FILTER_LOWSHELF_ATTENUATION -18.0f // in dB
 #define FILTER_TRANSITION_FREQ 1100.0f     // in Hz
 #define FILTER_SHELF_SLOPE 1.0f            // Q
-#define FILTER_GAIN 6.0f // linear gain
+#define FILTER_GAIN 5.5f // linear gain
 // such a huge gain is justified by how much energy in the low frequencies is "wasted" at the output
 // of the synthesis. The low shelving filter removes it, leaving room for amplification.
 
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 4eed7fe..0e60dd6 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -557,7 +557,12 @@
             Log.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
             for (PackageInfo p : targetPkgs) {
                 Log.v(TAG, "    " + p + " agent=" + p.applicationInfo.backupAgentName
-                        + " uid=" + p.applicationInfo.uid);
+                        + " uid=" + p.applicationInfo.uid
+                        + " killAfterRestore="
+                        + (((p.applicationInfo.flags & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) ? "true" : "false")
+                        + " restoreNeedsApplication="
+                        + (((p.applicationInfo.flags & ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION) != 0) ? "true" : "false")
+                        );
             }
         }
 
@@ -1244,11 +1249,21 @@
                             + "] is compatible with installed version ["
                             + packageInfo.versionCode + "]");
 
-                    // Now perform the actual restore
+                    // Now perform the actual restore:  first clear the app's data
+                    // if appropriate
                     clearApplicationDataSynchronous(packageName);
+
+                    // Then set up and bind the agent (with a restricted Application object
+                    // unless the application says otherwise)
+                    boolean useRealApp = (packageInfo.applicationInfo.flags
+                            & ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION) != 0;
+                    if (DEBUG && useRealApp) {
+                        Log.v(TAG, "agent requires real Application subclass for restore");
+                    }
                     IBackupAgent agent = bindToAgentSynchronous(
                             packageInfo.applicationInfo,
-                            IApplicationThread.BACKUP_MODE_RESTORE);
+                            (useRealApp ? IApplicationThread.BACKUP_MODE_INCREMENTAL
+                                    : IApplicationThread.BACKUP_MODE_RESTORE));
                     if (agent == null) {
                         Log.w(TAG, "Can't find backup agent for " + packageName);
                         EventLog.writeEvent(RESTORE_AGENT_FAILURE_EVENT, packageName,
@@ -1256,12 +1271,26 @@
                         continue;
                     }
 
+                    // And then finally run the restore on this agent
                     try {
                         processOneRestore(packageInfo, metaInfo.versionCode, agent);
                         ++count;
                     } finally {
-                        // unbind even on timeout or failure, just in case
+                        // unbind and tidy up even on timeout or failure, just in case
                         mActivityManager.unbindBackupAgent(packageInfo.applicationInfo);
+
+                        // The agent was probably running with a stub Application object,
+                        // which isn't a valid run mode for the main app logic.  Shut
+                        // down the app so that next time it's launched, it gets the
+                        // usual full initialization.
+                        if ((packageInfo.applicationInfo.flags
+                                & ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) {
+                            if (DEBUG) Log.d(TAG, "Restore complete, killing host process of "
+                                    + packageInfo.applicationInfo.processName);
+                            mActivityManager.killApplicationProcess(
+                                    packageInfo.applicationInfo.processName,
+                                    packageInfo.applicationInfo.uid);
+                        }
                     }
                 }
 
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 8ec6ec3..14cd7a8 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -62,6 +62,8 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.Environment;
@@ -140,7 +142,7 @@
 
     final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
             Process.THREAD_PRIORITY_BACKGROUND);
-    final Handler mHandler;
+    final PackageHandler mHandler;
 
     final int mSdkVersion = Build.VERSION.SDK_INT;
     final String mSdkCodename = "REL".equals(Build.VERSION.CODENAME)
@@ -272,6 +274,49 @@
     ComponentName mResolveComponentName;
     PackageParser.Package mPlatformPackage;
 
+    // Set of pending broadcasts for aggregating enable/disable of components.
+    final HashMap<String, String> mPendingBroadcasts = new HashMap<String, String>();
+    static final int SEND_PENDING_BROADCAST = 1;
+    // Delay time in millisecs
+    static final int BROADCAST_DELAY = 10 * 1000;
+
+    class PackageHandler extends Handler {
+        PackageHandler(Looper looper) {
+            super(looper);
+        }
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SEND_PENDING_BROADCAST : {
+                    int size = 0;
+                    String broadcastList[];
+                    HashMap<String, String> tmpMap;
+                    int uids[];
+                    synchronized (mPackages) {
+                        size = mPendingBroadcasts.size();
+                        if (size <= 0) {
+                            // Nothing to be done. Just return
+                            return;
+                        }
+                        broadcastList = new String[size];
+                        mPendingBroadcasts.keySet().toArray(broadcastList);
+                        tmpMap = new HashMap<String, String>(mPendingBroadcasts);
+                        uids = new int[size];
+                        for (int i = 0; i < size; i++) {
+                            PackageSetting ps = mSettings.mPackages.get(mPendingBroadcasts.get(broadcastList[i]));
+                            uids[i] = (ps != null) ? ps.userId : -1;
+                        }
+                        mPendingBroadcasts.clear();
+                    }
+                    // Send broadcasts
+                    for (int i = 0; i < size; i++) {
+                        String className = broadcastList[i];
+                        sendPackageChangedBroadcast(className, true, tmpMap.get(className), uids[i]);
+                    }
+                    break;
+                }
+            }
+        }
+    }
     public static final IPackageManager main(Context context, boolean factoryTest) {
         PackageManagerService m = new PackageManagerService(context, factoryTest);
         ServiceManager.addService("package", m);
@@ -355,7 +400,7 @@
         synchronized (mInstallLock) {
         synchronized (mPackages) {
             mHandlerThread.start();
-            mHandler = new Handler(mHandlerThread.getLooper());
+            mHandler = new PackageHandler(mHandlerThread.getLooper());
             
             File dataDir = Environment.getDataDirectory();
             mAppDataDir = new File(dataDir, "data");
@@ -4866,7 +4911,7 @@
     }
 
     private void setEnabledSetting(
-            final String packageNameStr, String classNameStr, int newState, final int flags) {
+            final String packageName, String className, int newState, final int flags) {
         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
               || newState == COMPONENT_ENABLED_STATE_ENABLED
               || newState == COMPONENT_ENABLED_STATE_DISABLED)) {
@@ -4878,17 +4923,20 @@
         final int permission = mContext.checkCallingPermission(
                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+        boolean sendNow = false;
+        boolean isApp = (className == null);
+        String key = isApp ? packageName : className;
         int packageUid = -1;
         synchronized (mPackages) {
-            pkgSetting = mSettings.mPackages.get(packageNameStr);
+            pkgSetting = mSettings.mPackages.get(packageName);
             if (pkgSetting == null) {
-                if (classNameStr == null) {
+                if (className == null) {
                     throw new IllegalArgumentException(
-                            "Unknown package: " + packageNameStr);
+                            "Unknown package: " + packageName);
                 }
                 throw new IllegalArgumentException(
-                        "Unknown component: " + packageNameStr
-                        + "/" + classNameStr);
+                        "Unknown component: " + packageName
+                        + "/" + className);
             }
             if (!allowedByPermission && (uid != pkgSetting.userId)) {
                 throw new SecurityException(
@@ -4896,41 +4944,67 @@
                         + Binder.getCallingPid()
                         + ", uid=" + uid + ", package uid=" + pkgSetting.userId);
             }
-            packageUid = pkgSetting.userId;
-            if (classNameStr == null) {
+            if (className == null) {
                 // We're dealing with an application/package level state change
                 pkgSetting.enabled = newState;
             } else {
                 // We're dealing with a component level state change
                 switch (newState) {
                 case COMPONENT_ENABLED_STATE_ENABLED:
-                    pkgSetting.enableComponentLP(classNameStr);
+                    pkgSetting.enableComponentLP(className);
                     break;
                 case COMPONENT_ENABLED_STATE_DISABLED:
-                    pkgSetting.disableComponentLP(classNameStr);
+                    pkgSetting.disableComponentLP(className);
                     break;
                 case COMPONENT_ENABLED_STATE_DEFAULT:
-                    pkgSetting.restoreComponentLP(classNameStr);
+                    pkgSetting.restoreComponentLP(className);
                     break;
                 default:
                     Log.e(TAG, "Invalid new component state: " + newState);
+                    return;
                 }
             }
             mSettings.writeLP();
+            packageUid = pkgSetting.userId;
+            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
+                sendNow = true;
+                // Purge entry from pending broadcast list if another one exists already
+                // since we are sending one right away.
+                if (mPendingBroadcasts.get(key) != null) {
+                    mPendingBroadcasts.remove(key);
+                    // Can ignore empty list since its handled in the handler anyway
+                }
+            } else {
+                if (mPendingBroadcasts.get(key) == null) {
+                    mPendingBroadcasts.put(key, packageName);
+                }
+                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
+                    // Schedule a message
+                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
+                }
+            }
         }
-        
+
         long callingId = Binder.clearCallingIdentity();
         try {
-            Bundle extras = new Bundle(2);
-            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP,
-                    (flags&PackageManager.DONT_KILL_APP) != 0);
-            extras.putInt(Intent.EXTRA_UID, packageUid);
-            sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED, packageNameStr, extras);
+            if (sendNow) {
+                sendPackageChangedBroadcast(packageName,
+                        (flags&PackageManager.DONT_KILL_APP) != 0, key, packageUid);
+            }
         } finally {
             Binder.restoreCallingIdentity(callingId);
         }
     }
 
+    private void sendPackageChangedBroadcast(String packageName,
+            boolean killFlag, String componentName, int packageUid) {
+        Bundle extras = new Bundle(2);
+        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentName);
+        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
+        extras.putInt(Intent.EXTRA_UID, packageUid);
+        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras);   
+    }
+
     public String getInstallerPackageName(String packageName) {
         synchronized (mPackages) {
             PackageSetting pkg = mSettings.mPackages.get(packageName);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d4e69c0..252a6d2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -68,6 +68,7 @@
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -4895,6 +4896,52 @@
         Binder.restoreCallingIdentity(origId);
     }
     
+    public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi)
+            throws RemoteException {
+        ProcessRecord proc;
+        synchronized (mPidsSelfLocked) {
+            proc = mPidsSelfLocked.get(pid);
+        }
+        
+        if (proc == null) {
+            throw new RemoteException();
+        }
+        
+        IApplicationThread thread = proc.thread;
+        if (thread == null) {
+            throw new RemoteException();
+        }
+        
+        thread.getMemoryInfo(mi);
+    }
+
+    public void killApplicationProcess(String processName, int uid) {
+        if (processName == null) {
+            return;
+        }
+
+        int callerUid = Binder.getCallingUid();
+        // Only the system server can kill an application
+        if (callerUid == Process.SYSTEM_UID) {
+            synchronized (this) {
+                ProcessRecord app = getProcessRecordLocked(processName, uid);
+                if (app != null) {
+                    try {
+                        app.thread.scheduleSuicide();
+                    } catch (RemoteException e) {
+                        // If the other end already died, then our work here is done.
+                    }
+                } else {
+                    Log.w(TAG, "Process/uid not found attempting kill of "
+                            + processName + " / " + uid);
+                }
+            }
+        } else {
+            throw new SecurityException(callerUid + " cannot kill app process: " +
+                    processName);
+        }
+    }
+
     private void restartPackageLocked(final String packageName, int uid) {
         uninstallPackageLocked(packageName, uid, false);
         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
@@ -9818,6 +9865,7 @@
         if (r.app != null) {
             info.pid = r.app.pid;
         }
+        info.uid = r.appInfo.uid;
         info.process = r.processName;
         info.foreground = r.isForeground;
         info.activeSince = r.createTime;
@@ -9825,6 +9873,18 @@
         info.clientCount = r.connections.size();
         info.crashCount = r.crashCount;
         info.lastActivityTime = r.lastActivity;
+        if (r.isForeground) {
+            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
+        }
+        if (r.startRequested) {
+            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
+        }
+        if (r.app != null && r.app.pid == Process.myPid()) {
+            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
+        }
+        if (r.app != null && r.app.persistent) {
+            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
+        }
         return info;
     }
     
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f3304a3..a690e3c 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -481,6 +481,13 @@
     public static final int SIM_STATE_READY = 5;
 
     /**
+     * @return true if a ICC card is present
+     */
+    public boolean hasIccCard() {
+        return PhoneFactory.getDefaultPhone().getIccCard().hasIccCard();
+    }
+
+    /**
      * Returns a constant indicating the state of the
      * device SIM card.
      *
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 6657060..200340e 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -667,6 +667,19 @@
         return false;
     }
 
+    /**
+     * @return true if a ICC card is present
+     */
+    public boolean hasIccCard() {
+        boolean isIccPresent;
+        if (mPhone.getPhoneName().equals("GSM")) {
+            return mIccCardStatus.getCardState().isCardPresent();
+        } else {
+            // TODO: Make work with a CDMA device with a RUIM card.
+            return false;
+        }
+    }
+
     private void log(String msg) {
         Log.d(mLogTag, "[IccCard] " + msg);
     }
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 7efaa2e..d26a092 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -150,7 +150,8 @@
     private static SmsMessage mSmsMessage;
     private static SmsMessageBase mSmsMessageBase;
     private SmsMessageBase.SubmitPduBase mSubmitPduBase;
-    private boolean mStorageAvailable = true;
+
+    protected boolean mStorageAvailable = true;
 
     protected static int getNextConcatenatedRef() {
         sConcatenatedRef += 1;
@@ -294,19 +295,15 @@
 
             sms = (SmsMessage) ar.result;
             try {
-                if (mStorageAvailable) {
-                    int result = dispatchMessage(sms.mWrappedSmsMessage);
-                    if (result != Activity.RESULT_OK) {
-                        // RESULT_OK means that message was broadcast for app(s) to handle.
-                        // Any other result, we should ack here.
-                        boolean handled = (result == Intents.RESULT_SMS_HANDLED);
-                        acknowledgeLastIncomingSms(handled, result, null);
-                    }
-                } else {
-                    acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null);
+                int result = dispatchMessage(sms.mWrappedSmsMessage);
+                if (result != Activity.RESULT_OK) {
+                    // RESULT_OK means that message was broadcast for app(s) to handle.
+                    // Any other result, we should ack here.
+                    boolean handled = (result == Intents.RESULT_SMS_HANDLED);
+                    notifyAndAcknowledgeLastIncomingSms(handled, result, null);
                 }
             } catch (RuntimeException ex) {
-                acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
+                notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null);
             }
 
             break;
@@ -866,6 +863,25 @@
             int result, Message response);
 
     /**
+     * Notify interested apps if the framework has rejected an incoming SMS,
+     * and send an acknowledge message to the network.
+     * @param success indicates that last message was successfully received.
+     * @param result result code indicating any error
+     * @param response callback message sent when operation completes.
+     */
+    private void notifyAndAcknowledgeLastIncomingSms(boolean success,
+            int result, Message response) {
+        if (!success) {
+            // broadcast SMS_REJECTED_ACTION intent
+            Intent intent = new Intent(Intents.SMS_REJECTED_ACTION);
+            intent.putExtra("result", result);
+            mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+            mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
+        }
+        acknowledgeLastIncomingSms(success, result, response);
+    }
+
+    /**
      * Check if a SmsTracker holds multi-part Sms
      *
      * @param tracker a SmsTracker could hold a multi-part Sms
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index e73039b..3f0213b 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -383,7 +383,7 @@
          * 2. [x@y][ ]/[body]
          */
          String[] parts = messageBody.split("( /)|( )", 2);
-         if (parts.length < 1 || parts[0].indexOf('@') == -1) return;
+         if (parts.length < 1) return;
          emailFrom = parts[0];
          emailBody = parts[1];
          isEmail = true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index ca15a03..1e3a2e1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -33,6 +33,7 @@
 import android.util.Config;
 import android.util.Log;
 import android.telephony.SmsManager;
+import android.telephony.SmsMessage.MessageClass;
 
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.CommandsInterface;
@@ -91,23 +92,8 @@
         int teleService = sms.getTeleService();
         boolean handled = false;
 
-        if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService) &&
-            (SmsEnvelope.TELESERVICE_VMN != teleService)) {
-            if (Config.LOGD) {
-                Log.d(TAG, "Received SMS without user data");
-            }
-            handled = true;
-        }
-
-        if (handled) {
-            return Intents.RESULT_SMS_HANDLED;
-        }
-
-        if (SmsEnvelope.TELESERVICE_WAP == teleService) {
-            return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
-                    sms.getOriginatingAddress());
-        } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
-                   (SmsEnvelope.TELESERVICE_MWI == teleService)) {
+        if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
+                (SmsEnvelope.TELESERVICE_MWI == teleService)) {
             // handling Voicemail
             int voicemailCount = sms.getNumOfVoicemails();
             Log.d(TAG, "Voicemail count=" + voicemailCount);
@@ -118,9 +104,30 @@
             editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
             editor.commit();
             ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
+            handled = true;
+        } else if ((sms.getUserData() == null)) {
+            if (Config.LOGD) {
+                Log.d(TAG, "Received SMS without user data");
+            }
+            handled = true;
+        }
+
+        if (handled) {
             return Intents.RESULT_SMS_HANDLED;
         }
 
+        if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+            // It's a storable message and there's no storage available.  Bail.
+            // (See C.S0015-B v2.0 for a description of "Immediate Display"
+            // messages, which we represent as CLASS_0.)
+            return Intents.RESULT_SMS_OUT_OF_MEMORY;
+        }
+
+        if (SmsEnvelope.TELESERVICE_WAP == teleService) {
+            return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
+                    sms.getOriginatingAddress());
+        }
+
         /**
          * TODO(cleanup): Why are we using a getter method for this
          * (and for so many other sms fields)?  Trivial getters and
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 4c958f6..dab529e 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -46,6 +46,7 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.DataConnectionTracker;
 import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.PhoneProxy;
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.TelephonyEventLog;
@@ -443,6 +444,8 @@
                     if (!mIsMinInfoReady) {
                         mIsMinInfoReady = true;
                     }
+                    phone.getIccCard().broadcastIccStateChangedIntent(IccCard.INTENT_VALUE_ICC_IMSI,
+                            null);
                 } else {
                     Log.w(LOG_TAG,"error parsing cdmaSubscription params num="
                             + cdmaSubscription.length);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index b412fec..0ca3148 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -37,6 +37,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
+import static android.telephony.SmsMessage.MessageClass;
 
 final class GsmSMSDispatcher extends SMSDispatcher {
     private static final String TAG = "GSM";
@@ -111,6 +112,12 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
+        if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+            // It's a storable message and there's no storage available.  Bail.
+            // (See TS 23.038 for a description of class 0 messages.)
+            return Intents.RESULT_SMS_OUT_OF_MEMORY;
+        }
+
         SmsHeader smsHeader = sms.getUserDataHeader();
          // See if message is partial or port addressed.
         if ((smsHeader == null) || (smsHeader.concatRef == null)) {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 2eecef8..e4c8716 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
@@ -16,6 +16,7 @@
 
 package com.android.dumprendertree;
 
+import com.android.dumprendertree.TestShellActivity.DumpDataType;
 import com.android.dumprendertree.forwarder.AdbUtils;
 import com.android.dumprendertree.forwarder.ForwardServer;
 
@@ -149,6 +150,8 @@
     static final String HTTP_WML_TESTS_PREFIX = "/sdcard/android/layout_tests/http/tests/wml/";
 
 
+    static final String DEFAULT_TEST_HOST = "android-browser-test.mtv.corp.google.com";
+    static final String FORWARD_HOST_CONF = "/sdcard/drt_forward_host.txt";
     private ForwardServer fs8000, fs8080, fs8443;
 
     private MyTestRecorder mResultRecorder;
@@ -160,12 +163,7 @@
     public LayoutTestsAutoTest() {
       super("com.android.dumprendertree", TestShellActivity.class);
 
-      int addr = -1;
-      try {
-          addr = AdbUtils.resolve("android-browser-test.mtv.corp.google.com");
-      } catch (IOException ioe) {
-          Log.e(LOGTAG, "failed to resolve server address.", ioe);
-      }
+      int addr = getForwardHostAddr();
       if(addr != -1) {
           fs8000 = new ForwardServer(8000, addr, 8000);
           fs8080 = new ForwardServer(8080, addr, 8080);
@@ -173,6 +171,38 @@
       }
     }
 
+    private int getForwardHostAddr() {
+        int addr = -1;
+        String host = null;
+        File forwardHostConf = new File(FORWARD_HOST_CONF);
+        if (forwardHostConf.isFile()) {
+            BufferedReader hostReader = null;
+            try {
+                hostReader = new BufferedReader(new FileReader(forwardHostConf));
+                host = hostReader.readLine();
+                Log.v(LOGTAG, "read forward host from file: " + host);
+            } catch (IOException ioe) {
+                Log.v(LOGTAG, "cannot read forward host from file", ioe);
+            } finally {
+                if (hostReader != null) {
+                    try {
+                        hostReader.close();
+                    } catch (IOException ioe) {
+                        // burn!!!
+                    }
+                }
+            }
+        }
+        if (host == null || host.length() == 0)
+            host = DEFAULT_TEST_HOST;
+        try {
+            addr = AdbUtils.resolve(host);
+        } catch (IOException ioe) {
+            Log.e(LOGTAG, "failed to resolve server address", ioe);
+        }
+        return addr;
+    }
+
     // This function writes the result of the layout test to
     // Am status so that it can be picked up from a script.
     private void passOrFailCallback(String file, boolean result) {
@@ -313,6 +343,7 @@
             }
 
             public void timedOut(String url) {
+                Log.v(LOGTAG, "layout timeout: " + url);
             }
         });
 
@@ -398,7 +429,8 @@
         if (resume)
             resumeTestList();
 
-        TestShellActivity activity = (TestShellActivity) getActivity();
+        TestShellActivity activity = getActivity();
+        activity.setDefaultDumpDataType(DumpDataType.DUMP_AS_TEXT);
 
         // Run tests.
         int addr = -1;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 95a2384..f9d2434 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -2364,13 +2364,12 @@
                         String8 region(config.string(), 2);
                         if (configSet.find(region) == configSet.end()) {
                             if (configSet.count(defaultLocale) == 0) {
-                                fprintf(stdout, "aapt: error: "
+                                fprintf(stdout, "aapt: warning: "
                                         "*** string '%s' has no default or required localization "
                                         "for '%s' in %s\n",
                                         String8(nameIter->first).string(),
                                         config.string(),
                                         mBundle->getResourceSourceDirs()[0]);
-                                err = UNKNOWN_ERROR;
                             }
                         }
                     }
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index 6daa0d2..d4d2a45c 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -219,7 +219,12 @@
             }
             spanStack.pop();
 
-            if (empty) {
+            /*
+             * This warning seems to be just an irritation to most people,
+             * since it is typically introduced by translators who then never
+             * see the warning.
+             */
+            if (0 && empty) {
                 fprintf(stderr, "%s:%d: warning: empty '%s' span found in text '%s'\n",
                         fileName, inXml->getLineNumber(),
                         String8(spanTag).string(), String8(*outString).string());