Merge change I923d7d72 into eclair

* changes:
  Fix issue 2242614: Wired headset not recognized: bogus "state" in ACTION_HEADSET_PLUG broadcast.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 398f211..0085f26 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1678,6 +1678,7 @@
      * <ul>
      *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
      *   <li><em>name</em> - Headset type, human readable string </li>
+     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
      * </ul>
      * </ul>
      */
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index e066177..bc3dd36 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -239,15 +239,11 @@
         DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
         DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
         DEVICE_OUT_AUX_DIGITAL = 0x400,
-        DEVICE_OUT_FM_HEADPHONE = 0x800,
-        DEVICE_OUT_FM_SPEAKER = 0x1000,
-        DEVICE_OUT_TTY = 0x2000,
         DEVICE_OUT_DEFAULT = 0x8000,
         DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET |
                 DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
                 DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-                DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_FM_HEADPHONE |
-                DEVICE_OUT_FM_SPEAKER | DEVICE_OUT_TTY | DEVICE_OUT_DEFAULT),
+                DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | DEVICE_OUT_DEFAULT),
 
         // input devices
         DEVICE_IN_COMMUNICATION = 0x10000,
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 58a0bba..3b40612 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -222,15 +222,6 @@
     // Broadcast receiver for device connections intent broadcasts
     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
 
-    //TODO: use common definitions with HeadsetObserver
-    private static final int BIT_HEADSET = (1 << 0);
-    private static final int BIT_HEADSET_NO_MIC = (1 << 1);
-    private static final int BIT_TTY = (1 << 2);
-    private static final int BIT_FM_HEADSET = (1 << 3);
-    private static final int BIT_FM_SPEAKER = (1 << 4);
-
-    private int mHeadsetState;
-
     // Devices currently connected
     private HashMap <Integer, String> mConnectedDevices = new HashMap <Integer, String>();
 
@@ -254,7 +245,6 @@
         mVolumePanel = new VolumePanel(context, this);
         mSettingsObserver = new SettingsObserver();
         mMode = AudioSystem.MODE_NORMAL;
-        mHeadsetState = 0;
         mForcedUseForComm = AudioSystem.FORCE_NONE;
         createAudioSystemThread();
         readPersistedSettings();
@@ -1460,72 +1450,35 @@
                 }
             } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
                 int state = intent.getIntExtra("state", 0);
-                if ((state & BIT_HEADSET) == 0 &&
-                    (mHeadsetState & BIT_HEADSET) != 0) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
-                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                            "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
-                } else if ((state & BIT_HEADSET) != 0 &&
-                    (mHeadsetState & BIT_HEADSET) == 0)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
-                            AudioSystem.DEVICE_STATE_AVAILABLE,
-                            "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), "");
+                int microphone = intent.getIntExtra("microphone", 0);
+
+                if (microphone != 0) {
+                    boolean isConnected = mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+                    if (state == 0 && isConnected) {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+                                AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                "");
+                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+                    } else if (state == 1 && !isConnected)  {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+                                AudioSystem.DEVICE_STATE_AVAILABLE,
+                                "");
+                        mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADSET), "");
+                    }
+                } else {
+                    boolean isConnected = mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+                    if (state == 0 && isConnected) {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+                                AudioSystem.DEVICE_STATE_UNAVAILABLE,
+                                "");
+                        mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+                    } else if (state == 1 && !isConnected)  {
+                        AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+                                AudioSystem.DEVICE_STATE_AVAILABLE,
+                                "");
+                        mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), "");
+                    }
                 }
