summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-05-08 10:50:03 -0700
committerEric Laurent <elaurent@google.com>2015-05-08 13:23:51 -0700
commitf6870aefc5e31d4220f3778c4e79ff34a61f48ad (patch)
tree6943c86c7143ffc113d91b8ed7a34d75ab183434
parent70c75d8c15707d5eade38fe3e622f8500c29556b (diff)
downloadframeworks_av-f6870aefc5e31d4220f3778c4e79ff34a61f48ad.zip
frameworks_av-f6870aefc5e31d4220f3778c4e79ff34a61f48ad.tar.gz
frameworks_av-f6870aefc5e31d4220f3778c4e79ff34a61f48ad.tar.bz2
audio flinger: fix fuzz test crash
Clear output stream pointer in duplicating thread when the main output to which it is attached is closed. Also do not forward master mute and volume commands to duplicating threads as this is not applicable. Also fix logic in AudioFlinger::primaryPlaybackThread_l() that could accidentally return a duplicating thread. This never happens because the primary thread is always first in the list. Bug: 20731946. Change-Id: Ic8869699836920351b23d09544c50a258d3fb585
-rw-r--r--services/audioflinger/AudioFlinger.cpp22
-rw-r--r--services/audioflinger/Threads.cpp5
-rw-r--r--services/audioflinger/Threads.h2
3 files changed, 22 insertions, 7 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 485e320..93b1642 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -757,8 +757,12 @@ status_t AudioFlinger::setMasterVolume(float value)
// assigned to HALs which do not have master volume support will apply
// master volume during the mix operation. Threads with HALs which do
// support master volume will simply ignore the setting.
- for (size_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
+ continue;
+ }
mPlaybackThreads.valueAt(i)->setMasterVolume(value);
+ }
return NO_ERROR;
}
@@ -875,8 +879,12 @@ status_t AudioFlinger::setMasterMute(bool muted)
// assigned to HALs which do not have master mute support will apply master
// mute during the mix operation. Threads with HALs which do support master
// mute will simply ignore the setting.
- for (size_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
+ continue;
+ }
mPlaybackThreads.valueAt(i)->setMasterMute(muted);
+ }
return NO_ERROR;
}
@@ -1894,11 +1902,10 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
if (thread->type() == ThreadBase::MIXER) {
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- if (mPlaybackThreads.valueAt(i)->type() == ThreadBase::DUPLICATING) {
+ if (mPlaybackThreads.valueAt(i)->isDuplicating()) {
DuplicatingThread *dupThread =
(DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
dupThread->removeOutputTrack((MixerThread *)thread.get());
-
}
}
}
@@ -1927,7 +1934,7 @@ status_t AudioFlinger::closeOutput_nonvirtual(audio_io_handle_t output)
// The thread entity (active unit of execution) is no longer running here,
// but the ThreadBase container still exists.
- if (thread->type() != ThreadBase::DUPLICATING) {
+ if (!thread->isDuplicating()) {
closeOutputFinish(thread);
}
@@ -2375,6 +2382,9 @@ AudioFlinger::PlaybackThread *AudioFlinger::primaryPlaybackThread_l() const
{
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
+ if(thread->isDuplicating()) {
+ continue;
+ }
AudioStreamOut *output = thread->getOutput();
if (output != NULL && output->audioHwDev == mPrimaryHardwareDev) {
return thread;
@@ -2689,7 +2699,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId,
// Check whether the destination thread has a channel count of FCC_2, which is
// currently required for (most) effects. Prevent moving the effect chain here rather
// than disabling the addEffect_l() call in dstThread below.
- if ((dstThread->type() == ThreadBase::MIXER || dstThread->type() == ThreadBase::DUPLICATING) &&
+ if ((dstThread->type() == ThreadBase::MIXER || dstThread->isDuplicating()) &&
dstThread->mChannelCount != FCC_2) {
ALOGW("moveEffectChain_l() effect chain failed because"
" destination thread %p channel count(%u) != %u",
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2c4d801..f2af312 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5215,10 +5215,13 @@ void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
mOutputTracks[i]->destroy();
mOutputTracks.removeAt(i);
updateWaitTime_l();
+ if (thread->getOutput() == mOutput) {
+ mOutput = NULL;
+ }
return;
}
}
- ALOGV("removeOutputTrack(): unkonwn thread: %p", thread);
+ ALOGV("removeOutputTrack(): unknown thread: %p", thread);
}
// caller must hold mLock
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0a5597f..37bacae 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -230,6 +230,8 @@ public:
// static externally-visible
type_t type() const { return mType; }
+ bool isDuplicating() const { return (mType == DUPLICATING); }
+
audio_io_handle_t id() const { return mId;}
// dynamic externally-visible