Merge change 9175

* changes:
  Fix 2016808. We used to send the new scale/scroll info to the UI thread after WebCore finish the first layout. As the picture in the UI thread is still the previous one, if there is a UI update happened before we generate the new picture, the new scale/scroll will be applied to the old picture.
diff --git a/api/current.xml b/api/current.xml
index b1e9c83..1f53be9 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -35725,39 +35725,6 @@
  visibility="public"
 >
 </field>
-<field name="ACTION_TTS_CHECK_TTS_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.intent.action.CHECK_TTS_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="ACTION_TTS_INSTALL_TTS_DATA"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.intent.action.INSTALL_TTS_DATA&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="ACTION_TTS_QUEUE_PROCESSING_COMPLETED"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACTION_UID_REMOVED"
  type="java.lang.String"
  transient="false"
@@ -84350,6 +84317,19 @@
  visibility="public"
 >
 </method>
+<method name="setReferenceCounted"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="refCounted" type="boolean">
+</parameter>
+</method>
 </class>
 <class name="WifiManager.WifiLock"
  extends="java.lang.Object"
@@ -116289,7 +116269,18 @@
 <parameter name="filename" type="java.lang.String">
 </parameter>
 </method>
-<field name="TTS_ERROR"
+<field name="ACTION_TTS_QUEUE_PROCESSING_COMPLETED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR"
  type="int"
  transient="false"
  volatile="false"
@@ -116300,7 +116291,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_LANG_AVAILABLE"
+<field name="LANG_AVAILABLE"
  type="int"
  transient="false"
  volatile="false"
@@ -116311,7 +116302,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_LANG_COUNTRY_AVAILABLE"
+<field name="LANG_COUNTRY_AVAILABLE"
  type="int"
  transient="false"
  volatile="false"
@@ -116322,7 +116313,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_LANG_COUNTRY_VAR_AVAILABLE"
+<field name="LANG_COUNTRY_VAR_AVAILABLE"
  type="int"
  transient="false"
  volatile="false"
@@ -116333,7 +116324,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_LANG_MISSING_DATA"
+<field name="LANG_MISSING_DATA"
  type="int"
  transient="false"
  volatile="false"
@@ -116344,7 +116335,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_LANG_NOT_SUPPORTED"
+<field name="LANG_NOT_SUPPORTED"
  type="int"
  transient="false"
  volatile="false"
@@ -116355,7 +116346,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_QUEUE_ADD"
+<field name="QUEUE_ADD"
  type="int"
  transient="false"
  volatile="false"
@@ -116366,7 +116357,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_QUEUE_FLUSH"
+<field name="QUEUE_FLUSH"
  type="int"
  transient="false"
  volatile="false"
@@ -116377,7 +116368,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_SUCCESS"
+<field name="SUCCESS"
  type="int"
  transient="false"
  volatile="false"
@@ -116405,6 +116396,28 @@
  visibility="public"
 >
 </constructor>
+<field name="ACTION_CHECK_TTS_DATA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.speech.tts.engine.CHECK_TTS_DATA&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_INSTALL_TTS_DATA"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.speech.tts.engine.INSTALL_TTS_DATA&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="CHECK_VOICE_DATA_BAD_DATA"
  type="int"
  transient="false"
@@ -116460,7 +116473,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_DEFAULT_STREAM"
+<field name="DEFAULT_STREAM"
  type="int"
  transient="false"
  volatile="false"
@@ -116471,29 +116484,7 @@
  visibility="public"
 >
 </field>
-<field name="TTS_KEY_PARAM_STREAM"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;streamType&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="TTS_KEY_PARAM_UTTERANCE_ID"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;utteranceId&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="VOICE_DATA_FILES"
+<field name="EXTRA_VOICE_DATA_FILES"
  type="java.lang.String"
  transient="false"
  volatile="false"
@@ -116504,7 +116495,7 @@
  visibility="public"
 >
 </field>
-<field name="VOICE_DATA_FILES_INFO"
+<field name="EXTRA_VOICE_DATA_FILES_INFO"
  type="java.lang.String"
  transient="false"
  volatile="false"
@@ -116515,7 +116506,7 @@
  visibility="public"
 >
 </field>
-<field name="VOICE_DATA_ROOT_DIRECTORY"
+<field name="EXTRA_VOICE_DATA_ROOT_DIRECTORY"
  type="java.lang.String"
  transient="false"
  volatile="false"
@@ -116526,6 +116517,28 @@
  visibility="public"
 >
 </field>
+<field name="KEY_PARAM_STREAM"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;streamType&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_PARAM_UTTERANCE_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;utteranceId&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <interface name="TextToSpeech.OnInitListener"
  abstract="true"
@@ -135031,9 +135044,33 @@
  type="android.text.style.ImageSpan"
  static="false"
  final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="b" type="android.graphics.Bitmap">
+</parameter>
+</constructor>
+<constructor name="ImageSpan"
+ type="android.text.style.ImageSpan"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="b" type="android.graphics.Bitmap">
+</parameter>
+<parameter name="verticalAlignment" type="int">
+</parameter>
+</constructor>
+<constructor name="ImageSpan"
+ type="android.text.style.ImageSpan"
+ static="false"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="context" type="android.content.Context">
+</parameter>
 <parameter name="b" type="android.graphics.Bitmap">
 </parameter>
 </constructor>
