diff options
author | Eric Laurent <elaurent@google.com> | 2009-11-12 12:09:06 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2009-11-12 12:09:06 -0800 |
commit | 923d7d721d37f6ba5148e7d79d61a4fa48e79df2 (patch) | |
tree | 79d0aae61449c8c048cfc494cf5a3354174749dc | |
parent | 3c58d279abed1da56b0ece74ded5854c509a42a4 (diff) | |
download | frameworks_base-923d7d721d37f6ba5148e7d79d61a4fa48e79df2.zip frameworks_base-923d7d721d37f6ba5148e7d79d61a4fa48e79df2.tar.gz frameworks_base-923d7d721d37f6ba5148e7d79d61a4fa48e79df2.tar.bz2 |
Fix issue 2242614: Wired headset not recognized: bogus "state" in ACTION_HEADSET_PLUG broadcast.
The headset state indicated by HeadsetObserver in the broadcast intent ACTION_HEADSET_PLUG was not 0 or 1 as specified in the java doc but contained a bit field indicating the type of headset connected.
Modified HeadsetObserver to broacast a state conforming to java doc.
Added an extra to intent ACTION_HEADSET_PLUG to indicate if headset has a microphone or not.
Removed handling of non standard headset indications from HeadsetObserver.
Removed platform specific devices from output devices defined in AudioSystem.
Modified AudioService to use new ACTION_HEADSET_PLUG intent extra instead of bitfield in state.
-rw-r--r-- | core/java/android/content/Intent.java | 1 | ||||
-rw-r--r-- | include/media/AudioSystem.h | 6 | ||||
-rw-r--r-- | media/java/android/media/AudioService.java | 103 | ||||
-rw-r--r-- | media/java/android/media/AudioSystem.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/HeadsetObserver.java | 32 |
5 files changed, 53 insertions, 92 deletions
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 @@ public class Intent implements Parcelable { * <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 @@ public: 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 @@ public class AudioService extends IAudioService.Stub { // 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 @@ public class AudioService extends IAudioService.Stub { mVolumePanel = new VolumePanel(context, this); mSettingsObserver = new SettingsObserver(); mMode = AudioSystem.MODE_NORMAL; - mHeadsetState = 0; mForcedUseForComm = AudioSystem.FORCE_NONE; createAudioSystemThread(); readPersistedSettings(); @@ -1460,72 +1450,35 @@ public class AudioService extends IAudioService.Stub { } } 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), ""); - } - 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), ""); + 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), ""); + } } - 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 class AudioSystem 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 @@ class HeadsetObserver extends UEventObserver { 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 @@ class HeadsetObserver extends UEventObserver { } 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 @@ class HeadsetObserver extends UEventObserver { // 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; + + 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", mHeadsetState); + intent.putExtra("state", state); intent.putExtra("name", mHeadsetName); + intent.putExtra("microphone", microphone); // TODO: Should we require a permission? ActivityManagerNative.broadcastStickyIntent(intent, null); |