-                if ((state & BIT_HEADSET_NO_MIC) == 0 &&
-                    (mHeadsetState & BIT_HEADSET_NO_MIC) != 0) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
-                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                            "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
-                } else if ((state & BIT_HEADSET_NO_MIC) != 0 &&
-                    (mHeadsetState & BIT_HEADSET_NO_MIC) == 0)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
-                            AudioSystem.DEVICE_STATE_AVAILABLE,
-                            "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE), "");
-                }
-                if ((state & BIT_TTY) == 0 &&
-                    (mHeadsetState & BIT_TTY) != 0) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_TTY,
-                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                            "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_TTY);
-                } else if ((state & BIT_TTY) != 0 &&
-                    (mHeadsetState & BIT_TTY) == 0)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_TTY,
-                            AudioSystem.DEVICE_STATE_AVAILABLE,
-                            "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_TTY), "");
-                }
-                if ((state & BIT_FM_HEADSET) == 0 &&
-                    (mHeadsetState & BIT_FM_HEADSET) != 0) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_HEADPHONE,
-                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                            "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_FM_HEADPHONE);
-                } else if ((state & BIT_FM_HEADSET) != 0 &&
-                    (mHeadsetState & BIT_FM_HEADSET) == 0)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_HEADPHONE,
-                            AudioSystem.DEVICE_STATE_AVAILABLE,
-                            "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_FM_HEADPHONE), "");
-                }
-                if ((state & BIT_FM_SPEAKER) == 0 &&
-                    (mHeadsetState & BIT_FM_SPEAKER) != 0) {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_SPEAKER,
-                            AudioSystem.DEVICE_STATE_UNAVAILABLE,
-                            "");
-                    mConnectedDevices.remove(AudioSystem.DEVICE_OUT_FM_SPEAKER);
-                } else if ((state & BIT_FM_SPEAKER) != 0 &&
-                    (mHeadsetState & BIT_FM_SPEAKER) == 0)  {
-                    AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM_SPEAKER,
-                            AudioSystem.DEVICE_STATE_AVAILABLE,
-                            "");
-                    mConnectedDevices.put( new Integer(AudioSystem.DEVICE_OUT_FM_SPEAKER), "");
-                }
-                mHeadsetState = state;
             }
         }
     }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index dbf6d9d..9fe5328 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -243,9 +243,6 @@
     public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100;
     public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200;
     public static final int DEVICE_OUT_AUX_DIGITAL = 0x400;
-    public static final int DEVICE_OUT_FM_HEADPHONE = 0x800;
-    public static final int DEVICE_OUT_FM_SPEAKER = 0x1000;
-    public static final int DEVICE_OUT_TTY = 0x2000;
     public static final int DEVICE_OUT_DEFAULT = 0x8000;
     // input devices
     public static final int DEVICE_IN_COMMUNICATION = 0x10000;
diff --git a/services/java/com/android/server/HeadsetObserver.java b/services/java/com/android/server/HeadsetObserver.java
index bee3108..58fa69e 100644
--- a/services/java/com/android/server/HeadsetObserver.java
+++ b/services/java/com/android/server/HeadsetObserver.java
@@ -43,9 +43,6 @@
 
     private static final int BIT_HEADSET = (1 << 0);
     private static final int BIT_HEADSET_NO_MIC = (1 << 1);
-    private static final int BIT_TTY = (1 << 2);
-    private static final int BIT_FM_HEADSET = (1 << 3);
-    private static final int BIT_FM_SPEAKER = (1 << 4);
 
     private int mHeadsetState;
     private int mPrevHeadsetState;
@@ -102,15 +99,18 @@
     }
 
     private synchronized final void update(String newName, int newState) {
-        if (newName != mHeadsetName || newState != mHeadsetState) {
+        // Retain only relevant bits
+        int headsetState = newState & (BIT_HEADSET|BIT_HEADSET_NO_MIC);
+
+        if (headsetState != mHeadsetState) {
             boolean isUnplug = false;
-            if ( (mHeadsetState & BIT_HEADSET) > 0 || (mHeadsetState & BIT_HEADSET_NO_MIC) > 0) {
-                if ((newState & BIT_HEADSET) == 0 && (newState & BIT_HEADSET_NO_MIC) == 0)
-                    isUnplug = true;
+            if (((mHeadsetState & BIT_HEADSET) != 0 && (headsetState & BIT_HEADSET) == 0) ||
+                ((mHeadsetState & BIT_HEADSET_NO_MIC) != 0 && (headsetState & BIT_HEADSET_NO_MIC) == 0)) {
+                isUnplug = true;
             }
             mHeadsetName = newName;
             mPrevHeadsetState = mHeadsetState;
-            mHeadsetState = newState;
+            mHeadsetState = headsetState;
             mPendingIntent = true;
 
             if (isUnplug) {
@@ -135,9 +135,23 @@
         //  Pack up the values and broadcast them to everyone
         Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+        int state = 0;
+        int microphone = 0;
 
-        intent.putExtra("state", mHeadsetState);
+        if ((mHeadsetState & BIT_HEADSET) != (mPrevHeadsetState & BIT_HEADSET)) {
+            microphone = 1;
+            if ((mHeadsetState & BIT_HEADSET) != 0) {
+                state = 1;
+            }
+        } else if ((mHeadsetState & BIT_HEADSET_NO_MIC) != (mPrevHeadsetState & BIT_HEADSET_NO_MIC)) {
+            if ((mHeadsetState & BIT_HEADSET_NO_MIC) != 0) {
+                state = 1;
+            }
+        }
+
+        intent.putExtra("state", state);
         intent.putExtra("name", mHeadsetName);
+        intent.putExtra("microphone", microphone);
 
         // TODO: Should we require a permission?
         ActivityManagerNative.broadcastStickyIntent(intent, null);