Merge change I2083b297 into eclair

* changes:
  Fix issue 2265111: Loss of downlink audio while listening, and get a MT call.
This commit is contained in:
Android (Google) Code Review
2009-11-23 11:11:55 -08:00

View File

@@ -43,6 +43,8 @@ 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 SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC);
private static final int HEADSETS_WITH_MIC = BIT_HEADSET;
private int mHeadsetState;
private int mPrevHeadsetState;
@@ -100,68 +102,76 @@ class HeadsetObserver extends UEventObserver {
private synchronized final void update(String newName, int newState) {
// Retain only relevant bits
int headsetState = newState & (BIT_HEADSET|BIT_HEADSET_NO_MIC);
int headsetState = newState & SUPPORTED_HEADSETS;
int newOrOld = headsetState | mHeadsetState;
// reject all suspect transitions: only accept state changes from:
// - a: 0 heaset to 1 headset
// - b: 1 headset to 0 headset
if (mHeadsetState == headsetState || ((newOrOld & (newOrOld - 1)) != 0)) {
return;
}
if (headsetState != mHeadsetState) {
boolean isUnplug = false;
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 = headsetState;
mPendingIntent = true;
mHeadsetName = newName;
mPrevHeadsetState = mHeadsetState;
mHeadsetState = headsetState;
mPendingIntent = true;
if (isUnplug) {
Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
mContext.sendBroadcast(intent);
if (headsetState == 0) {
Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
mContext.sendBroadcast(intent);
// It can take hundreds of ms flush the audio pipeline after
// apps pause audio playback, but audio route changes are
// immediate, so delay the route change by 1000ms.
// This could be improved once the audio sub-system provides an
// interface to clear the audio pipeline.
mWakeLock.acquire();
mHandler.sendEmptyMessageDelayed(0, 1000);
} else {
sendIntent();
mPendingIntent = false;
// It can take hundreds of ms flush the audio pipeline after
// apps pause audio playback, but audio route changes are
// immediate, so delay the route change by 1000ms.
// This could be improved once the audio sub-system provides an
// interface to clear the audio pipeline.
mWakeLock.acquire();
mHandler.sendEmptyMessageDelayed(0, 1000);
} else {
sendIntents();
mPendingIntent = false;
}
}
private synchronized final void sendIntents() {
int allHeadsets = SUPPORTED_HEADSETS;
for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
if ((curHeadset & allHeadsets) != 0) {
sendIntent(curHeadset);
allHeadsets &= ~curHeadset;
}
}
}
private synchronized final void sendIntent() {
// 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;
private final void sendIntent(int headset) {
if ((mHeadsetState & headset) != (mPrevHeadsetState & headset)) {
// 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) {
if ((headset & HEADSETS_WITH_MIC) != 0) {
microphone = 1;
}
if ((mHeadsetState & headset) != 0) {
state = 1;
}
intent.putExtra("state", state);
intent.putExtra("name", mHeadsetName);
intent.putExtra("microphone", microphone);
if (LOG) Log.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+mHeadsetName+" mic: "+microphone);
// TODO: Should we require a permission?
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
intent.putExtra("state", state);
intent.putExtra("name", mHeadsetName);
intent.putExtra("microphone", microphone);
// TODO: Should we require a permission?
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (mPendingIntent) {
sendIntent();
sendIntents();
mPendingIntent = false;
}
mWakeLock.release();