Merge change Ifb28d340 into eclair
* changes:
Import revised translations. DO NOT MERGE
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/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index ebd470f..d918998 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1185,7 +1185,6 @@
mFrameSize = mOutput->frameSize();
mFrameCount = mOutput->bufferSize() / mFrameSize;
- mMinBytesToWrite = (mOutput->latency() * mSampleRate * mFrameSize) / 1000;
// FIXME - Current mixer implementation only supports stereo output: Always
// Allocate a stereo buffer even if HW output is mono.
if (mMixBuffer != NULL) delete mMixBuffer;
@@ -1215,23 +1214,25 @@
bool AudioFlinger::MixerThread::threadLoop()
{
- uint32_t sleepTime = 1000;
- uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
int16_t* curBuf = mMixBuffer;
Vector< sp<Track> > tracksToRemove;
- size_t enabledTracks = 0;
+ uint32_t mixerStatus = MIXER_IDLE;
nsecs_t standbyTime = systemTime();
size_t mixBufferSize = mFrameCount * mFrameSize;
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
nsecs_t lastWarning = 0;
+ bool longStandbyExit = false;
+ uint32_t activeSleepTime = activeSleepTimeUs();
+ uint32_t idleSleepTime = idleSleepTimeUs();
+ uint32_t sleepTime = idleSleepTime;
while (!exitPending())
{
processConfigEvents();
- enabledTracks = 0;
+ mixerStatus = MIXER_IDLE;
{ // scope for mLock
Mutex::Autolock _l(mLock);
@@ -1241,7 +1242,8 @@
// FIXME: Relaxed timing because of a certain device that can't meet latency
// Should be reduced to 2x after the vendor fixes the driver issue
maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
- maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
+ activeSleepTime = activeSleepTimeUs();
+ idleSleepTime = idleSleepTimeUs();
}
const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -1277,15 +1279,15 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
- sleepTime = 1000;
+ sleepTime = idleSleepTime;
continue;
}
}
- enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
+ mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
}
- if (LIKELY(enabledTracks)) {
+ if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
mAudioMixer->process(curBuf);
sleepTime = 0;
@@ -1294,15 +1296,22 @@
// If no tracks are ready, sleep once for the duration of an output
// buffer size, then write 0s to the output
if (sleepTime == 0) {
- sleepTime = maxBufferRecoveryInUsecs;
- } else if (mBytesWritten != 0) {
+ if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ sleepTime = activeSleepTime;
+ } else {
+ sleepTime = idleSleepTime;
+ }
+ } else if (mBytesWritten != 0 ||
+ (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
+ LOGV("NO DATA READY, %p", this);
memset (curBuf, 0, mixBufferSize);
sleepTime = 0;
+ LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
}
}
if (mSuspended) {
- sleepTime = maxBufferRecoveryInUsecs;
+ sleepTime = idleSleepTime;
}
// sleepTime == 0 means we must write to audio hardware
if (sleepTime == 0) {
@@ -1312,7 +1321,6 @@
if (bytesWritten > 0) mBytesWritten += bytesWritten;
mNumWrites++;
mInWrite = false;
- mStandby = false;
nsecs_t now = systemTime();
nsecs_t delta = now - mLastWriteTime;
if (delta > maxPeriod) {
@@ -1322,7 +1330,11 @@
ns2ms(delta), mNumDelayedWrites, this);
lastWarning = now;
}
+ if (mStandby) {
+ longStandbyExit = true;
+ }
}
+ mStandby = false;
} else {
usleep(sleepTime);
}
@@ -1342,10 +1354,10 @@
}
// prepareTracks_l() must be called with ThreadBase::mLock held
-size_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
+uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
{
- size_t enabledTracks = 0;
+ uint32_t mixerStatus = MIXER_IDLE;
// find out which tracks need to be processed
size_t count = activeTracks.size();
for (size_t i=0 ; i<count ; i++) {
@@ -1415,7 +1427,7 @@
// reset retry count
track->mRetryCount = kMaxTrackRetries;
- enabledTracks++;
+ mixerStatus = MIXER_TRACKS_READY;
} else {
//LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if (track->isStopped()) {
@@ -1432,16 +1444,11 @@
if (--(track->mRetryCount) <= 0) {
LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
tracksToRemove->add(track);
+ } else if (mixerStatus != MIXER_TRACKS_READY) {
+ mixerStatus = MIXER_TRACKS_ENABLED;
}
- // For tracks using static shared memory buffer, make sure that we have
- // written enough data to audio hardware before disabling the track
- // NOTE: this condition with arrive before track->mRetryCount <= 0 so we
- // don't care about code removing track from active list above.
- if ((track->mSharedBuffer == 0) || (mBytesWritten >= mMinBytesToWrite)) {
- mAudioMixer->disable(AudioMixer::MIXING);
- } else {
- enabledTracks++;
- }
+
+ mAudioMixer->disable(AudioMixer::MIXING);
}
}
}
@@ -1459,7 +1466,7 @@
}
}
- return enabledTracks;
+ return mixerStatus;
}
void AudioFlinger::MixerThread::getTracks(
@@ -1621,14 +1628,14 @@
return NO_ERROR;
}
-uint32_t AudioFlinger::MixerThread::getMaxBufferRecoveryInUsecs()
+uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
{
- uint32_t time = ((mFrameCount * 1000) / mSampleRate) * 1000;
- // Add some margin with regard to scheduling precision
- if (time > 10000) {
- time -= 10000;
- }
- return time;
+ return (uint32_t)(mOutput->latency() * 1000) / 2;
+}
+
+uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
+{
+ return (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
}
// ----------------------------------------------------------------------------
@@ -1646,25 +1653,31 @@
bool AudioFlinger::DirectOutputThread::threadLoop()
{
- uint32_t sleepTime = 1000;
- uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
+ uint32_t mixerStatus = MIXER_IDLE;
sp<Track> trackToRemove;
sp<Track> activeTrack;
nsecs_t standbyTime = systemTime();
int8_t *curBuf;
size_t mixBufferSize = mFrameCount*mFrameSize;
+ uint32_t activeSleepTime = activeSleepTimeUs();
+ uint32_t idleSleepTime = idleSleepTimeUs();
+ uint32_t sleepTime = idleSleepTime;
+
while (!exitPending())
{
processConfigEvents();
+ mixerStatus = MIXER_IDLE;
+
{ // scope for the mLock
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
mixBufferSize = mFrameCount*mFrameSize;
- maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
+ activeSleepTime = activeSleepTimeUs();
+ idleSleepTime = idleSleepTimeUs();
}
// put audio hardware into standby after short delay
@@ -1698,7 +1711,7 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
- sleepTime = 1000;
+ sleepTime = idleSleepTime;
continue;
}
}
@@ -1753,6 +1766,7 @@
// reset retry count
track->mRetryCount = kMaxTrackRetries;
activeTrack = t;
+ mixerStatus = MIXER_TRACKS_READY;
} else {
//LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if (track->isStopped()) {
@@ -1768,16 +1782,10 @@
if (--(track->mRetryCount) <= 0) {
LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
trackToRemove = track;
+ } else {
+ mixerStatus = MIXER_TRACKS_ENABLED;
}
-
- // For tracks using static shared memry buffer, make sure that we have
- // written enough data to audio hardware before disabling the track
- // NOTE: this condition with arrive before track->mRetryCount <= 0 so we
- // don't care about code removing track from active list above.
- if ((track->mSharedBuffer != 0) && (mBytesWritten < mMinBytesToWrite)) {
- activeTrack = t;
- }
- }
+ }
}
}
@@ -1791,7 +1799,7 @@
}
}
- if (activeTrack != 0) {
+ if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
AudioBufferProvider::Buffer buffer;
size_t frameCount = mFrameCount;
curBuf = (int8_t *)mMixBuffer;
@@ -1812,7 +1820,11 @@
standbyTime = systemTime() + kStandbyTimeInNsecs;
} else {
if (sleepTime == 0) {
- sleepTime = maxBufferRecoveryInUsecs;
+ if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ sleepTime = activeSleepTime;
+ } else {
+ sleepTime = idleSleepTime;
+ }
} else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
memset (mMixBuffer, 0, mFrameCount * mFrameSize);
sleepTime = 0;
@@ -1820,7 +1832,7 @@
}
if (mSuspended) {
- sleepTime = maxBufferRecoveryInUsecs;
+ sleepTime = idleSleepTime;
}
// sleepTime == 0 means we must write to audio hardware
if (sleepTime == 0) {
@@ -1905,15 +1917,22 @@
return reconfig;
}
-uint32_t AudioFlinger::DirectOutputThread::getMaxBufferRecoveryInUsecs()
+uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs()
{
uint32_t time;
if (AudioSystem::isLinearPCM(mFormat)) {
- time = ((mFrameCount * 1000) / mSampleRate) * 1000;
- // Add some margin with regard to scheduling precision
- if (time > 10000) {
- time -= 10000;
- }
+ time = (uint32_t)(mOutput->latency() * 1000) / 2;
+ } else {
+ time = 10000;
+ }
+ return time;
+}
+
+uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs()
+{
+ uint32_t time;
+ if (AudioSystem::isLinearPCM(mFormat)) {
+ time = (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
} else {
time = 10000;
}
@@ -1936,28 +1955,30 @@
bool AudioFlinger::DuplicatingThread::threadLoop()
{
- uint32_t sleepTime = 1000;
- uint32_t maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
int16_t* curBuf = mMixBuffer;
Vector< sp<Track> > tracksToRemove;
- size_t enabledTracks = 0;
+ uint32_t mixerStatus = MIXER_IDLE;
nsecs_t standbyTime = systemTime();
size_t mixBufferSize = mFrameCount*mFrameSize;
SortedVector< sp<OutputTrack> > outputTracks;
uint32_t writeFrames = 0;
+ uint32_t activeSleepTime = activeSleepTimeUs();
+ uint32_t idleSleepTime = idleSleepTimeUs();
+ uint32_t sleepTime = idleSleepTime;
while (!exitPending())
{
processConfigEvents();
- enabledTracks = 0;
+ mixerStatus = MIXER_IDLE;
{ // scope for the mLock
Mutex::Autolock _l(mLock);
if (checkForNewParameters_l()) {
mixBufferSize = mFrameCount*mFrameSize;
- maxBufferRecoveryInUsecs = getMaxBufferRecoveryInUsecs();
+ activeSleepTime = activeSleepTimeUs();
+ idleSleepTime = idleSleepTimeUs();
}
const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
@@ -1997,22 +2018,26 @@
}
standbyTime = systemTime() + kStandbyTimeInNsecs;
- sleepTime = 1000;
+ sleepTime = idleSleepTime;
continue;
}
}
- enabledTracks = prepareTracks_l(activeTracks, &tracksToRemove);
+ mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
}
- if (LIKELY(enabledTracks)) {
+ if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
mAudioMixer->process(curBuf);
sleepTime = 0;
writeFrames = mFrameCount;
} else {
if (sleepTime == 0) {
- sleepTime = maxBufferRecoveryInUsecs;
+ if (mixerStatus == MIXER_TRACKS_ENABLED) {
+ sleepTime = activeSleepTime;
+ } else {
+ sleepTime = idleSleepTime;
+ }
} else if (mBytesWritten != 0) {
// flush remaining overflow buffers in output tracks
for (size_t i = 0; i < outputTracks.size(); i++) {
@@ -2026,7 +2051,7 @@
}
if (mSuspended) {
- sleepTime = maxBufferRecoveryInUsecs;
+ sleepTime = idleSleepTime;
}
// sleepTime == 0 means we must write to audio hardware
if (sleepTime == 0) {
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 22d15c9..594d878 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -361,6 +361,12 @@
DUPLICATING
};
+ enum mixer_state {
+ MIXER_IDLE,
+ MIXER_TRACKS_ENABLED,
+ MIXER_TRACKS_READY
+ };
+
// playback track
class Track : public TrackBase {
public:
@@ -530,7 +536,8 @@
virtual int getTrackName_l() = 0;
virtual void deleteTrackName_l(int name) = 0;
- virtual uint32_t getMaxBufferRecoveryInUsecs() = 0;
+ virtual uint32_t activeSleepTimeUs() = 0;
+ virtual uint32_t idleSleepTimeUs() = 0;
private:
@@ -562,7 +569,6 @@
int mNumWrites;
int mNumDelayedWrites;
bool mInWrite;
- int mMinBytesToWrite;
};
class MixerThread : public PlaybackThread {
@@ -582,10 +588,11 @@
virtual status_t dumpInternals(int fd, const Vector<String16>& args);
protected:
- size_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove);
+ uint32_t prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove);
virtual int getTrackName_l();
virtual void deleteTrackName_l(int name);
- virtual uint32_t getMaxBufferRecoveryInUsecs();
+ virtual uint32_t activeSleepTimeUs();
+ virtual uint32_t idleSleepTimeUs();
AudioMixer* mAudioMixer;
};
@@ -604,7 +611,8 @@
protected:
virtual int getTrackName_l();
virtual void deleteTrackName_l(int name);
- virtual uint32_t getMaxBufferRecoveryInUsecs();
+ virtual uint32_t activeSleepTimeUs();
+ virtual uint32_t idleSleepTimeUs();
private:
float mLeftVolume;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index d7daf73..2d4e10d 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -41,7 +41,7 @@
#include <sys/mman.h>
#include <sys/stat.h>
-#define BINDER_VM_SIZE (1*1024*1024)
+#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
static bool gSingleProcess = false;
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/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 8529a8e..cedd79d 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -318,26 +318,35 @@
}
if (android_atomic_or(1, &mActive) == 0) {
- audio_io_handle_t output = AudioTrack::getOutput();
+ audio_io_handle_t output = getOutput();
+ AudioSystem::startOutput(output, (AudioSystem::stream_type)mStreamType);
+ mNewPosition = mCblk->server + mUpdatePeriod;
+ mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+ mCblk->waitTimeMs = 0;
+ if (t != 0) {
+ t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
+ } else {
+ setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+ }
+
status_t status = mAudioTrack->start();
if (status == DEAD_OBJECT) {
LOGV("start() dead IAudioTrack: creating a new one");
status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
mFrameCount, mFlags, mSharedBuffer, output);
- }
- if (status == NO_ERROR) {
- AudioSystem::startOutput(output, (AudioSystem::stream_type)mStreamType);
mNewPosition = mCblk->server + mUpdatePeriod;
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
- if (t != 0) {
- t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
- } else {
- setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
- }
- } else {
+ }
+ if (status != NO_ERROR) {
LOGV("start() failed");
android_atomic_and(~1, &mActive);
+ if (t != 0) {
+ t->requestExit();
+ } else {
+ setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
+ }
+ AudioSystem::stopOutput(output, (AudioSystem::stream_type)mStreamType);
}
}
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);