summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-11 12:11:56 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-11 12:11:56 -0700
commitbcef13b666c7459241235bc6209837ae81884d2f (patch)
treea1313bb849f73fd1b62d221f60196fe8fd44edf5
parent22f8defddca562244d43611d99ce76c3ae65a73e (diff)
downloadframeworks_native-bcef13b666c7459241235bc6209837ae81884d2f.zip
frameworks_native-bcef13b666c7459241235bc6209837ae81884d2f.tar.gz
frameworks_native-bcef13b666c7459241235bc6209837ae81884d2f.tar.bz2
auto import from //branches/cupcake/...@137873
-rw-r--r--libs/audioflinger/AudioFlinger.cpp81
-rw-r--r--libs/audioflinger/AudioFlinger.h11
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp18
-rw-r--r--libs/utils/String16.cpp20
4 files changed, 112 insertions, 18 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 440778d..57a53bd 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -119,7 +119,8 @@ static bool settingsAllowed() {
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
- mForcedSpeakerCount(0), mForcedRoute(0), mRouteRestoreTime(0), mMusicMuteSaved(false)
+ mForcedSpeakerCount(0), mA2dpDisableCount(0), mA2dpSuppressed(false), mForcedRoute(0),
+ mRouteRestoreTime(0), mMusicMuteSaved(false)
{
mHardwareStatus = AUDIO_HW_IDLE;
mAudioHardware = AudioHardwareInterface::create();
@@ -166,7 +167,7 @@ AudioFlinger::AudioFlinger()
setMasterMute(false);
// Start record thread
- mAudioRecordThread = new AudioRecordThread(mAudioHardware);
+ mAudioRecordThread = new AudioRecordThread(mAudioHardware, this);
if (mAudioRecordThread != 0) {
mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);
}
@@ -242,6 +243,12 @@ bool AudioFlinger::streamForcedToSpeaker(int streamType)
streamType == AudioSystem::NOTIFICATION);
}
+bool AudioFlinger::streamDisablesA2dp(int streamType)
+{
+ return (streamType == AudioSystem::VOICE_CALL ||
+ streamType == AudioSystem::BLUETOOTH_SCO);
+}
+
status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -482,7 +489,11 @@ status_t AudioFlinger::setRouting(int mode, uint32_t routes, uint32_t mask)
if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
enableA2dp = true;
}
- setA2dpEnabled_l(enableA2dp);
+ if (mA2dpDisableCount > 0) {
+ mA2dpSuppressed = enableA2dp;
+ } else {
+ setA2dpEnabled_l(enableA2dp);
+ }
LOGV("setOutput done\n");
}
#endif
@@ -798,9 +809,9 @@ void AudioFlinger::handleForcedSpeakerRoute(int command)
if (--mForcedSpeakerCount == 0) {
mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
}
- LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
+ LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
} else {
- LOGE("mForcedSpeakerCount is already zero");
+ LOGE("mForcedSpeakerCount is already zero");
}
}
break;
@@ -825,6 +836,41 @@ void AudioFlinger::handleForcedSpeakerRoute(int command)
}
}
+#ifdef WITH_A2DP
+void AudioFlinger::handleStreamDisablesA2dp(int command)
+{
+ switch(command) {
+ case ACTIVE_TRACK_ADDED:
+ {
+ AutoMutex lock(mHardwareLock);
+ if (mA2dpDisableCount++ == 0) {
+ if (mA2dpEnabled) {
+ setA2dpEnabled_l(false);
+ mA2dpSuppressed = true;
+ }
+ }
+ LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
+ }
+ break;
+ case ACTIVE_TRACK_REMOVED:
+ {
+ AutoMutex lock(mHardwareLock);
+ if (mA2dpDisableCount > 0){
+ if (--mA2dpDisableCount == 0) {
+ if (mA2dpSuppressed) {
+ setA2dpEnabled_l(true);
+ mA2dpSuppressed = false;
+ }
+ }
+ LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
+ } else {
+ LOGE("mA2dpDisableCount is already zero");
+ }
+ }
+ break;
+ }
+}
+#endif
// ----------------------------------------------------------------------------
@@ -1455,6 +1501,11 @@ void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
if (streamForcedToSpeaker(track->type())) {
mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
}
+#ifdef WITH_A2DP
+ if (streamDisablesA2dp(track->type())) {
+ mAudioFlinger->handleStreamDisablesA2dp(ACTIVE_TRACK_ADDED);
+ }
+#endif
}
}
@@ -1472,6 +1523,11 @@ void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
if (streamForcedToSpeaker(track->type())) {
mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
}
+#ifdef WITH_A2DP
+ if (streamDisablesA2dp(track->type())) {
+ mAudioFlinger->handleStreamDisablesA2dp(ACTIVE_TRACK_REMOVED);
+ }
+#endif
}
}
@@ -2311,8 +2367,10 @@ status_t AudioFlinger::RecordHandle::onTransact(
// ----------------------------------------------------------------------------
-AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
+AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware,
+ const sp<AudioFlinger>& audioFlinger) :
mAudioHardware(audioHardware),
+ mAudioFlinger(audioFlinger),
mActive(false)
{
}
@@ -2417,6 +2475,12 @@ status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* record
mRecordTrack = recordTrack;
+#ifdef WITH_A2DP
+ if (streamDisablesA2dp(recordTrack->type())) {
+ mAudioFlinger->handleStreamDisablesA2dp(ACTIVE_TRACK_ADDED);
+ }
+#endif
+
// signal thread to start
LOGV("Signal record thread");
mWaitWorkCV.signal();
@@ -2429,6 +2493,11 @@ void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack
LOGV("AudioRecordThread::stop");
AutoMutex lock(&mLock);
if (mActive && (recordTrack == mRecordTrack.get())) {
+#ifdef WITH_A2DP
+ if (streamDisablesA2dp(recordTrack->type())) {
+ mAudioFlinger->handleStreamDisablesA2dp(ACTIVE_TRACK_REMOVED);
+ }
+#endif
mActive = false;
mStopped.wait(mLock);
}
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index c505336..596e7f3 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -165,6 +165,7 @@ private:
void checkA2dpEnabledChange_l();
#endif
static bool streamForcedToSpeaker(int streamType);
+ static bool streamDisablesA2dp(int streamType);
// Management of forced route to speaker for certain track types.
enum force_speaker_command {
@@ -174,6 +175,9 @@ private:
FORCE_ROUTE_RESTORE
};
void handleForcedSpeakerRoute(int command);
+#ifdef WITH_A2DP
+ void handleStreamDisablesA2dp(int command);
+#endif
// Internal dump utilites.
status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
@@ -576,7 +580,7 @@ private:
class AudioRecordThread : public Thread
{
public:
- AudioRecordThread(AudioHardwareInterface* audioHardware);
+ AudioRecordThread(AudioHardwareInterface* audioHardware, const sp<AudioFlinger>& audioFlinger);
virtual ~AudioRecordThread();
virtual bool threadLoop();
virtual status_t readyToRun() { return NO_ERROR; }
@@ -590,6 +594,7 @@ private:
private:
AudioRecordThread();
AudioHardwareInterface *mAudioHardware;
+ sp<AudioFlinger> mAudioFlinger;
sp<MixerThread::RecordTrack> mRecordTrack;
Mutex mLock;
Condition mWaitWorkCV;
@@ -620,6 +625,10 @@ private:
mutable int mHardwareStatus;
SortedVector< wp<IBinder> > mNotificationClients;
int mForcedSpeakerCount;
+ int mA2dpDisableCount;
+
+ // true if A2DP should resume when mA2dpDisableCount returns to zero
+ bool mA2dpSuppressed;
uint32_t mSavedRoute;
uint32_t mForcedRoute;
nsecs_t mRouteRestoreTime;
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 900282a..d915a84 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -179,6 +179,7 @@ SurfaceFlinger::SurfaceFlinger()
mDeferReleaseConsole(false),
mFreezeDisplay(false),
mFreezeCount(0),
+ mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugCpu(0),
mDebugFps(0),
@@ -467,16 +468,24 @@ void SurfaceFlinger::waitForEvent()
// wait for something to do
if (UNLIKELY(isFrozen())) {
// wait 5 seconds
- int err = mSyncObject.wait(ms2ns(5000));
+ const nsecs_t freezeDisplayTimeout = ms2ns(5000);
+ const nsecs_t now = systemTime();
+ if (mFreezeDisplayTime == 0) {
+ mFreezeDisplayTime = now;
+ }
+ nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
+ int err = (waitTime > 0) ? mSyncObject.wait(waitTime) : TIMED_OUT;
if (err != NO_ERROR) {
if (isFrozen()) {
// we timed out and are still frozen
LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
mFreezeDisplay, mFreezeCount);
mFreezeCount = 0;
+ mFreezeDisplay = false;
}
}
} else {
+ mFreezeDisplayTime = 0;
mSyncObject.wait();
}
}
@@ -671,13 +680,6 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
// freezing or unfreezing the display -> trigger animation if needed
mFreezeDisplay = mCurrentState.freezeDisplay;
- const nsecs_t now = systemTime();
- if (mFreezeDisplay) {
- mFreezeDisplayTime = now;
- } else {
- //LOGD("Screen was frozen for %llu us",
- // ns2us(now-mFreezeDisplayTime));
- }
}
// some layers might have been removed, so
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index ae0ae1e..aef67f2 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -244,7 +244,6 @@ void terminate_string16()
// ---------------------------------------------------------------------------
-// Note: not dealing with generating surrogate pairs.
static char16_t* allocFromUTF8(const char* in, size_t len)
{
if (len == 0) return getEmptyString();
@@ -255,7 +254,10 @@ static char16_t* allocFromUTF8(const char* in, size_t len)
while (p < end) {
chars++;
- p += utf8_char_len(*p);
+ int utf8len = utf8_char_len(*p);
+ uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, utf8len);
+ if (codepoint > 0xFFFF) chars++; // this will be a surrogate pair in utf16
+ p += utf8len;
}
SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
@@ -265,7 +267,19 @@ static char16_t* allocFromUTF8(const char* in, size_t len)
char16_t* d = str;
while (p < end) {
size_t len = utf8_char_len(*p);
- *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
+ uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, len);
+
+ // Convert the UTF32 codepoint to one or more UTF16 codepoints
+ if (codepoint <= 0xFFFF) {
+ // Single UTF16 character
+ *d++ = (char16_t) codepoint;
+ } else {
+ // Multiple UTF16 characters with surrogates
+ codepoint = codepoint - 0x10000;
+ *d++ = (char16_t) ((codepoint >> 10) + 0xD800);
+ *d++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+ }
+
p += len;
}
*d = 0;