diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-11 12:11:56 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-11 12:11:56 -0700 |
commit | bcef13b666c7459241235bc6209837ae81884d2f (patch) | |
tree | a1313bb849f73fd1b62d221f60196fe8fd44edf5 | |
parent | 22f8defddca562244d43611d99ce76c3ae65a73e (diff) | |
download | frameworks_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.cpp | 81 | ||||
-rw-r--r-- | libs/audioflinger/AudioFlinger.h | 11 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 18 | ||||
-rw-r--r-- | libs/utils/String16.cpp | 20 |
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; |