summaryrefslogtreecommitdiffstats
path: root/media/libmedia/ToneGenerator.cpp
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2009-07-09 01:56:20 -0700
committerEric Laurent <elaurent@google.com>2009-07-09 01:56:20 -0700
commitc38bb0614dc0b5dee682b9a1de47de5ae7d215d8 (patch)
treea4c3a62dd99209982f673410f1b8123ff91b8094 /media/libmedia/ToneGenerator.cpp
parent573266210fb2b2e7d86fbd46d0dfe16763611d91 (diff)
downloadframeworks_av-c38bb0614dc0b5dee682b9a1de47de5ae7d215d8.zip
frameworks_av-c38bb0614dc0b5dee682b9a1de47de5ae7d215d8.tar.gz
frameworks_av-c38bb0614dc0b5dee682b9a1de47de5ae7d215d8.tar.bz2
Fix issue 1946033: dialer deadlocks and/or ANRs when using dialpad in-call
The cause is very likely that the WaveGenerator *lpWaveGen returned by lpToneGen->mWaveGens.valueFor(lFrequency) just before calling lpWaveGen->getSamples(lpOut, lGenSmp, lWaveCmd) is invalid. The frequency lFrequency is not part of the frequencies in mWaveGens. This can happen if a different tone is started while the callback function is active: The state is changed to TONE_RESTARTING and the call to prepareWave() at line 1226 will change the tone descriptor pointed to by mpToneDesc as well as the content of mWaveGens. However, mpToneDesc was cached in a local variable lpToneDesc when entering the callback and is not reloaded when exiting prepareWave(). This causes a mismatch between the tone frequencies listed in lpToneDesc and the frequencies present in mWaveGens. This regression was introduced in change 973 when mpToneDesc was cached in a local variable.
Diffstat (limited to 'media/libmedia/ToneGenerator.cpp')
-rw-r--r--media/libmedia/ToneGenerator.cpp2
1 files changed, 2 insertions, 0 deletions
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index c22cd53..5435da7 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -1225,6 +1225,8 @@ audioCallback_EndLoop:
LOGV("Cbk restarting track\n");
if (lpToneGen->prepareWave()) {
lpToneGen->mState = TONE_STARTING;
+ // must reload lpToneDesc as prepareWave() may change mpToneDesc
+ lpToneDesc = lpToneGen->mpToneDesc;
} else {
LOGW("Cbk restarting prepareWave() failed\n");
lpToneGen->mState = TONE_IDLE;