summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornfullagar@google.com <nfullagar@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-25 00:22:52 +0000
committernfullagar@google.com <nfullagar@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-25 00:22:52 +0000
commit7b388d13ee6426d341a4543954318147b6eac17b (patch)
tree8f08504ed2f15c7a3b310eaad87e1276b655164e
parenta24e984c2214b9cf21748e4165ba49c5327caff1 (diff)
downloadchromium_src-7b388d13ee6426d341a4543954318147b6eac17b.zip
chromium_src-7b388d13ee6426d341a4543954318147b6eac17b.tar.gz
chromium_src-7b388d13ee6426d341a4543954318147b6eac17b.tar.bz2
Fix back-to-back StartPlayback/StopPlayback issue in PPAPI IPC proxy
where subsequent StartPlayback on the same audio device was not triggering audio callbacks. BUG=144037 TEST=updated test included Review URL: https://chromiumcodereview.appspot.com/10868034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153359 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ppapi/shared_impl/ppb_audio_shared.cc8
-rw-r--r--ppapi/tests/test_audio.cc69
-rw-r--r--ppapi/tests/test_audio.h1
3 files changed, 74 insertions, 4 deletions
diff --git a/ppapi/shared_impl/ppb_audio_shared.cc b/ppapi/shared_impl/ppb_audio_shared.cc
index 5cf3002..d131bb3 100644
--- a/ppapi/shared_impl/ppb_audio_shared.cc
+++ b/ppapi/shared_impl/ppb_audio_shared.cc
@@ -29,6 +29,9 @@ PPB_Audio_Shared::PPB_Audio_Shared()
}
PPB_Audio_Shared::~PPB_Audio_Shared() {
+ // Shut down the socket to escape any hanging |Receive|s.
+ if (socket_.get())
+ socket_->Shutdown();
StopThread();
}
@@ -105,10 +108,7 @@ void PPB_Audio_Shared::StartThread() {
}
void PPB_Audio_Shared::StopThread() {
- // Shut down the socket to escape any hanging |Receive|s.
- if (socket_.get())
- socket_->Shutdown();
- #if !defined(OS_NACL)
+#if !defined(OS_NACL)
if (audio_thread_.get()) {
audio_thread_->Join();
audio_thread_.reset();
diff --git a/ppapi/tests/test_audio.cc b/ppapi/tests/test_audio.cc
index a718274..0f70156 100644
--- a/ppapi/tests/test_audio.cc
+++ b/ppapi/tests/test_audio.cc
@@ -46,6 +46,7 @@ void TestAudio::RunTests(const std::string& filter) {
RUN_TEST(Failures, filter);
RUN_TEST(AudioCallback1, filter);
RUN_TEST(AudioCallback2, filter);
+ RUN_TEST(AudioCallback3, filter);
}
// Test creating audio resources for all guaranteed sample rates and various
@@ -286,6 +287,74 @@ std::string TestAudio::TestAudioCallback2() {
PASS();
}
+// This is the same as |TestAudioCallback1()|, except that it attempts a second
+// round of |StartPlayback| and |StopPlayback| to make sure the callback
+// function still responds when using the same audio resource.
+std::string TestAudio::TestAudioCallback3() {
+ const PP_AudioSampleRate kSampleRate = PP_AUDIOSAMPLERATE_44100;
+ const uint32_t kRequestFrameCount = 1024;
+
+ uint32_t frame_count = audio_config_interface_->RecommendSampleFrameCount(
+ instance_->pp_instance(), kSampleRate, kRequestFrameCount);
+ PP_Resource ac = audio_config_interface_->CreateStereo16Bit(
+ instance_->pp_instance(), kSampleRate, frame_count);
+ ASSERT_TRUE(ac);
+ audio_callback_method_ = NULL;
+ PP_Resource audio = audio_interface_->Create(
+ instance_->pp_instance(), ac, AudioCallbackTrampoline, this);
+ core_interface_->ReleaseResource(ac);
+ ac = 0;
+
+ // |AudioCallbackTest()| calls |test_callback_|, sleeps a bit, then sets
+ // |test_done_|.
+ TestCompletionCallback test_callback_1(instance_->pp_instance());
+ test_callback_ = static_cast<pp::CompletionCallback>(
+ test_callback_1).pp_completion_callback();
+ test_done_ = false;
+ callback_fired_ = false;
+
+ audio_callback_method_ = &TestAudio::AudioCallbackTest;
+ ASSERT_TRUE(audio_interface_->StartPlayback(audio));
+
+ // Wait for the audio callback to be called.
+ test_callback_1.WaitForResult();
+ ASSERT_EQ(kMagicValue, test_callback_1.result());
+
+ ASSERT_TRUE(audio_interface_->StopPlayback(audio));
+
+ // |StopPlayback()| should wait for the audio callback to finish.
+ ASSERT_TRUE(callback_fired_);
+
+ TestCompletionCallback test_callback_2(instance_->pp_instance());
+ test_callback_ = static_cast<pp::CompletionCallback>(
+ test_callback_2).pp_completion_callback();
+
+ // Repeat one more |StartPlayback| & |StopPlayback| cycle, and verify again
+ // that the callback function was invoked.
+ callback_fired_ = false;
+ ASSERT_TRUE(audio_interface_->StartPlayback(audio));
+
+ // Wait for the audio callback to be called.
+ test_callback_2.WaitForResult();
+ ASSERT_EQ(kMagicValue, test_callback_2.result());
+
+ ASSERT_TRUE(audio_interface_->StopPlayback(audio));
+
+ // |StopPlayback()| should wait for the audio callback to finish.
+ ASSERT_TRUE(callback_fired_);
+
+ test_done_ = true;
+
+ // If any more audio callbacks are generated, we should crash (which is good).
+ audio_callback_method_ = NULL;
+ test_callback_ = PP_CompletionCallback();
+
+ core_interface_->ReleaseResource(audio);
+
+ PASS();
+}
+
+
// TODO(raymes): Test that actually playback happens correctly, etc.
static void Crash() {
diff --git a/ppapi/tests/test_audio.h b/ppapi/tests/test_audio.h
index 811fb0d..9554661 100644
--- a/ppapi/tests/test_audio.h
+++ b/ppapi/tests/test_audio.h
@@ -27,6 +27,7 @@ class TestAudio : public TestCase {
std::string TestFailures();
std::string TestAudioCallback1();
std::string TestAudioCallback2();
+ std::string TestAudioCallback3();
// Calls |audio_callback_method_| (where |user_data| is "this").
static void AudioCallbackTrampoline(void* sample_buffer,