@@ -135044,6 +135081,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="context" type="android.content.Context">
+</parameter>
 <parameter name="b" type="android.graphics.Bitmap">
 </parameter>
 <parameter name="verticalAlignment" type="int">
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index fcfbd17..4dd2433 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -270,6 +270,16 @@
         if (!mGlobalSearchMode) {
             mStoredComponentName = mLaunchComponent;
             mStoredAppSearchData = mAppSearchData;
+            
+            // If this is the browser, we have a special case to not show the icon to the left
+            // of the text field, for extra space for url entry (this should be reconciled in
+            // Eclair). So special case a second tap of the search button to remove any
+            // already-entered text so that we can be sure to show the "Quick Search Box" hint
+            // text to still make it clear to the user that we've jumped out to global search.
+            //
+            // TODO: When the browser icon issue is reconciled in Eclair, remove this special case.
+            if (isBrowserSearch()) currentSearchText = "";
+            
             return doShow(currentSearchText, false, null, mAppSearchData, true);
         } else {
             if (mStoredComponentName != null) {
@@ -577,7 +587,11 @@
     }
     
     private void updateSearchAppIcon() {
-        if (mGlobalSearchMode) {
+        // In Donut, we special-case the case of the browser to hide the app icon as if it were
+        // global search, for extra space for url entry.
+        //
+        // TODO: Remove this special case once the issue has been reconciled in Eclair. 
+        if (mGlobalSearchMode || isBrowserSearch()) {
             mAppIcon.setImageResource(0);
             mAppIcon.setVisibility(View.GONE);
             mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL,
@@ -668,6 +682,16 @@
         }
         mVoiceButton.setVisibility(visibility);
     }
+    
+    /**
+     * Hack to determine whether this is the browser, so we can remove the browser icon
+     * to the left of the search field, as a special requirement for Donut.
+     * 
+     * TODO: For Eclair, reconcile this with the rest of the global search UI.
+     */
+    private boolean isBrowserSearch() {
+        return mLaunchComponent.flattenToShortString().startsWith("com.android.browser/");
+    }
 
     /*
      * Menu.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 64ee60e..f9b082f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1409,6 +1409,17 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
     /**
+     * Activity Action:  Start this activity to request system shutdown.
+     * The optional boolean extra field {@link #EXTRA_KEY_CONFIRM} can be set to true
+     * to request confirmation from the user before shutting down.
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * {@hide}
+     */
+    public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";
+    /**
      * Broadcast Action:  Indicates low memory condition on the device
      * 
      * <p class="note">This is a protected intent that can only be sent
@@ -1684,53 +1695,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_REBOOT =
             "android.intent.action.REBOOT";
-    /**
-     * Broadcast Action: Triggers the platform Text-To-Speech engine to
-     * start the activity that installs the resource files on the device
-     * that are required for TTS to be operational. Since the installation
-     * of the data can be interrupted or declined by the user, the application
-     * shouldn't expect successful installation upon return from that intent,
-     * and if need be, should check installation status with 
-     * {@link #ACTION_TTS_CHECK_TTS_DATA}.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TTS_INSTALL_TTS_DATA =
-            "android.intent.action.INSTALL_TTS_DATA";
 
-    /**
-     * Broadcast Action: Starts the activity from the platform Text-To-Speech
-     * engine to verify the proper installation and availability of the
-     * resource files on the system. Upon completion, the activity will
-     * return one of the following codes: 
-     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_PASS},
-     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_FAIL},
-     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_BAD_DATA},
-     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_DATA}, or
-     * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_VOLUME}.
-     * <p> Moreover, the data received in the activity result will contain the following
-     * fields:
-     * <ul>
-     *   <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_ROOT_DIRECTORY} which
-     *       indicates the path to the location of the resource files</li>,
-     *   <li>{@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES} which contains
-     *       the list of all the resource files</li>,
-     *   <li>and {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES_INFO} which
-     *       contains, for each resource file, the description of the language covered by
-     *       the file in the xxx-YYY format, where xxx is the 3-letter ISO language code,
-     *       and YYY is the 3-letter ISO country code.</li>
-     * </ul>
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TTS_CHECK_TTS_DATA =
-            "android.intent.action.CHECK_TTS_DATA";
-
-    /**
-     * Broadcast Action: The TextToSpeech synthesizer has completed processing 
-     * all of the text in the speech queue.
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED =
-            "android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED";
 
     /**
      * Broadcast Action: a remote intent is to be broadcasted.
@@ -1939,6 +1904,14 @@
     public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
 
     /**
+     * Set to true in {@link #ACTION_REQUEST_SHUTDOWN} to request confirmation from the user
+     * before shutting down.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_KEY_CONFIRM = "android.intent.extra.KEY_CONFIRM";
+
+    /**
      * Used as an boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
      * {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
      * of restarting the application.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 0c2b65e..1db17c8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -879,6 +879,17 @@
         public static final String AIRPLANE_MODE_RADIOS = "airplane_mode_radios";
 
         /**
+         * A comma separated list of radios that should to be disabled when airplane mode
+         * is on, but can be manually reenabled by the user.  For example, if RADIO_WIFI is
+         * added to both AIRPLANE_MODE_RADIOS and AIRPLANE_MODE_TOGGLEABLE_RADIOS, then Wifi
+         * will be turned off when entering airplane mode, but the user will be able to reenable
+         * Wifi in the Settings app.
+         *
+         * {@hide}
+         */
+        public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
+
+        /**
          * The policy for deciding when Wi-Fi should go to sleep (which will in
          * turn switch to using the mobile data as an Internet connection).
          * <p>
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 8f8d976..b033c6a 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -18,6 +18,8 @@
 import android.speech.tts.ITts;
 import android.speech.tts.ITtsCallback;
 
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -41,51 +43,60 @@
     /**
      * Denotes a successful operation.
      */
-    public static final int TTS_SUCCESS                = 0;
+    public static final int SUCCESS                = 0;
     /**
      * Denotes a generic operation failure.
      */
-    public static final int TTS_ERROR                  = -1;
+    public static final int ERROR                  = -1;
 
     /**
      * Queue mode where all entries in the playback queue (media to be played
      * and text to be synthesized) are dropped and replaced by the new entry.
      */
-    public static final int TTS_QUEUE_FLUSH = 0;
+    public static final int QUEUE_FLUSH = 0;
     /**
      * Queue mode where the new entry is added at the end of the playback queue.
      */
-    public static final int TTS_QUEUE_ADD = 1;
+    public static final int QUEUE_ADD = 1;
 
 
     /**
      * Denotes the language is available exactly as specified by the locale
      */
-    public static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = 2;
+    public static final int LANG_COUNTRY_VAR_AVAILABLE = 2;
 
 
     /**
      * Denotes the language is available for the language and country specified 
      * by the locale, but not the variant.
      */
-    public static final int TTS_LANG_COUNTRY_AVAILABLE = 1;
+    public static final int LANG_COUNTRY_AVAILABLE = 1;
 
 
     /**
      * Denotes the language is available for the language by the locale, 
      * but not the country and variant.
      */
-    public static final int TTS_LANG_AVAILABLE = 0;
+    public static final int LANG_AVAILABLE = 0;
 
     /**
      * Denotes the language data is missing.
      */
-    public static final int TTS_LANG_MISSING_DATA = -1;
+    public static final int LANG_MISSING_DATA = -1;
 
     /**
      * Denotes the language is not supported by the current TTS engine.
      */
-    public static final int TTS_LANG_NOT_SUPPORTED = -2;
+    public static final int LANG_NOT_SUPPORTED = -2;
+
+
+    /**
+     * Broadcast Action: The TextToSpeech synthesizer has completed processing
+     * of all the text in the speech queue.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED =
+            "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
 
 
     /**
@@ -119,126 +130,167 @@
         /**
          * {@hide}
          */
-        public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
+        public static final int DEFAULT_RATE = 100; // 1x
         /**
          * {@hide}
          */
-        public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
+        public static final int DEFAULT_PITCH = 100;// 1x
         /**
          * {@hide}
          */
-        public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
+        public static final int USE_DEFAULTS = 0; // false
         /**
          * {@hide}
          */
-        public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico";
+        public static final String DEFAULT_SYNTH = "com.svox.pico";
 
         // default values for rendering
-        public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
+        public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
 
         // return codes for a TTS engine's check data activity
         /**
          * Indicates success when checking the installation status of the resources used by the
-         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
          */
         public static final int CHECK_VOICE_DATA_PASS = 1;
         /**
          * Indicates failure when checking the installation status of the resources used by the
-         * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
          */
         public static final int CHECK_VOICE_DATA_FAIL = 0;
         /**
          * Indicates erroneous data when checking the installation status of the resources used by
-         * the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         * the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
          */
         public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
         /**
          * Indicates missing resources when checking the installation status of the resources used
-         * by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         * by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
          */
         public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
         /**
          * Indicates missing storage volume when checking the installation status of the resources
-         * used by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+         * used by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
          */
         public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
 
-        // return codes for a TTS engine's check data activity
+        // intents to ask engine to install data or check its data
         /**
-         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * Broadcast Action: Triggers the platform Text-To-Speech engine to
+         * start the activity that installs the resource files on the device
+         * that are required for TTS to be operational. Since the installation
+         * of the data can be interrupted or declined by the user, the application
+         * shouldn't expect successful installation upon return from that intent,
+         * and if need be, should check installation status with
+         * {@link #ACTION_CHECK_TTS_DATA}.
+         */
+        @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+        public static final String ACTION_INSTALL_TTS_DATA =
+                "android.speech.tts.engine.INSTALL_TTS_DATA";
+
+        /**
+         * Broadcast Action: Starts the activity from the platform Text-To-Speech
+         * engine to verify the proper installation and availability of the
+         * resource files on the system. Upon completion, the activity will
+         * return one of the following codes:
+         * {@link #CHECK_VOICE_DATA_PASS},
+         * {@link #CHECK_VOICE_DATA_FAIL},
+         * {@link #CHECK_VOICE_DATA_BAD_DATA},
+         * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or
+         * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}.
+         * <p> Moreover, the data received in the activity result will contain the following
+         * fields:
+         * <ul>
+         *   <li>{@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which
+         *       indicates the path to the location of the resource files</li>,
+         *   <li>{@link #EXTRA_VOICE_DATA_FILES} which contains
+         *       the list of all the resource files</li>,
+         *   <li>and {@link #EXTRA_VOICE_DATA_FILES_INFO} which
+         *       contains, for each resource file, the description of the language covered by
+         *       the file in the xxx-YYY format, where xxx is the 3-letter ISO language code,
+         *       and YYY is the 3-letter ISO country code.</li>
+         * </ul>
+         */
+        @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+        public static final String ACTION_CHECK_TTS_DATA =
+                "android.speech.tts.engine.CHECK_TTS_DATA";
+
+        // extras for a TTS engine's check data activity
+        /**
+         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
          * the text-to-speech engine specifies the path to its resources.
          */
-        public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
+        public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
         /**
-         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
          * the text-to-speech engine specifies the file names of its resources under the
          * resource path.
          */
-        public static final String VOICE_DATA_FILES = "dataFiles";
+        public static final String EXTRA_VOICE_DATA_FILES = "dataFiles";
         /**
-         * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
          * the text-to-speech engine specifies the locale associated with each resource file.
          */
-        public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo";
+        public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
 
         // keys for the parameters passed with speak commands. Hidden keys are used internally
         // to maintain engine state for each TextToSpeech instance.
         /**
          * {@hide}
          */
-        public static final String TTS_KEY_PARAM_RATE = "rate";
+        public static final String KEY_PARAM_RATE = "rate";
         /**
          * {@hide}
          */
-        public static final String TTS_KEY_PARAM_LANGUAGE = "language";
+        public static final String KEY_PARAM_LANGUAGE = "language";
         /**
          * {@hide}
          */
-        public static final String TTS_KEY_PARAM_COUNTRY = "country";
+        public static final String KEY_PARAM_COUNTRY = "country";
         /**
          * {@hide}
          */
-        public static final String TTS_KEY_PARAM_VARIANT = "variant";
+        public static final String KEY_PARAM_VARIANT = "variant";
         /**
          * Parameter key to specify the audio stream type to be used when speaking text
          * or playing back a file.
          */
-        public static final String TTS_KEY_PARAM_STREAM = "streamType";
+        public static final String KEY_PARAM_STREAM = "streamType";
         /**
          * Parameter key to identify an utterance in the completion listener after text has been
          * spoken, a file has been played back or a silence duration has elapsed.
          */
-        public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId";
+        public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
 
         // key positions in the array of cached parameters
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_RATE = 0;
+        protected static final int PARAM_POSITION_RATE = 0;
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_LANGUAGE = 2;
+        protected static final int PARAM_POSITION_LANGUAGE = 2;
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_COUNTRY = 4;
+        protected static final int PARAM_POSITION_COUNTRY = 4;
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_VARIANT = 6;
+        protected static final int PARAM_POSITION_VARIANT = 6;
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_STREAM = 8;
+        protected static final int PARAM_POSITION_STREAM = 8;
         /**
          * {@hide}
          */
-        protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10;
+        protected static final int PARAM_POSITION_UTTERANCE_ID = 10;
         /**
          * {@hide}
          */
-        protected static final int TTS_NB_CACHED_PARAMS = 6;
+        protected static final int NB_CACHED_PARAMS = 6;
     }
 
     /**
@@ -273,25 +325,25 @@
         mPackageName = mContext.getPackageName();
         mInitListener = listener;
 
-        mCachedParams = new String[2*Engine.TTS_NB_CACHED_PARAMS]; // store key and value
-        mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE;
-        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE;
-        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY;
-        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT;
-        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM;
-        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = Engine.TTS_KEY_PARAM_UTTERANCE_ID;
+        mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value
+        mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE;
+        mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE;
+        mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY;
+        mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT;
+        mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM;
+        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID;
 
-        mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] =
-                String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE);
+        mCachedParams[Engine.PARAM_POSITION_RATE + 1] =
+                String.valueOf(Engine.DEFAULT_RATE);
         // initialize the language cached parameters with the current Locale
         Locale defaultLoc = Locale.getDefault();
-        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
-        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
-        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
+        mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
+        mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
+        mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
 
-        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
-                String.valueOf(Engine.TTS_DEFAULT_STREAM);
-        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = "";
+        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
+                String.valueOf(Engine.DEFAULT_STREAM);
+        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
 
         initTts();
     }
@@ -308,7 +360,7 @@
                     mStarted = true;
                     if (mInitListener != null) {
                         // TODO manage failures and missing resources
-                        mInitListener.onInit(TTS_SUCCESS);
+                        mInitListener.onInit(SUCCESS);
                     }
                 }
             }
@@ -349,8 +401,7 @@
     /**
      * Adds a mapping between a string of text and a sound resource in a
      * package.
-     *
-     * @see #TTS.speak(String text, int queueMode, String[] params)
+     * @see #speak(String, int, HashMap)
      *
      * @param text
      *            Example: <b><code>"south_south_east"</code></b><br/>
@@ -371,16 +422,16 @@
      * @param resourceId
      *            Example: <b><code>R.raw.south_south_east</code></b>
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int addSpeech(String text, String packagename, int resourceId) {
         synchronized(mStartLock) {
             if (!mStarted) {
-                return TTS_ERROR;
+                return ERROR;
             }
             try {
                 mITts.addSpeech(mPackageName, text, packagename, resourceId);
-                return TTS_SUCCESS;
+                return SUCCESS;
             } catch (RemoteException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - addSpeech", "RemoteException");
@@ -400,7 +451,7 @@
                 mStarted = false;
                 initTts();
             }
-            return TTS_ERROR;
+            return ERROR;
         }
     }
 
@@ -415,16 +466,16 @@
      *            The full path to the sound file (for example:
      *            "/sdcard/mysounds/hello.wav")
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int addSpeech(String text, String filename) {
         synchronized (mStartLock) {
             if (!mStarted) {
-                return TTS_ERROR;
+                return ERROR;
             }
             try {
                 mITts.addSpeechFile(mPackageName, text, filename);
-                return TTS_SUCCESS;
+                return SUCCESS;
             } catch (RemoteException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - addSpeech", "RemoteException");
@@ -444,7 +495,7 @@
                 mStarted = false;
                 initTts();
             }
-            return TTS_ERROR;
+            return ERROR;
         }
     }
 
@@ -453,7 +504,7 @@
      * Adds a mapping between a string of text and a sound resource in a
      * package.
      *
-     * @see #TTS.playEarcon(String earcon, int queueMode, String[] params)
+     * @see #playEarcon(String, int, HashMap)
      *
      * @param earcon The name of the earcon
      *            Example: <b><code>"[tick]"</code></b><br/>
@@ -474,16 +525,16 @@
      * @param resourceId
      *            Example: <b><code>R.raw.tick_snd</code></b>
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int addEarcon(String earcon, String packagename, int resourceId) {
         synchronized(mStartLock) {
             if (!mStarted) {
-                return TTS_ERROR;
+                return ERROR;
             }
             try {
                 mITts.addEarcon(mPackageName, earcon, packagename, resourceId);
-                return TTS_SUCCESS;
+                return SUCCESS;
             } catch (RemoteException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - addEarcon", "RemoteException");
@@ -503,7 +554,7 @@
                 mStarted = false;
                 initTts();
             }
-            return TTS_ERROR;
+            return ERROR;
         }
     }
 
@@ -518,16 +569,16 @@
      *            The full path to the sound file (for example:
      *            "/sdcard/mysounds/tick.wav")
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int addEarcon(String earcon, String filename) {
         synchronized (mStartLock) {
             if (!mStarted) {
-                return TTS_ERROR;
+                return ERROR;
             }
             try {
                 mITts.addEarconFile(mPackageName, earcon, filename);
-                return TTS_SUCCESS;
+                return SUCCESS;
             } catch (RemoteException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - addEarcon", "RemoteException");
@@ -547,7 +598,7 @@
                 mStarted = false;
                 initTts();
             }
-            return TTS_ERROR;
+            return ERROR;
         }
     }
 
@@ -563,29 +614,29 @@
      *            The string of text to be spoken.
      * @param queueMode
      *            The queuing strategy to use.
-     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+     *            See QUEUE_ADD and QUEUE_FLUSH.
      * @param params
      *            The hashmap of speech parameters to be used.
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int speak(String text, int queueMode, HashMap<String,String> params)
     {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             Log.i("TTS received: ", text);
             if (!mStarted) {
                 return result;
             }
             try {
                 if ((params != null) && (!params.isEmpty())) {
-                    String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
+                    String extra = params.get(Engine.KEY_PARAM_STREAM);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
                     }
-                    extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+                    extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
                     }
                 }
                 result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
@@ -621,28 +672,28 @@
      * @param earcon
      *            The earcon that should be played
      * @param queueMode
-     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+     *            See QUEUE_ADD and QUEUE_FLUSH.
      * @param params
      *            The hashmap of parameters to be used.
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int playEarcon(String earcon, int queueMode,
             HashMap<String,String> params) {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
             try {
                 if ((params != null) && (!params.isEmpty())) {
-                    String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
+                    String extra = params.get(Engine.KEY_PARAM_STREAM);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
                     }
-                    extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+                    extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
                     }
                 }
                 result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
@@ -678,21 +729,21 @@
      * @param durationInMs
      *            A long that indicates how long the silence should last.
      * @param queueMode
-     *            See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+     *            See QUEUE_ADD and QUEUE_FLUSH.
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int playSilence(long durationInMs, int queueMode, HashMap<String,String> params) {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
             try {
                 if ((params != null) && (!params.isEmpty())) {
-                    String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+                    String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
                     }
                 }
                 result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
@@ -760,11 +811,11 @@
     /**
      * Stops speech from the TTS.
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int stop() {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
@@ -808,24 +859,24 @@
      *            lower values slow down the speech (0.5 is half the normal speech rate),
      *            greater values accelerate it (2 is twice the normal speech rate).
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int setSpeechRate(float speechRate) {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
             try {
                 if (speechRate > 0) {
                     int rate = (int)(speechRate*100);
-                    mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate);
+                    mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate);
                     // the rate is not set here, instead it is cached so it will be associated
                     // with all upcoming utterances.
                     if (speechRate > 0.0f) {
-                        result = TTS_SUCCESS;
+                        result = SUCCESS;
                     } else {
-                        result = TTS_ERROR;
+                        result = ERROR;
                     }
                 }
             } catch (NullPointerException e) {
@@ -860,11 +911,11 @@
      *            lower values lower the tone of the synthesized voice,
      *            greater values increase it.
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int setPitch(float pitch) {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
@@ -907,27 +958,27 @@
      * @param loc
      *            The locale describing the language to be used.
      *
-     * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
-     *         {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
-     *         {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
+     * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
+     *         {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
+     *         {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
      */
     public int setLanguage(Locale loc) {
         synchronized (mStartLock) {
-            int result = TTS_LANG_NOT_SUPPORTED;
+            int result = LANG_NOT_SUPPORTED;
             if (!mStarted) {
                 return result;
             }
             try {
-                mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
-                mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
-                mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant();
+                mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
+                mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
+                mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant();
                 // the language is not set here, instead it is cached so it will be associated
                 // with all upcoming utterances. But we still need to report the language support,
                 // which is achieved by calling isLanguageAvailable()
                 result = mITts.isLanguageAvailable(
-                        mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
-                        mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
-                        mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] );
+                        mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
+                        mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
+                        mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] );
             } catch (RemoteException e) {
                 // TTS died; restart it.
                 Log.e("TextToSpeech.java - setLanguage", "RemoteException");
@@ -999,13 +1050,13 @@
      * @param loc
      *            The Locale describing the language to be used.
      *
-     * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
-     *         {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
-     *         {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
+     * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
+     *         {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
+     *         {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
      */
     public int isLanguageAvailable(Locale loc) {
         synchronized (mStartLock) {
-            int result = TTS_LANG_NOT_SUPPORTED;
+            int result = LANG_NOT_SUPPORTED;
             if (!mStarted) {
                 return result;
             }
@@ -1048,25 +1099,25 @@
      *            The string that gives the full output filename; it should be
      *            something like "/sdcard/myappsounds/mysound.wav".
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int synthesizeToFile(String text, HashMap<String,String> params,
             String filename) {
         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
             try {
                 if ((params != null) && (!params.isEmpty())) {
                     // no need to read the stream type here
-                    String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+                    String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
                     if (extra != null) {
-                        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+                        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
                     }
                 }
                 if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){
-                    result = TTS_SUCCESS;
+                    result = SUCCESS;
                 }
             } catch (RemoteException e) {
                 // TTS died; restart it.
@@ -1099,9 +1150,9 @@
      * if they are not persistent between calls to the service.
      */
     private void resetCachedParams() {
-        mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
-                String.valueOf(Engine.TTS_DEFAULT_STREAM);
-        mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = "";
+        mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
+                String.valueOf(Engine.DEFAULT_STREAM);
+        mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID+ 1] = "";
     }
 
     /**
@@ -1110,12 +1161,12 @@
      * @param listener
      *            The OnUtteranceCompletedListener
      *
-     * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+     * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      */
     public int setOnUtteranceCompletedListener(

             final OnUtteranceCompletedListener listener) {

         synchronized (mStartLock) {
-            int result = TTS_ERROR;
+            int result = ERROR;
             if (!mStarted) {
                 return result;
             }
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 911a23c..86ef5f6 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -33,17 +33,34 @@
     private Context mContext;
     private String mSource;
 
+    /**
+     * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
+     */
     public ImageSpan(Bitmap b) {
-        this(b, ALIGN_BOTTOM);
+        this(null, b, ALIGN_BOTTOM);
+    }
+
+    /**
+     * @deprecated Use {@link #ImageSpan(Context, Bitmap, int) instead.
+     */
+    public ImageSpan(Bitmap b, int verticalAlignment) {
+        this(null, b, verticalAlignment);
+    }
+
+    public ImageSpan(Context context, Bitmap b) {
+        this(context, b, ALIGN_BOTTOM);
     }
 
     /**
      * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
      * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
      */
-    public ImageSpan(Bitmap b, int verticalAlignment) {
+    public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
         super(verticalAlignment);
-        mDrawable = new BitmapDrawable(mContext.getResources(), b);
+        mContext = context;
+        mDrawable = context != null
+                ? new BitmapDrawable(context.getResources(), b)
+                : new BitmapDrawable(b);
         int width = mDrawable.getIntrinsicWidth();
         int height = mDrawable.getIntrinsicHeight();
         mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0); 
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index a26bfa2..47f5c6c 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -277,7 +277,7 @@
         if (child.getLayoutParams() == null) {
             final LinearLayout.LayoutParams lp = new LayoutParams(
                     0,
-                    ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+                    ViewGroup.LayoutParams.FILL_PARENT, 1.0f);
             lp.setMargins(0, 0, 0, 0);
             child.setLayoutParams(lp);
         }
@@ -289,10 +289,10 @@
         // If we have dividers between the tabs and we already have at least one
         // tab, then add a divider before adding the next tab.
         if (mDividerDrawable != null && getTabCount() > 0) {
-            View divider = new View(mContext);
+            ImageView divider = new ImageView(mContext);
             final LinearLayout.LayoutParams lp = new LayoutParams(
                     mDividerDrawable.getIntrinsicWidth(),
-                    mDividerDrawable.getIntrinsicHeight());
+                    LayoutParams.FILL_PARENT);
             lp.setMargins(0, 0, 0, 0);
             divider.setLayoutParams(lp);
             divider.setBackgroundDrawable(mDividerDrawable);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1cd04f1..5f94ee5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1130,6 +1130,16 @@
                 android:exported="true">
         </activity>
 
+        <activity android:name="com.android.server.ShutdownActivity"
+            android:permission="android.permission.SHUTDOWN"
+            android:excludeFromRecents="true"
+            android:multiprocess="true">
+            <intent-filter>
+                <action android:name="android.intent.action.ACTION_REQUEST_SHUTDOWN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <service android:name="com.android.server.LoadAverageService"
             android:exported="true" />
 
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index ad27903..13316a9 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -93,10 +93,6 @@
     VIDEO_ENCODER_LIST_END // must be the last - used to validate the video encoder type
 };
 
-
-// Maximum frames per second is 24
-#define MEDIA_RECORDER_MAX_FRAME_RATE         24
-
 /*
  * The state machine of the media_recorder uses a set of different state names.
  * The mapping between the media_recorder and the pvauthorengine is shown below:
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 0273a5a..304f521 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -276,7 +276,7 @@
 android_media_MediaRecorder_setVideoFrameRate(JNIEnv *env, jobject thiz, jint rate)
 {
     LOGV("setVideoFrameRate(%d)", rate);
-    if (rate <= 0 || rate > MEDIA_RECORDER_MAX_FRAME_RATE) {
+    if (rate <= 0) {
         jniThrowException(env, "java/lang/IllegalArgumentException", "invalid frame rate");
         return;
     }
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index c33bdd7..6b20445 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -22,6 +22,7 @@
     <bool name="def_airplane_mode_on">false</bool>
     <!-- Comma-separated list of bluetooth, wifi, and cell. -->
     <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
+    <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
     <bool name="def_auto_time">true</bool>
     <bool name="def_accelerometer_rotation">true</bool>
     <!-- Default screen brightness, from 0 to 255.  102 is 40%. -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index f00fd39..835c683 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -64,7 +64,7 @@
 
     private static final String TAG = "SettingsProvider";
     private static final String DATABASE_NAME = "settings.db";
-    private static final int DATABASE_VERSION = 37;
+    private static final int DATABASE_VERSION = 38;
 
     private Context mContext;
 
@@ -435,6 +435,21 @@
             upgradeVersion = 36;
         }
 
+        if (upgradeVersion == 37) {
+            db.beginTransaction();
+            try {
+                SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
+                        R.string.airplane_mode_toggleable_radios);
+                stmt.close();
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+            upgradeVersion = 38;
+        }
+
         if (upgradeVersion != currentVersion) {
             Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
                     + ", must wipe the settings provider");
@@ -662,6 +677,9 @@
         loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
                 R.string.def_airplane_mode_radios);
 
+        loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
+                R.string.airplane_mode_toggleable_radios);
+
         loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
                 R.bool.def_auto_time); // Sync time to NITZ
 
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 6832862..1b99d32 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -194,7 +194,7 @@
     private boolean isDefaultEnforced() {
         return (android.provider.Settings.Secure.getInt(mResolver,
                     android.provider.Settings.Secure.TTS_USE_DEFAULTS,
-                    TextToSpeech.Engine.FALLBACK_TTS_USE_DEFAULTS)
+                    TextToSpeech.Engine.USE_DEFAULTS)
                 == 1 );
     }
 
@@ -202,7 +202,7 @@
     private int getDefaultRate() {
         return android.provider.Settings.Secure.getInt(mResolver,
                 android.provider.Settings.Secure.TTS_DEFAULT_RATE,
-                TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_RATE);
+                TextToSpeech.Engine.DEFAULT_RATE);
     }
 
 
@@ -346,7 +346,7 @@
      */
     private int speak(String callingApp, String text, int queueMode, ArrayList<String> params) {
         Log.v("TtsService", "TTS service received " + text);
-        if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
+        if (queueMode == TextToSpeech.QUEUE_FLUSH) {
             stop(callingApp);
         } else if (queueMode == 2) {
             stopAll(callingApp);
@@ -355,7 +355,7 @@
         if (!mIsSpeaking) {
             processSpeechQueue();
         }
-        return TextToSpeech.TTS_SUCCESS;
+        return TextToSpeech.SUCCESS;
     }
 
     /**
@@ -372,7 +372,7 @@
      */
     private int playEarcon(String callingApp, String earcon, int queueMode,
             ArrayList<String> params) {
-        if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
+        if (queueMode == TextToSpeech.QUEUE_FLUSH) {
             stop(callingApp);
         } else if (queueMode == 2) {
             stopAll(callingApp);
@@ -381,14 +381,14 @@
         if (!mIsSpeaking) {
             processSpeechQueue();
         }
-        return TextToSpeech.TTS_SUCCESS;
+        return TextToSpeech.SUCCESS;
     }
 
     /**
      * Stops all speech output and removes any utterances still in the queue for the calling app.
      */
     private int stop(String callingApp) {
-        int result = TextToSpeech.TTS_ERROR;
+        int result = TextToSpeech.ERROR;
         boolean speechQueueAvailable = false;
         try{
             speechQueueAvailable =
@@ -414,7 +414,7 @@
                     mIsSpeaking = false;
                     mCurrentSpeechItem = null;
                 } else {
-                    result = TextToSpeech.TTS_SUCCESS;
+                    result = TextToSpeech.SUCCESS;
                 }
                 Log.i("TtsService", "Stopped");
             }
@@ -437,7 +437,7 @@
      * Stops all speech output and removes any utterances still in the queue globally.
      */
     private int stopAll(String callingApp) {
-        int result = TextToSpeech.TTS_ERROR;
+        int result = TextToSpeech.ERROR;
         boolean speechQueueAvailable = false;
         try{
             speechQueueAvailable =
@@ -463,7 +463,7 @@
                     mIsSpeaking = false;
                     mCurrentSpeechItem = null;
                 } else {
-                    result = TextToSpeech.TTS_SUCCESS;
+                    result = TextToSpeech.SUCCESS;
                 }
                 Log.i("TtsService", "Stopped all");
             }
@@ -487,7 +487,7 @@
         if (params != null){
             for (int i = 0; i < params.size() - 1; i = i + 2){
             String param = params.get(i);
-                if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
+                if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){
                     utteranceId = params.get(i+1);
                 }
             }
@@ -500,14 +500,14 @@
 
     private int playSilence(String callingApp, long duration, int queueMode,
             ArrayList<String> params) {
-        if (queueMode == TextToSpeech.TTS_QUEUE_FLUSH) {
+        if (queueMode == TextToSpeech.QUEUE_FLUSH) {
             stop(callingApp);
         }
         mSpeechQueue.add(new SpeechItem(callingApp, duration, params));
         if (!mIsSpeaking) {
             processSpeechQueue();
         }
-        return TextToSpeech.TTS_SUCCESS;
+        return TextToSpeech.SUCCESS;
     }
 
     private void silence(final SpeechItem speechItem) {
@@ -517,7 +517,7 @@
                 if (speechItem.mParams != null){
                     for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
                         String param = speechItem.mParams.get(i);
-                        if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
+                        if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){
                             utteranceId = speechItem.mParams.get(i+1);
                         }
                     }
@@ -562,17 +562,17 @@
                         for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
                             String param = speechItem.mParams.get(i);
                             if (param != null) {
-                                if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) {
+                                if (param.equals(TextToSpeech.Engine.KEY_PARAM_RATE)) {
                                     speechRate = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_LANGUAGE)){
                                     language = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_COUNTRY)){
                                     country = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_VARIANT)){
                                     variant = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){
                                     utteranceId = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM)) {
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_STREAM)) {
                                     try {
                                         streamType
                                                 = Integer.parseInt(speechItem.mParams.get(i + 1));
@@ -638,15 +638,15 @@
                         for (int i = 0; i < speechItem.mParams.size() - 1; i = i + 2){
                             String param = speechItem.mParams.get(i);
                             if (param != null) {
-                                if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_RATE)) {
+                                if (param.equals(TextToSpeech.Engine.KEY_PARAM_RATE)) {
                                     speechRate = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_LANGUAGE)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_LANGUAGE)){
                                     language = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_COUNTRY)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_COUNTRY)){
                                     country = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_VARIANT)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_VARIANT)){
                                     variant = speechItem.mParams.get(i+1);
-                                } else if (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_UTTERANCE_ID)){
+                                } else if (param.equals(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID)){
                                     utteranceId = speechItem.mParams.get(i+1);
                                 }
                             }
@@ -698,7 +698,7 @@
     }
 
     private void broadcastTtsQueueProcessingCompleted(){
-        Intent i = new Intent(Intent.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
+        Intent i = new Intent(TextToSpeech.ACTION_TTS_QUEUE_PROCESSING_COMPLETED);
         sendBroadcast(i);
     }
 
@@ -843,7 +843,7 @@
         }
         for (int i = 0; i < paramList.size() - 1; i = i + 2) {
             String param = paramList.get(i);
-            if ((param != null) && (param.equals(TextToSpeech.Engine.TTS_KEY_PARAM_STREAM))) {
+            if ((param != null) && (param.equals(TextToSpeech.Engine.KEY_PARAM_STREAM))) {
                 try {
                     streamType = Integer.parseInt(paramList.get(i + 1));
                 } catch (NumberFormatException e) {
@@ -910,18 +910,18 @@
             if (cb != null) {
                 mCallbacks.register(cb);
                 mCallbacksMap.put(packageName, cb);
-                return TextToSpeech.TTS_SUCCESS;
+                return TextToSpeech.SUCCESS;
             }
-            return TextToSpeech.TTS_ERROR;
+            return TextToSpeech.ERROR;
         }
 
         public int unregisterCallback(String packageName, ITtsCallback cb) {
             if (cb != null) {
                 mCallbacksMap.remove(packageName);
                 mCallbacks.unregister(cb);
-                return TextToSpeech.TTS_SUCCESS;
+                return TextToSpeech.SUCCESS;
             }
-            return TextToSpeech.TTS_ERROR;
+            return TextToSpeech.ERROR;
         }
 
         /**
diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java
index 63c9eaa..55007ba 100644
--- a/services/java/com/android/server/AccessibilityManagerService.java
+++ b/services/java/com/android/server/AccessibilityManagerService.java
@@ -323,15 +323,22 @@
      */
     private void notifyAccessibilityServicesDelayedLocked(AccessibilityEvent event,
             boolean isDefault) {
-        for (int i = 0, count = mServices.size(); i < count; i++) {
-            Service service = mServices.get(i);
+        try {
+            for (int i = 0, count = mServices.size(); i < count; i++) {
+                Service service = mServices.get(i);
 
-            if (service.mIsDefault == isDefault) {
-                if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) {
-                    mHandledFeedbackTypes |= service.mFeedbackType;
-                    notifyAccessibilityServiceDelayedLocked(service, event);
+                if (service.mIsDefault == isDefault) {
+                    if (canDispathEventLocked(service, event, mHandledFeedbackTypes)) {
+                        mHandledFeedbackTypes |= service.mFeedbackType;
+                        notifyAccessibilityServiceDelayedLocked(service, event);
+                    }
                 }
             }
+        } catch (IndexOutOfBoundsException oobe) {
+            // An out of bounds exception can happen if services are going away
+            // as the for loop is running. If that happens, just bail because
+            // there are no more services to notify.
+            return;
         }
     }
 
diff --git a/services/java/com/android/server/ShutdownActivity.java b/services/java/com/android/server/ShutdownActivity.java
new file mode 100644
index 0000000..7f0e90d
--- /dev/null
+++ b/services/java/com/android/server/ShutdownActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import com.android.internal.app.ShutdownThread;
+
+public class ShutdownActivity extends Activity {
+
+    private static final String TAG = "ShutdownActivity";
+    private boolean mConfirm;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mConfirm = getIntent().getBooleanExtra(Intent.EXTRA_KEY_CONFIRM, false);
+        Log.i(TAG, "onCreate(): confirm=" + mConfirm);
+
+        Handler h = new Handler();
+        h.post(new Runnable() {
+            public void run() {
+                ShutdownThread.shutdown(ShutdownActivity.this, mConfirm);
+            }
+        });
+    }
+}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index f25c221..d4e57d2 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -93,6 +93,9 @@
     private boolean mDeviceIdle;
     private int mPluggedType;
 
+    // true if the user enabled Wifi while in airplane mode
+    private boolean mAirplaneModeOverwridden;
+
     private final LockList mLocks = new LockList();
     // some wifi lock statistics
     private int mFullLocksAcquired;
@@ -219,6 +222,8 @@
                 new BroadcastReceiver() {
                     @Override
                     public void onReceive(Context context, Intent intent) {
+                        // clear our flag indicating the user has overwridden airplane mode
+                        mAirplaneModeOverwridden = false;
                         updateWifiState();
                     }
                 },
@@ -292,6 +297,8 @@
         synchronized (mWifiHandler) {
             sWakeLock.acquire();
             mLastEnableUid = Binder.getCallingUid();
+            // set a flag if the user is enabling Wifi while in airplane mode
+            mAirplaneModeOverwridden = (enable && isAirplaneModeOn() && isAirplaneToggleable());
             sendEnableMessage(enable, true, Binder.getCallingUid());
         }
 
@@ -312,7 +319,7 @@
         if (mWifiState == eventualWifiState) {
             return true;
         }
-        if (enable && isAirplaneModeOn()) {
+        if (enable && isAirplaneModeOn() && !mAirplaneModeOverwridden) {
             return false;
         }
 
@@ -1495,7 +1502,7 @@
 
     private void updateWifiState() {
         boolean wifiEnabled = getPersistedWifiEnabled();
-        boolean airplaneMode = isAirplaneModeOn();
+        boolean airplaneMode = isAirplaneModeOn() && !mAirplaneModeOverwridden;
         boolean lockHeld = mLocks.hasLocks();
         int strongestLockMode;
         boolean wifiShouldBeEnabled = wifiEnabled && !airplaneMode;
@@ -1559,6 +1566,13 @@
             || airplaneModeRadios.contains(Settings.System.RADIO_WIFI);
     }
 
+    private boolean isAirplaneToggleable() {
+        String toggleableRadios = Settings.System.getString(mContext.getContentResolver(),
+                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
+        return toggleableRadios != null
+            && toggleableRadios.contains(Settings.System.RADIO_WIFI);
+    }
+
     /**
      * Returns true if Wi-Fi is sensitive to airplane mode, and airplane mode is
      * currently on.
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ba5c6e7..ed9af66 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -256,7 +256,7 @@
      * No phone module
      *
      */
-    public static final int PHONE_TYPE_NONE = 0;
+    public static final int PHONE_TYPE_NONE = RILConstants.NO_PHONE;
 
     /**
      * GSM phone
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index ebdac4e..c52fe06 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -1225,8 +1225,10 @@
      * Request the device MDN / H_SID / H_NID / MIN.
      * "response" is const char **
      *   [0] is MDN if CDMA subscription is available
-     *   [1] is H_SID (Home SID) in hexadecimal if CDMA subscription is available
-     *   [2] is H_NID (Home NID) in hexadecimal if CDMA subscription is available
+     *   [1] is a comma separated list of H_SID (Home SID) in decimal format
+     *       if CDMA subscription is available
+     *   [2] is a comma separated list of H_NID (Home NID) in decimal format
+     *       if CDMA subscription is available
      *   [3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
      */
     public void getCDMASubscription(Message response);
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 7834018..1f4ce3d 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -68,8 +68,9 @@
     int CDMA_CELL_BROADCAST_SMS_DISABLED = 1;
     int CDMA_CELL_BROADCAST_SMS_ENABLED  = 0;
 
-    int CDMA_PHONE = 0;
+    int NO_PHONE = 0;
     int GSM_PHONE = 1;
+    int CDMA_PHONE = 2;
 
     int CDM_TTY_MODE_DISABLED = 0;
     int CDM_TTY_MODE_ENABLED = 1;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index c4db609..3ab1f77 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -88,7 +88,7 @@
         int teleService = sms.getTeleService();
         boolean handled = false;
 
-        if (sms.getUserData() == null) {
+        if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService)) {
             if (Config.LOGD) {
                 Log.d(TAG, "Received SMS without user data");
             }
@@ -99,10 +99,11 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
-        if (SmsEnvelope.TELESERVICE_WAP == teleService){
+        if (SmsEnvelope.TELESERVICE_WAP == teleService) {
             return processCdmaWapPdu(sms.getUserData(), sms.messageRef,
                     sms.getOriginatingAddress());
-        } else if (SmsEnvelope.TELESERVICE_VMN == teleService) {
+        } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) ||
+                   (SmsEnvelope.TELESERVICE_MWI == teleService)) {
             // handling Voicemail
             int voicemailCount = sms.getNumOfVoicemails();
             Log.d(TAG, "Voicemail count=" + voicemailCount);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index 6356473..0cae604 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -401,11 +401,19 @@
                     // TODO: Only grabbing the first SID/NID for now.
                     if (cdmaSubscription[1] != null) {
                         String[] sid = cdmaSubscription[1].split(",");
-                        mHomeSystemId = sid.length > 0 ? Integer.parseInt(sid[0], 16) : 0;
+                        try {
+                            mHomeSystemId = sid.length > 0 ? Integer.parseInt(sid[0]) : 0;
+                        } catch (NumberFormatException e) {
+                            mHomeSystemId = 0;
+                        }
                     }
                     if (cdmaSubscription[2] != null) {
                         String[] nid = cdmaSubscription[2].split(",");
-                        mHomeNetworkId = nid.length > 0 ? Integer.parseInt(nid[0], 16) : 0;
+                        try {
+                            mHomeNetworkId = nid.length > 0 ? Integer.parseInt(nid[0]) : 0;
+                        } catch (NumberFormatException e) {
+                            mHomeNetworkId = 0;
+                        }
                     }
                     mMin = cdmaSubscription[3];
                     mPrlVersion = cdmaSubscription[4];
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 30adc52..9c04305 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -527,6 +527,19 @@
      * Parses a SMS message from its BearerData stream. (mobile-terminated only)
      */
     protected void parseSms() {
+        // Message Waiting Info Record defined in 3GPP2 C.S-0005, 3.7.5.6
+        // It contains only an 8-bit number with the number of messages waiting
+        if (mEnvelope.teleService == SmsEnvelope.TELESERVICE_MWI) {
+            mBearerData = new BearerData();
+            if (mEnvelope.bearerData != null) {
+                mBearerData.numberOfMessages = 0x000000FF & mEnvelope.bearerData[0];
+            }
+            if (Config.DEBUG) {
+                Log.d(LOG_TAG, "parseSms: get MWI " +
+                      Integer.toString(mBearerData.numberOfMessages));
+            }
+            return;
+        }
         mBearerData = BearerData.decode(mEnvelope.bearerData);
         messageRef = mBearerData.messageId;
         if (mBearerData.userData != null) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
index f80e8c0..0dcacc1 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/SmsEnvelope.java
@@ -36,6 +36,14 @@
     static public final int TELESERVICE_WAP               = 0x1004;
     static public final int TELESERVICE_WEMT              = 0x1005;
 
+    /**
+     * The following are defined as extensions to the standard teleservices
+     */
+    // Voice mail notification through Message Waiting Indication in CDMA mode or Analog mode.
+    // Defined in 3GPP2 C.S-0005, 3.7.5.6, an Info Record containing an 8-bit number with the
+    // number of messages waiting, it's used by some CDMA carriers for a voice mail count.
+    static public final int TELESERVICE_MWI               = 0x40000;
+
     // ServiceCategories for Cell Broadcast, see 3GPP2 C.R1001 table 9.3.1-1
     //static public final int SERVICECATEGORY_EMERGENCY      = 0x0010;
     //...
diff --git a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java
index 7dc1314..67fcd61 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/VpnTest.java
@@ -16,10 +16,22 @@
 
 package com.android.unit_tests;
 
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.L2tpProfile;
 import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
 import android.net.vpn.VpnType;
+import android.os.ConditionVariable;
+import android.os.Parcel;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
 
 /**
  * Unit test class to test VPN api
@@ -29,6 +41,12 @@
  *   -w com.android.unit_tests/android.test.InstrumentationTestRunner
  */
 public class VpnTest extends AndroidTestCase {
+    private static final String NAME = "a name";
+    private static final String SERVER_NAME = "a server name";
+    private static final String ID = "some id";
+    private static final String SUFFICES = "some suffices";
+    private static final String ROUTES = "some routes";
+    private static final String SAVED_NAME = "some name";
 
     @Override
     public void setUp() {
@@ -39,8 +57,102 @@
     }
 
     @SmallTest
+    public void testVpnType() {
+        testVpnType(VpnType.L2TP);
+        testVpnType(VpnType.L2TP_IPSEC);
+        testVpnType(VpnType.L2TP_IPSEC_PSK);
+        testVpnType(VpnType.PPTP);
+    }
+
+    @SmallTest
+    public void testVpnProfile() {
+        VpnState state = VpnState.CONNECTING;
+        testVpnProfile(createTestProfile(state), state);
+    }
+
+    @SmallTest
     public void testGetType() {
-        L2tpIpsecProfile li = new L2tpIpsecProfile();
-        assertTrue(VpnType.L2TP_IPSEC== li.getType());
+        assertEquals(VpnType.L2TP, new L2tpProfile().getType());
+        assertEquals(VpnType.L2TP_IPSEC, new L2tpIpsecProfile().getType());
+        assertEquals(VpnType.L2TP_IPSEC_PSK, 
+                new L2tpIpsecPskProfile().getType());
+        assertEquals(VpnType.PPTP, new PptpProfile().getType());
+    }
+
+    @SmallTest
+    public void testVpnTypes() {
+        assertTrue(VpnManager.getSupportedVpnTypes().length > 0);
+    }
+
+    @SmallTest
+    public void testGetTypeFromManager() {
+        VpnManager m = new VpnManager(getContext());
+        VpnType[] types = VpnManager.getSupportedVpnTypes();
+        for (VpnType t : types) {
+            assertEquals(t, m.createVpnProfile(t).getType());
+        }
+    }
+
+    @SmallTest
+    public void testParcelable() {
+        VpnProfile p = createTestProfile(VpnState.CONNECTED);
+        Parcel parcel = Parcel.obtain();
+        p.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        // VpnState is transient and not saved in the parcel
+        testVpnProfile(VpnProfile.CREATOR.createFromParcel(parcel), null);
+    }
+
+    @SmallTest
+    public void testReceiver() {
+        final String profileName = "whatever";
+        final VpnState state = VpnState.DISCONNECTING;
+        final ConditionVariable cv = new ConditionVariable();
+        cv.close();
+        BroadcastReceiver r = new BroadcastReceiver() {
+            public void onReceive(Context c, Intent i) {
+                assertEquals(profileName,
+                        i.getStringExtra(VpnManager.BROADCAST_PROFILE_NAME));
+                assertEquals(state, i.getSerializableExtra(
+                        VpnManager.BROADCAST_CONNECTION_STATE));
+                cv.open();
+            }
+        };
+
+        VpnManager m = new VpnManager(getContext());
+        m.registerConnectivityReceiver(r);
+        m.broadcastConnectivity(profileName, state);
+
+        // fail it if onReceive() doesn't get executed in 5 sec
+        assertTrue(cv.block(5000));
+    }
+
+    private void testVpnType(VpnType type) {
+        assertFalse(TextUtils.isEmpty(type.getDisplayName()));
+        assertNotNull(type.getDescription());
+        assertNotNull(type.getProfileClass());
+    }
+
+    private VpnProfile createTestProfile(VpnState state) {
+        VpnProfile p = new L2tpProfile();
+        p.setName(NAME);
+        p.setServerName(SERVER_NAME);
+        p.setId(ID);
+        p.setDomainSuffices(SUFFICES);
+        p.setRouteList(ROUTES);
+        p.setSavedUsername(SAVED_NAME);
+        p.setState(state);
+        return p;
+    }
+
+    private void testVpnProfile(VpnProfile p, VpnState state) {
+        assertEquals(NAME, p.getName());
+        assertEquals(SERVER_NAME, p.getServerName());
+        assertEquals(ID, p.getId());
+        assertEquals(SUFFICES, p.getDomainSuffices());
+        assertEquals(ROUTES, p.getRouteList());
+        assertEquals(SAVED_NAME, p.getSavedUsername());
+        if (state != null) assertEquals(state, p.getState());
     }
 }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 2ee1945..d8a03a9 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -871,7 +871,10 @@
      * Create a new MulticastLock
      *
      * @param tag a tag for the MulticastLock to identify it in debugging
-     *            messages.
+     *            messages.  This string is never shown to the user under
+     *            normal conditions, but should be descriptive enough to
+     *            identify your application and the specific MulticastLock
+     *            within it, if it holds multiple MulticastLocks.
      *
      * @return a new, unacquired MulticastLock with the given tag.
      *
@@ -887,26 +890,36 @@
      * addressed to this device.  Acquring a MulticastLock will
      * cause the stack to receive packets addressed to multicast
      * addresses.  Processing these extra packets can cause a noticable
-     * battery drain and should be disabled when not needed
+     * battery drain and should be disabled when not needed.
      */
     public class MulticastLock {
         private String mTag;
         private final IBinder mBinder;
+        private int mRefCount;
+        private boolean mRefCounted;
         private boolean mHeld;
 
         private MulticastLock(String tag) {
             mTag = tag;
             mBinder = new Binder();
+            mRefCount = 0;
+            mRefCounted = true;
             mHeld = false;
         }
 
         /**
          * Locks Wifi Multicast on until {@link #release} is called.
          *
-         * The first call to {@code acquire} will lock the Multicast on
-         * but subsequent calls will be ignored.  Only one call to
-         * {@link #release} will be required, regardless of the number of
-         * times that {@code acquire} is called.
+         * If this MulticastLock is reference-counted each call to
+         * {@code acquire} will increment the reference count, and the
+         * wifi interface will receive multicast packets as long as the
+         * reference count is above zero.
+         *
+         * If this MulticastLock is not reference-counted, the first call to
+         * {@code acquire} will turn on the multicast packets, but subsequent
+         * calls will be ignored.  Only one call to {@link #release} will
+         * be required, regardless of the number of times that {@code acquire}
+         * is called.
          *
          * Note that other applications may also lock Wifi Multicast on.
          * Only they can relinquish their lock.
@@ -916,7 +929,7 @@
          */
         public void acquire() {
             synchronized (mBinder) {
-                if (!mHeld) {
+                if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) {
                     try {
                         mService.acquireMulticastLock(mBinder, mTag);
                         synchronized (WifiManager.this) {
@@ -927,9 +940,9 @@
                             }
                             mActiveLockCount++;
                         }
-                        mHeld = true;
                     } catch (RemoteException ignore) {
                     }
+                    mHeld = true;
                 }
             }
         }
@@ -938,6 +951,18 @@
          * Unlocks Wifi Multicast, restoring the filter of packets
          * not addressed specifically to this device and saving power.
          *
+         * If this MulticastLock is reference-counted, each call to
+         * {@code release} will decrement the reference count, and the
+         * multicast packets will only stop being received when the reference
+         * count reaches zero.  If the reference count goes below zero (that
+         * is, if {@code release} is called a greater number of times than
+         * {@link #acquire}), an exception is thrown.
+         *
+         * If this MulticastLock is not reference-counted, the first call to
+         * {@code release} (after the radio was multicast locked using
+         * {@linke #acquire}) will unlock the multicast, and subsequent calls
+         * will be ignored.
+         *
          * Note that if any other Wifi Multicast Locks are still outstanding
          * this {@code release} call will not have an immediate effect.  Only
          * when all applications have released all their Multicast Locks will
@@ -948,20 +973,43 @@
          */
         public void release() {
             synchronized (mBinder) {
-                if (mHeld) {
+                if (mRefCounted ? (--mRefCount == 0) : (mHeld)) {
                     try {
                         mService.releaseMulticastLock();
                         synchronized (WifiManager.this) {
                             mActiveLockCount--;
                         }
-                        mHeld = false;
                     } catch (RemoteException ignore) {
                     }
+                    mHeld = false;
+                }
+                if (mRefCount < 0) {
+                    throw new RuntimeException("MulticastLock under-locked "
+                            + mTag);
                 }
             }
         }
 
         /**
+         * Controls whether this is a reference-counted or non-reference-
+         * counted MulticastLock.
+         *
+         * Reference-counted MulticastLocks keep track of the number of calls
+         * to {@link #acquire} and {@link #release}, and only stop the
+         * reception of multicast packets when every call to {@link #acquire}
+         * has been balanced with a call to {@link #release}.  Non-reference-
+         * counted MulticastLocks allow the reception of multicast packets
+         * whenever {@link #acquire} is called and stop accepting multicast
+         * packets whenever {@link #release} is called.
+         *
+         * @param refCounted true if this MulticastLock should keep a reference
+         * count
+         */
+        public void setReferenceCounted(boolean refCounted) {
+            mRefCounted = refCounted;
+        }
+
+        /**
          * Checks whether this MulticastLock is currently held.
          *
          * @return true if this MulticastLock is held, false otherwise
@@ -973,17 +1021,23 @@
         }
 
         public String toString() {
-            String s1, s2;
+            String s1, s2, s3;
             synchronized (mBinder) {
                 s1 = Integer.toHexString(System.identityHashCode(this));
                 s2 = mHeld ? "held; " : "";
-                return "MulticastLock{ " + s1 + "; " + s2 + " }";
+                if (mRefCounted) {
+                    s3 = "refcounted: refcount = " + mRefCount;
+                } else {
+                    s3 = "not refcounted";
+                }
+                return "MulticastLock{ " + s1 + "; " + s2 + s3 + " }";
             }
         }
 
         @Override
         protected void finalize() throws Throwable {
             super.finalize();
+            setReferenceCounted(false);
             release();
         }
     }